View Javadoc
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.oracle.webservices.internal.api.databinding.JavaCallInfo;
29  import com.sun.xml.internal.ws.api.message.Message;
30  import com.sun.xml.internal.ws.api.message.Packet;
31  import com.sun.xml.internal.ws.client.RequestContext;
32  import com.sun.xml.internal.ws.client.ResponseContextReceiver;
33  import com.sun.xml.internal.ws.encoding.soap.DeserializationException;
34  import com.sun.xml.internal.ws.message.jaxb.JAXBMessage;
35  import com.sun.xml.internal.ws.model.JavaMethodImpl;
36  import com.sun.xml.internal.ws.resources.DispatchMessages;
37  
38  import javax.xml.bind.JAXBException;
39  import javax.xml.stream.XMLStreamException;
40  import javax.xml.ws.Holder;
41  import javax.xml.ws.WebServiceException;
42  
43  import java.lang.reflect.Method;
44  
45  /**
46   * {@link MethodHandler} that handles synchronous method invocations.
47   *
48   * <p>
49   * This class mainly performs the following two tasks:
50   * <ol>
51   *  <li>Accepts Object[] that represents arguments for a Java method,
52   *      and creates {@link JAXBMessage} that represents a request message.
53   *  <li>Takes a {@link Message] that represents a response,
54   *      and extracts the return value (and updates {@link Holder}s.)
55   * </ol>
56   *
57   * <h2>Creating {@link JAXBMessage}</h2>
58   * <p>
59   * At the construction time, we prepare {@link BodyBuilder} and {@link MessageFiller}s
60   * that know how to move arguments into a {@link Message}.
61   * Some arguments go to the payload, some go to headers, still others go to attachments.
62   *
63   * @author Kohsuke Kawaguchi
64   */
65  final class SyncMethodHandler extends MethodHandler {
66      final boolean isVoid;
67      final boolean isOneway;
68      final JavaMethodImpl javaMethod;
69      SyncMethodHandler(SEIStub owner, JavaMethodImpl jm) {
70          super(owner, jm.getMethod());
71          javaMethod = jm;
72          isVoid = void.class.equals(jm.getMethod().getReturnType());
73          isOneway = jm.getMEP().isOneWay();
74      }
75  
76      Object invoke(Object proxy, Object[] args) throws Throwable {
77          return invoke(proxy,args,owner.requestContext,owner);
78      }
79  
80      /**
81       * Invokes synchronously, but with the given {@link RequestContext}
82       * and {@link ResponseContextReceiver}.
83       *
84       * @param rc
85       *      This {@link RequestContext} is used for invoking this method.
86       *      We take this as a separate parameter because of the async invocation
87       *      handling, which requires a separate copy.
88       */
89      Object invoke(Object proxy, Object[] args, RequestContext rc, ResponseContextReceiver receiver) throws Throwable {
90          JavaCallInfo call = owner.databinding.createJavaCallInfo(method, args);
91          Packet req = (Packet) owner.databinding.serializeRequest(call);
92          // process the message
93          Packet reply = owner.doProcess(req,rc,receiver);
94  
95          Message msg = reply.getMessage();
96          if(msg == null) {
97              if (!isOneway || !isVoid) {
98                  throw new WebServiceException(DispatchMessages.INVALID_RESPONSE());
99              }
100             return null;
101         }
102 
103         try {
104             call = owner.databinding.deserializeResponse(reply, call);
105             if (call.getException() != null) {
106                 throw call.getException();
107             } else {
108                 return call.getReturnValue();
109             }
110         } catch (JAXBException e) {
111             throw new DeserializationException(DispatchMessages.INVALID_RESPONSE_DESERIALIZATION(), e);
112         } catch (XMLStreamException e) {
113             throw new DeserializationException(DispatchMessages.INVALID_RESPONSE_DESERIALIZATION(),e);
114         } finally {
115             if (reply.transportBackChannel != null)
116                 reply.transportBackChannel.close();
117         }
118     }
119 
120     ValueGetterFactory getValueGetterFactory() {
121         return ValueGetterFactory.SYNC;
122     }
123 
124 }