src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/SEIStub.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.client.sei;
27
28 import com.sun.istack.internal.NotNull;
29 import com.sun.istack.internal.Nullable;
30 import com.sun.xml.internal.ws.api.SOAPVersion;
31 import com.sun.xml.internal.ws.api.addressing.WSEndpointReference;
32 import com.sun.xml.internal.ws.api.client.WSPortInfo;
33 import com.sun.xml.internal.ws.api.databinding.Databinding;
34 import com.sun.xml.internal.ws.api.addressing.WSEndpointReference;
35 import com.sun.xml.internal.ws.api.message.Header;
36 import com.sun.xml.internal.ws.api.message.Headers;
37 import com.sun.xml.internal.ws.api.message.Packet;
38 import com.sun.xml.internal.ws.api.model.MEP;
39 import com.sun.xml.internal.ws.api.model.wsdl.WSDLBoundOperation;
40 import com.sun.xml.internal.ws.api.pipe.Fiber;
41 import com.sun.xml.internal.ws.api.pipe.Tube;
42 import com.sun.xml.internal.ws.api.server.Container;
43 import com.sun.xml.internal.ws.api.server.ContainerResolver;
44 import com.sun.xml.internal.ws.binding.BindingImpl;
45 import com.sun.xml.internal.ws.client.AsyncResponseImpl;
46 import com.sun.xml.internal.ws.client.RequestContext;
47 import com.sun.xml.internal.ws.client.ResponseContextReceiver;
48 import com.sun.xml.internal.ws.client.Stub;
49 import com.sun.xml.internal.ws.client.WSServiceDelegate;
50 import com.sun.xml.internal.ws.model.JavaMethodImpl;
51 import com.sun.xml.internal.ws.model.SOAPSEIModel;
52 import com.sun.xml.internal.ws.wsdl.OperationDispatcher;
53
54 import javax.xml.namespace.QName;
55 import java.lang.reflect.InvocationHandler;
56 import java.lang.reflect.InvocationTargetException;
57 import java.lang.reflect.Method;
58 import java.lang.reflect.Modifier;
59 import java.lang.reflect.Proxy;
60 import java.util.HashMap;
61 import java.util.Map;
62
63 /**
64 * {@link Stub} that handles method invocations
65 * through a strongly-typed endpoint interface.
66 *
67 * @author Kohsuke Kawaguchi
68 */
69 public final class SEIStub extends Stub implements InvocationHandler {
70
71 Databinding databinding;
72
73 @Deprecated
74 public SEIStub(WSServiceDelegate owner, BindingImpl binding, SOAPSEIModel seiModel, Tube master, WSEndpointReference epr) {
75 super(owner, master, binding, seiModel.getPort(), seiModel.getPort().getAddress(), epr);
76 this.seiModel = seiModel;
77 this.soapVersion = binding.getSOAPVersion();
78 databinding = seiModel.getDatabinding();
79 initMethodHandlers();
80 }
81
82 // added portInterface to the constructor, otherwise AsyncHandler won't work
83 public SEIStub(WSPortInfo portInfo, BindingImpl binding, SOAPSEIModel seiModel, WSEndpointReference epr) {
84 super(portInfo, binding, seiModel.getPort().getAddress(),epr);
85 this.seiModel = seiModel;
86 this.soapVersion = binding.getSOAPVersion();
87 databinding = seiModel.getDatabinding();
88 initMethodHandlers();
89 }
90
91 private void initMethodHandlers() {
92 Map<WSDLBoundOperation, JavaMethodImpl> syncs = new HashMap<WSDLBoundOperation, JavaMethodImpl>();
93
94 // fill in methodHandlers.
95 // first fill in sychronized versions
96 for (JavaMethodImpl m : seiModel.getJavaMethods()) {
97 if (!m.getMEP().isAsync) {
98 SyncMethodHandler handler = new SyncMethodHandler(this, m);
99 syncs.put(m.getOperation(), m);
100 methodHandlers.put(m.getMethod(), handler);
101 }
102 }
103
104 for (JavaMethodImpl jm : seiModel.getJavaMethods()) {
105 JavaMethodImpl sync = syncs.get(jm.getOperation());
106 if (jm.getMEP() == MEP.ASYNC_CALLBACK) {
107 Method m = jm.getMethod();
108 CallbackMethodHandler handler = new CallbackMethodHandler(
109 this, m, m.getParameterTypes().length - 1);
110 methodHandlers.put(m, handler);
111 }
112 if (jm.getMEP() == MEP.ASYNC_POLL) {
113 Method m = jm.getMethod();
114 PollingMethodHandler handler = new PollingMethodHandler(this, m);
115 methodHandlers.put(m, handler);
116 }
117 }
118 }
119
120 public final SOAPSEIModel seiModel;
121
122 public final SOAPVersion soapVersion;
123
124 /**
125 * Nullable when there is no associated WSDL Model
126 * @return
127 */
128 public @Nullable
129 OperationDispatcher getOperationDispatcher() {
130 if(operationDispatcher == null && wsdlPort != null)
131 operationDispatcher = new OperationDispatcher(wsdlPort,binding,seiModel);
132 return operationDispatcher;
133 }
134
135 /**
136 * For each method on the port interface we have
137 * a {@link MethodHandler} that processes it.
138 */
139 private final Map<Method, MethodHandler> methodHandlers = new HashMap<Method, MethodHandler>();
140
141 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
142 validateInputs(proxy, method);
143 Container old = ContainerResolver.getDefault().enterContainer(owner.getContainer());
144 try {
145 MethodHandler handler = methodHandlers.get(method);
146 if (handler != null) {
147 return handler.invoke(proxy, args);
148 } else {
149 // we handle the other method invocations by ourselves
150 try {
151 return method.invoke(this, args);
152 } catch (IllegalAccessException e) {
153 // impossible
154 throw new AssertionError(e);
155 } catch (IllegalArgumentException e) {
156 throw new AssertionError(e);
157 } catch (InvocationTargetException e) {
158 throw e.getCause();
159 }
160 }
161 } finally {
162 ContainerResolver.getDefault().exitContainer(old);
163 }
164 }
165
166 private void validateInputs(Object proxy, Method method) {
167 if (proxy == null || !Proxy.isProxyClass(proxy.getClass())) {
168 throw new IllegalStateException("Passed object is not proxy!");
169 }
170 Class<?> declaringClass = method.getDeclaringClass();
171 if (method == null || declaringClass == null
172 || Modifier.isStatic(method.getModifiers())) {
173 throw new IllegalStateException("Invoking static method is not allowed!");
174 }
175 }
176
177 public final Packet doProcess(Packet request, RequestContext rc, ResponseContextReceiver receiver) {
178 return super.process(request, rc, receiver);
179 }
180
181 public final void doProcessAsync(AsyncResponseImpl<?> receiver, Packet request, RequestContext rc, Fiber.CompletionCallback callback) {
182 super.processAsync(receiver, request, rc, callback);
183 }
184
185 protected final @NotNull QName getPortName() {
186 return wsdlPort.getName();
187 }
188
189
190 public void setOutboundHeaders(Object... headers) {
191 if(headers==null)
192 throw new IllegalArgumentException();
193 Header[] hl = new Header[headers.length];
194 for( int i=0; i<hl.length; i++ ) {
195 if(headers[i]==null)
196 throw new IllegalArgumentException();
197 hl[i] = Headers.create(seiModel.getBindingContext(),headers[i]);
198 }
199 super.setOutboundHeaders(hl);
200 }
201 }

mercurial