src/share/jaxws_classes/com/sun/xml/internal/ws/model/AbstractSEIModelImpl.java

changeset 0
373ffda63c9a
child 637
9c07ef4934dd
equal deleted inserted replaced
-1:000000000000 0:373ffda63c9a
1 /*
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package com.sun.xml.internal.ws.model;
27
28 import com.sun.istack.internal.NotNull;
29 import com.sun.xml.internal.bind.api.Bridge;
30 import com.sun.xml.internal.bind.api.JAXBRIContext;
31 import com.sun.xml.internal.bind.api.TypeReference;
32 import com.sun.xml.internal.ws.api.BindingID;
33 import com.sun.xml.internal.ws.api.WSBinding;
34 import com.sun.xml.internal.ws.api.databinding.Databinding;
35 import com.sun.xml.internal.ws.api.model.JavaMethod;
36 import com.sun.xml.internal.ws.api.model.ParameterBinding;
37 import com.sun.xml.internal.ws.api.model.SEIModel;
38 import com.sun.xml.internal.ws.api.model.wsdl.WSDLModel;
39 import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort;
40 import com.sun.xml.internal.ws.api.model.wsdl.WSDLPart;
41 import com.sun.xml.internal.ws.api.model.wsdl.WSDLBoundPortType;
42 import com.sun.xml.internal.ws.api.model.wsdl.WSDLBoundOperation;
43 import com.sun.xml.internal.ws.encoding.soap.streaming.SOAPNamespaceConstants;
44 import com.sun.xml.internal.ws.resources.ModelerMessages;
45 import com.sun.xml.internal.ws.spi.db.BindingContext;
46 import com.sun.xml.internal.ws.spi.db.BindingContextFactory;
47 import com.sun.xml.internal.ws.spi.db.BindingInfo;
48 import com.sun.xml.internal.ws.spi.db.XMLBridge;
49 import com.sun.xml.internal.ws.spi.db.TypeInfo;
50 import com.sun.xml.internal.ws.util.Pool;
51 import com.sun.xml.internal.ws.developer.UsesJAXBContextFeature;
52 import com.sun.xml.internal.ws.developer.JAXBContextFactory;
53 import com.sun.xml.internal.ws.binding.WebServiceFeatureList;
54
55 import javax.jws.WebParam.Mode;
56 import javax.xml.bind.JAXBContext;
57 import javax.xml.bind.annotation.XmlSeeAlso;
58 import javax.xml.namespace.QName;
59 import javax.xml.ws.WebServiceException;
60
61
62 import java.lang.reflect.Method;
63 import java.security.AccessController;
64 import java.security.PrivilegedActionException;
65 import java.security.PrivilegedExceptionAction;
66 import java.util.ArrayList;
67 import java.util.Collection;
68 import java.util.Collections;
69 import java.util.HashMap;
70 import java.util.List;
71 import java.util.Map;
72 import java.util.logging.Level;
73 import java.util.logging.Logger;
74
75 /**
76 * model of the web service. Used by the runtime marshall/unmarshall
77 * web service invocations
78 *
79 * @author JAXWS Development Team
80 */
81 public abstract class AbstractSEIModelImpl implements SEIModel {
82
83 protected AbstractSEIModelImpl(WebServiceFeatureList features) {
84 this.features = features;
85 databindingInfo = new BindingInfo();
86 databindingInfo.setSEIModel(this);
87 }
88
89 void postProcess() {
90 // should be called only once.
91 if (jaxbContext != null) {
92 return;
93 }
94 populateMaps();
95 createJAXBContext();
96 }
97
98 /**
99 * Link {@link SEIModel} to {@link WSDLModel}.
100 * Merge it with {@link #postProcess()}.
101 */
102 public void freeze(WSDLPort port) {
103 this.port = port;
104 for (JavaMethodImpl m : javaMethods) {
105 m.freeze(port);
106 putOp(m.getOperationQName(),m);
107
108 }
109 if (databinding != null) {
110 ((com.sun.xml.internal.ws.db.DatabindingImpl)databinding).freeze(port);
111 }
112 }
113
114 /**
115 * Populate methodToJM and nameToJM maps.
116 */
117 abstract protected void populateMaps();
118
119 @Override
120 public Pool.Marshaller getMarshallerPool() {
121 return marshallers;
122 }
123
124 /**
125 * @return the <code>JAXBRIContext</code>
126 * @deprecated
127 */
128 @Override
129 public JAXBContext getJAXBContext() {
130 JAXBContext jc = bindingContext.getJAXBContext();
131 if (jc != null) {
132 return jc;
133 }
134 return jaxbContext;
135 }
136
137 public BindingContext getBindingContext() {
138 return bindingContext;
139 }
140
141 /**
142 * @return the known namespaces from JAXBRIContext
143 */
144 public List<String> getKnownNamespaceURIs() {
145 return knownNamespaceURIs;
146 }
147
148 /**
149 * @return the <code>Bridge</code> for the <code>type</code>
150 * @deprecated use getBond
151 */
152 public final Bridge getBridge(TypeReference type) {
153 Bridge b = bridgeMap.get(type);
154 assert b!=null; // we should have created Bridge for all TypeReferences known to this model
155 return b;
156 }
157
158 public final XMLBridge getXMLBridge(TypeInfo type) {
159 XMLBridge b = xmlBridgeMap.get(type);
160 assert b!=null; // we should have created Bridge for all TypeReferences known to this model
161 return b;
162 }
163
164 private void /*JAXBRIContext*/ createJAXBContext() {
165 final List<TypeInfo> types = getAllTypeInfos();
166 final List<Class> cls = new ArrayList<Class>(types.size() + additionalClasses.size());
167
168 cls.addAll(additionalClasses);
169 for (TypeInfo type : types) {
170 cls.add((Class) type.type);
171 }
172
173 try {
174 //jaxbContext = JAXBRIContext.newInstance(cls, types, targetNamespace, false);
175 // Need to avoid doPriv block once JAXB is fixed. Afterwards, use the above
176 bindingContext = AccessController.doPrivileged(new PrivilegedExceptionAction<BindingContext>() {
177 public BindingContext run() throws Exception {
178 if(LOGGER.isLoggable(Level.FINEST)) {
179 LOGGER.log(Level.FINEST, "Creating JAXBContext with classes={0} and types={1}", new Object[]{cls, types});
180 }
181 UsesJAXBContextFeature f = features.get(UsesJAXBContextFeature.class);
182 com.oracle.webservices.internal.api.databinding.DatabindingModeFeature dmf =
183 features.get(com.oracle.webservices.internal.api.databinding.DatabindingModeFeature.class);
184 JAXBContextFactory factory = f!=null ? f.getFactory() : null;
185 if(factory==null) factory=JAXBContextFactory.DEFAULT;
186
187 // return factory.createJAXBContext(AbstractSEIModelImpl.this,cls,types);
188
189 databindingInfo.properties().put(JAXBContextFactory.class.getName(), factory);
190 if (dmf != null) {
191 if (LOGGER.isLoggable(Level.FINE))
192 LOGGER.log(Level.FINE, "DatabindingModeFeature in SEI specifies mode: {0}", dmf.getMode());
193 databindingInfo.setDatabindingMode(dmf
194 .getMode());
195 }
196
197 if (f!=null) databindingInfo.setDatabindingMode(BindingContextFactory.DefaultDatabindingMode);
198 databindingInfo.setClassLoader(classLoader);
199 databindingInfo.contentClasses().addAll(cls);
200 databindingInfo.typeInfos().addAll(types);
201 databindingInfo.properties().put("c14nSupport", Boolean.FALSE);
202 databindingInfo.setDefaultNamespace(AbstractSEIModelImpl.this.getDefaultSchemaNamespace());
203 BindingContext bc = BindingContextFactory.create(databindingInfo);
204 if (LOGGER.isLoggable(Level.FINE))
205 LOGGER.log(Level.FINE,
206 "Created binding context: "
207 + bc.getClass().getName());
208 // System.out.println("---------------------- databinding " + bc);
209 return bc;
210 }
211 });
212 // createBridgeMap(types);
213 createBondMap(types);
214 } catch (PrivilegedActionException e) {
215 throw new WebServiceException(ModelerMessages.UNABLE_TO_CREATE_JAXB_CONTEXT(), e);
216 }
217 knownNamespaceURIs = new ArrayList<String>();
218 for (String namespace : bindingContext.getKnownNamespaceURIs()) {
219 if (namespace.length() > 0) {
220 if (!namespace.equals(SOAPNamespaceConstants.XSD) && !namespace.equals(SOAPNamespaceConstants.XMLNS))
221 knownNamespaceURIs.add(namespace);
222 }
223 }
224
225 marshallers = new Pool.Marshaller(jaxbContext);
226
227 //return getJAXBContext();
228 }
229
230 /**
231 * @return returns non-null list of TypeReference
232 */
233 private List<TypeInfo> getAllTypeInfos() {
234 List<TypeInfo> types = new ArrayList<TypeInfo>();
235 Collection<JavaMethodImpl> methods = methodToJM.values();
236 for (JavaMethodImpl m : methods) {
237 m.fillTypes(types);
238 }
239 return types;
240 }
241
242 private void createBridgeMap(List<TypeReference> types) {
243 for (TypeReference type : types) {
244 Bridge bridge = jaxbContext.createBridge(type);
245 bridgeMap.put(type, bridge);
246 }
247 }
248 private void createBondMap(List<TypeInfo> types) {
249 for (TypeInfo type : types) {
250 XMLBridge binding = bindingContext.createBridge(type);
251 xmlBridgeMap.put(type, binding);
252 }
253 }
254
255
256 /**
257 * @return true if <code>name</code> is the name
258 * of a known fault name for the <code>Method method</code>
259 */
260 public boolean isKnownFault(QName name, Method method) {
261 JavaMethodImpl m = getJavaMethod(method);
262 for (CheckedExceptionImpl ce : m.getCheckedExceptions()) {
263 if (ce.getDetailType().tagName.equals(name))
264 return true;
265 }
266 return false;
267 }
268
269 /**
270 * @return true if <code>ex</code> is a Checked Exception
271 * for <code>Method m</code>
272 */
273 public boolean isCheckedException(Method m, Class ex) {
274 JavaMethodImpl jm = getJavaMethod(m);
275 for (CheckedExceptionImpl ce : jm.getCheckedExceptions()) {
276 if (ce.getExceptionClass().equals(ex))
277 return true;
278 }
279 return false;
280 }
281
282 /**
283 * @return the <code>JavaMethod</code> representing the <code>method</code>
284 */
285 public JavaMethodImpl getJavaMethod(Method method) {
286 return methodToJM.get(method);
287 }
288
289 /**
290 * @return the <code>JavaMethod</code> associated with the
291 * operation named name
292 */
293 public JavaMethodImpl getJavaMethod(QName name) {
294 return nameToJM.get(name);
295 }
296
297 public JavaMethod getJavaMethodForWsdlOperation(QName operationName) {
298 return wsdlOpToJM.get(operationName);
299 }
300
301
302 /**
303 * @return the <code>QName</code> associated with the
304 * JavaMethod jm.
305 *
306 * @deprecated
307 * Use {@link JavaMethod#getOperationName()}.
308 */
309 public QName getQNameForJM(JavaMethodImpl jm) {
310 for (QName key : nameToJM.keySet()) {
311 JavaMethodImpl jmethod = nameToJM.get(key);
312 if (jmethod.getOperationName().equals(jm.getOperationName())){
313 return key;
314 }
315 }
316 return null;
317 }
318
319 /**
320 * @return a <code>Collection</code> of <code>JavaMethods</code>
321 * associated with this <code>RuntimeModel</code>
322 */
323 public final Collection<JavaMethodImpl> getJavaMethods() {
324 return Collections.unmodifiableList(javaMethods);
325 }
326
327 void addJavaMethod(JavaMethodImpl jm) {
328 if (jm != null)
329 javaMethods.add(jm);
330 }
331
332 /**
333 * Applies binding related information to the RpcLitPayload. The payload map is populated correctly
334 * @return
335 * Returns attachment parameters if/any.
336 */
337 private List<ParameterImpl> applyRpcLitParamBinding(JavaMethodImpl method, WrapperParameter wrapperParameter, WSDLBoundPortType boundPortType, Mode mode) {
338 QName opName = new QName(boundPortType.getPortTypeName().getNamespaceURI(), method.getOperationName());
339 WSDLBoundOperation bo = boundPortType.get(opName);
340 Map<Integer, ParameterImpl> bodyParams = new HashMap<Integer, ParameterImpl>();
341 List<ParameterImpl> unboundParams = new ArrayList<ParameterImpl>();
342 List<ParameterImpl> attachParams = new ArrayList<ParameterImpl>();
343 for(ParameterImpl param : wrapperParameter.wrapperChildren){
344 String partName = param.getPartName();
345 if(partName == null)
346 continue;
347
348 ParameterBinding paramBinding = boundPortType.getBinding(opName,
349 partName, mode);
350 if(paramBinding != null){
351 if(mode == Mode.IN)
352 param.setInBinding(paramBinding);
353 else if(mode == Mode.OUT || mode == Mode.INOUT)
354 param.setOutBinding(paramBinding);
355
356 if(paramBinding.isUnbound()){
357 unboundParams.add(param);
358 } else if(paramBinding.isAttachment()){
359 attachParams.add(param);
360 }else if(paramBinding.isBody()){
361 if(bo != null){
362 WSDLPart p = bo.getPart(param.getPartName(), mode);
363 if(p != null)
364 bodyParams.put(p.getIndex(), param);
365 else
366 bodyParams.put(bodyParams.size(), param);
367 }else{
368 bodyParams.put(bodyParams.size(), param);
369 }
370 }
371 }
372
373 }
374 wrapperParameter.clear();
375 for(int i = 0; i < bodyParams.size();i++){
376 ParameterImpl p = bodyParams.get(i);
377 wrapperParameter.addWrapperChild(p);
378 }
379
380 //add unbounded parts
381 for(ParameterImpl p:unboundParams){
382 wrapperParameter.addWrapperChild(p);
383 }
384 return attachParams;
385 }
386
387
388 void put(QName name, JavaMethodImpl jm) {
389 nameToJM.put(name, jm);
390 }
391
392 void put(Method method, JavaMethodImpl jm) {
393 methodToJM.put(method, jm);
394 }
395
396 void putOp(QName opName, JavaMethodImpl jm) {
397 wsdlOpToJM.put(opName, jm);
398 }
399 public String getWSDLLocation() {
400 return wsdlLocation;
401 }
402
403 void setWSDLLocation(String location) {
404 wsdlLocation = location;
405 }
406
407 public QName getServiceQName() {
408 return serviceName;
409 }
410
411 public WSDLPort getPort() {
412 return port;
413 }
414
415 public QName getPortName() {
416 return portName;
417 }
418
419 public QName getPortTypeName() {
420 return portTypeName;
421 }
422
423 void setServiceQName(QName name) {
424 serviceName = name;
425 }
426
427 void setPortName(QName name) {
428 portName = name;
429 }
430
431 void setPortTypeName(QName name) {
432 portTypeName = name;
433 }
434
435 /**
436 * This is the targetNamespace for the WSDL containing the PortType
437 * definition
438 */
439 void setTargetNamespace(String namespace) {
440 targetNamespace = namespace;
441 }
442
443 /**
444 * This is the targetNamespace for the WSDL containing the PortType
445 * definition
446 */
447 public String getTargetNamespace() {
448 return targetNamespace;
449 }
450
451 String getDefaultSchemaNamespace() {
452 String defaultNamespace = getTargetNamespace();
453 if (defaultSchemaNamespaceSuffix == null) return defaultNamespace;
454 if (!defaultNamespace.endsWith("/")) {
455 defaultNamespace += "/";
456 }
457 return (defaultNamespace + defaultSchemaNamespaceSuffix);
458 }
459
460 @NotNull
461 public QName getBoundPortTypeName() {
462 assert portName != null;
463 return new QName(portName.getNamespaceURI(), portName.getLocalPart()+"Binding");
464 }
465
466 /**
467 * Adds additional classes obtained from {@link XmlSeeAlso} annotation. In starting
468 * from wsdl case these classes would most likely be JAXB ObjectFactory that references other classes.
469 */
470 public void addAdditionalClasses(Class... additionalClasses) {
471 for(Class cls : additionalClasses)
472 this.additionalClasses.add(cls);
473 }
474
475 public Databinding getDatabinding() {
476 return databinding;
477 }
478
479 public void setDatabinding(Databinding wsRuntime) {
480 this.databinding = wsRuntime;
481 }
482
483 public WSBinding getWSBinding() {
484 return wsBinding;
485 }
486
487 public Class getContractClass() {
488 return contractClass;
489 }
490
491 public Class getEndpointClass() {
492 return endpointClass;
493 }
494
495 private List<Class> additionalClasses = new ArrayList<Class>();
496
497 private Pool.Marshaller marshallers;
498 /**
499 * @deprecated
500 */
501 protected JAXBRIContext jaxbContext;
502 protected BindingContext bindingContext;
503 private String wsdlLocation;
504 private QName serviceName;
505 private QName portName;
506 private QName portTypeName;
507 private Map<Method,JavaMethodImpl> methodToJM = new HashMap<Method, JavaMethodImpl>();
508 /**
509 * Payload QName to the method that handles it.
510 */
511 private Map<QName,JavaMethodImpl> nameToJM = new HashMap<QName, JavaMethodImpl>();
512 /**
513 * Wsdl Operation QName to the method that handles it.
514 */
515 private Map<QName, JavaMethodImpl> wsdlOpToJM = new HashMap<QName, JavaMethodImpl>();
516
517 private List<JavaMethodImpl> javaMethods = new ArrayList<JavaMethodImpl>();
518 private final Map<TypeReference, Bridge> bridgeMap = new HashMap<TypeReference, Bridge>();
519 private final Map<TypeInfo, XMLBridge> xmlBridgeMap = new HashMap<TypeInfo, XMLBridge>();
520 protected final QName emptyBodyName = new QName("");
521 private String targetNamespace = "";
522 private List<String> knownNamespaceURIs = null;
523 private WSDLPort port;
524 private final WebServiceFeatureList features;
525 private Databinding databinding;
526 BindingID bindingId;
527 protected Class contractClass;
528 protected Class endpointClass;
529 protected ClassLoader classLoader = null;
530 protected WSBinding wsBinding;
531 protected BindingInfo databindingInfo;
532 protected String defaultSchemaNamespaceSuffix;
533 private static final Logger LOGGER = Logger.getLogger(AbstractSEIModelImpl.class.getName());
534 }

mercurial