Thu, 31 Aug 2017 15:18:52 +0800
merge
aoqi@0 | 1 | /* |
aoqi@0 | 2 | * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. |
aoqi@0 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
aoqi@0 | 4 | * |
aoqi@0 | 5 | * This code is free software; you can redistribute it and/or modify it |
aoqi@0 | 6 | * under the terms of the GNU General Public License version 2 only, as |
aoqi@0 | 7 | * published by the Free Software Foundation. Oracle designates this |
aoqi@0 | 8 | * particular file as subject to the "Classpath" exception as provided |
aoqi@0 | 9 | * by Oracle in the LICENSE file that accompanied this code. |
aoqi@0 | 10 | * |
aoqi@0 | 11 | * This code is distributed in the hope that it will be useful, but WITHOUT |
aoqi@0 | 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
aoqi@0 | 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
aoqi@0 | 14 | * version 2 for more details (a copy is included in the LICENSE file that |
aoqi@0 | 15 | * accompanied this code). |
aoqi@0 | 16 | * |
aoqi@0 | 17 | * You should have received a copy of the GNU General Public License version |
aoqi@0 | 18 | * 2 along with this work; if not, write to the Free Software Foundation, |
aoqi@0 | 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
aoqi@0 | 20 | * |
aoqi@0 | 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
aoqi@0 | 22 | * or visit www.oracle.com if you need additional information or have any |
aoqi@0 | 23 | * questions. |
aoqi@0 | 24 | */ |
aoqi@0 | 25 | |
aoqi@0 | 26 | package com.sun.xml.internal.ws.model; |
aoqi@0 | 27 | |
aoqi@0 | 28 | import com.oracle.xmlns.internal.webservices.jaxws_databinding.JavaMethod; |
aoqi@0 | 29 | import com.oracle.xmlns.internal.webservices.jaxws_databinding.JavaParam; |
aoqi@0 | 30 | import com.oracle.xmlns.internal.webservices.jaxws_databinding.JavaWsdlMappingType; |
aoqi@0 | 31 | import com.oracle.xmlns.internal.webservices.jaxws_databinding.ObjectFactory; |
aoqi@0 | 32 | import com.sun.xml.internal.bind.api.JAXBRIContext; |
aoqi@0 | 33 | import com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil; |
aoqi@0 | 34 | import com.sun.xml.internal.ws.util.xml.XmlUtil; |
aoqi@0 | 35 | import org.w3c.dom.Element; |
aoqi@0 | 36 | import org.xml.sax.SAXException; |
aoqi@0 | 37 | |
aoqi@0 | 38 | import javax.xml.bind.JAXBContext; |
aoqi@0 | 39 | import javax.xml.bind.JAXBElement; |
aoqi@0 | 40 | import javax.xml.bind.JAXBException; |
aoqi@0 | 41 | import javax.xml.bind.Unmarshaller; |
aoqi@0 | 42 | import javax.xml.bind.util.JAXBResult; |
aoqi@0 | 43 | import javax.xml.stream.XMLInputFactory; |
aoqi@0 | 44 | import javax.xml.stream.XMLStreamException; |
aoqi@0 | 45 | import javax.xml.stream.XMLStreamReader; |
aoqi@0 | 46 | import javax.xml.transform.Source; |
aoqi@0 | 47 | import javax.xml.transform.Transformer; |
aoqi@0 | 48 | import javax.xml.transform.TransformerException; |
aoqi@0 | 49 | import javax.xml.transform.TransformerFactory; |
aoqi@0 | 50 | import javax.xml.transform.stream.StreamSource; |
aoqi@0 | 51 | import javax.xml.validation.Schema; |
aoqi@0 | 52 | import javax.xml.validation.SchemaFactory; |
aoqi@0 | 53 | import java.io.*; |
aoqi@0 | 54 | import java.lang.annotation.Annotation; |
aoqi@0 | 55 | import java.lang.reflect.Method; |
aoqi@0 | 56 | import java.net.URL; |
aoqi@0 | 57 | import java.util.*; |
aoqi@0 | 58 | |
aoqi@0 | 59 | import static com.oracle.xmlns.internal.webservices.jaxws_databinding.ExistingAnnotationsType.MERGE; |
aoqi@0 | 60 | |
aoqi@0 | 61 | /** |
aoqi@0 | 62 | * Metadata Reader able to read from either class annotations or external metadata files or combine both, |
aoqi@0 | 63 | * depending on configuration provided in xml file itself. |
aoqi@0 | 64 | * |
aoqi@0 | 65 | * @author shih-chang.chen@oracle.com, miroslav.kos@oracle.com |
aoqi@0 | 66 | */ |
aoqi@0 | 67 | public class ExternalMetadataReader extends ReflectAnnotationReader { |
aoqi@0 | 68 | |
aoqi@0 | 69 | private static final String NAMESPACE_WEBLOGIC_WSEE_DATABINDING = "http://xmlns.oracle.com/weblogic/weblogic-wsee-databinding"; |
aoqi@0 | 70 | private static final String NAMESPACE_JAXWS_RI_EXTERNAL_METADATA = "http://xmlns.oracle.com/webservices/jaxws-databinding"; |
aoqi@0 | 71 | |
aoqi@0 | 72 | /** |
aoqi@0 | 73 | * map of readers for defined java types |
aoqi@0 | 74 | */ |
aoqi@0 | 75 | private Map<String, JavaWsdlMappingType> readers = new HashMap<String, JavaWsdlMappingType>(); |
aoqi@0 | 76 | |
aoqi@0 | 77 | public ExternalMetadataReader(Collection<File> files, Collection<String> resourcePaths, ClassLoader classLoader, |
aoqi@0 | 78 | boolean xsdValidation, boolean disableXmlSecurity) { |
aoqi@0 | 79 | |
aoqi@0 | 80 | if (files != null) { |
aoqi@0 | 81 | for (File file : files) { |
aoqi@0 | 82 | try { |
aoqi@0 | 83 | String namespace = Util.documentRootNamespace(newSource(file), disableXmlSecurity); |
aoqi@0 | 84 | JavaWsdlMappingType externalMapping = parseMetadata(xsdValidation, newSource(file), namespace, disableXmlSecurity); |
aoqi@0 | 85 | readers.put(externalMapping.getJavaTypeName(), externalMapping); |
aoqi@0 | 86 | } catch (Exception e) { |
aoqi@0 | 87 | throw new RuntimeModelerException("runtime.modeler.external.metadata.unable.to.read", file.getAbsolutePath()); |
aoqi@0 | 88 | } |
aoqi@0 | 89 | } |
aoqi@0 | 90 | } |
aoqi@0 | 91 | |
aoqi@0 | 92 | if (resourcePaths != null) { |
aoqi@0 | 93 | for (String resourcePath : resourcePaths) { |
aoqi@0 | 94 | try { |
aoqi@0 | 95 | String namespace = Util.documentRootNamespace(newSource(resourcePath, classLoader), disableXmlSecurity); |
aoqi@0 | 96 | JavaWsdlMappingType externalMapping = parseMetadata(xsdValidation, newSource(resourcePath, classLoader), namespace, disableXmlSecurity); |
aoqi@0 | 97 | readers.put(externalMapping.getJavaTypeName(), externalMapping); |
aoqi@0 | 98 | } catch (Exception e) { |
aoqi@0 | 99 | throw new RuntimeModelerException("runtime.modeler.external.metadata.unable.to.read", resourcePath); |
aoqi@0 | 100 | } |
aoqi@0 | 101 | } |
aoqi@0 | 102 | } |
aoqi@0 | 103 | } |
aoqi@0 | 104 | |
aoqi@0 | 105 | private StreamSource newSource(String resourcePath, ClassLoader classLoader) { |
aoqi@0 | 106 | InputStream is = classLoader.getResourceAsStream(resourcePath); |
aoqi@0 | 107 | return new StreamSource(is); |
aoqi@0 | 108 | } |
aoqi@0 | 109 | |
aoqi@0 | 110 | private JavaWsdlMappingType parseMetadata(boolean xsdValidation, StreamSource source, String namespace, boolean disableXmlSecurity) throws JAXBException, IOException, TransformerException { |
aoqi@0 | 111 | if (NAMESPACE_WEBLOGIC_WSEE_DATABINDING.equals(namespace)) { |
aoqi@0 | 112 | return Util.transformAndRead(source, disableXmlSecurity); |
aoqi@0 | 113 | } if (NAMESPACE_JAXWS_RI_EXTERNAL_METADATA.equals(namespace)) { |
aoqi@0 | 114 | return Util.read(source, xsdValidation, disableXmlSecurity); |
aoqi@0 | 115 | } else { |
aoqi@0 | 116 | throw new RuntimeModelerException("runtime.modeler.external.metadata.unsupported.schema", namespace, Arrays.asList(NAMESPACE_WEBLOGIC_WSEE_DATABINDING, NAMESPACE_JAXWS_RI_EXTERNAL_METADATA).toString()); |
aoqi@0 | 117 | } |
aoqi@0 | 118 | } |
aoqi@0 | 119 | |
aoqi@0 | 120 | private StreamSource newSource(File file) { |
aoqi@0 | 121 | try { |
aoqi@0 | 122 | return new StreamSource(new FileInputStream(file)); |
aoqi@0 | 123 | } catch (FileNotFoundException e) { |
aoqi@0 | 124 | throw new RuntimeModelerException("runtime.modeler.external.metadata.unable.to.read", file.getAbsolutePath()); |
aoqi@0 | 125 | } |
aoqi@0 | 126 | } |
aoqi@0 | 127 | |
aoqi@0 | 128 | public <A extends Annotation> A getAnnotation(Class<A> annType, Class<?> cls) { |
aoqi@0 | 129 | JavaWsdlMappingType r = reader(cls); |
aoqi@0 | 130 | return r == null ? super.getAnnotation(annType, cls) : Util.annotation(r, annType); |
aoqi@0 | 131 | } |
aoqi@0 | 132 | |
aoqi@0 | 133 | private JavaWsdlMappingType reader(Class<?> cls) { |
aoqi@0 | 134 | return readers.get(cls.getName()); |
aoqi@0 | 135 | } |
aoqi@0 | 136 | |
aoqi@0 | 137 | Annotation[] getAnnotations(List<Object> objects) { |
aoqi@0 | 138 | ArrayList<Annotation> list = new ArrayList<Annotation>(); |
aoqi@0 | 139 | for (Object a : objects) { |
aoqi@0 | 140 | if (Annotation.class.isInstance(a)) { |
aoqi@0 | 141 | list.add(Annotation.class.cast(a)); |
aoqi@0 | 142 | } |
aoqi@0 | 143 | } |
aoqi@0 | 144 | return list.toArray(new Annotation[list.size()]); |
aoqi@0 | 145 | } |
aoqi@0 | 146 | |
aoqi@0 | 147 | public Annotation[] getAnnotations(final Class<?> c) { |
aoqi@0 | 148 | |
aoqi@0 | 149 | Merger<Annotation[]> merger = new Merger<Annotation[]>(reader(c)) { |
aoqi@0 | 150 | Annotation[] reflection() { |
aoqi@0 | 151 | return ExternalMetadataReader.super.getAnnotations(c); |
aoqi@0 | 152 | } |
aoqi@0 | 153 | |
aoqi@0 | 154 | Annotation[] external() { |
aoqi@0 | 155 | return getAnnotations(reader.getClassAnnotation()); |
aoqi@0 | 156 | } |
aoqi@0 | 157 | }; |
aoqi@0 | 158 | return merger.merge(); |
aoqi@0 | 159 | } |
aoqi@0 | 160 | |
aoqi@0 | 161 | public Annotation[] getAnnotations(final Method m) { |
aoqi@0 | 162 | Merger<Annotation[]> merger = new Merger<Annotation[]>(reader(m.getDeclaringClass())) { |
aoqi@0 | 163 | Annotation[] reflection() { |
aoqi@0 | 164 | return ExternalMetadataReader.super.getAnnotations(m); |
aoqi@0 | 165 | } |
aoqi@0 | 166 | |
aoqi@0 | 167 | Annotation[] external() { |
aoqi@0 | 168 | JavaMethod jm = getJavaMethod(m, reader); |
aoqi@0 | 169 | return (jm == null) ? new Annotation[0] : getAnnotations(jm.getMethodAnnotation()); |
aoqi@0 | 170 | } |
aoqi@0 | 171 | }; |
aoqi@0 | 172 | return merger.merge(); |
aoqi@0 | 173 | } |
aoqi@0 | 174 | |
aoqi@0 | 175 | @SuppressWarnings("unchecked") |
aoqi@0 | 176 | public <A extends Annotation> A getAnnotation(final Class<A> annType, final Method m) { |
aoqi@0 | 177 | Merger<Annotation> merger = new Merger<Annotation>(reader(m.getDeclaringClass())) { |
aoqi@0 | 178 | Annotation reflection() { |
aoqi@0 | 179 | return ExternalMetadataReader.super.getAnnotation(annType, m); |
aoqi@0 | 180 | } |
aoqi@0 | 181 | |
aoqi@0 | 182 | Annotation external() { |
aoqi@0 | 183 | JavaMethod jm = getJavaMethod(m, reader); |
aoqi@0 | 184 | return Util.annotation(jm, annType); |
aoqi@0 | 185 | } |
aoqi@0 | 186 | }; |
aoqi@0 | 187 | return (A) merger.merge(); |
aoqi@0 | 188 | } |
aoqi@0 | 189 | |
aoqi@0 | 190 | public Annotation[][] getParameterAnnotations(final Method m) { |
aoqi@0 | 191 | Merger<Annotation[][]> merger = new Merger<Annotation[][]>(reader(m.getDeclaringClass())) { |
aoqi@0 | 192 | Annotation[][] reflection() { |
aoqi@0 | 193 | return ExternalMetadataReader.super.getParameterAnnotations(m); |
aoqi@0 | 194 | } |
aoqi@0 | 195 | |
aoqi@0 | 196 | Annotation[][] external() { |
aoqi@0 | 197 | JavaMethod jm = getJavaMethod(m, reader); |
aoqi@0 | 198 | Annotation[][] a = m.getParameterAnnotations(); |
aoqi@0 | 199 | for (int i = 0; i < m.getParameterTypes().length; i++) { |
aoqi@0 | 200 | if (jm == null) continue; |
aoqi@0 | 201 | JavaParam jp = jm.getJavaParams().getJavaParam().get(i); |
aoqi@0 | 202 | a[i] = getAnnotations(jp.getParamAnnotation()); |
aoqi@0 | 203 | } |
aoqi@0 | 204 | return a; |
aoqi@0 | 205 | } |
aoqi@0 | 206 | }; |
aoqi@0 | 207 | return merger.merge(); |
aoqi@0 | 208 | } |
aoqi@0 | 209 | |
aoqi@0 | 210 | public void getProperties(final Map<String, Object> prop, final Class<?> cls) { |
aoqi@0 | 211 | |
aoqi@0 | 212 | JavaWsdlMappingType r = reader(cls); |
aoqi@0 | 213 | |
aoqi@0 | 214 | // no external reader or it requires annotations merging ... |
aoqi@0 | 215 | if (r == null || MERGE.equals(r.getExistingAnnotations())) { |
aoqi@0 | 216 | super.getProperties(prop, cls); |
aoqi@0 | 217 | } |
aoqi@0 | 218 | |
aoqi@0 | 219 | } |
aoqi@0 | 220 | |
aoqi@0 | 221 | public void getProperties(final Map<String, Object> prop, final Method m) { |
aoqi@0 | 222 | |
aoqi@0 | 223 | JavaWsdlMappingType r = reader(m.getDeclaringClass()); |
aoqi@0 | 224 | |
aoqi@0 | 225 | // no external reader or it requires annotations merging ... |
aoqi@0 | 226 | if (r == null || MERGE.equals(r.getExistingAnnotations())) { |
aoqi@0 | 227 | super.getProperties(prop, m); |
aoqi@0 | 228 | } |
aoqi@0 | 229 | |
aoqi@0 | 230 | if (r != null) { |
aoqi@0 | 231 | JavaMethod jm = getJavaMethod(m, r); |
aoqi@0 | 232 | Element[] e = Util.annotation(jm); |
aoqi@0 | 233 | prop.put("eclipselink-oxm-xml.xml-element", findXmlElement(e)); |
aoqi@0 | 234 | } |
aoqi@0 | 235 | |
aoqi@0 | 236 | } |
aoqi@0 | 237 | |
aoqi@0 | 238 | public void getProperties(final Map<String, Object> prop, final Method m, int pos) { |
aoqi@0 | 239 | |
aoqi@0 | 240 | JavaWsdlMappingType r = reader(m.getDeclaringClass()); |
aoqi@0 | 241 | |
aoqi@0 | 242 | // no external reader or it requires annotations merging ... |
aoqi@0 | 243 | if (r == null || MERGE.equals(r.getExistingAnnotations())) { |
aoqi@0 | 244 | super.getProperties(prop, m, pos); |
aoqi@0 | 245 | } |
aoqi@0 | 246 | |
aoqi@0 | 247 | if (r != null) { |
aoqi@0 | 248 | JavaMethod jm = getJavaMethod(m, r); |
aoqi@0 | 249 | if (jm == null) return; |
aoqi@0 | 250 | JavaParam jp = jm.getJavaParams().getJavaParam().get(pos); |
aoqi@0 | 251 | Element[] e = Util.annotation(jp); |
aoqi@0 | 252 | prop.put("eclipselink-oxm-xml.xml-element", findXmlElement(e)); |
aoqi@0 | 253 | } |
aoqi@0 | 254 | } |
aoqi@0 | 255 | |
aoqi@0 | 256 | JavaMethod getJavaMethod(Method method, JavaWsdlMappingType r) { |
aoqi@0 | 257 | |
aoqi@0 | 258 | JavaWsdlMappingType.JavaMethods javaMethods = r.getJavaMethods(); |
aoqi@0 | 259 | if (javaMethods == null) { |
aoqi@0 | 260 | return null; |
aoqi@0 | 261 | } |
aoqi@0 | 262 | |
aoqi@0 | 263 | List<JavaMethod> sameName = new ArrayList<JavaMethod>(); |
aoqi@0 | 264 | for (JavaMethod jm : javaMethods.getJavaMethod()) { |
aoqi@0 | 265 | if (method.getName().equals(jm.getName())) { |
aoqi@0 | 266 | sameName.add(jm); |
aoqi@0 | 267 | } |
aoqi@0 | 268 | } |
aoqi@0 | 269 | |
aoqi@0 | 270 | if (sameName.isEmpty()) { |
aoqi@0 | 271 | return null; |
aoqi@0 | 272 | } else { |
aoqi@0 | 273 | if (sameName.size() == 1) { |
aoqi@0 | 274 | return sameName.get(0); |
aoqi@0 | 275 | } else { |
aoqi@0 | 276 | Class<?>[] argCls = method.getParameterTypes(); |
aoqi@0 | 277 | for (JavaMethod jm : sameName) { |
aoqi@0 | 278 | JavaMethod.JavaParams params = jm.getJavaParams(); |
aoqi@0 | 279 | if (params != null && params.getJavaParam() != null && params.getJavaParam().size() == argCls.length) { |
aoqi@0 | 280 | int count = 0; |
aoqi@0 | 281 | for (int i = 0; i < argCls.length; i++) { |
aoqi@0 | 282 | JavaParam jp = params.getJavaParam().get(i); |
aoqi@0 | 283 | if (argCls[i].getName().equals(jp.getJavaType())) { |
aoqi@0 | 284 | count++; |
aoqi@0 | 285 | } |
aoqi@0 | 286 | } |
aoqi@0 | 287 | if (count == argCls.length) { |
aoqi@0 | 288 | return jm; |
aoqi@0 | 289 | } |
aoqi@0 | 290 | } |
aoqi@0 | 291 | } |
aoqi@0 | 292 | } |
aoqi@0 | 293 | } |
aoqi@0 | 294 | return null; |
aoqi@0 | 295 | } |
aoqi@0 | 296 | |
aoqi@0 | 297 | Element findXmlElement(Element[] xa) { |
aoqi@0 | 298 | if (xa == null) return null; |
aoqi@0 | 299 | for (Element e : xa) { |
aoqi@0 | 300 | if (e.getLocalName().equals("java-type")) return e; |
aoqi@0 | 301 | if (e.getLocalName().equals("xml-element")) return e; |
aoqi@0 | 302 | } |
aoqi@0 | 303 | return null; |
aoqi@0 | 304 | } |
aoqi@0 | 305 | |
aoqi@0 | 306 | /** |
aoqi@0 | 307 | * Helper class to merge two different arrays of annotation objects. It merges annotations based on attribute |
aoqi@0 | 308 | * <code>existing-annotations</code> in external customization file. |
aoqi@0 | 309 | * <p/> |
aoqi@0 | 310 | * We suppose that in the result array there wouldn't be two annotations of same type: |
aoqi@0 | 311 | * annotation.annotationType().getName(); if there are found such annotations the one from reflection is |
aoqi@0 | 312 | * considered overriden and is thrown away. |
aoqi@0 | 313 | * <p/> |
aoqi@0 | 314 | * The helper can work either with one and two dimensional array, but it can be used for two single Annotation |
aoqi@0 | 315 | * objects; |
aoqi@0 | 316 | */ |
aoqi@0 | 317 | static abstract class Merger<T> { |
aoqi@0 | 318 | |
aoqi@0 | 319 | JavaWsdlMappingType reader; |
aoqi@0 | 320 | |
aoqi@0 | 321 | Merger(JavaWsdlMappingType r) { |
aoqi@0 | 322 | this.reader = r; |
aoqi@0 | 323 | } |
aoqi@0 | 324 | |
aoqi@0 | 325 | abstract T reflection(); |
aoqi@0 | 326 | |
aoqi@0 | 327 | abstract T external(); |
aoqi@0 | 328 | |
aoqi@0 | 329 | @SuppressWarnings("unchecked") |
aoqi@0 | 330 | T merge() { |
aoqi@0 | 331 | T reflection = reflection(); |
aoqi@0 | 332 | if (reader == null) { |
aoqi@0 | 333 | return reflection; |
aoqi@0 | 334 | } |
aoqi@0 | 335 | |
aoqi@0 | 336 | T external = external(); |
aoqi@0 | 337 | if (!MERGE.equals(reader.getExistingAnnotations())) { |
aoqi@0 | 338 | return external; |
aoqi@0 | 339 | } |
aoqi@0 | 340 | |
aoqi@0 | 341 | if (reflection instanceof Annotation) { |
aoqi@0 | 342 | return (T) doMerge((Annotation) reflection, (Annotation) external); |
aoqi@0 | 343 | } else if (reflection instanceof Annotation[][]) { |
aoqi@0 | 344 | return (T) doMerge((Annotation[][]) reflection, (Annotation[][]) external); |
aoqi@0 | 345 | } else { |
aoqi@0 | 346 | return (T) doMerge((Annotation[]) reflection, (Annotation[]) external); |
aoqi@0 | 347 | } |
aoqi@0 | 348 | } |
aoqi@0 | 349 | |
aoqi@0 | 350 | private Annotation doMerge(Annotation reflection, Annotation external) { |
aoqi@0 | 351 | return external != null ? external : reflection; |
aoqi@0 | 352 | } |
aoqi@0 | 353 | |
aoqi@0 | 354 | private Annotation[][] doMerge(Annotation[][] reflection, Annotation[][] external) { |
aoqi@0 | 355 | for (int i = 0; i < reflection.length; i++) { |
aoqi@0 | 356 | reflection[i] = doMerge(reflection[i], external.length > i ? external[i] : null); |
aoqi@0 | 357 | } |
aoqi@0 | 358 | return reflection; |
aoqi@0 | 359 | } |
aoqi@0 | 360 | |
aoqi@0 | 361 | private Annotation[] doMerge(Annotation[] annotations, Annotation[] externalAnnotations) { |
aoqi@0 | 362 | HashMap<String, Annotation> mergeMap = new HashMap<String, Annotation>(); |
aoqi@0 | 363 | if (annotations != null) { |
aoqi@0 | 364 | for (Annotation reflectionAnnotation : annotations) { |
aoqi@0 | 365 | mergeMap.put(reflectionAnnotation.annotationType().getName(), reflectionAnnotation); |
aoqi@0 | 366 | } |
aoqi@0 | 367 | } |
aoqi@0 | 368 | |
aoqi@0 | 369 | // overriding happens here, based on annotationType().getName() ... |
aoqi@0 | 370 | if (externalAnnotations != null) { |
aoqi@0 | 371 | for (Annotation externalAnnotation : externalAnnotations) { |
aoqi@0 | 372 | mergeMap.put(externalAnnotation.annotationType().getName(), externalAnnotation); |
aoqi@0 | 373 | } |
aoqi@0 | 374 | } |
aoqi@0 | 375 | Collection<Annotation> values = mergeMap.values(); |
aoqi@0 | 376 | int size = values.size(); |
aoqi@0 | 377 | return size == 0 ? null : values.toArray(new Annotation[size]); |
aoqi@0 | 378 | } |
aoqi@0 | 379 | |
aoqi@0 | 380 | } |
aoqi@0 | 381 | |
aoqi@0 | 382 | static class Util { |
aoqi@0 | 383 | |
aoqi@0 | 384 | //private static final String DATABINDING_XSD = "com/sun/xml/internal/ws/model/jaxws-databinding.xsd"; |
aoqi@0 | 385 | private static final String DATABINDING_XSD = "jaxws-databinding.xsd"; |
aoqi@0 | 386 | //private static final String TRANSLATE_NAMESPACES_XSL = "/com/sun/xml/internal/ws/model/jaxws-databinding-translate-namespaces.xml"; |
aoqi@0 | 387 | private static final String TRANSLATE_NAMESPACES_XSL = "jaxws-databinding-translate-namespaces.xml"; |
aoqi@0 | 388 | |
aoqi@0 | 389 | static Schema schema; |
aoqi@0 | 390 | static JAXBContext jaxbContext; |
aoqi@0 | 391 | |
aoqi@0 | 392 | static { |
aoqi@0 | 393 | SchemaFactory sf = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema"); |
aoqi@0 | 394 | try { |
aoqi@0 | 395 | URL xsdUrl = getResource(); |
aoqi@0 | 396 | if (xsdUrl != null) { |
aoqi@0 | 397 | schema = sf.newSchema(xsdUrl); |
aoqi@0 | 398 | } |
aoqi@0 | 399 | } catch (SAXException e1) { |
aoqi@0 | 400 | // e1.printStackTrace(); |
aoqi@0 | 401 | } |
aoqi@0 | 402 | |
aoqi@0 | 403 | jaxbContext = createJaxbContext(false); |
aoqi@0 | 404 | } |
aoqi@0 | 405 | |
aoqi@0 | 406 | private static URL getResource() { |
aoqi@0 | 407 | ClassLoader classLoader = Util.class.getClassLoader(); |
aoqi@0 | 408 | return classLoader != null ? classLoader.getResource(DATABINDING_XSD) : ClassLoader.getSystemResource(DATABINDING_XSD); |
aoqi@0 | 409 | } |
aoqi@0 | 410 | |
aoqi@0 | 411 | private static JAXBContext createJaxbContext(boolean disableXmlSecurity) { |
aoqi@0 | 412 | Class[] cls = {ObjectFactory.class}; |
aoqi@0 | 413 | try { |
aoqi@0 | 414 | if (disableXmlSecurity) { |
aoqi@0 | 415 | Map<String, Object> properties = new HashMap<String, Object>(); |
aoqi@0 | 416 | properties.put(JAXBRIContext.DISABLE_XML_SECURITY, disableXmlSecurity); |
aoqi@0 | 417 | return JAXBContext.newInstance(cls, properties); |
aoqi@0 | 418 | } else { |
aoqi@0 | 419 | return JAXBContext.newInstance(cls); |
aoqi@0 | 420 | } |
aoqi@0 | 421 | } catch (JAXBException e) { |
aoqi@0 | 422 | e.printStackTrace(); |
aoqi@0 | 423 | return null; |
aoqi@0 | 424 | } |
aoqi@0 | 425 | } |
aoqi@0 | 426 | |
aoqi@0 | 427 | @SuppressWarnings("unchecked") |
aoqi@0 | 428 | public static JavaWsdlMappingType read(Source src, boolean xsdValidation, boolean disableXmlSecurity) throws IOException, JAXBException { |
aoqi@0 | 429 | JAXBContext ctx = jaxbContext(disableXmlSecurity); |
aoqi@0 | 430 | try { |
aoqi@0 | 431 | Unmarshaller um = ctx.createUnmarshaller(); |
aoqi@0 | 432 | if (xsdValidation) { |
aoqi@0 | 433 | if (schema == null) { |
aoqi@0 | 434 | //TODO 0 warning for schema == null |
aoqi@0 | 435 | } |
aoqi@0 | 436 | um.setSchema(schema); |
aoqi@0 | 437 | } |
aoqi@0 | 438 | Object o = um.unmarshal(src); |
aoqi@0 | 439 | return getJavaWsdlMapping(o); |
aoqi@0 | 440 | } catch (JAXBException e) { |
aoqi@0 | 441 | // throw new |
aoqi@0 | 442 | // WebServiceException(WsDatabindingMessages.mappingFileCannotRead |
aoqi@0 | 443 | // (src.getSystemId()), e); |
aoqi@0 | 444 | URL url = new URL(src.getSystemId()); |
aoqi@0 | 445 | Source s = new StreamSource(url.openStream()); |
aoqi@0 | 446 | Unmarshaller um = ctx.createUnmarshaller(); |
aoqi@0 | 447 | if (xsdValidation) { |
aoqi@0 | 448 | if (schema == null) { |
aoqi@0 | 449 | //TODO 0 warning for schema == null |
aoqi@0 | 450 | } |
aoqi@0 | 451 | um.setSchema(schema); |
aoqi@0 | 452 | } |
aoqi@0 | 453 | Object o = um.unmarshal(s); |
aoqi@0 | 454 | return getJavaWsdlMapping(o); |
aoqi@0 | 455 | } |
aoqi@0 | 456 | } |
aoqi@0 | 457 | |
aoqi@0 | 458 | private static JAXBContext jaxbContext(boolean disableXmlSecurity) { |
aoqi@0 | 459 | // as it is supposed to have security enabled in most cases, we create and don't cache |
aoqi@0 | 460 | // "insecure" JAXBContext - these should be corner cases |
aoqi@0 | 461 | return disableXmlSecurity ? createJaxbContext(true) : jaxbContext; |
aoqi@0 | 462 | } |
aoqi@0 | 463 | |
aoqi@0 | 464 | public static JavaWsdlMappingType transformAndRead(Source src, boolean disableXmlSecurity) throws TransformerException, JAXBException { |
aoqi@0 | 465 | Source xsl = new StreamSource(Util.class.getResourceAsStream(TRANSLATE_NAMESPACES_XSL)); |
aoqi@0 | 466 | JAXBResult result = new JAXBResult(jaxbContext(disableXmlSecurity)); |
aoqi@0 | 467 | TransformerFactory tf = XmlUtil.newTransformerFactory(!disableXmlSecurity); |
aoqi@0 | 468 | Transformer transformer = tf.newTemplates(xsl).newTransformer(); |
aoqi@0 | 469 | transformer.transform(src, result); |
aoqi@0 | 470 | return getJavaWsdlMapping(result.getResult()); |
aoqi@0 | 471 | } |
aoqi@0 | 472 | |
aoqi@0 | 473 | |
aoqi@0 | 474 | static JavaWsdlMappingType getJavaWsdlMapping(Object o) { |
aoqi@0 | 475 | Object val = (o instanceof JAXBElement) ? ((JAXBElement) o).getValue() : o; |
aoqi@0 | 476 | if (val instanceof JavaWsdlMappingType) return (JavaWsdlMappingType) val; |
aoqi@0 | 477 | // else if (val instanceof JavaWsdlMappings) |
aoqi@0 | 478 | // for (JavaWsdlMappingType m: ((JavaWsdlMappings) val).getJavaWsdlMapping()) |
aoqi@0 | 479 | // if (seiName.equals(m.javaTypeName)) return m; |
aoqi@0 | 480 | return null; |
aoqi@0 | 481 | } |
aoqi@0 | 482 | |
aoqi@0 | 483 | static <T> T findInstanceOf(Class<T> type, List<Object> objects) { |
aoqi@0 | 484 | for (Object o : objects) { |
aoqi@0 | 485 | if (type.isInstance(o)) { |
aoqi@0 | 486 | return type.cast(o); |
aoqi@0 | 487 | } |
aoqi@0 | 488 | } |
aoqi@0 | 489 | return null; |
aoqi@0 | 490 | } |
aoqi@0 | 491 | |
aoqi@0 | 492 | static public <T> T annotation(JavaWsdlMappingType jwse, Class<T> anntype) { |
aoqi@0 | 493 | if (jwse == null || jwse.getClassAnnotation() == null) { |
aoqi@0 | 494 | return null; |
aoqi@0 | 495 | } |
aoqi@0 | 496 | return findInstanceOf(anntype, jwse.getClassAnnotation()); |
aoqi@0 | 497 | } |
aoqi@0 | 498 | |
aoqi@0 | 499 | static public <T> T annotation(JavaMethod jm, Class<T> anntype) { |
aoqi@0 | 500 | if (jm == null || jm.getMethodAnnotation() == null) { |
aoqi@0 | 501 | return null; |
aoqi@0 | 502 | } |
aoqi@0 | 503 | return findInstanceOf(anntype, jm.getMethodAnnotation()); |
aoqi@0 | 504 | } |
aoqi@0 | 505 | |
aoqi@0 | 506 | static public <T> T annotation(JavaParam jp, Class<T> anntype) { |
aoqi@0 | 507 | if (jp == null || jp.getParamAnnotation() == null) { |
aoqi@0 | 508 | return null; |
aoqi@0 | 509 | } |
aoqi@0 | 510 | return findInstanceOf(anntype, jp.getParamAnnotation()); |
aoqi@0 | 511 | } |
aoqi@0 | 512 | |
aoqi@0 | 513 | static public Element[] annotation(JavaMethod jm) { |
aoqi@0 | 514 | if (jm == null || jm.getMethodAnnotation() == null) { |
aoqi@0 | 515 | return null; |
aoqi@0 | 516 | } |
aoqi@0 | 517 | return findElements(jm.getMethodAnnotation()); |
aoqi@0 | 518 | } |
aoqi@0 | 519 | |
aoqi@0 | 520 | static public Element[] annotation(JavaParam jp) { |
aoqi@0 | 521 | if (jp == null || jp.getParamAnnotation() == null) { |
aoqi@0 | 522 | return null; |
aoqi@0 | 523 | } |
aoqi@0 | 524 | return findElements(jp.getParamAnnotation()); |
aoqi@0 | 525 | } |
aoqi@0 | 526 | |
aoqi@0 | 527 | private static Element[] findElements(List<Object> objects) { |
aoqi@0 | 528 | List<Element> elems = new ArrayList<Element>(); |
aoqi@0 | 529 | for (Object o : objects) { |
aoqi@0 | 530 | if (o instanceof Element) { |
aoqi@0 | 531 | elems.add((Element) o); |
aoqi@0 | 532 | } |
aoqi@0 | 533 | } |
aoqi@0 | 534 | return elems.toArray(new Element[elems.size()]); |
aoqi@0 | 535 | } |
aoqi@0 | 536 | |
aoqi@0 | 537 | static String documentRootNamespace(Source src, boolean disableXmlSecurity) throws XMLStreamException { |
aoqi@0 | 538 | XMLInputFactory factory; |
aoqi@0 | 539 | factory = XmlUtil.newXMLInputFactory(!disableXmlSecurity); |
aoqi@0 | 540 | XMLStreamReader streamReader = factory.createXMLStreamReader(src); |
aoqi@0 | 541 | XMLStreamReaderUtil.nextElementContent(streamReader); |
aoqi@0 | 542 | String namespaceURI = streamReader.getName().getNamespaceURI(); |
aoqi@0 | 543 | XMLStreamReaderUtil.close(streamReader); |
aoqi@0 | 544 | return namespaceURI; |
aoqi@0 | 545 | } |
aoqi@0 | 546 | } |
aoqi@0 | 547 | |
aoqi@0 | 548 | |
aoqi@0 | 549 | } |