001: package com.sun.xml.ws.client.sei;
002:
003: import com.sun.xml.ws.api.message.Message;
004: import com.sun.xml.ws.model.CheckedExceptionImpl;
005: import com.sun.xml.ws.model.JavaMethodImpl;
006: import com.sun.xml.ws.model.ParameterImpl;
007: import com.sun.xml.ws.model.WrapperParameter;
008:
009: import javax.xml.namespace.QName;
010: import java.util.ArrayList;
011: import java.util.HashMap;
012: import java.util.List;
013: import java.util.Map;
014:
015: /**
016: * {@link com.sun.xml.ws.client.sei.MethodHandler} that handles synchronous method invocations.
017: *
018: * <p>
019: * This class mainly performs the following two tasks:
020: * <ol>
021: * <li>Accepts Object[] that represents arguments for a Java method,
022: * and creates {@link com.sun.xml.ws.message.jaxb.JAXBMessage} that represents a request message.
023: * <li>Takes a {@link com.sun.xml.ws.api.message.Message] that represents a response,
024: * and extracts the return value (and updates {@link javax.xml.ws.Holder }s.)
025: * </ol>
026: *
027: * <h2>Creating {@link com.sun.xml.ws.message.jaxb.JAXBMessage }</h2>
028: * <p>
029: * At the construction time, we prepare {@link com.sun.xml.ws.client.sei.BodyBuilder} and {@link com.sun.xml.ws.client.sei.MessageFiller}s
030: * that know how to move arguments into a {@link com.sun.xml.ws.api.message.Message }.
031: * Some arguments go to the payload, some go to headers, still others go to attachments.
032: *
033: * @author Kohsuke Kawaguchi
034: * @author Jitendra Kotamraju
035: */
036: abstract class SEIMethodHandler extends MethodHandler {
037:
038: // these objects together create a message from method parameters
039: private final BodyBuilder bodyBuilder;
040: private final MessageFiller[] inFillers;
041:
042: protected final String soapAction;
043:
044: protected final boolean isOneWay;
045:
046: protected final JavaMethodImpl javaMethod;
047:
048: protected final Map<QName, CheckedExceptionImpl> checkedExceptions;
049:
050: SEIMethodHandler(SEIStub owner, JavaMethodImpl method) {
051: super (owner);
052:
053: //keep all the CheckedException model for the detail qname
054: this .checkedExceptions = new HashMap<QName, CheckedExceptionImpl>();
055: for (CheckedExceptionImpl ce : method.getCheckedExceptions()) {
056: checkedExceptions.put(
057: ce.getBridge().getTypeReference().tagName, ce);
058: }
059: //If a non-"" soapAction is specified, wsa:action the SOAPAction
060: if (method.getInputAction() != null
061: && !method.getBinding().getSOAPAction().equals("")) {
062: this .soapAction = method.getInputAction();
063: } else {
064: this .soapAction = method.getBinding().getSOAPAction();
065: }
066: this .javaMethod = method;
067:
068: {// prepare objects for creating messages
069: List<ParameterImpl> rp = method.getRequestParameters();
070:
071: BodyBuilder bodyBuilder = null;
072: List<MessageFiller> fillers = new ArrayList<MessageFiller>();
073:
074: for (ParameterImpl param : rp) {
075: ValueGetter getter = getValueGetterFactory().get(param);
076:
077: switch (param.getInBinding().kind) {
078: case BODY:
079: if (param.isWrapperStyle()) {
080: if (param.getParent().getBinding().isRpcLit())
081: bodyBuilder = new BodyBuilder.RpcLit(
082: (WrapperParameter) param,
083: owner.soapVersion,
084: getValueGetterFactory());
085: else
086: bodyBuilder = new BodyBuilder.DocLit(
087: (WrapperParameter) param,
088: owner.soapVersion,
089: getValueGetterFactory());
090: } else {
091: bodyBuilder = new BodyBuilder.Bare(param,
092: owner.soapVersion, getter);
093: }
094: break;
095: case HEADER:
096: fillers.add(new MessageFiller.Header(param
097: .getIndex(), param.getBridge(), getter));
098: break;
099: case ATTACHMENT:
100: fillers.add(MessageFiller.AttachmentFiller
101: .createAttachmentFiller(param, getter));
102: break;
103: case UNBOUND:
104: break;
105: default:
106: throw new AssertionError(); // impossible
107: }
108: }
109:
110: if (bodyBuilder == null) {
111: // no parameter binds to body. we create an empty message
112: switch (owner.soapVersion) {
113: case SOAP_11:
114: bodyBuilder = BodyBuilder.EMPTY_SOAP11;
115: break;
116: case SOAP_12:
117: bodyBuilder = BodyBuilder.EMPTY_SOAP12;
118: break;
119: default:
120: throw new AssertionError();
121: }
122: }
123:
124: this .bodyBuilder = bodyBuilder;
125: this .inFillers = fillers.toArray(new MessageFiller[fillers
126: .size()]);
127: }
128:
129: this .isOneWay = method.getMEP().isOneWay();
130: }
131:
132: ResponseBuilder buildResponseBuilder(JavaMethodImpl method,
133: ValueSetterFactory setterFactory) {
134: // prepare objects for processing response
135: List<ParameterImpl> rp = method.getResponseParameters();
136: List<ResponseBuilder> builders = new ArrayList<ResponseBuilder>();
137:
138: for (ParameterImpl param : rp) {
139: ValueSetter setter;
140: switch (param.getOutBinding().kind) {
141: case BODY:
142: if (param.isWrapperStyle()) {
143: if (param.getParent().getBinding().isRpcLit())
144: builders
145: .add(new ResponseBuilder.RpcLit(
146: (WrapperParameter) param,
147: setterFactory));
148: else
149: builders
150: .add(new ResponseBuilder.DocLit(
151: (WrapperParameter) param,
152: setterFactory));
153: } else {
154: setter = setterFactory.get(param);
155: builders.add(new ResponseBuilder.Body(param
156: .getBridge(), setter));
157: }
158: break;
159: case HEADER:
160: setter = setterFactory.get(param);
161: builders.add(new ResponseBuilder.Header(
162: owner.soapVersion, param, setter));
163: break;
164: case ATTACHMENT:
165: setter = setterFactory.get(param);
166: builders.add(ResponseBuilder.AttachmentBuilder
167: .createAttachmentBuilder(param, setter));
168: break;
169: case UNBOUND:
170: setter = setterFactory.get(param);
171: builders.add(new ResponseBuilder.NullSetter(setter,
172: ResponseBuilder.getVMUninitializedValue(param
173: .getTypeReference().type)));
174: break;
175: default:
176: throw new AssertionError();
177: }
178: }
179: ResponseBuilder rb;
180: switch (builders.size()) {
181: case 0:
182: rb = ResponseBuilder.NONE;
183: break;
184: case 1:
185: rb = builders.get(0);
186: break;
187: default:
188: rb = new ResponseBuilder.Composite(builders);
189: }
190: return rb;
191: }
192:
193: /**
194: * Creates a request {@link com.sun.xml.ws.message.jaxb.JAXBMessage} from method arguments.
195: * @param args proxy invocation arguments
196: * @return Message for the arguments
197: */
198: Message createRequestMessage(Object[] args) {
199: Message msg = bodyBuilder.createMessage(args);
200:
201: for (MessageFiller filler : inFillers)
202: filler.fillIn(args, msg);
203:
204: return msg;
205: }
206:
207: abstract ValueGetterFactory getValueGetterFactory();
208:
209: }
|