001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common Development
008: * and Distribution License("CDDL") (collectively, the "License"). You
009: * may not use this file except in compliance with the License. You can obtain
010: * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
011: * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
012: * language governing permissions and limitations under the License.
013: *
014: * When distributing the software, include this License Header Notice in each
015: * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
016: * Sun designates this particular file as subject to the "Classpath" exception
017: * as provided by Sun in the GPL Version 2 section of the License file that
018: * accompanied this code. If applicable, add the following below the License
019: * Header, with the fields enclosed by brackets [] replaced by your own
020: * identifying information: "Portions Copyrighted [year]
021: * [name of copyright owner]"
022: *
023: * Contributor(s):
024: *
025: * If you wish your version of this file to be governed by only the CDDL or
026: * only the GPL Version 2, indicate your decision by adding "[Contributor]
027: * elects to include this software in this distribution under the [CDDL or GPL
028: * Version 2] license." If you don't indicate a single choice of license, a
029: * recipient has the option to distribute your version of this file under
030: * either the CDDL, the GPL Version 2 or to extend the choice of license to
031: * its licensees as provided above. However, if you add GPL Version 2 code
032: * and therefore, elected the GPL Version 2 license, then the option applies
033: * only if the new code is made subject to such option by the copyright
034: * holder.
035: */
036: package com.sun.xml.ws.model;
037:
038: import com.sun.istack.NotNull;
039: import com.sun.xml.bind.api.TypeReference;
040: import com.sun.xml.ws.api.model.JavaMethod;
041: import com.sun.xml.ws.api.model.MEP;
042: import com.sun.xml.ws.api.model.SEIModel;
043: import com.sun.xml.ws.api.model.wsdl.WSDLBoundOperation;
044: import com.sun.xml.ws.model.soap.SOAPBindingImpl;
045: import com.sun.xml.ws.model.wsdl.WSDLBoundOperationImpl;
046: import com.sun.xml.ws.model.wsdl.WSDLPortImpl;
047: import com.sun.istack.Nullable;
048:
049: import javax.xml.namespace.QName;
050: import javax.xml.ws.Action;
051: import java.lang.reflect.Method;
052: import java.util.ArrayList;
053: import java.util.Collections;
054: import java.util.List;
055:
056: /**
057: * Build this runtime model using java SEI and annotations
058: *
059: * @author Vivek Pandey
060: */
061: public final class JavaMethodImpl implements JavaMethod {
062:
063: private String inputAction;
064: private String outputAction;
065: private final List<CheckedExceptionImpl> exceptions = new ArrayList<CheckedExceptionImpl>();
066: private final Method method;
067: /*package*/final List<ParameterImpl> requestParams = new ArrayList<ParameterImpl>();
068: /*package*/final List<ParameterImpl> responseParams = new ArrayList<ParameterImpl>();
069: private final List<ParameterImpl> unmReqParams = Collections
070: .unmodifiableList(requestParams);
071: private final List<ParameterImpl> unmResParams = Collections
072: .unmodifiableList(responseParams);
073: private SOAPBindingImpl binding;
074: private MEP mep;
075: private String operationName;
076: private WSDLBoundOperationImpl wsdlOperation;
077: /*package*/final AbstractSEIModelImpl owner;
078: private final Method seiMethod;
079:
080: /**
081: * @param owner
082: * @param method : Implementation class method
083: * @param seiMethod : corresponding SEI Method.
084: * Is there is no SEI, it should be Implementation class method
085: */
086: public JavaMethodImpl(AbstractSEIModelImpl owner, Method method,
087: Method seiMethod) {
088: this .owner = owner;
089: this .method = method;
090: this .seiMethod = seiMethod;
091: Action action = method.getAnnotation(Action.class);
092: if (action != null) {
093: inputAction = action.input();
094: outputAction = action.output();
095: }
096: }
097:
098: public SEIModel getOwner() {
099: return owner;
100: }
101:
102: /**
103: * @see {@link JavaMethod}
104: *
105: * @return Returns the method.
106: */
107: public Method getMethod() {
108: return method;
109: }
110:
111: /**
112: * @see {@link JavaMethod}
113: *
114: * @return Returns the SEI method where annotations are present
115: */
116: public Method getSEIMethod() {
117: return seiMethod;
118: }
119:
120: /**
121: * @return Returns the mep.
122: */
123: public MEP getMEP() {
124: return mep;
125: }
126:
127: /**
128: * @param mep
129: * The mep to set.
130: */
131: void setMEP(MEP mep) {
132: this .mep = mep;
133: }
134:
135: /**
136: * @return the Binding object
137: */
138: public SOAPBindingImpl getBinding() {
139: if (binding == null)
140: return new SOAPBindingImpl();
141: return binding;
142: }
143:
144: /**
145: * @param binding
146: */
147: void setBinding(SOAPBindingImpl binding) {
148: this .binding = binding;
149: }
150:
151: /**
152: * Returns the {@link WSDLBoundOperation} Operation associated with {@link this}
153: * operation.
154: *
155: * @return the WSDLBoundOperation for this JavaMethod
156: */
157: public @NotNull
158: WSDLBoundOperation getOperation() {
159: assert wsdlOperation != null;
160: return wsdlOperation;
161: }
162:
163: public void setOperationName(String name) {
164: this .operationName = name;
165: }
166:
167: public String getOperationName() {
168: return operationName;
169: }
170:
171: public String getRequestMessageName() {
172: return operationName;
173: }
174:
175: public String getResponseMessageName() {
176: if (mep.isOneWay())
177: return null;
178: return operationName + "Response";
179: }
180:
181: /**
182: * @return soap:Body's first child name for request message.
183: */
184: public @Nullable
185: QName getRequestPayloadName() {
186: return wsdlOperation.getReqPayloadName();
187: }
188:
189: /**
190: * @return soap:Body's first child name for response message.
191: */
192: public @Nullable
193: QName getResponsePayloadName() {
194: return (mep == MEP.ONE_WAY) ? null : wsdlOperation
195: .getResPayloadName();
196: }
197:
198: /**
199: * @return returns unmodifiable list of request parameters
200: */
201: public List<ParameterImpl> getRequestParameters() {
202: return unmReqParams;
203: }
204:
205: /**
206: * @return returns unmodifiable list of response parameters
207: */
208: public List<ParameterImpl> getResponseParameters() {
209: return unmResParams;
210: }
211:
212: void addParameter(ParameterImpl p) {
213: if (p.isIN() || p.isINOUT()) {
214: assert !requestParams.contains(p);
215: requestParams.add(p);
216: }
217:
218: if (p.isOUT() || p.isINOUT()) {
219: // this check is only for out parameters
220: assert !responseParams.contains(p);
221: responseParams.add(p);
222: }
223: }
224:
225: void addRequestParameter(ParameterImpl p) {
226: if (p.isIN() || p.isINOUT()) {
227: requestParams.add(p);
228: }
229: }
230:
231: void addResponseParameter(ParameterImpl p) {
232: if (p.isOUT() || p.isINOUT()) {
233: responseParams.add(p);
234: }
235: }
236:
237: /**
238: * @return Returns number of java method parameters - that will be all the
239: * IN, INOUT and OUT holders
240: *
241: * @deprecated no longer use in the new architecture
242: */
243: public int getInputParametersCount() {
244: int count = 0;
245: for (ParameterImpl param : requestParams) {
246: if (param.isWrapperStyle()) {
247: count += ((WrapperParameter) param)
248: .getWrapperChildren().size();
249: } else {
250: count++;
251: }
252: }
253:
254: for (ParameterImpl param : responseParams) {
255: if (param.isWrapperStyle()) {
256: for (ParameterImpl wc : ((WrapperParameter) param)
257: .getWrapperChildren()) {
258: if (!wc.isResponse() && wc.isOUT()) {
259: count++;
260: }
261: }
262: } else if (!param.isResponse() && param.isOUT()) {
263: count++;
264: }
265: }
266:
267: return count;
268: }
269:
270: /**
271: * @param ce
272: */
273: void addException(CheckedExceptionImpl ce) {
274: if (!exceptions.contains(ce))
275: exceptions.add(ce);
276: }
277:
278: /**
279: * @param exceptionClass
280: * @return CheckedException corresponding to the exceptionClass. Returns
281: * null if not found.
282: */
283: public CheckedExceptionImpl getCheckedException(Class exceptionClass) {
284: for (CheckedExceptionImpl ce : exceptions) {
285: if (ce.getExceptionClass() == exceptionClass)
286: return ce;
287: }
288: return null;
289: }
290:
291: /**
292: * @return a list of checked Exceptions thrown by this method
293: */
294: public List<CheckedExceptionImpl> getCheckedExceptions() {
295: return Collections.unmodifiableList(exceptions);
296: }
297:
298: public String getInputAction() {
299: return inputAction;
300: }
301:
302: public String getOutputAction() {
303: return outputAction;
304: }
305:
306: /**
307: * @param detailType
308: * @return Gets the CheckedException corresponding to detailType. Returns
309: * null if no CheckedExcpetion with the detailType found.
310: */
311: public CheckedExceptionImpl getCheckedException(
312: TypeReference detailType) {
313: for (CheckedExceptionImpl ce : exceptions) {
314: TypeReference actual = ce.getDetailType();
315: if (actual.tagName.equals(detailType.tagName)
316: && actual.type == detailType.type) {
317: return ce;
318: }
319: }
320: return null;
321: }
322:
323: /**
324: * Returns if the java method is async
325: * @return if this is an Asynch
326: */
327: public boolean isAsync() {
328: return mep.isAsync;
329: }
330:
331: /*package*/void freeze(WSDLPortImpl portType) {
332: this .wsdlOperation = portType.getBinding().get(
333: new QName(portType.getBinding().getPortType().getName()
334: .getNamespaceURI(), operationName));
335: // TODO: replace this with proper error handling
336: if (wsdlOperation == null)
337: throw new Error("Undefined operation name " + operationName);
338: }
339:
340: final void fillTypes(List<TypeReference> types) {
341: fillTypes(requestParams, types);
342: fillTypes(responseParams, types);
343:
344: for (CheckedExceptionImpl ce : exceptions) {
345: types.add(ce.getDetailType());
346: }
347: }
348:
349: private void fillTypes(List<ParameterImpl> params,
350: List<TypeReference> types) {
351: for (ParameterImpl p : params) {
352: p.fillTypes(types);
353: }
354: }
355:
356: }
|