feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.client.sei;
|
||||
|
||||
//import com.sun.tools.internal.ws.wsdl.document.soap.SOAPBinding;
|
||||
|
||||
import com.oracle.webservices.internal.api.databinding.JavaCallInfo;
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import com.sun.xml.internal.ws.api.message.Message;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.api.pipe.Fiber;
|
||||
import com.sun.xml.internal.ws.client.AsyncInvoker;
|
||||
import com.sun.xml.internal.ws.client.AsyncResponseImpl;
|
||||
import com.sun.xml.internal.ws.client.RequestContext;
|
||||
import com.sun.xml.internal.ws.client.ResponseContext;
|
||||
|
||||
import javax.xml.ws.AsyncHandler;
|
||||
import javax.xml.ws.Response;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Common part between {@link CallbackMethodHandler} and {@link PollingMethodHandler}.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
abstract class AsyncMethodHandler extends MethodHandler {
|
||||
|
||||
AsyncMethodHandler(SEIStub owner, Method m) {
|
||||
super(owner, m);
|
||||
}
|
||||
|
||||
// private final ResponseBuilder responseBuilder;
|
||||
// /**
|
||||
// * Async bean class that has setters for all out parameters
|
||||
// */
|
||||
// private final @Nullable Class asyncBeanClass;
|
||||
//
|
||||
// AsyncMethodHandler(SEIStub owner, JavaMethodImpl jm, JavaMethodImpl sync) {
|
||||
// super(owner, sync);
|
||||
//
|
||||
// List<ParameterImpl> rp = sync.getResponseParameters();
|
||||
// int size = 0;
|
||||
// for( ParameterImpl param : rp ) {
|
||||
// if (param.isWrapperStyle()) {
|
||||
// WrapperParameter wrapParam = (WrapperParameter)param;
|
||||
// size += wrapParam.getWrapperChildren().size();
|
||||
// if (sync.getBinding().getStyle() == Style.DOCUMENT) {
|
||||
// // doc/asyncBeanClass - asyncBeanClass bean is in async signature
|
||||
// // Add 2 or more so that it is considered as async bean case
|
||||
// size += 2;
|
||||
// }
|
||||
// } else {
|
||||
// ++size;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Class tempWrap = null;
|
||||
// if (size > 1) {
|
||||
// rp = jm.getResponseParameters();
|
||||
// for(ParameterImpl param : rp) {
|
||||
// if (param.isWrapperStyle()) {
|
||||
// WrapperParameter wrapParam = (WrapperParameter)param;
|
||||
// if (sync.getBinding().getStyle() == Style.DOCUMENT) {
|
||||
// // doc/asyncBeanClass style
|
||||
// tempWrap = (Class)wrapParam.getTypeReference().type;
|
||||
// break;
|
||||
// }
|
||||
// for(ParameterImpl p : wrapParam.getWrapperChildren()) {
|
||||
// if (p.getIndex() == -1) {
|
||||
// tempWrap = (Class)p.getTypeReference().type;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (tempWrap != null) {
|
||||
// break;
|
||||
// }
|
||||
// } else {
|
||||
// if (param.getIndex() == -1) {
|
||||
// tempWrap = (Class)param.getTypeReference().type;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// asyncBeanClass = tempWrap;
|
||||
//
|
||||
// switch(size) {
|
||||
// case 0 :
|
||||
// responseBuilder = buildResponseBuilder(sync, ValueSetterFactory.NONE);
|
||||
// break;
|
||||
// case 1 :
|
||||
// responseBuilder = buildResponseBuilder(sync, ValueSetterFactory.SINGLE);
|
||||
// break;
|
||||
// default :
|
||||
// responseBuilder = buildResponseBuilder(sync, new ValueSetterFactory.AsyncBeanValueSetterFactory(asyncBeanClass));
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
protected final Response<Object> doInvoke(Object proxy, Object[] args, AsyncHandler handler) {
|
||||
|
||||
AsyncInvoker invoker = new SEIAsyncInvoker(proxy, args);
|
||||
invoker.setNonNullAsyncHandlerGiven(handler != null);
|
||||
AsyncResponseImpl<Object> ft = new AsyncResponseImpl<Object>(invoker,handler);
|
||||
invoker.setReceiver(ft);
|
||||
ft.run();
|
||||
return ft;
|
||||
}
|
||||
|
||||
private class SEIAsyncInvoker extends AsyncInvoker {
|
||||
// snapshot the context now. this is necessary to avoid concurrency issue,
|
||||
// and is required by the spec
|
||||
private final RequestContext rc = owner.requestContext.copy();
|
||||
private final Object[] args;
|
||||
|
||||
SEIAsyncInvoker(Object proxy, Object[] args) {
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
public void do_run () {
|
||||
JavaCallInfo call = owner.databinding.createJavaCallInfo(method, args);
|
||||
Packet req = (Packet)owner.databinding.serializeRequest(call);
|
||||
|
||||
Fiber.CompletionCallback callback = new Fiber.CompletionCallback() {
|
||||
|
||||
public void onCompletion(@NotNull Packet response) {
|
||||
responseImpl.setResponseContext(new ResponseContext(response));
|
||||
Message msg = response.getMessage();
|
||||
if (msg == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Object[] rargs = new Object[1];
|
||||
JavaCallInfo call = owner.databinding.createJavaCallInfo(method, rargs);
|
||||
call = owner.databinding.deserializeResponse(response, call);
|
||||
if (call.getException() != null) {
|
||||
throw call.getException();
|
||||
} else {
|
||||
responseImpl.set(rargs[0], null);
|
||||
}
|
||||
// dbHandler.readResponse(response, call);
|
||||
// responseImpl.set(rargs[0], null);
|
||||
// if(msg.isFault()) {
|
||||
// SOAPFaultBuilder faultBuilder = SOAPFaultBuilder.create(msg);
|
||||
// throw faultBuilder.createException(checkedExceptions);
|
||||
// } else {
|
||||
// Object[] rargs = new Object[1];
|
||||
// if (asyncBeanClass != null) {
|
||||
// rargs[0] = asyncBeanClass.newInstance();
|
||||
// }
|
||||
// responseBuilder.readResponse(msg, rargs);
|
||||
// responseImpl.set(rargs[0], null);
|
||||
// }
|
||||
} catch (Throwable t) {
|
||||
if (t instanceof RuntimeException) {
|
||||
if (t instanceof WebServiceException) {
|
||||
responseImpl.set(null, t);
|
||||
return;
|
||||
}
|
||||
} else if (t instanceof Exception) {
|
||||
responseImpl.set(null, t);
|
||||
return;
|
||||
}
|
||||
//its RuntimeException or some other exception resulting from user error, wrap it in
|
||||
// WebServiceException
|
||||
responseImpl.set(null, new WebServiceException(t));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void onCompletion(@NotNull Throwable error) {
|
||||
if (error instanceof WebServiceException) {
|
||||
responseImpl.set(null, error);
|
||||
} else {
|
||||
//its RuntimeException or some other exception resulting from user error, wrap it in
|
||||
// WebServiceException
|
||||
responseImpl.set(null, new WebServiceException(error));
|
||||
}
|
||||
}
|
||||
};
|
||||
owner.doProcessAsync(responseImpl, req, rc, callback);
|
||||
}
|
||||
}
|
||||
|
||||
ValueGetterFactory getValueGetterFactory() {
|
||||
return ValueGetterFactory.ASYNC;
|
||||
}
|
||||
|
||||
}
|
||||
298
jdkSrc/jdk8/com/sun/xml/internal/ws/client/sei/BodyBuilder.java
Normal file
298
jdkSrc/jdk8/com/sun/xml/internal/ws/client/sei/BodyBuilder.java
Normal file
@@ -0,0 +1,298 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.client.sei;
|
||||
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.message.Message;
|
||||
import com.sun.xml.internal.ws.api.message.Messages;
|
||||
import com.sun.xml.internal.ws.message.jaxb.JAXBMessage;
|
||||
import com.sun.xml.internal.ws.model.ParameterImpl;
|
||||
import com.sun.xml.internal.ws.model.WrapperParameter;
|
||||
import com.sun.xml.internal.ws.spi.db.BindingContext;
|
||||
import com.sun.xml.internal.ws.spi.db.XMLBridge;
|
||||
import com.sun.xml.internal.ws.spi.db.PropertyAccessor;
|
||||
import com.sun.xml.internal.ws.spi.db.WrapperComposite;
|
||||
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.ws.Holder;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Builds a JAXB object that represents the payload.
|
||||
*
|
||||
* @see MessageFiller
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
abstract class BodyBuilder {
|
||||
abstract Message createMessage(Object[] methodArgs);
|
||||
|
||||
static final BodyBuilder EMPTY_SOAP11 = new Empty(SOAPVersion.SOAP_11);
|
||||
static final BodyBuilder EMPTY_SOAP12 = new Empty(SOAPVersion.SOAP_12);
|
||||
|
||||
private static final class Empty extends BodyBuilder {
|
||||
private final SOAPVersion soapVersion;
|
||||
|
||||
public Empty(SOAPVersion soapVersion) {
|
||||
this.soapVersion = soapVersion;
|
||||
}
|
||||
|
||||
Message createMessage(Object[] methodArgs) {
|
||||
return Messages.createEmpty(soapVersion);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for those {@link BodyBuilder}s that build a {@link Message}
|
||||
* from JAXB objects.
|
||||
*/
|
||||
private static abstract class JAXB extends BodyBuilder {
|
||||
/**
|
||||
* This object determines the binding of the object returned
|
||||
* from {@link #build(Object[])}.
|
||||
*/
|
||||
private final XMLBridge bridge;
|
||||
private final SOAPVersion soapVersion;
|
||||
|
||||
protected JAXB(XMLBridge bridge, SOAPVersion soapVersion) {
|
||||
assert bridge!=null;
|
||||
this.bridge = bridge;
|
||||
this.soapVersion = soapVersion;
|
||||
}
|
||||
|
||||
final Message createMessage(Object[] methodArgs) {
|
||||
return JAXBMessage.create( bridge, build(methodArgs), soapVersion );
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a JAXB object that becomes the payload.
|
||||
*/
|
||||
abstract Object build(Object[] methodArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to create a payload JAXB object just by taking
|
||||
* one of the parameters.
|
||||
*/
|
||||
final static class Bare extends JAXB {
|
||||
/**
|
||||
* The index of the method invocation parameters that goes into the payload.
|
||||
*/
|
||||
private final int methodPos;
|
||||
|
||||
private final ValueGetter getter;
|
||||
|
||||
/**
|
||||
* Creates a {@link BodyBuilder} from a bare parameter.
|
||||
*/
|
||||
Bare(ParameterImpl p, SOAPVersion soapVersion, ValueGetter getter) {
|
||||
super(p.getXMLBridge(), soapVersion);
|
||||
this.methodPos = p.getIndex();
|
||||
this.getter = getter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Picks up an object from the method arguments and uses it.
|
||||
*/
|
||||
Object build(Object[] methodArgs) {
|
||||
return getter.get(methodArgs[methodPos]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used to handle a 'wrapper' style request.
|
||||
* Common part of rpc/lit and doc/lit.
|
||||
*/
|
||||
abstract static class Wrapped extends JAXB {
|
||||
|
||||
/**
|
||||
* Where in the method argument list do they come from?
|
||||
*/
|
||||
protected final int[] indices;
|
||||
|
||||
/**
|
||||
* Abstracts away the {@link Holder} handling when touching method arguments.
|
||||
*/
|
||||
protected final ValueGetter[] getters;
|
||||
|
||||
/**
|
||||
* How does each wrapped parameter binds to XML?
|
||||
*/
|
||||
protected XMLBridge[] parameterBridges;
|
||||
|
||||
/**
|
||||
* List of Parameters packed in the body.
|
||||
* Only used for error diagnostics.
|
||||
*/
|
||||
protected List<ParameterImpl> children;
|
||||
|
||||
protected Wrapped(WrapperParameter wp, SOAPVersion soapVersion, ValueGetterFactory getter) {
|
||||
super(wp.getXMLBridge(), soapVersion);
|
||||
children = wp.getWrapperChildren();
|
||||
indices = new int[children.size()];
|
||||
getters = new ValueGetter[children.size()];
|
||||
for( int i=0; i<indices.length; i++ ) {
|
||||
ParameterImpl p = children.get(i);
|
||||
indices[i] = p.getIndex();
|
||||
getters[i] = getter.get(p);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Packs a bunch of arguments into a {@link WrapperComposite}.
|
||||
*/
|
||||
protected WrapperComposite buildWrapperComposite(Object[] methodArgs) {
|
||||
WrapperComposite cs = new WrapperComposite();
|
||||
cs.bridges = parameterBridges;
|
||||
cs.values = new Object[parameterBridges.length];
|
||||
|
||||
// fill in wrapped parameters from methodArgs
|
||||
for( int i=indices.length-1; i>=0; i-- ) {
|
||||
Object arg = getters[i].get(methodArgs[indices[i]]);
|
||||
if(arg==null) {
|
||||
throw new WebServiceException("Method Parameter: "+
|
||||
children.get(i).getName()+" cannot be null. This is BP 1.1 R2211 violation.");
|
||||
}
|
||||
cs.values[i] = arg;
|
||||
}
|
||||
|
||||
return cs;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to create a payload JAXB object by wrapping
|
||||
* multiple parameters into one "wrapper bean".
|
||||
*/
|
||||
final static class DocLit extends Wrapped {
|
||||
/**
|
||||
* How does each wrapped parameter binds to XML?
|
||||
*/
|
||||
private final PropertyAccessor[] accessors;
|
||||
|
||||
/**
|
||||
* Wrapper bean.
|
||||
*/
|
||||
private final Class wrapper;
|
||||
|
||||
/**
|
||||
* Needed to get wrapper instantiation method.
|
||||
*/
|
||||
private BindingContext bindingContext;
|
||||
private boolean dynamicWrapper;
|
||||
|
||||
/**
|
||||
* Creates a {@link BodyBuilder} from a {@link WrapperParameter}.
|
||||
*/
|
||||
DocLit(WrapperParameter wp, SOAPVersion soapVersion, ValueGetterFactory getter) {
|
||||
super(wp, soapVersion, getter);
|
||||
bindingContext = wp.getOwner().getBindingContext();
|
||||
wrapper = (Class)wp.getXMLBridge().getTypeInfo().type;
|
||||
dynamicWrapper = WrapperComposite.class.equals(wrapper);
|
||||
parameterBridges = new XMLBridge[children.size()];
|
||||
accessors = new PropertyAccessor[children.size()];
|
||||
for( int i=0; i<accessors.length; i++ ) {
|
||||
ParameterImpl p = children.get(i);
|
||||
QName name = p.getName();
|
||||
if (dynamicWrapper) {
|
||||
parameterBridges[i] = children.get(i).getInlinedRepeatedElementBridge();
|
||||
if (parameterBridges[i] == null) parameterBridges[i] = children.get(i).getXMLBridge();
|
||||
} else {
|
||||
try {
|
||||
accessors[i] = p.getOwner().getBindingContext().getElementPropertyAccessor(
|
||||
wrapper, name.getNamespaceURI(), name.getLocalPart() );
|
||||
} catch (JAXBException e) {
|
||||
throw new WebServiceException( // TODO: i18n
|
||||
wrapper+" do not have a property of the name "+name,e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Packs a bunch of arguments into a {@link WrapperComposite}.
|
||||
*/
|
||||
Object build(Object[] methodArgs) {
|
||||
if (dynamicWrapper) return buildWrapperComposite(methodArgs);
|
||||
try {
|
||||
//Object bean = wrapper.newInstance();
|
||||
Object bean = bindingContext.newWrapperInstace(wrapper);
|
||||
|
||||
// fill in wrapped parameters from methodArgs
|
||||
for( int i=indices.length-1; i>=0; i-- ) {
|
||||
accessors[i].set(bean,getters[i].get(methodArgs[indices[i]]));
|
||||
}
|
||||
|
||||
return bean;
|
||||
} catch (InstantiationException e) {
|
||||
// this is irrecoverable
|
||||
Error x = new InstantiationError(e.getMessage());
|
||||
x.initCause(e);
|
||||
throw x;
|
||||
} catch (IllegalAccessException e) {
|
||||
// this is irrecoverable
|
||||
Error x = new IllegalAccessError(e.getMessage());
|
||||
x.initCause(e);
|
||||
throw x;
|
||||
} catch (com.sun.xml.internal.ws.spi.db.DatabindingException e) {
|
||||
// this can happen when the set method throw a checked exception or something like that
|
||||
throw new WebServiceException(e); // TODO:i18n
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used to create a payload JAXB object by wrapping
|
||||
* multiple parameters into a {@link WrapperComposite}.
|
||||
*
|
||||
* <p>
|
||||
* This is used for rpc/lit, as we don't have a wrapper bean for it.
|
||||
* (TODO: Why don't we have a wrapper bean for this, when doc/lit does!?)
|
||||
*/
|
||||
final static class RpcLit extends Wrapped {
|
||||
|
||||
/**
|
||||
* Creates a {@link BodyBuilder} from a {@link WrapperParameter}.
|
||||
*/
|
||||
RpcLit(WrapperParameter wp, SOAPVersion soapVersion, ValueGetterFactory getter) {
|
||||
super(wp, soapVersion, getter);
|
||||
// we'll use CompositeStructure to pack requests
|
||||
assert wp.getTypeInfo().type==WrapperComposite.class;
|
||||
|
||||
parameterBridges = new XMLBridge[children.size()];
|
||||
for( int i=0; i<parameterBridges.length; i++ )
|
||||
parameterBridges[i] = children.get(i).getXMLBridge();
|
||||
}
|
||||
|
||||
Object build(Object[] methodArgs) {
|
||||
return buildWrapperComposite(methodArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.client.sei;
|
||||
|
||||
import com.sun.xml.internal.ws.api.databinding.ClientCallBridge;
|
||||
import com.sun.xml.internal.ws.model.JavaMethodImpl;
|
||||
import javax.xml.ws.AsyncHandler;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
/**
|
||||
* {@link MethodHandler} that uses {@link AsyncHandler}.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
final class CallbackMethodHandler extends AsyncMethodHandler {
|
||||
|
||||
/**
|
||||
* Position of the argument that takes {@link AsyncHandler}.
|
||||
*/
|
||||
private final int handlerPos;
|
||||
|
||||
CallbackMethodHandler(SEIStub owner, Method m, int handlerPos) {
|
||||
super(owner, m);
|
||||
this.handlerPos = handlerPos;
|
||||
}
|
||||
|
||||
// CallbackMethodHandler(SEIStub owner, JavaMethodImpl jm, JavaMethodImpl core, int handlerPos) {
|
||||
// super(owner,jm,core);
|
||||
// this.handlerPos = handlerPos;
|
||||
// }
|
||||
|
||||
Future<?> invoke(Object proxy, Object[] args) throws WebServiceException {
|
||||
// the spec requires the last argument
|
||||
final AsyncHandler handler = (AsyncHandler)args[handlerPos];
|
||||
|
||||
return doInvoke(proxy, args, handler);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.client.sei;
|
||||
|
||||
import com.sun.xml.internal.ws.api.message.Attachment;
|
||||
import com.sun.xml.internal.ws.api.message.Headers;
|
||||
import com.sun.xml.internal.ws.api.message.Message;
|
||||
import com.sun.xml.internal.ws.message.ByteArrayAttachment;
|
||||
import com.sun.xml.internal.ws.message.DataHandlerAttachment;
|
||||
import com.sun.xml.internal.ws.message.JAXBAttachment;
|
||||
import com.sun.xml.internal.ws.model.ParameterImpl;
|
||||
import com.sun.xml.internal.ws.spi.db.XMLBridge;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.UUID;
|
||||
import javax.activation.DataHandler;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
|
||||
/**
|
||||
* Puts a non-payload message parameter to {@link Message}.
|
||||
*
|
||||
* <p>
|
||||
* Instance of this class is used to handle header parameters and attachment parameters.
|
||||
* They add things to {@link Message}.
|
||||
*
|
||||
* @see BodyBuilder
|
||||
* @author Kohsuke Kawaguchi
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
abstract class MessageFiller {
|
||||
|
||||
/**
|
||||
* The index of the method invocation parameters that this object looks for.
|
||||
*/
|
||||
protected final int methodPos;
|
||||
|
||||
protected MessageFiller( int methodPos) {
|
||||
this.methodPos = methodPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves an argument of a method invocation into a {@link Message}.
|
||||
*/
|
||||
abstract void fillIn(Object[] methodArgs, Message msg);
|
||||
|
||||
/**
|
||||
* Adds a parameter as an MIME attachment to {@link Message}.
|
||||
*/
|
||||
static abstract class AttachmentFiller extends MessageFiller {
|
||||
protected final ParameterImpl param;
|
||||
protected final ValueGetter getter;
|
||||
protected final String mimeType;
|
||||
private final String contentIdPart;
|
||||
|
||||
protected AttachmentFiller(ParameterImpl param, ValueGetter getter) {
|
||||
super(param.getIndex());
|
||||
this.param = param;
|
||||
this.getter = getter;
|
||||
mimeType = param.getBinding().getMimeType();
|
||||
try {
|
||||
contentIdPart = URLEncoder.encode(param.getPartName(), "UTF-8")+'=';
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new WebServiceException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an MessageFiller based on the parameter type
|
||||
*
|
||||
* @param param
|
||||
* runtime Parameter that abstracts the annotated java parameter
|
||||
* @param getter
|
||||
* Gets a value from an object that represents a parameter passed
|
||||
* as a method argument.
|
||||
*/
|
||||
public static MessageFiller createAttachmentFiller(ParameterImpl param, ValueGetter getter) {
|
||||
Class type = (Class)param.getTypeInfo().type;
|
||||
if (DataHandler.class.isAssignableFrom(type) || Source.class.isAssignableFrom(type)) {
|
||||
return new DataHandlerFiller(param, getter);
|
||||
} else if (byte[].class==type) {
|
||||
return new ByteArrayFiller(param, getter);
|
||||
} else if(isXMLMimeType(param.getBinding().getMimeType())) {
|
||||
return new JAXBFiller(param, getter);
|
||||
} else {
|
||||
return new DataHandlerFiller(param, getter);
|
||||
}
|
||||
}
|
||||
|
||||
String getContentId() {
|
||||
return contentIdPart+UUID.randomUUID()+"@jaxws.sun.com";
|
||||
}
|
||||
}
|
||||
|
||||
private static class ByteArrayFiller extends AttachmentFiller {
|
||||
protected ByteArrayFiller(ParameterImpl param, ValueGetter getter) {
|
||||
super(param, getter);
|
||||
}
|
||||
void fillIn(Object[] methodArgs, Message msg) {
|
||||
String contentId = getContentId();
|
||||
Object obj = getter.get(methodArgs[methodPos]);
|
||||
Attachment att = new ByteArrayAttachment(contentId,(byte[])obj,mimeType);
|
||||
msg.getAttachments().add(att);
|
||||
}
|
||||
}
|
||||
|
||||
private static class DataHandlerFiller extends AttachmentFiller {
|
||||
protected DataHandlerFiller(ParameterImpl param, ValueGetter getter) {
|
||||
super(param, getter);
|
||||
}
|
||||
void fillIn(Object[] methodArgs, Message msg) {
|
||||
String contentId = getContentId();
|
||||
Object obj = getter.get(methodArgs[methodPos]);
|
||||
DataHandler dh = (obj instanceof DataHandler) ? (DataHandler)obj : new DataHandler(obj,mimeType);
|
||||
Attachment att = new DataHandlerAttachment(contentId, dh);
|
||||
msg.getAttachments().add(att);
|
||||
}
|
||||
}
|
||||
|
||||
private static class JAXBFiller extends AttachmentFiller {
|
||||
protected JAXBFiller(ParameterImpl param, ValueGetter getter) {
|
||||
super(param, getter);
|
||||
}
|
||||
void fillIn(Object[] methodArgs, Message msg) {
|
||||
String contentId = getContentId();
|
||||
Object obj = getter.get(methodArgs[methodPos]);
|
||||
Attachment att = new JAXBAttachment(contentId, obj, param.getXMLBridge(), mimeType);
|
||||
msg.getAttachments().add(att);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a parameter as an header.
|
||||
*/
|
||||
static final class Header extends MessageFiller {
|
||||
private final XMLBridge bridge;
|
||||
private final ValueGetter getter;
|
||||
|
||||
protected Header(int methodPos, XMLBridge bridge, ValueGetter getter) {
|
||||
super(methodPos);
|
||||
this.bridge = bridge;
|
||||
this.getter = getter;
|
||||
}
|
||||
|
||||
void fillIn(Object[] methodArgs, Message msg) {
|
||||
Object value = getter.get(methodArgs[methodPos]);
|
||||
msg.getHeaders().add(Headers.create(bridge,value));
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isXMLMimeType(String mimeType){
|
||||
return (mimeType.equals("text/xml") || mimeType.equals("application/xml"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.client.sei;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
|
||||
import com.sun.xml.internal.ws.api.databinding.ClientCallBridge;
|
||||
|
||||
/**
|
||||
* Handles an invocation of a method.
|
||||
*
|
||||
* <p>
|
||||
* Each instance of {@link MethodHandler} has an implicit knowledge of
|
||||
* a particular method that it handles.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public abstract class MethodHandler {
|
||||
|
||||
protected final SEIStub owner;
|
||||
protected Method method;
|
||||
|
||||
protected MethodHandler(SEIStub owner, Method m) {
|
||||
this.owner = owner;
|
||||
method = m;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the method invocation.
|
||||
*
|
||||
* @param proxy
|
||||
* The proxy object exposed to the user. Must not be null.
|
||||
* @param args
|
||||
* The method invocation arguments. To handle asynchroonus method invocations
|
||||
* without array reallocation, this aray is allowed to be longer than the
|
||||
* actual number of arguments to the method. Additional array space should be
|
||||
* simply ignored.
|
||||
* @return
|
||||
* a return value from the method invocation. may be null.
|
||||
*
|
||||
* @throws WebServiceException
|
||||
* If used on the client side, a {@link WebServiceException} signals an error
|
||||
* during the service invocation.
|
||||
* @throws Throwable
|
||||
* some faults are reported in terms of checked exceptions.
|
||||
*/
|
||||
abstract Object invoke(Object proxy, Object[] args) throws WebServiceException, Throwable;
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.client.sei;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Utility class to invoke sun.reflect.misc.MethodUtil.invoke() if available. If not (other then Oracle JDK) fallbacks
|
||||
* to java.lang,reflect.Method.invoke()
|
||||
* <p/>
|
||||
* Be careful, copy of this class exists in several packages, iny modification must be done to other copies too!
|
||||
*/
|
||||
class MethodUtil {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(MethodUtil.class.getName());
|
||||
private static final Method INVOKE_METHOD;
|
||||
|
||||
static {
|
||||
Method method;
|
||||
try {
|
||||
Class<?> clazz = Class.forName("sun.reflect.misc.MethodUtil");
|
||||
method = clazz.getMethod("invoke", Method.class, Object.class, Object[].class);
|
||||
if (LOGGER.isLoggable(Level.FINE)) {
|
||||
LOGGER.log(Level.FINE, "Class sun.reflect.misc.MethodUtil found; it will be used to invoke methods.");
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
method = null;
|
||||
if (LOGGER.isLoggable(Level.FINE)) {
|
||||
LOGGER.log(Level.FINE, "Class sun.reflect.misc.MethodUtil not found, probably non-Oracle JVM");
|
||||
}
|
||||
}
|
||||
INVOKE_METHOD = method;
|
||||
}
|
||||
|
||||
static Object invoke(Object target, Method method, Object[] args) throws IllegalAccessException, InvocationTargetException {
|
||||
if (INVOKE_METHOD != null) {
|
||||
// sun.reflect.misc.MethodUtil.invoke(method, owner, args)
|
||||
if (LOGGER.isLoggable(Level.FINE)) {
|
||||
LOGGER.log(Level.FINE, "Invoking method using sun.reflect.misc.MethodUtil");
|
||||
}
|
||||
try {
|
||||
return INVOKE_METHOD.invoke(null, method, target, args);
|
||||
} catch (InvocationTargetException ite) {
|
||||
// unwrap invocation exception added by reflection code ...
|
||||
throw unwrapException(ite);
|
||||
}
|
||||
} else {
|
||||
// other then Oracle JDK ...
|
||||
if (LOGGER.isLoggable(Level.FINE)) {
|
||||
LOGGER.log(Level.FINE, "Invoking method directly, probably non-Oracle JVM");
|
||||
}
|
||||
return method.invoke(target, args);
|
||||
}
|
||||
}
|
||||
|
||||
private static InvocationTargetException unwrapException(InvocationTargetException ite) {
|
||||
Throwable targetException = ite.getTargetException();
|
||||
if (targetException != null && targetException instanceof InvocationTargetException) {
|
||||
if (LOGGER.isLoggable(Level.FINE)) {
|
||||
LOGGER.log(Level.FINE, "Unwrapping invocation target exception");
|
||||
}
|
||||
return (InvocationTargetException) targetException;
|
||||
} else {
|
||||
return ite;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.client.sei;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import com.sun.xml.internal.ws.api.databinding.ClientCallBridge;
|
||||
import com.sun.xml.internal.ws.model.JavaMethodImpl;
|
||||
import javax.xml.ws.Response;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
|
||||
/**
|
||||
* {@link MethodHandler} that handles asynchronous invocations through {@link Response}.
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
final class PollingMethodHandler extends AsyncMethodHandler {
|
||||
|
||||
// PollingMethodHandler(SEIStub owner, JavaMethodImpl jm, JavaMethodImpl core) {
|
||||
// super(owner, jm, core);
|
||||
// }
|
||||
|
||||
PollingMethodHandler(SEIStub owner, Method m) {
|
||||
super(owner, m);
|
||||
}
|
||||
|
||||
Response<?> invoke(Object proxy, Object[] args) throws WebServiceException {
|
||||
return doInvoke(proxy,args,null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,721 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.client.sei;
|
||||
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.message.Attachment;
|
||||
import com.sun.xml.internal.ws.api.message.AttachmentSet;
|
||||
import com.sun.xml.internal.ws.api.message.Message;
|
||||
import com.sun.xml.internal.ws.api.model.ParameterBinding;
|
||||
import com.sun.xml.internal.ws.api.streaming.XMLStreamReaderFactory;
|
||||
import com.sun.xml.internal.ws.message.AttachmentUnmarshallerImpl;
|
||||
import com.sun.xml.internal.ws.model.ParameterImpl;
|
||||
import com.sun.xml.internal.ws.model.WrapperParameter;
|
||||
import com.sun.xml.internal.ws.resources.ServerMessages;
|
||||
import com.sun.xml.internal.ws.spi.db.RepeatedElementBridge;
|
||||
import com.sun.xml.internal.ws.spi.db.XMLBridge;
|
||||
import com.sun.xml.internal.ws.spi.db.DatabindingException;
|
||||
import com.sun.xml.internal.ws.spi.db.PropertyAccessor;
|
||||
import com.sun.xml.internal.ws.spi.db.WrapperComposite;
|
||||
import com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil;
|
||||
import com.sun.xml.internal.ws.encoding.StringDataContentHandler;
|
||||
import com.sun.xml.internal.ws.encoding.DataHandlerDataSource;
|
||||
|
||||
import javax.activation.DataHandler;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.soap.SOAPException;
|
||||
import javax.xml.soap.SOAPFault;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
import javax.xml.stream.XMLStreamConstants;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.ws.Holder;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
import javax.xml.ws.soap.SOAPFaultException;
|
||||
import java.awt.Image;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Reads a response {@link Message}, disassembles it, and moves obtained Java values
|
||||
* to the expected places.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
public abstract class ResponseBuilder {
|
||||
/**
|
||||
* Reads a response {@link Message}, disassembles it, and moves obtained Java values
|
||||
* to the expected places.
|
||||
*
|
||||
* @param reply
|
||||
* The reply {@link Message} to be de-composed.
|
||||
* @param args
|
||||
* The Java arguments given to the SEI method invocation.
|
||||
* Some parts of the reply message may be set to {@link Holder}s in the arguments.
|
||||
* @return
|
||||
* If a part of the reply message is returned as a return value from
|
||||
* the SEI method, this method returns that value. Otherwise null.
|
||||
* @throws JAXBException
|
||||
* if there's an error during unmarshalling the reply message.
|
||||
* @throws XMLStreamException
|
||||
* if there's an error during unmarshalling the reply message.
|
||||
*/
|
||||
public abstract Object readResponse(Message reply, Object[] args) throws JAXBException, XMLStreamException;
|
||||
|
||||
static final class WrappedPartBuilder {
|
||||
private final XMLBridge bridge;
|
||||
private final ValueSetter setter;
|
||||
public WrappedPartBuilder(XMLBridge bridge, ValueSetter setter) {
|
||||
this.bridge = bridge;
|
||||
this.setter = setter;
|
||||
}
|
||||
final Object readResponse(Object[] args, XMLStreamReader r, AttachmentSet att) throws JAXBException {
|
||||
Object obj;
|
||||
AttachmentUnmarshallerImpl au = (att != null)?new AttachmentUnmarshallerImpl(att):null;
|
||||
if (bridge instanceof RepeatedElementBridge) {
|
||||
RepeatedElementBridge rbridge = (RepeatedElementBridge)bridge;
|
||||
ArrayList list = new ArrayList();
|
||||
QName name = r.getName();
|
||||
while (r.getEventType()==XMLStreamReader.START_ELEMENT && name.equals(r.getName())) {
|
||||
list.add(rbridge.unmarshal(r, au));
|
||||
XMLStreamReaderUtil.toNextTag(r, name);
|
||||
}
|
||||
obj = rbridge.collectionHandler().convert(list);
|
||||
} else {
|
||||
obj = bridge.unmarshal(r, au);
|
||||
}
|
||||
return setter.put(obj,args);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* {@link ResponseBuilder.PartBuilder} keyed by the element name (inside the wrapper element.)
|
||||
*/
|
||||
protected Map<QName,WrappedPartBuilder> wrappedParts = null;
|
||||
protected QName wrapperName;
|
||||
|
||||
protected Object readWrappedResponse(Message msg, Object[] args) throws JAXBException, XMLStreamException {
|
||||
Object retVal = null;
|
||||
|
||||
if (!msg.hasPayload()) {
|
||||
throw new WebServiceException("No payload. Expecting payload with "+wrapperName+" element");
|
||||
}
|
||||
XMLStreamReader reader = msg.readPayload();
|
||||
XMLStreamReaderUtil.verifyTag(reader,wrapperName);
|
||||
reader.nextTag();
|
||||
|
||||
while(reader.getEventType()==XMLStreamReader.START_ELEMENT) {
|
||||
// TODO: QName has a performance issue
|
||||
WrappedPartBuilder part = wrappedParts.get(reader.getName());
|
||||
if(part==null) {
|
||||
// no corresponding part found. ignore
|
||||
XMLStreamReaderUtil.skipElement(reader);
|
||||
reader.nextTag();
|
||||
} else {
|
||||
Object o = part.readResponse(args,reader, msg.getAttachments());
|
||||
// there's only at most one ResponseBuilder that returns a value.
|
||||
if(o!=null) {
|
||||
assert retVal==null;
|
||||
retVal = o;
|
||||
}
|
||||
}
|
||||
// skip any whitespace
|
||||
if (reader.getEventType() != XMLStreamConstants.START_ELEMENT &&
|
||||
reader.getEventType() != XMLStreamConstants.END_ELEMENT) {
|
||||
XMLStreamReaderUtil.nextElementContent(reader);
|
||||
}
|
||||
}
|
||||
|
||||
// we are done with the body
|
||||
reader.close();
|
||||
XMLStreamReaderFactory.recycle(reader);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
static final class None extends ResponseBuilder {
|
||||
private None(){
|
||||
}
|
||||
@Override
|
||||
public Object readResponse(Message msg, Object[] args) {
|
||||
msg.consume();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The singleton instance that produces null return value.
|
||||
* Used for operations that doesn't have any output.
|
||||
*/
|
||||
public final static ResponseBuilder NONE = new None();
|
||||
|
||||
/**
|
||||
* Returns the 'uninitialized' value for the given type.
|
||||
*
|
||||
* <p>
|
||||
* For primitive types, it's '0', and for reference types, it's null.
|
||||
*/
|
||||
@SuppressWarnings("element-type-mismatch")
|
||||
public static Object getVMUninitializedValue(Type type) {
|
||||
// if this map returns null, that means the 'type' is a reference type,
|
||||
// in which case 'null' is the correct null value, so this code is correct.
|
||||
return primitiveUninitializedValues.get(type);
|
||||
}
|
||||
|
||||
private static final Map<Class,Object> primitiveUninitializedValues = new HashMap<Class, Object>();
|
||||
|
||||
static {
|
||||
Map<Class, Object> m = primitiveUninitializedValues;
|
||||
m.put(int.class,(int)0);
|
||||
m.put(char.class,(char)0);
|
||||
m.put(byte.class,(byte)0);
|
||||
m.put(short.class,(short)0);
|
||||
m.put(long.class,(long)0);
|
||||
m.put(float.class,(float)0);
|
||||
m.put(double.class,(double)0);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link ResponseBuilder} that sets the VM uninitialized value to the type.
|
||||
*/
|
||||
public static final class NullSetter extends ResponseBuilder {
|
||||
private final ValueSetter setter;
|
||||
private final Object nullValue;
|
||||
|
||||
public NullSetter(ValueSetter setter, Object nullValue){
|
||||
assert setter!=null;
|
||||
this.nullValue = nullValue;
|
||||
this.setter = setter;
|
||||
}
|
||||
@Override
|
||||
public Object readResponse(Message msg, Object[] args) {
|
||||
return setter.put(nullValue, args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link ResponseBuilder} that is a composition of multiple
|
||||
* {@link ResponseBuilder}s.
|
||||
*
|
||||
* <p>
|
||||
* Sometimes we need to look at multiple parts of the reply message
|
||||
* (say, two header params, one body param, and three attachments, etc.)
|
||||
* and that's when this object is used to combine multiple {@link ResponseBuilder}s
|
||||
* (that each responsible for handling one part).
|
||||
*
|
||||
* <p>
|
||||
* The model guarantees that only at most one {@link ResponseBuilder} will
|
||||
* return a value as a return value (and everything else has to go to
|
||||
* {@link Holder}s.)
|
||||
*/
|
||||
public static final class Composite extends ResponseBuilder {
|
||||
private final ResponseBuilder[] builders;
|
||||
|
||||
public Composite(ResponseBuilder... builders) {
|
||||
this.builders = builders;
|
||||
}
|
||||
|
||||
public Composite(Collection<? extends ResponseBuilder> builders) {
|
||||
this(builders.toArray(new ResponseBuilder[builders.size()]));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readResponse(Message msg, Object[] args) throws JAXBException, XMLStreamException {
|
||||
Object retVal = null;
|
||||
for (ResponseBuilder builder : builders) {
|
||||
Object r = builder.readResponse(msg,args);
|
||||
// there's only at most one ResponseBuilder that returns a value.
|
||||
if(r!=null) {
|
||||
assert retVal==null;
|
||||
retVal = r;
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an Attachment into a Java parameter.
|
||||
*/
|
||||
public static abstract class AttachmentBuilder extends ResponseBuilder {
|
||||
protected final ValueSetter setter;
|
||||
protected final ParameterImpl param;
|
||||
private final String pname;
|
||||
private final String pname1;
|
||||
|
||||
AttachmentBuilder(ParameterImpl param, ValueSetter setter) {
|
||||
this.setter = setter;
|
||||
this.param = param;
|
||||
this.pname = param.getPartName();
|
||||
this.pname1 = "<"+pname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an AttachmentBuilder based on the parameter type
|
||||
*
|
||||
* @param param
|
||||
* runtime Parameter that abstracts the annotated java parameter
|
||||
* @param setter
|
||||
* specifies how the obtained value is set into the argument. Takes
|
||||
* care of Holder arguments.
|
||||
*/
|
||||
public static ResponseBuilder createAttachmentBuilder(ParameterImpl param, ValueSetter setter) {
|
||||
Class type = (Class)param.getTypeInfo().type;
|
||||
if (DataHandler.class.isAssignableFrom(type)) {
|
||||
return new DataHandlerBuilder(param, setter);
|
||||
} else if (byte[].class==type) {
|
||||
return new ByteArrayBuilder(param, setter);
|
||||
} else if(Source.class.isAssignableFrom(type)) {
|
||||
return new SourceBuilder(param, setter);
|
||||
} else if(Image.class.isAssignableFrom(type)) {
|
||||
return new ImageBuilder(param, setter);
|
||||
} else if(InputStream.class==type) {
|
||||
return new InputStreamBuilder(param, setter);
|
||||
} else if(isXMLMimeType(param.getBinding().getMimeType())) {
|
||||
return new JAXBBuilder(param, setter);
|
||||
} else if(String.class.isAssignableFrom(type)) {
|
||||
return new StringBuilder(param, setter);
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Unexpected Attachment type ="+type);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readResponse(Message msg, Object[] args) throws JAXBException, XMLStreamException {
|
||||
// TODO not to loop
|
||||
for (Attachment att : msg.getAttachments()) {
|
||||
String part = getWSDLPartName(att);
|
||||
if (part == null) {
|
||||
continue;
|
||||
}
|
||||
if(part.equals(pname) || part.equals(pname1)){
|
||||
return mapAttachment(att, args);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
abstract Object mapAttachment(Attachment att, Object[] args) throws JAXBException;
|
||||
}
|
||||
|
||||
private static final class DataHandlerBuilder extends AttachmentBuilder {
|
||||
DataHandlerBuilder(ParameterImpl param, ValueSetter setter) {
|
||||
super(param, setter);
|
||||
}
|
||||
|
||||
@Override
|
||||
Object mapAttachment(Attachment att, Object[] args) {
|
||||
return setter.put(att.asDataHandler(), args);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class StringBuilder extends AttachmentBuilder {
|
||||
StringBuilder(ParameterImpl param, ValueSetter setter) {
|
||||
super(param, setter);
|
||||
}
|
||||
|
||||
@Override
|
||||
Object mapAttachment(Attachment att, Object[] args) {
|
||||
att.getContentType();
|
||||
StringDataContentHandler sdh = new StringDataContentHandler();
|
||||
try {
|
||||
String str = (String)sdh.getContent(new DataHandlerDataSource(att.asDataHandler()));
|
||||
return setter.put(str, args);
|
||||
} catch(Exception e) {
|
||||
throw new WebServiceException(e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ByteArrayBuilder extends AttachmentBuilder {
|
||||
ByteArrayBuilder(ParameterImpl param, ValueSetter setter) {
|
||||
super(param, setter);
|
||||
}
|
||||
|
||||
@Override
|
||||
Object mapAttachment(Attachment att, Object[] args) {
|
||||
return setter.put(att.asByteArray(), args);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class SourceBuilder extends AttachmentBuilder {
|
||||
SourceBuilder(ParameterImpl param, ValueSetter setter) {
|
||||
super(param, setter);
|
||||
}
|
||||
|
||||
@Override
|
||||
Object mapAttachment(Attachment att, Object[] args) {
|
||||
return setter.put(att.asSource(), args);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ImageBuilder extends AttachmentBuilder {
|
||||
ImageBuilder(ParameterImpl param, ValueSetter setter) {
|
||||
super(param, setter);
|
||||
}
|
||||
|
||||
@Override
|
||||
Object mapAttachment(Attachment att, Object[] args) {
|
||||
Image image;
|
||||
InputStream is = null;
|
||||
try {
|
||||
is = att.asInputStream();
|
||||
image = ImageIO.read(is);
|
||||
} catch(IOException ioe) {
|
||||
throw new WebServiceException(ioe);
|
||||
} finally {
|
||||
if (is != null) {
|
||||
try {
|
||||
is.close();
|
||||
} catch(IOException ioe) {
|
||||
throw new WebServiceException(ioe);
|
||||
}
|
||||
}
|
||||
}
|
||||
return setter.put(image, args);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class InputStreamBuilder extends AttachmentBuilder {
|
||||
InputStreamBuilder(ParameterImpl param, ValueSetter setter) {
|
||||
super(param, setter);
|
||||
}
|
||||
|
||||
@Override
|
||||
Object mapAttachment(Attachment att, Object[] args) {
|
||||
return setter.put(att.asInputStream(), args);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class JAXBBuilder extends AttachmentBuilder {
|
||||
JAXBBuilder(ParameterImpl param, ValueSetter setter) {
|
||||
super(param, setter);
|
||||
}
|
||||
|
||||
@Override
|
||||
Object mapAttachment(Attachment att, Object[] args) throws JAXBException {
|
||||
Object obj = param.getXMLBridge().unmarshal(att.asInputStream());
|
||||
return setter.put(obj, args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the WSDL part name of this attachment.
|
||||
*
|
||||
* <p>
|
||||
* According to WSI AP 1.0
|
||||
* <PRE>
|
||||
* 3.8 Value-space of Content-Id Header
|
||||
* Definition: content-id part encoding
|
||||
* The "content-id part encoding" consists of the concatenation of:
|
||||
* The value of the name attribute of the wsdl:part element referenced by the mime:content, in which characters disallowed in content-id headers (non-ASCII characters as represented by code points above 0x7F) are escaped as follows:
|
||||
* o Each disallowed character is converted to UTF-8 as one or more bytes.
|
||||
* o Any bytes corresponding to a disallowed character are escaped with the URI escaping mechanism (that is, converted to %HH, where HH is the hexadecimal notation of the byte value).
|
||||
* o The original character is replaced by the resulting character sequence.
|
||||
* The character '=' (0x3D).
|
||||
* A globally unique value such as a UUID.
|
||||
* The character '@' (0x40).
|
||||
* A valid domain name under the authority of the entity constructing the message.
|
||||
* </PRE>
|
||||
*
|
||||
* So a wsdl:part fooPart will be encoded as:
|
||||
* <fooPart=somereallybignumberlikeauuid@example.com>
|
||||
*
|
||||
* @return null
|
||||
* if the parsing fails.
|
||||
*/
|
||||
@SuppressWarnings("FinalStaticMethod")
|
||||
public static final String getWSDLPartName(com.sun.xml.internal.ws.api.message.Attachment att){
|
||||
String cId = att.getContentId();
|
||||
|
||||
int index = cId.lastIndexOf('@', cId.length());
|
||||
if(index == -1){
|
||||
return null;
|
||||
}
|
||||
String localPart = cId.substring(0, index);
|
||||
index = localPart.lastIndexOf('=', localPart.length());
|
||||
if(index == -1){
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return java.net.URLDecoder.decode(localPart.substring(0, index), "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new WebServiceException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads a header into a JAXB object.
|
||||
*/
|
||||
public static final class Header extends ResponseBuilder {
|
||||
private final XMLBridge<?> bridge;
|
||||
private final ValueSetter setter;
|
||||
private final QName headerName;
|
||||
private final SOAPVersion soapVersion;
|
||||
|
||||
/**
|
||||
* @param soapVersion
|
||||
* SOAP1.1 or 1.2
|
||||
* @param name
|
||||
* The name of the header element.
|
||||
* @param bridge
|
||||
* specifies how to unmarshal a header into a JAXB object.
|
||||
* @param setter
|
||||
* specifies how the obtained value is returned to the client.
|
||||
*/
|
||||
public Header(SOAPVersion soapVersion, QName name, XMLBridge<?> bridge, ValueSetter setter) {
|
||||
this.soapVersion = soapVersion;
|
||||
this.headerName = name;
|
||||
this.bridge = bridge;
|
||||
this.setter = setter;
|
||||
}
|
||||
|
||||
public Header(SOAPVersion soapVersion, ParameterImpl param, ValueSetter setter) {
|
||||
this(soapVersion,
|
||||
param.getTypeInfo().tagName,
|
||||
param.getXMLBridge(),
|
||||
setter);
|
||||
assert param.getOutBinding()== ParameterBinding.HEADER;
|
||||
}
|
||||
|
||||
private SOAPFaultException createDuplicateHeaderException() {
|
||||
try {
|
||||
SOAPFault fault = soapVersion.getSOAPFactory().createFault();
|
||||
fault.setFaultCode(soapVersion.faultCodeServer);
|
||||
fault.setFaultString(ServerMessages.DUPLICATE_PORT_KNOWN_HEADER(headerName));
|
||||
return new SOAPFaultException(fault);
|
||||
} catch(SOAPException e) {
|
||||
throw new WebServiceException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readResponse(Message msg, Object[] args) throws JAXBException {
|
||||
com.sun.xml.internal.ws.api.message.Header header = null;
|
||||
Iterator<com.sun.xml.internal.ws.api.message.Header> it =
|
||||
msg.getHeaders().getHeaders(headerName,true);
|
||||
if (it.hasNext()) {
|
||||
header = it.next();
|
||||
if (it.hasNext()) {
|
||||
throw createDuplicateHeaderException();
|
||||
}
|
||||
}
|
||||
|
||||
if(header!=null)
|
||||
return setter.put( header.readAsJAXB(bridge), args );
|
||||
else
|
||||
// header not found.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the whole payload into a single JAXB bean.
|
||||
*/
|
||||
public static final class Body extends ResponseBuilder {
|
||||
private final XMLBridge<?> bridge;
|
||||
private final ValueSetter setter;
|
||||
|
||||
/**
|
||||
* @param bridge
|
||||
* specifies how to unmarshal the payload into a JAXB object.
|
||||
* @param setter
|
||||
* specifies how the obtained value is returned to the client.
|
||||
*/
|
||||
public Body(XMLBridge<?> bridge, ValueSetter setter) {
|
||||
this.bridge = bridge;
|
||||
this.setter = setter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readResponse(Message msg, Object[] args) throws JAXBException {
|
||||
return setter.put( msg.readPayloadAsJAXB(bridge), args );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Treats a payload as multiple parts wrapped into one element,
|
||||
* and processes all such wrapped parts.
|
||||
*/
|
||||
public static final class DocLit extends ResponseBuilder {
|
||||
/**
|
||||
* {@link PartBuilder} keyed by the element name (inside the wrapper element.)
|
||||
*/
|
||||
private final PartBuilder[] parts;
|
||||
|
||||
private final XMLBridge wrapper;
|
||||
|
||||
private boolean dynamicWrapper;
|
||||
|
||||
public DocLit(WrapperParameter wp, ValueSetterFactory setterFactory) {
|
||||
wrapperName = wp.getName();
|
||||
wrapper = wp.getXMLBridge();
|
||||
Class wrapperType = (Class) wrapper.getTypeInfo().type;
|
||||
dynamicWrapper = WrapperComposite.class.equals(wrapperType);
|
||||
|
||||
List<PartBuilder> tempParts = new ArrayList<PartBuilder>();
|
||||
|
||||
List<ParameterImpl> children = wp.getWrapperChildren();
|
||||
for (ParameterImpl p : children) {
|
||||
if(p.isIN())
|
||||
continue;
|
||||
QName name = p.getName();
|
||||
if (dynamicWrapper) {
|
||||
if (wrappedParts == null) wrappedParts = new HashMap<QName,WrappedPartBuilder>();
|
||||
XMLBridge xmlBridge = p.getInlinedRepeatedElementBridge();
|
||||
if (xmlBridge == null) xmlBridge = p.getXMLBridge();
|
||||
wrappedParts.put( p.getName(), new WrappedPartBuilder(xmlBridge, setterFactory.get(p)));
|
||||
} else {
|
||||
try {
|
||||
tempParts.add(new PartBuilder(
|
||||
wp.getOwner().getBindingContext().getElementPropertyAccessor(
|
||||
wrapperType,
|
||||
name.getNamespaceURI(),
|
||||
p.getName().getLocalPart()),
|
||||
setterFactory.get(p)
|
||||
));
|
||||
// wrapper parameter itself always bind to body, and
|
||||
// so do all its children
|
||||
assert p.getBinding()== ParameterBinding.BODY;
|
||||
} catch (JAXBException e) {
|
||||
throw new WebServiceException( // TODO: i18n
|
||||
wrapperType+" do not have a property of the name "+name,e);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.parts = tempParts.toArray(new PartBuilder[tempParts.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readResponse(Message msg, Object[] args) throws JAXBException, XMLStreamException {
|
||||
if (dynamicWrapper) return readWrappedResponse(msg, args);
|
||||
Object retVal = null;
|
||||
|
||||
if (parts.length>0) {
|
||||
if (!msg.hasPayload()) {
|
||||
throw new WebServiceException("No payload. Expecting payload with "+wrapperName+" element");
|
||||
}
|
||||
XMLStreamReader reader = msg.readPayload();
|
||||
XMLStreamReaderUtil.verifyTag(reader,wrapperName);
|
||||
Object wrapperBean = wrapper.unmarshal(reader, (msg.getAttachments() != null) ?
|
||||
new AttachmentUnmarshallerImpl(msg.getAttachments()): null);
|
||||
|
||||
try {
|
||||
for (PartBuilder part : parts) {
|
||||
Object o = part.readResponse(args,wrapperBean);
|
||||
// there's only at most one ResponseBuilder that returns a value.
|
||||
// TODO: reorder parts so that the return value comes at the end.
|
||||
if(o!=null) {
|
||||
assert retVal==null;
|
||||
retVal = o;
|
||||
}
|
||||
}
|
||||
} catch (DatabindingException e) {
|
||||
// this can happen when the set method throw a checked exception or something like that
|
||||
throw new WebServiceException(e); // TODO:i18n
|
||||
}
|
||||
|
||||
// we are done with the body
|
||||
reader.close();
|
||||
XMLStreamReaderFactory.recycle(reader);
|
||||
} else {
|
||||
msg.consume();
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmarshals each wrapped part into a JAXB object and moves it
|
||||
* to the expected place.
|
||||
*/
|
||||
static final class PartBuilder {
|
||||
private final PropertyAccessor accessor;
|
||||
private final ValueSetter setter;
|
||||
|
||||
/**
|
||||
* @param accessor
|
||||
* specifies which portion of the wrapper bean to obtain the value from.
|
||||
* @param setter
|
||||
* specifies how the obtained value is returned to the client.
|
||||
*/
|
||||
public PartBuilder(PropertyAccessor accessor, ValueSetter setter) {
|
||||
this.accessor = accessor;
|
||||
this.setter = setter;
|
||||
assert accessor!=null && setter!=null;
|
||||
}
|
||||
|
||||
final Object readResponse( Object[] args, Object wrapperBean ) {
|
||||
Object obj = accessor.get(wrapperBean);
|
||||
return setter.put(obj,args);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Treats a payload as multiple parts wrapped into one element,
|
||||
* and processes all such wrapped parts.
|
||||
*/
|
||||
public static final class RpcLit extends ResponseBuilder {
|
||||
public RpcLit(WrapperParameter wp, ValueSetterFactory setterFactory) {
|
||||
assert wp.getTypeInfo().type== WrapperComposite.class;
|
||||
wrapperName = wp.getName();
|
||||
wrappedParts = new HashMap<QName,WrappedPartBuilder>();
|
||||
List<ParameterImpl> children = wp.getWrapperChildren();
|
||||
for (ParameterImpl p : children) {
|
||||
wrappedParts.put( p.getName(), new WrappedPartBuilder(
|
||||
p.getXMLBridge(), setterFactory.get(p)
|
||||
));
|
||||
// wrapper parameter itself always bind to body, and
|
||||
// so do all its children
|
||||
assert p.getBinding()== ParameterBinding.BODY;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readResponse(Message msg, Object[] args) throws JAXBException, XMLStreamException {
|
||||
return readWrappedResponse(msg, args);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isXMLMimeType(String mimeType){
|
||||
return mimeType.equals("text/xml") || mimeType.equals("application/xml");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.client.sei;
|
||||
|
||||
import com.sun.xml.internal.ws.api.message.Message;
|
||||
import com.sun.xml.internal.ws.model.CheckedExceptionImpl;
|
||||
import com.sun.xml.internal.ws.model.JavaMethodImpl;
|
||||
import com.sun.xml.internal.ws.model.ParameterImpl;
|
||||
import com.sun.xml.internal.ws.model.WrapperParameter;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* {@link com.sun.xml.internal.ws.client.sei.MethodHandler} that handles synchronous method invocations.
|
||||
*
|
||||
* <p>
|
||||
* This class mainly performs the following two tasks:
|
||||
* <ol>
|
||||
* <li>Accepts Object[] that represents arguments for a Java method,
|
||||
* and creates {@link com.sun.xml.internal.ws.message.jaxb.JAXBMessage} that represents a request message.
|
||||
* <li>Takes a {@link com.sun.xml.internal.ws.api.message.Message] that represents a response,
|
||||
* and extracts the return value (and updates {@link javax.xml.ws.Holder }s.)
|
||||
* </ol>
|
||||
*
|
||||
* <h2>Creating {@link com.sun.xml.internal.ws.message.jaxb.JAXBMessage }</h2>
|
||||
* <p>
|
||||
* At the construction time, we prepare {@link com.sun.xml.internal.ws.client.sei.BodyBuilder} and {@link com.sun.xml.internal.ws.client.sei.MessageFiller}s
|
||||
* that know how to move arguments into a {@link com.sun.xml.internal.ws.api.message.Message }.
|
||||
* Some arguments go to the payload, some go to headers, still others go to attachments.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
abstract class SEIMethodHandler extends MethodHandler {
|
||||
|
||||
// these objects together create a message from method parameters
|
||||
private BodyBuilder bodyBuilder;
|
||||
private MessageFiller[] inFillers;
|
||||
|
||||
protected String soapAction;
|
||||
|
||||
protected boolean isOneWay;
|
||||
|
||||
protected JavaMethodImpl javaMethod;
|
||||
|
||||
protected Map<QName, CheckedExceptionImpl> checkedExceptions;
|
||||
|
||||
SEIMethodHandler(SEIStub owner) {
|
||||
super(owner, null);
|
||||
}
|
||||
|
||||
SEIMethodHandler(SEIStub owner, JavaMethodImpl method) {
|
||||
super(owner, null);
|
||||
|
||||
//keep all the CheckedException model for the detail qname
|
||||
this.checkedExceptions = new HashMap<QName, CheckedExceptionImpl>();
|
||||
for(CheckedExceptionImpl ce : method.getCheckedExceptions()){
|
||||
checkedExceptions.put(ce.getBond().getTypeInfo().tagName, ce);
|
||||
}
|
||||
//If a non-"" soapAction is specified, wsa:action the SOAPAction
|
||||
if(method.getInputAction() != null && !method.getBinding().getSOAPAction().equals("") ) {
|
||||
this.soapAction = method.getInputAction();
|
||||
} else {
|
||||
this.soapAction = method.getBinding().getSOAPAction();
|
||||
}
|
||||
this.javaMethod = method;
|
||||
|
||||
{// prepare objects for creating messages
|
||||
List<ParameterImpl> rp = method.getRequestParameters();
|
||||
|
||||
BodyBuilder tmpBodyBuilder = null;
|
||||
List<MessageFiller> fillers = new ArrayList<MessageFiller>();
|
||||
|
||||
for (ParameterImpl param : rp) {
|
||||
ValueGetter getter = getValueGetterFactory().get(param);
|
||||
|
||||
switch(param.getInBinding().kind) {
|
||||
case BODY:
|
||||
if(param.isWrapperStyle()) {
|
||||
if(param.getParent().getBinding().isRpcLit())
|
||||
tmpBodyBuilder = new BodyBuilder.RpcLit((WrapperParameter)param, owner.soapVersion, getValueGetterFactory());
|
||||
else
|
||||
tmpBodyBuilder = new BodyBuilder.DocLit((WrapperParameter)param, owner.soapVersion, getValueGetterFactory());
|
||||
} else {
|
||||
tmpBodyBuilder = new BodyBuilder.Bare(param, owner.soapVersion, getter);
|
||||
}
|
||||
break;
|
||||
case HEADER:
|
||||
fillers.add(new MessageFiller.Header(
|
||||
param.getIndex(),
|
||||
param.getXMLBridge(),
|
||||
getter ));
|
||||
break;
|
||||
case ATTACHMENT:
|
||||
fillers.add(MessageFiller.AttachmentFiller.createAttachmentFiller(param, getter));
|
||||
break;
|
||||
case UNBOUND:
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError(); // impossible
|
||||
}
|
||||
}
|
||||
|
||||
if(tmpBodyBuilder==null) {
|
||||
// no parameter binds to body. we create an empty message
|
||||
switch(owner.soapVersion) {
|
||||
case SOAP_11:
|
||||
tmpBodyBuilder = BodyBuilder.EMPTY_SOAP11;
|
||||
break;
|
||||
case SOAP_12:
|
||||
tmpBodyBuilder = BodyBuilder.EMPTY_SOAP12;
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
this.bodyBuilder = tmpBodyBuilder;
|
||||
this.inFillers = fillers.toArray(new MessageFiller[fillers.size()]);
|
||||
}
|
||||
|
||||
this.isOneWay = method.getMEP().isOneWay();
|
||||
}
|
||||
|
||||
ResponseBuilder buildResponseBuilder(JavaMethodImpl method, ValueSetterFactory setterFactory) {
|
||||
// prepare objects for processing response
|
||||
List<ParameterImpl> rp = method.getResponseParameters();
|
||||
List<ResponseBuilder> builders = new ArrayList<ResponseBuilder>();
|
||||
|
||||
for( ParameterImpl param : rp ) {
|
||||
ValueSetter setter;
|
||||
switch(param.getOutBinding().kind) {
|
||||
case BODY:
|
||||
if(param.isWrapperStyle()) {
|
||||
if(param.getParent().getBinding().isRpcLit())
|
||||
builders.add(new ResponseBuilder.RpcLit((WrapperParameter)param, setterFactory));
|
||||
else
|
||||
builders.add(new ResponseBuilder.DocLit((WrapperParameter)param, setterFactory));
|
||||
} else {
|
||||
setter = setterFactory.get(param);
|
||||
builders.add(new ResponseBuilder.Body(param.getXMLBridge(),setter));
|
||||
}
|
||||
break;
|
||||
case HEADER:
|
||||
setter = setterFactory.get(param);
|
||||
builders.add(new ResponseBuilder.Header(owner.soapVersion, param, setter));
|
||||
break;
|
||||
case ATTACHMENT:
|
||||
setter = setterFactory.get(param);
|
||||
builders.add(ResponseBuilder.AttachmentBuilder.createAttachmentBuilder(param, setter));
|
||||
break;
|
||||
case UNBOUND:
|
||||
setter = setterFactory.get(param);
|
||||
builders.add(new ResponseBuilder.NullSetter(setter,
|
||||
ResponseBuilder.getVMUninitializedValue(param.getTypeInfo().type)));
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
ResponseBuilder rb;
|
||||
switch(builders.size()) {
|
||||
case 0:
|
||||
rb = ResponseBuilder.NONE;
|
||||
break;
|
||||
case 1:
|
||||
rb = builders.get(0);
|
||||
break;
|
||||
default:
|
||||
rb = new ResponseBuilder.Composite(builders);
|
||||
}
|
||||
return rb;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a request {@link com.sun.xml.internal.ws.message.jaxb.JAXBMessage} from method arguments.
|
||||
* @param args proxy invocation arguments
|
||||
* @return Message for the arguments
|
||||
*/
|
||||
Message createRequestMessage(Object[] args) {
|
||||
Message msg = bodyBuilder.createMessage(args);
|
||||
|
||||
for (MessageFiller filler : inFillers)
|
||||
filler.fillIn(args,msg);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
abstract ValueGetterFactory getValueGetterFactory();
|
||||
|
||||
}
|
||||
201
jdkSrc/jdk8/com/sun/xml/internal/ws/client/sei/SEIStub.java
Normal file
201
jdkSrc/jdk8/com/sun/xml/internal/ws/client/sei/SEIStub.java
Normal file
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.client.sei;
|
||||
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import com.sun.istack.internal.Nullable;
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.addressing.WSEndpointReference;
|
||||
import com.sun.xml.internal.ws.api.client.WSPortInfo;
|
||||
import com.sun.xml.internal.ws.api.databinding.Databinding;
|
||||
import com.sun.xml.internal.ws.api.addressing.WSEndpointReference;
|
||||
import com.sun.xml.internal.ws.api.message.Header;
|
||||
import com.sun.xml.internal.ws.api.message.Headers;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.api.model.MEP;
|
||||
import com.sun.xml.internal.ws.api.model.wsdl.WSDLBoundOperation;
|
||||
import com.sun.xml.internal.ws.api.pipe.Fiber;
|
||||
import com.sun.xml.internal.ws.api.pipe.Tube;
|
||||
import com.sun.xml.internal.ws.api.server.Container;
|
||||
import com.sun.xml.internal.ws.api.server.ContainerResolver;
|
||||
import com.sun.xml.internal.ws.binding.BindingImpl;
|
||||
import com.sun.xml.internal.ws.client.AsyncResponseImpl;
|
||||
import com.sun.xml.internal.ws.client.RequestContext;
|
||||
import com.sun.xml.internal.ws.client.ResponseContextReceiver;
|
||||
import com.sun.xml.internal.ws.client.Stub;
|
||||
import com.sun.xml.internal.ws.client.WSServiceDelegate;
|
||||
import com.sun.xml.internal.ws.model.JavaMethodImpl;
|
||||
import com.sun.xml.internal.ws.model.SOAPSEIModel;
|
||||
import com.sun.xml.internal.ws.wsdl.OperationDispatcher;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* {@link Stub} that handles method invocations
|
||||
* through a strongly-typed endpoint interface.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public final class SEIStub extends Stub implements InvocationHandler {
|
||||
|
||||
Databinding databinding;
|
||||
|
||||
@Deprecated
|
||||
public SEIStub(WSServiceDelegate owner, BindingImpl binding, SOAPSEIModel seiModel, Tube master, WSEndpointReference epr) {
|
||||
super(owner, master, binding, seiModel.getPort(), seiModel.getPort().getAddress(), epr);
|
||||
this.seiModel = seiModel;
|
||||
this.soapVersion = binding.getSOAPVersion();
|
||||
databinding = seiModel.getDatabinding();
|
||||
initMethodHandlers();
|
||||
}
|
||||
|
||||
// added portInterface to the constructor, otherwise AsyncHandler won't work
|
||||
public SEIStub(WSPortInfo portInfo, BindingImpl binding, SOAPSEIModel seiModel, WSEndpointReference epr) {
|
||||
super(portInfo, binding, seiModel.getPort().getAddress(),epr);
|
||||
this.seiModel = seiModel;
|
||||
this.soapVersion = binding.getSOAPVersion();
|
||||
databinding = seiModel.getDatabinding();
|
||||
initMethodHandlers();
|
||||
}
|
||||
|
||||
private void initMethodHandlers() {
|
||||
Map<WSDLBoundOperation, JavaMethodImpl> syncs = new HashMap<WSDLBoundOperation, JavaMethodImpl>();
|
||||
|
||||
// fill in methodHandlers.
|
||||
// first fill in sychronized versions
|
||||
for (JavaMethodImpl m : seiModel.getJavaMethods()) {
|
||||
if (!m.getMEP().isAsync) {
|
||||
SyncMethodHandler handler = new SyncMethodHandler(this, m);
|
||||
syncs.put(m.getOperation(), m);
|
||||
methodHandlers.put(m.getMethod(), handler);
|
||||
}
|
||||
}
|
||||
|
||||
for (JavaMethodImpl jm : seiModel.getJavaMethods()) {
|
||||
JavaMethodImpl sync = syncs.get(jm.getOperation());
|
||||
if (jm.getMEP() == MEP.ASYNC_CALLBACK) {
|
||||
Method m = jm.getMethod();
|
||||
CallbackMethodHandler handler = new CallbackMethodHandler(
|
||||
this, m, m.getParameterTypes().length - 1);
|
||||
methodHandlers.put(m, handler);
|
||||
}
|
||||
if (jm.getMEP() == MEP.ASYNC_POLL) {
|
||||
Method m = jm.getMethod();
|
||||
PollingMethodHandler handler = new PollingMethodHandler(this, m);
|
||||
methodHandlers.put(m, handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final SOAPSEIModel seiModel;
|
||||
|
||||
public final SOAPVersion soapVersion;
|
||||
|
||||
/**
|
||||
* Nullable when there is no associated WSDL Model
|
||||
* @return
|
||||
*/
|
||||
public @Nullable
|
||||
OperationDispatcher getOperationDispatcher() {
|
||||
if(operationDispatcher == null && wsdlPort != null)
|
||||
operationDispatcher = new OperationDispatcher(wsdlPort,binding,seiModel);
|
||||
return operationDispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* For each method on the port interface we have
|
||||
* a {@link MethodHandler} that processes it.
|
||||
*/
|
||||
private final Map<Method, MethodHandler> methodHandlers = new HashMap<Method, MethodHandler>();
|
||||
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
validateInputs(proxy, method);
|
||||
Container old = ContainerResolver.getDefault().enterContainer(owner.getContainer());
|
||||
try {
|
||||
MethodHandler handler = methodHandlers.get(method);
|
||||
if (handler != null) {
|
||||
return handler.invoke(proxy, args);
|
||||
} else {
|
||||
// we handle the other method invocations by ourselves
|
||||
try {
|
||||
return method.invoke(this, args);
|
||||
} catch (IllegalAccessException e) {
|
||||
// impossible
|
||||
throw new AssertionError(e);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new AssertionError(e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw e.getCause();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
ContainerResolver.getDefault().exitContainer(old);
|
||||
}
|
||||
}
|
||||
|
||||
private void validateInputs(Object proxy, Method method) {
|
||||
if (proxy == null || !Proxy.isProxyClass(proxy.getClass())) {
|
||||
throw new IllegalStateException("Passed object is not proxy!");
|
||||
}
|
||||
Class<?> declaringClass = method.getDeclaringClass();
|
||||
if (method == null || declaringClass == null
|
||||
|| Modifier.isStatic(method.getModifiers())) {
|
||||
throw new IllegalStateException("Invoking static method is not allowed!");
|
||||
}
|
||||
}
|
||||
|
||||
public final Packet doProcess(Packet request, RequestContext rc, ResponseContextReceiver receiver) {
|
||||
return super.process(request, rc, receiver);
|
||||
}
|
||||
|
||||
public final void doProcessAsync(AsyncResponseImpl<?> receiver, Packet request, RequestContext rc, Fiber.CompletionCallback callback) {
|
||||
super.processAsync(receiver, request, rc, callback);
|
||||
}
|
||||
|
||||
protected final @NotNull QName getPortName() {
|
||||
return wsdlPort.getName();
|
||||
}
|
||||
|
||||
|
||||
public void setOutboundHeaders(Object... headers) {
|
||||
if(headers==null)
|
||||
throw new IllegalArgumentException();
|
||||
Header[] hl = new Header[headers.length];
|
||||
for( int i=0; i<hl.length; i++ ) {
|
||||
if(headers[i]==null)
|
||||
throw new IllegalArgumentException();
|
||||
hl[i] = Headers.create(seiModel.getBindingContext(),headers[i]);
|
||||
}
|
||||
super.setOutboundHeaders(hl);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.client.sei;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.jws.soap.SOAPBinding.Style;
|
||||
|
||||
import com.sun.xml.internal.ws.api.message.MessageContextFactory;
|
||||
import com.sun.xml.internal.ws.model.JavaMethodImpl;
|
||||
import com.sun.xml.internal.ws.model.ParameterImpl;
|
||||
import com.sun.xml.internal.ws.model.WrapperParameter;
|
||||
|
||||
public class StubAsyncHandler extends StubHandler {
|
||||
|
||||
private final Class asyncBeanClass;
|
||||
|
||||
public StubAsyncHandler(JavaMethodImpl jm, JavaMethodImpl sync, MessageContextFactory mcf) {
|
||||
super(sync, mcf);
|
||||
|
||||
List<ParameterImpl> rp = sync.getResponseParameters();
|
||||
int size = 0;
|
||||
for( ParameterImpl param : rp ) {
|
||||
if (param.isWrapperStyle()) {
|
||||
WrapperParameter wrapParam = (WrapperParameter)param;
|
||||
size += wrapParam.getWrapperChildren().size();
|
||||
if (sync.getBinding().getStyle() == Style.DOCUMENT) {
|
||||
// doc/asyncBeanClass - asyncBeanClass bean is in async signature
|
||||
// Add 2 or more so that it is considered as async bean case
|
||||
size += 2;
|
||||
}
|
||||
} else {
|
||||
++size;
|
||||
}
|
||||
}
|
||||
|
||||
Class tempWrap = null;
|
||||
if (size > 1) {
|
||||
rp = jm.getResponseParameters();
|
||||
for(ParameterImpl param : rp) {
|
||||
if (param.isWrapperStyle()) {
|
||||
WrapperParameter wrapParam = (WrapperParameter)param;
|
||||
if (sync.getBinding().getStyle() == Style.DOCUMENT) {
|
||||
// doc/asyncBeanClass style
|
||||
tempWrap = (Class)wrapParam.getTypeInfo().type;
|
||||
break;
|
||||
}
|
||||
for(ParameterImpl p : wrapParam.getWrapperChildren()) {
|
||||
if (p.getIndex() == -1) {
|
||||
tempWrap = (Class)p.getTypeInfo().type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tempWrap != null) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (param.getIndex() == -1) {
|
||||
tempWrap = (Class)param.getTypeInfo().type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
asyncBeanClass = tempWrap;
|
||||
|
||||
switch(size) {
|
||||
case 0 :
|
||||
responseBuilder = buildResponseBuilder(sync, ValueSetterFactory.NONE);
|
||||
break;
|
||||
case 1 :
|
||||
responseBuilder = buildResponseBuilder(sync, ValueSetterFactory.SINGLE);
|
||||
break;
|
||||
default :
|
||||
responseBuilder = buildResponseBuilder(sync, new ValueSetterFactory.AsyncBeanValueSetterFactory(asyncBeanClass));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void initArgs(Object[] args) throws Exception {
|
||||
if (asyncBeanClass != null) {
|
||||
args[0] = asyncBeanClass.newInstance();
|
||||
}
|
||||
}
|
||||
|
||||
ValueGetterFactory getValueGetterFactory() {
|
||||
return ValueGetterFactory.ASYNC;
|
||||
}
|
||||
}
|
||||
272
jdkSrc/jdk8/com/sun/xml/internal/ws/client/sei/StubHandler.java
Normal file
272
jdkSrc/jdk8/com/sun/xml/internal/ws/client/sei/StubHandler.java
Normal file
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.client.sei;
|
||||
|
||||
import com.oracle.webservices.internal.api.databinding.JavaCallInfo;
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.databinding.ClientCallBridge;
|
||||
import com.sun.xml.internal.ws.api.message.Message;
|
||||
import com.sun.xml.internal.ws.api.message.MessageContextFactory;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.api.model.JavaMethod;
|
||||
import com.sun.xml.internal.ws.fault.SOAPFaultBuilder;
|
||||
import com.sun.xml.internal.ws.model.CheckedExceptionImpl;
|
||||
import com.sun.xml.internal.ws.model.JavaMethodImpl;
|
||||
import com.sun.xml.internal.ws.model.ParameterImpl;
|
||||
import com.sun.xml.internal.ws.model.WrapperParameter;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* {@link com.sun.xml.internal.ws.client.sei.MethodHandler} that handles synchronous method invocations.
|
||||
* This is refactored from SEIMethodHandler.
|
||||
* <p>
|
||||
* This class mainly performs the following two tasks:
|
||||
* <ol>
|
||||
* <li>Accepts Object[] that represents arguments for a Java method,
|
||||
* and creates {@link com.sun.xml.internal.ws.message.jaxb.JAXBMessage} that represents a request message.
|
||||
* <li>Takes a {@link com.sun.xml.internal.ws.api.message.Message} that represents a response,
|
||||
* and extracts the return value (and updates {@link javax.xml.ws.Holder }s.)
|
||||
* </ol>
|
||||
*
|
||||
* <h2>Creating {@link com.sun.xml.internal.ws.message.jaxb.JAXBMessage }</h2>
|
||||
* <p>
|
||||
* At the construction time, we prepare {@link com.sun.xml.internal.ws.client.sei.BodyBuilder} and {@link com.sun.xml.internal.ws.client.sei.MessageFiller}s
|
||||
* that know how to move arguments into a {@link com.sun.xml.internal.ws.api.message.Message }.
|
||||
* Some arguments go to the payload, some go to headers, still others go to attachments.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
* @author Jitendra Kotamraju
|
||||
* @author shih-chang.chen@oracle.com
|
||||
*/
|
||||
public class StubHandler implements ClientCallBridge {
|
||||
|
||||
// these objects together create a message from method parameters
|
||||
private final BodyBuilder bodyBuilder;
|
||||
private final MessageFiller[] inFillers;
|
||||
protected final String soapAction;
|
||||
protected final boolean isOneWay;
|
||||
protected final JavaMethodImpl javaMethod;
|
||||
protected final Map<QName, CheckedExceptionImpl> checkedExceptions;
|
||||
protected SOAPVersion soapVersion = SOAPVersion.SOAP_11;
|
||||
protected ResponseBuilder responseBuilder;
|
||||
protected MessageContextFactory packetFactory;
|
||||
|
||||
public StubHandler(JavaMethodImpl method, MessageContextFactory mcf) {
|
||||
//keep all the CheckedException model for the detail qname
|
||||
this.checkedExceptions = new HashMap<QName, CheckedExceptionImpl>();
|
||||
for(CheckedExceptionImpl ce : method.getCheckedExceptions()){
|
||||
checkedExceptions.put(ce.getBond().getTypeInfo().tagName, ce);
|
||||
}
|
||||
//If a non-"" soapAction is specified, wsa:action the SOAPAction
|
||||
String soapActionFromBinding = method.getBinding().getSOAPAction();
|
||||
if(method.getInputAction() != null && soapActionFromBinding != null && !soapActionFromBinding.equals("") ) {
|
||||
this.soapAction = method.getInputAction();
|
||||
} else {
|
||||
this.soapAction = soapActionFromBinding;
|
||||
}
|
||||
this.javaMethod = method;
|
||||
packetFactory = mcf;
|
||||
|
||||
soapVersion = javaMethod.getBinding().getSOAPVersion();
|
||||
|
||||
{// prepare objects for creating messages
|
||||
List<ParameterImpl> rp = method.getRequestParameters();
|
||||
|
||||
BodyBuilder bodyBuilder = null;
|
||||
List<MessageFiller> fillers = new ArrayList<MessageFiller>();
|
||||
|
||||
for (ParameterImpl param : rp) {
|
||||
ValueGetter getter = getValueGetterFactory().get(param);
|
||||
|
||||
switch(param.getInBinding().kind) {
|
||||
case BODY:
|
||||
if(param.isWrapperStyle()) {
|
||||
if(param.getParent().getBinding().isRpcLit())
|
||||
bodyBuilder = new BodyBuilder.RpcLit((WrapperParameter)param, soapVersion, getValueGetterFactory());
|
||||
else
|
||||
bodyBuilder = new BodyBuilder.DocLit((WrapperParameter)param, soapVersion, getValueGetterFactory());
|
||||
} else {
|
||||
bodyBuilder = new BodyBuilder.Bare(param, soapVersion, getter);
|
||||
}
|
||||
break;
|
||||
case HEADER:
|
||||
fillers.add(new MessageFiller.Header(
|
||||
param.getIndex(),
|
||||
param.getXMLBridge(),
|
||||
getter ));
|
||||
break;
|
||||
case ATTACHMENT:
|
||||
fillers.add(MessageFiller.AttachmentFiller.createAttachmentFiller(param, getter));
|
||||
break;
|
||||
case UNBOUND:
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError(); // impossible
|
||||
}
|
||||
}
|
||||
|
||||
if(bodyBuilder==null) {
|
||||
// no parameter binds to body. we create an empty message
|
||||
switch(soapVersion) {
|
||||
case SOAP_11:
|
||||
bodyBuilder = BodyBuilder.EMPTY_SOAP11;
|
||||
break;
|
||||
case SOAP_12:
|
||||
bodyBuilder = BodyBuilder.EMPTY_SOAP12;
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
this.bodyBuilder = bodyBuilder;
|
||||
this.inFillers = fillers.toArray(new MessageFiller[fillers.size()]);
|
||||
}
|
||||
|
||||
this.isOneWay = method.getMEP().isOneWay();
|
||||
responseBuilder = buildResponseBuilder(method, ValueSetterFactory.SYNC);
|
||||
}
|
||||
|
||||
ResponseBuilder buildResponseBuilder(JavaMethodImpl method, ValueSetterFactory setterFactory) {
|
||||
// prepare objects for processing response
|
||||
List<ParameterImpl> rp = method.getResponseParameters();
|
||||
List<ResponseBuilder> builders = new ArrayList<ResponseBuilder>();
|
||||
|
||||
for( ParameterImpl param : rp ) {
|
||||
ValueSetter setter;
|
||||
switch(param.getOutBinding().kind) {
|
||||
case BODY:
|
||||
if(param.isWrapperStyle()) {
|
||||
if(param.getParent().getBinding().isRpcLit())
|
||||
builders.add(new ResponseBuilder.RpcLit((WrapperParameter)param, setterFactory));
|
||||
else
|
||||
builders.add(new ResponseBuilder.DocLit((WrapperParameter)param, setterFactory));
|
||||
} else {
|
||||
setter = setterFactory.get(param);
|
||||
builders.add(new ResponseBuilder.Body(param.getXMLBridge(),setter));
|
||||
}
|
||||
break;
|
||||
case HEADER:
|
||||
setter = setterFactory.get(param);
|
||||
builders.add(new ResponseBuilder.Header(soapVersion, param, setter));
|
||||
break;
|
||||
case ATTACHMENT:
|
||||
setter = setterFactory.get(param);
|
||||
builders.add(ResponseBuilder.AttachmentBuilder.createAttachmentBuilder(param, setter));
|
||||
break;
|
||||
case UNBOUND:
|
||||
setter = setterFactory.get(param);
|
||||
builders.add(new ResponseBuilder.NullSetter(setter,
|
||||
ResponseBuilder.getVMUninitializedValue(param.getTypeInfo().type)));
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
ResponseBuilder rb;
|
||||
switch(builders.size()) {
|
||||
case 0:
|
||||
rb = ResponseBuilder.NONE;
|
||||
break;
|
||||
case 1:
|
||||
rb = builders.get(0);
|
||||
break;
|
||||
default:
|
||||
rb = new ResponseBuilder.Composite(builders);
|
||||
}
|
||||
return rb;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a request {@link com.sun.xml.internal.ws.message.jaxb.JAXBMessage} from method arguments.
|
||||
* @param args proxy invocation arguments
|
||||
* @return Message for the arguments
|
||||
*/
|
||||
public Packet createRequestPacket(JavaCallInfo args) {
|
||||
Message msg = bodyBuilder.createMessage(args.getParameters());
|
||||
|
||||
for (MessageFiller filler : inFillers) filler.fillIn(args.getParameters(),msg);
|
||||
|
||||
Packet req = (Packet)packetFactory.createContext(msg);
|
||||
req.setState(Packet.State.ClientRequest);
|
||||
req.soapAction = soapAction;
|
||||
req.expectReply = !isOneWay;
|
||||
req.getMessage().assertOneWay(isOneWay);
|
||||
req.setWSDLOperation(getOperationName());
|
||||
return req;
|
||||
}
|
||||
|
||||
ValueGetterFactory getValueGetterFactory() {
|
||||
return ValueGetterFactory.SYNC;
|
||||
}
|
||||
|
||||
public JavaCallInfo readResponse(Packet p, JavaCallInfo call) throws Throwable {
|
||||
Message msg = p.getMessage();
|
||||
if(msg.isFault()) {
|
||||
SOAPFaultBuilder faultBuilder = SOAPFaultBuilder.create(msg);
|
||||
Throwable t = faultBuilder.createException(checkedExceptions);
|
||||
call.setException(t);
|
||||
throw t;
|
||||
} else {
|
||||
initArgs(call.getParameters());
|
||||
Object ret = responseBuilder.readResponse(msg, call.getParameters());
|
||||
call.setReturnValue(ret);
|
||||
return call;
|
||||
}
|
||||
}
|
||||
|
||||
public QName getOperationName() {
|
||||
//TODO javaMethod.getOperation()
|
||||
return javaMethod.getOperationQName();
|
||||
}
|
||||
|
||||
public String getSoapAction() {
|
||||
return soapAction;
|
||||
}
|
||||
|
||||
public boolean isOneWay() {
|
||||
return isOneWay;
|
||||
}
|
||||
|
||||
protected void initArgs(Object[] args) throws Exception {
|
||||
}
|
||||
|
||||
public Method getMethod() {
|
||||
return javaMethod.getMethod();
|
||||
}
|
||||
|
||||
public JavaMethod getOperationModel() {
|
||||
return javaMethod;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.client.sei;
|
||||
|
||||
import com.oracle.webservices.internal.api.databinding.JavaCallInfo;
|
||||
import com.sun.xml.internal.ws.api.message.Message;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.client.RequestContext;
|
||||
import com.sun.xml.internal.ws.client.ResponseContextReceiver;
|
||||
import com.sun.xml.internal.ws.encoding.soap.DeserializationException;
|
||||
import com.sun.xml.internal.ws.message.jaxb.JAXBMessage;
|
||||
import com.sun.xml.internal.ws.model.JavaMethodImpl;
|
||||
import com.sun.xml.internal.ws.resources.DispatchMessages;
|
||||
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.ws.Holder;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* {@link MethodHandler} that handles synchronous method invocations.
|
||||
*
|
||||
* <p>
|
||||
* This class mainly performs the following two tasks:
|
||||
* <ol>
|
||||
* <li>Accepts Object[] that represents arguments for a Java method,
|
||||
* and creates {@link JAXBMessage} that represents a request message.
|
||||
* <li>Takes a {@link Message] that represents a response,
|
||||
* and extracts the return value (and updates {@link Holder}s.)
|
||||
* </ol>
|
||||
*
|
||||
* <h2>Creating {@link JAXBMessage}</h2>
|
||||
* <p>
|
||||
* At the construction time, we prepare {@link BodyBuilder} and {@link MessageFiller}s
|
||||
* that know how to move arguments into a {@link Message}.
|
||||
* Some arguments go to the payload, some go to headers, still others go to attachments.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
final class SyncMethodHandler extends MethodHandler {
|
||||
final boolean isVoid;
|
||||
final boolean isOneway;
|
||||
final JavaMethodImpl javaMethod;
|
||||
SyncMethodHandler(SEIStub owner, JavaMethodImpl jm) {
|
||||
super(owner, jm.getMethod());
|
||||
javaMethod = jm;
|
||||
isVoid = void.class.equals(jm.getMethod().getReturnType());
|
||||
isOneway = jm.getMEP().isOneWay();
|
||||
}
|
||||
|
||||
Object invoke(Object proxy, Object[] args) throws Throwable {
|
||||
return invoke(proxy,args,owner.requestContext,owner);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes synchronously, but with the given {@link RequestContext}
|
||||
* and {@link ResponseContextReceiver}.
|
||||
*
|
||||
* @param rc
|
||||
* This {@link RequestContext} is used for invoking this method.
|
||||
* We take this as a separate parameter because of the async invocation
|
||||
* handling, which requires a separate copy.
|
||||
*/
|
||||
Object invoke(Object proxy, Object[] args, RequestContext rc, ResponseContextReceiver receiver) throws Throwable {
|
||||
JavaCallInfo call = owner.databinding.createJavaCallInfo(method, args);
|
||||
Packet req = (Packet) owner.databinding.serializeRequest(call);
|
||||
// process the message
|
||||
Packet reply = owner.doProcess(req,rc,receiver);
|
||||
|
||||
Message msg = reply.getMessage();
|
||||
if(msg == null) {
|
||||
if (!isOneway || !isVoid) {
|
||||
throw new WebServiceException(DispatchMessages.INVALID_RESPONSE());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
call = owner.databinding.deserializeResponse(reply, call);
|
||||
if (call.getException() != null) {
|
||||
throw call.getException();
|
||||
} else {
|
||||
return call.getReturnValue();
|
||||
}
|
||||
} catch (JAXBException e) {
|
||||
throw new DeserializationException(DispatchMessages.INVALID_RESPONSE_DESERIALIZATION(), e);
|
||||
} catch (XMLStreamException e) {
|
||||
throw new DeserializationException(DispatchMessages.INVALID_RESPONSE_DESERIALIZATION(),e);
|
||||
} finally {
|
||||
if (reply.transportBackChannel != null)
|
||||
reply.transportBackChannel.close();
|
||||
}
|
||||
}
|
||||
|
||||
ValueGetterFactory getValueGetterFactory() {
|
||||
return ValueGetterFactory.SYNC;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.client.sei;
|
||||
|
||||
import javax.jws.WebParam.Mode;
|
||||
import javax.xml.ws.Holder;
|
||||
|
||||
/**
|
||||
* Gets a value from an object that represents a parameter passed
|
||||
* as a method argument.
|
||||
*
|
||||
* <p>
|
||||
* This abstraction hides the handling of {@link Holder}.
|
||||
*
|
||||
* <p>
|
||||
* {@link ValueGetter} is a stateless behavior encapsulation.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
enum ValueGetter {
|
||||
/**
|
||||
* {@link ValueGetter} that works for {@link Mode#IN} parameter.
|
||||
*
|
||||
* <p>
|
||||
* Since it's the IN mode, the parameter is not a {@link Holder},
|
||||
* therefore the parameter itself is a value.
|
||||
*/
|
||||
PLAIN() {
|
||||
Object get(Object parameter) {
|
||||
return parameter;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Creates {@link ValueGetter} that works for {@link Holder},
|
||||
* which is {@link Mode#INOUT} or {@link Mode#OUT}.
|
||||
*
|
||||
* <p>
|
||||
* In those {@link Mode}s, the parameter is a {@link Holder},
|
||||
* so the value to be sent is obtained by getting the value of the holder.
|
||||
*/
|
||||
HOLDER() {
|
||||
Object get(Object parameter) {
|
||||
if(parameter==null)
|
||||
// the user is allowed to pass in null where a Holder is expected.
|
||||
return null;
|
||||
return ((Holder)parameter).value;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the value to be sent, from a parameter given as a method argument.
|
||||
* @param parameter that is passed by proxy
|
||||
* @return if it holder then its value, otherise parameter itself
|
||||
*/
|
||||
abstract Object get(Object parameter);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.client.sei;
|
||||
|
||||
import com.sun.xml.internal.ws.model.ParameterImpl;
|
||||
|
||||
import javax.jws.WebParam;
|
||||
|
||||
/**
|
||||
* {@link ValueGetterFactory} is used to create {@link ValueGetter} objects.
|
||||
*
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
abstract class ValueGetterFactory {
|
||||
|
||||
abstract ValueGetter get(ParameterImpl p);
|
||||
|
||||
static final ValueGetterFactory SYNC = new ValueGetterFactory() {
|
||||
ValueGetter get(ParameterImpl p) {
|
||||
return (p.getMode()== WebParam.Mode.IN || p.getIndex() == -1)
|
||||
? ValueGetter.PLAIN : ValueGetter.HOLDER;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* In case of SEI async signatures, there are no holders. The OUT
|
||||
* parameters go in async bean class
|
||||
*/
|
||||
static final ValueGetterFactory ASYNC = new ValueGetterFactory() {
|
||||
ValueGetter get(ParameterImpl p) {
|
||||
return ValueGetter.PLAIN;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
193
jdkSrc/jdk8/com/sun/xml/internal/ws/client/sei/ValueSetter.java
Normal file
193
jdkSrc/jdk8/com/sun/xml/internal/ws/client/sei/ValueSetter.java
Normal file
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.client.sei;
|
||||
|
||||
import com.sun.xml.internal.ws.api.model.Parameter;
|
||||
import com.sun.xml.internal.ws.model.ParameterImpl;
|
||||
import com.sun.xml.internal.ws.spi.db.PropertyAccessor;
|
||||
|
||||
import javax.xml.ws.Holder;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.bind.JAXBException;
|
||||
|
||||
/**
|
||||
* Moves a Java value unmarshalled from a response message
|
||||
* to the right place.
|
||||
*
|
||||
* <p>
|
||||
* Sometimes values are returned as a return value, and
|
||||
* others are returned in the {@link Holder} value. Instances
|
||||
* of this interface abstracts this detail.
|
||||
*
|
||||
* <p>
|
||||
* {@link ValueSetter} is a stateless behavior encapsulation.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public abstract class ValueSetter {
|
||||
private ValueSetter() {}
|
||||
|
||||
/**
|
||||
* Moves the value to the expected place.
|
||||
*
|
||||
* @param obj
|
||||
* The unmarshalled object.
|
||||
* @param args
|
||||
* The arguments given to the Java method invocation. If <tt>obj</tt>
|
||||
* is supposed to be returned as a {@link Holder} value, a suitable
|
||||
* {@link Holder} is obtained from this argument list and <tt>obj</tt>
|
||||
* is set.
|
||||
*
|
||||
* @return
|
||||
* if <tt>obj</tt> is supposed to be returned as a return value
|
||||
* from the method, this method returns <tt>obj</tt>. Otherwise null.
|
||||
*/
|
||||
abstract Object put(Object obj, Object[] args);
|
||||
|
||||
/**
|
||||
* Singleton instance.
|
||||
*/
|
||||
private static final ValueSetter RETURN_VALUE = new ReturnValue();
|
||||
/**
|
||||
* {@link Param}s with small index numbers are used often,
|
||||
* so we pool them to reduce the footprint.
|
||||
*/
|
||||
private static final ValueSetter[] POOL = new ValueSetter[16];
|
||||
|
||||
static {
|
||||
for( int i=0; i<POOL.length; i++ )
|
||||
POOL[i] = new Param(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link ValueSetter} suitable for the given {@link Parameter}.
|
||||
*/
|
||||
static ValueSetter getSync(ParameterImpl p) {
|
||||
int idx = p.getIndex();
|
||||
|
||||
if(idx==-1)
|
||||
return RETURN_VALUE;
|
||||
if(idx<POOL.length)
|
||||
return POOL[idx];
|
||||
else
|
||||
return new Param(idx);
|
||||
}
|
||||
|
||||
|
||||
private static final class ReturnValue extends ValueSetter {
|
||||
Object put(Object obj, Object[] args) {
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
static final class Param extends ValueSetter {
|
||||
/**
|
||||
* Index of the argument to put the value to.
|
||||
*/
|
||||
private final int idx;
|
||||
|
||||
public Param(int idx) {
|
||||
this.idx = idx;
|
||||
}
|
||||
|
||||
Object put(Object obj, Object[] args) {
|
||||
Object arg = args[idx];
|
||||
if(arg!=null) {
|
||||
// we build model in such a way that this is guaranteed
|
||||
assert arg instanceof Holder;
|
||||
((Holder)arg).value = obj;
|
||||
}
|
||||
// else {
|
||||
// if null is given as a Holder, there's no place to return
|
||||
// the value, so just ignore.
|
||||
// }
|
||||
|
||||
// no value to return
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Singleton instance.
|
||||
*/
|
||||
static final ValueSetter SINGLE_VALUE = new SingleValue();
|
||||
|
||||
/**
|
||||
* Used in case of async invocation, where there is only one OUT parameter
|
||||
*/
|
||||
private static final class SingleValue extends ValueSetter {
|
||||
/**
|
||||
* Set args[0] as the value
|
||||
*/
|
||||
Object put(Object obj, Object[] args) {
|
||||
args[0] = obj;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* OUT parameters are set in async bean
|
||||
*/
|
||||
static final class AsyncBeanValueSetter extends ValueSetter {
|
||||
|
||||
private final PropertyAccessor accessor;
|
||||
|
||||
AsyncBeanValueSetter(ParameterImpl p, Class wrapper) {
|
||||
QName name = p.getName();
|
||||
try {
|
||||
accessor = p.getOwner().getBindingContext().getElementPropertyAccessor(
|
||||
wrapper, name.getNamespaceURI(), name.getLocalPart() );
|
||||
} catch (JAXBException e) {
|
||||
throw new WebServiceException( // TODO: i18n
|
||||
wrapper+" do not have a property of the name "+name,e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the property in async bean instance
|
||||
*
|
||||
* @param obj property in async bean
|
||||
* @param args args[0] contains async bean instance
|
||||
* @return null always
|
||||
*/
|
||||
Object put(Object obj, Object[] args) {
|
||||
assert args != null;
|
||||
assert args.length == 1;
|
||||
assert args[0] != null;
|
||||
|
||||
Object bean = args[0];
|
||||
try {
|
||||
accessor.set(bean, obj);
|
||||
} catch (Exception e) {
|
||||
throw new WebServiceException(e); // TODO:i18n
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.client.sei;
|
||||
|
||||
import com.sun.xml.internal.ws.model.ParameterImpl;
|
||||
|
||||
import javax.xml.ws.WebServiceException;
|
||||
|
||||
/**
|
||||
* {@link ValueSetterFactory} is used to create {@link ValueSetter}.
|
||||
*
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
public abstract class ValueSetterFactory {
|
||||
|
||||
public abstract ValueSetter get(ParameterImpl p);
|
||||
|
||||
public static final ValueSetterFactory SYNC = new ValueSetterFactory() {
|
||||
public ValueSetter get(ParameterImpl p) {
|
||||
return ValueSetter.getSync(p);
|
||||
}
|
||||
};
|
||||
|
||||
public static final ValueSetterFactory NONE = new ValueSetterFactory() {
|
||||
public ValueSetter get(ParameterImpl p) {
|
||||
throw new WebServiceException("This shouldn't happen. No response parameters.");
|
||||
}
|
||||
};
|
||||
|
||||
public static final ValueSetterFactory SINGLE = new ValueSetterFactory() {
|
||||
public ValueSetter get(ParameterImpl p) {
|
||||
return ValueSetter.SINGLE_VALUE;
|
||||
}
|
||||
};
|
||||
|
||||
public static final class AsyncBeanValueSetterFactory extends ValueSetterFactory {
|
||||
private Class asyncBean;
|
||||
|
||||
public AsyncBeanValueSetterFactory(Class asyncBean) {
|
||||
this.asyncBean = asyncBean;
|
||||
}
|
||||
|
||||
public ValueSetter get(ParameterImpl p) {
|
||||
return new ValueSetter.AsyncBeanValueSetter(p, asyncBean);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* {@link SEIStub} and its supporting code.
|
||||
*/
|
||||
package com.sun.xml.internal.ws.client.sei;
|
||||
Reference in New Issue
Block a user