001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019: package org.apache.axis2.jaxws.marshaller.factory;
020:
021: import org.apache.axis2.jaxws.ExceptionFactory;
022: import org.apache.axis2.jaxws.description.OperationDescription;
023: import org.apache.axis2.jaxws.description.ParameterDescription;
024: import org.apache.axis2.jaxws.description.ServiceDescription;
025: import org.apache.axis2.jaxws.marshaller.MethodMarshaller;
026: import org.apache.axis2.jaxws.marshaller.impl.alt.DocLitBareMethodMarshaller;
027: import org.apache.axis2.jaxws.marshaller.impl.alt.DocLitBareMinimalMethodMarshaller;
028: import org.apache.axis2.jaxws.marshaller.impl.alt.DocLitWrappedMethodMarshaller;
029: import org.apache.axis2.jaxws.marshaller.impl.alt.DocLitWrappedMinimalMethodMarshaller;
030: import org.apache.axis2.jaxws.marshaller.impl.alt.DocLitWrappedPlusMethodMarshaller;
031: import org.apache.axis2.jaxws.marshaller.impl.alt.RPCLitMethodMarshaller;
032: import org.apache.axis2.jaxws.message.databinding.JAXBUtils;
033: import org.apache.axis2.jaxws.runtime.description.marshal.MarshalServiceRuntimeDescription;
034: import org.apache.axis2.jaxws.runtime.description.marshal.MarshalServiceRuntimeDescriptionFactory;
035:
036: import javax.jws.soap.SOAPBinding;
037: import javax.xml.bind.JAXBContext;
038: import javax.xml.bind.JAXBException;
039: import javax.xml.ws.Holder;
040:
041: /**
042: * The MethodMarshallerFactory creates a Doc/Lit Wrapped, Doc/Lit Bare or RPC Marshaller using
043: * SOAPBinding information
044: */
045: public class MethodMarshallerFactory {
046:
047: private enum SUBTYPE {
048: NORMAL, PLUS, MINIMAL
049: }
050:
051: ;
052:
053: /** Intentionally private */
054: private MethodMarshallerFactory() {
055: }
056:
057: /**
058: * Create Marshaller usining the Binding information
059: *
060: * @param style
061: * @param paramStyle
062: * @param isPlus used to designated DOCLITWRAPPED plus additional rules (i.e. header
063: * processing)
064: * @param isClient
065: * @return
066: */
067: private static MethodMarshaller createMethodMarshaller(
068: SOAPBinding.Style style,
069: SOAPBinding.ParameterStyle paramStyle, SUBTYPE subType,
070: boolean isClient) { // This flag is for testing only !
071: if (style == SOAPBinding.Style.RPC) {
072: return new RPCLitMethodMarshaller();
073: } else if (paramStyle == SOAPBinding.ParameterStyle.WRAPPED) {
074: if (subType == SUBTYPE.PLUS) {
075: // Abnormal case
076: return new DocLitWrappedPlusMethodMarshaller();
077: } else if (subType == SUBTYPE.MINIMAL) {
078: // Abnormal case
079: return new DocLitWrappedMinimalMethodMarshaller();
080: } else {
081: return new DocLitWrappedMethodMarshaller();
082: }
083: } else if (paramStyle == SOAPBinding.ParameterStyle.BARE) {
084: if (subType == SUBTYPE.MINIMAL) {
085: // Abnormal case
086: return new DocLitBareMinimalMethodMarshaller();
087: } else {
088: return new DocLitBareMethodMarshaller();
089: }
090: }
091: return null;
092: }
093:
094: public static MethodMarshaller getMarshaller(
095: OperationDescription op, boolean isClient) {
096:
097: MethodMarshaller marshaller = null;
098: if (isClient) {
099: if (op.getSoapBindingStyle() == SOAPBinding.Style.DOCUMENT) {
100: marshaller = createDocLitMethodMarshaller(op, isClient);
101: } else if (op.getSoapBindingStyle() == SOAPBinding.Style.RPC) {
102: marshaller = createRPCLitMethodMarshaller(isClient);
103: }
104: } else { // SERVER
105: if (op.getSoapBindingStyle() == SOAPBinding.Style.DOCUMENT) {
106: marshaller = createDocLitMethodMarshaller(op, isClient);
107: } else if (op.getSoapBindingStyle() == SOAPBinding.Style.RPC) {
108: marshaller = createRPCLitMethodMarshaller(isClient);
109: }
110: }
111: return marshaller;
112: }
113:
114: private static MethodMarshaller createDocLitMethodMarshaller(
115: OperationDescription op, boolean isClient) {
116: SOAPBinding.ParameterStyle parameterStyle = null;
117: SUBTYPE subType = SUBTYPE.NORMAL;
118: if (isDocLitBare(op)) {
119: if (isDocLitBareMinimal(op)) {
120: subType = SUBTYPE.MINIMAL;
121: }
122: parameterStyle = SOAPBinding.ParameterStyle.BARE;
123: } else {
124: if (isDocLitWrappedMinimal(op)) {
125: subType = SUBTYPE.MINIMAL;
126: } else if (isDocLitWrappedPlus(op)) {
127: subType = SUBTYPE.PLUS;
128: }
129: parameterStyle = SOAPBinding.ParameterStyle.WRAPPED;
130: }
131: return createMethodMarshaller(SOAPBinding.Style.DOCUMENT,
132: parameterStyle, subType, isClient);
133: }
134:
135: private static MethodMarshaller createRPCLitMethodMarshaller(
136: boolean isClient) {
137: return createMethodMarshaller(SOAPBinding.Style.RPC,
138: SOAPBinding.ParameterStyle.WRAPPED, SUBTYPE.NORMAL,
139: isClient);
140: }
141:
142: protected static boolean isDocLitBare(OperationDescription op) {
143: SOAPBinding.ParameterStyle methodParamStyle = op
144: .getSoapBindingParameterStyle();
145: if (methodParamStyle != null) {
146: return methodParamStyle == SOAPBinding.ParameterStyle.BARE;
147: } else {
148: SOAPBinding.ParameterStyle SEIParamStyle = op
149: .getEndpointInterfaceDescription()
150: .getSoapBindingParameterStyle();
151: return SEIParamStyle == SOAPBinding.ParameterStyle.BARE;
152: }
153: }
154:
155: protected static boolean isDocLitWrapped(OperationDescription op) {
156: SOAPBinding.ParameterStyle methodParamStyle = op
157: .getSoapBindingParameterStyle();
158: if (methodParamStyle != null) {
159: return methodParamStyle == SOAPBinding.ParameterStyle.WRAPPED;
160: } else {
161: SOAPBinding.ParameterStyle SEIParamStyle = op
162: .getEndpointInterfaceDescription()
163: .getSoapBindingParameterStyle();
164: return SEIParamStyle == SOAPBinding.ParameterStyle.WRAPPED;
165: }
166: }
167:
168: /**
169: * If an web service is created using wsgen, it is possible that the sei does not comply with
170: * the wrapped rules. For example, wsgen will allow header parameters and return values. In
171: * such cases we will use the DocLitWrappedPlus marshaller to marshal and unmarshal the xml in
172: * these extraordinary situations
173: *
174: * @param op
175: * @return
176: */
177: protected static boolean isDocLitWrappedPlus(OperationDescription op) {
178: if (isDocLitWrapped(op)) {
179: if (op.isResultHeader()) {
180: return true;
181: }
182: ParameterDescription[] pds = op.getParameterDescriptions();
183: for (int i = 0; i < pds.length; i++) {
184: if (pds[i].isHeader()) {
185: return true;
186: }
187: }
188: }
189: return false;
190: }
191:
192: /**
193: * If a webservices is created without xjc, then there will be no ObjectFactory classes packaged
194: * with the webservice. In such cases, use the doc/lit bare minimal marshaller. This marshaller
195: * will use "by java type" marshalling/unmarshalling for primitives and Strings.
196: *
197: * @param op
198: * @return
199: */
200: protected static boolean isDocLitBareMinimal(OperationDescription op) {
201: return isDocLitBare(op) && !isContextPathConstruction(op);
202: }
203:
204: /**
205: * @param op
206: * @return true if JAXBContext constructed using CONTEXT PATH
207: */
208: private static boolean isContextPathConstruction(
209: OperationDescription op) {
210: ServiceDescription serviceDesc = op
211: .getEndpointInterfaceDescription()
212: .getEndpointDescription().getServiceDescription();
213: MarshalServiceRuntimeDescription marshalDesc = MarshalServiceRuntimeDescriptionFactory
214: .get(serviceDesc);
215: // Get the JAXBContext...Since this is a cached object we incur no penalty by looking at this point.
216: Holder<JAXBUtils.CONSTRUCTION_TYPE> holder = new Holder<JAXBUtils.CONSTRUCTION_TYPE>();
217: try {
218: JAXBContext context = JAXBUtils.getJAXBContext(marshalDesc
219: .getPackages(), holder, marshalDesc
220: .getPackagesKey());
221: } catch (JAXBException e) {
222: throw ExceptionFactory.makeWebServiceException(e);
223: }
224: if (holder.value == JAXBUtils.CONSTRUCTION_TYPE.BY_CONTEXT_PATH) {
225: // If JAXBContext was constructed with a context path, this indicates that ObjectFactory (or other
226: // objects) are available.
227: return true;
228: } else {
229: // If JAXBContext was constructed using a class[] or we don't know how it was constructed, then assume
230: // that we need to do the specialized "minimal" marshalling.
231: return false;
232: }
233: }
234:
235: /**
236: * If a web service is created without wsgen, it is possible that the wrapper elements are
237: * missing. In such cases, use the doc/lit wrapped minimal marshaller
238: *
239: * @param op
240: * @return
241: */
242: protected static boolean isDocLitWrappedMinimal(
243: OperationDescription op) {
244: if (isDocLitWrapped(op)) {
245: ServiceDescription serviceDesc = op
246: .getEndpointInterfaceDescription()
247: .getEndpointDescription().getServiceDescription();
248: MarshalServiceRuntimeDescription marshalDesc = MarshalServiceRuntimeDescriptionFactory
249: .get(serviceDesc);
250: String requestWrapper = marshalDesc
251: .getRequestWrapperClassName(op);
252: if (!exists(requestWrapper)) {
253: // TODO DEBUG
254: return true;
255: }
256:
257: String responseWrapper = marshalDesc
258: .getRequestWrapperClassName(op);
259: if (!exists(responseWrapper)) {
260: // TODO DEBUG
261: return true;
262: }
263: // TODO Do the same for the fault beans
264: }
265: return false;
266: }
267:
268: private static boolean exists(String className) {
269: if (className == null || className.length() == 0) {
270: return false;
271: }
272: // TODO try and load the class
273: return true;
274: }
275: }
|