feat(jdk8): move files to new folder to avoid resources compiled.

This commit is contained in:
2025-09-07 15:25:52 +08:00
parent 3f0047bf6f
commit 8c35cfb1c0
17415 changed files with 217 additions and 213 deletions

View File

@@ -0,0 +1,692 @@
/*
* 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.server.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.jws.WebParam.Mode;
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.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 request {@link Message}, disassembles it, and moves obtained Java values
* to the expected places.
*
* @author Jitendra Kotamraju
*/
public abstract class EndpointArgumentsBuilder {
/**
* Reads a request {@link Message}, disassembles it, and moves obtained
* Java values to the expected places.
*
* @param request
* The request {@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.
* @throws JAXBException
* if there's an error during unmarshalling the request message.
* @throws XMLStreamException
* if there's an error during unmarshalling the request message.
*/
public abstract void readRequest(Message request, Object[] args)
throws JAXBException, XMLStreamException;
static final class None extends EndpointArgumentsBuilder {
private None(){
}
@Override
public void readRequest(Message msg, Object[] args) {
msg.consume();
}
}
/**
* The singleton instance that produces null return value.
* Used for operations that doesn't have any output.
*/
public final static EndpointArgumentsBuilder 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);
}
protected QName wrapperName;
static final class WrappedPartBuilder {
private final XMLBridge bridge;
private final EndpointValueSetter setter;
/**
* @param bridge
* specifies how the part is unmarshalled.
* @param setter
* specifies how the obtained value is returned to the endpoint.
*/
public WrappedPartBuilder(XMLBridge bridge, EndpointValueSetter setter) {
this.bridge = bridge;
this.setter = setter;
}
void readRequest( Object[] args, XMLStreamReader r, AttachmentSet att) throws JAXBException {
Object obj = null;
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);
}
setter.put(obj,args);
}
}
protected Map<QName,WrappedPartBuilder> wrappedParts = null;
protected void readWrappedRequest(Message msg, Object[] args) throws JAXBException, XMLStreamException {
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
QName name = reader.getName();
WrappedPartBuilder part = wrappedParts.get(name);
if(part==null) {
// no corresponding part found. ignore
XMLStreamReaderUtil.skipElement(reader);
reader.nextTag();
} else {
part.readRequest(args,reader, msg.getAttachments());
}
XMLStreamReaderUtil.toNextTag(reader, name);
}
// we are done with the body
reader.close();
XMLStreamReaderFactory.recycle(reader);
}
/**
* {@link EndpointArgumentsBuilder} that sets the VM uninitialized value to the type.
*/
public static final class NullSetter extends EndpointArgumentsBuilder {
private final EndpointValueSetter setter;
private final Object nullValue;
public NullSetter(EndpointValueSetter setter, Object nullValue){
assert setter!=null;
this.nullValue = nullValue;
this.setter = setter;
}
public void readRequest(Message msg, Object[] args) {
setter.put(nullValue, args);
}
}
/**
* {@link EndpointArgumentsBuilder} that is a composition of multiple
* {@link EndpointArgumentsBuilder}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 EndpointArgumentsBuilder}s
* (that each responsible for handling one part).
*
* <p>
* The model guarantees that only at most one {@link EndpointArgumentsBuilder} will
* return a value as a return value (and everything else has to go to
* {@link Holder}s.)
*/
public static final class Composite extends EndpointArgumentsBuilder {
private final EndpointArgumentsBuilder[] builders;
public Composite(EndpointArgumentsBuilder... builders) {
this.builders = builders;
}
public Composite(Collection<? extends EndpointArgumentsBuilder> builders) {
this(builders.toArray(new EndpointArgumentsBuilder[builders.size()]));
}
public void readRequest(Message msg, Object[] args) throws JAXBException, XMLStreamException {
for (EndpointArgumentsBuilder builder : builders) {
builder.readRequest(msg,args);
}
}
}
/**
* Reads an Attachment into a Java parameter.
*/
public static abstract class AttachmentBuilder extends EndpointArgumentsBuilder {
protected final EndpointValueSetter setter;
protected final ParameterImpl param;
protected final String pname;
protected final String pname1;
AttachmentBuilder(ParameterImpl param, EndpointValueSetter 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 EndpointArgumentsBuilder createAttachmentBuilder(ParameterImpl param, EndpointValueSetter 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("Unknown Type="+type+" Attachment is not mapped.");
}
}
public void readRequest(Message msg, Object[] args) throws JAXBException, XMLStreamException {
boolean foundAttachment = false;
// TODO not to loop
for (Attachment att : msg.getAttachments()) {
String part = getWSDLPartName(att);
if (part == null) {
continue;
}
if(part.equals(pname) || part.equals(pname1)){
foundAttachment = true;
mapAttachment(att, args);
break;
}
}
if (!foundAttachment) {
throw new WebServiceException("Missing Attachment for "+pname);
}
}
abstract void mapAttachment(Attachment att, Object[] args) throws JAXBException;
}
private static final class DataHandlerBuilder extends AttachmentBuilder {
DataHandlerBuilder(ParameterImpl param, EndpointValueSetter setter) {
super(param, setter);
}
void mapAttachment(Attachment att, Object[] args) {
setter.put(att.asDataHandler(), args);
}
}
private static final class ByteArrayBuilder extends AttachmentBuilder {
ByteArrayBuilder(ParameterImpl param, EndpointValueSetter setter) {
super(param, setter);
}
void mapAttachment(Attachment att, Object[] args) {
setter.put(att.asByteArray(), args);
}
}
private static final class SourceBuilder extends AttachmentBuilder {
SourceBuilder(ParameterImpl param, EndpointValueSetter setter) {
super(param, setter);
}
void mapAttachment(Attachment att, Object[] args) {
setter.put(att.asSource(), args);
}
}
private static final class ImageBuilder extends AttachmentBuilder {
ImageBuilder(ParameterImpl param, EndpointValueSetter setter) {
super(param, setter);
}
void 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);
}
}
}
setter.put(image, args);
}
}
private static final class InputStreamBuilder extends AttachmentBuilder {
InputStreamBuilder(ParameterImpl param, EndpointValueSetter setter) {
super(param, setter);
}
void mapAttachment(Attachment att, Object[] args) {
setter.put(att.asInputStream(), args);
}
}
private static final class JAXBBuilder extends AttachmentBuilder {
JAXBBuilder(ParameterImpl param, EndpointValueSetter setter) {
super(param, setter);
}
void mapAttachment(Attachment att, Object[] args) throws JAXBException {
Object obj = param.getXMLBridge().unmarshal(att.asInputStream());
setter.put(obj, args);
}
}
private static final class StringBuilder extends AttachmentBuilder {
StringBuilder(ParameterImpl param, EndpointValueSetter setter) {
super(param, setter);
}
void mapAttachment(Attachment att, Object[] args) {
att.getContentType();
StringDataContentHandler sdh = new StringDataContentHandler();
try {
String str = (String)sdh.getContent(new DataHandlerDataSource(att.asDataHandler()));
setter.put(str, args);
} catch(Exception e) {
throw new WebServiceException(e);
}
}
}
/**
* 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.
*/
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 EndpointArgumentsBuilder {
private final XMLBridge<?> bridge;
private final EndpointValueSetter setter;
private final QName headerName;
private final SOAPVersion soapVersion;
/**
* @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, EndpointValueSetter setter) {
this.soapVersion = soapVersion;
this.headerName = name;
this.bridge = bridge;
this.setter = setter;
}
public Header(SOAPVersion soapVersion, ParameterImpl param, EndpointValueSetter 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.faultCodeClient);
fault.setFaultString(ServerMessages.DUPLICATE_PORT_KNOWN_HEADER(headerName));
return new SOAPFaultException(fault);
} catch(SOAPException e) {
throw new WebServiceException(e);
}
}
public void readRequest(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) {
setter.put( header.readAsJAXB(bridge), args );
} else {
// header not found.
}
}
}
/**
* Reads the whole payload into a single JAXB bean.
*/
public static final class Body extends EndpointArgumentsBuilder {
private final XMLBridge<?> bridge;
private final EndpointValueSetter 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, EndpointValueSetter setter) {
this.bridge = bridge;
this.setter = setter;
}
public void readRequest(Message msg, Object[] args) throws JAXBException {
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 EndpointArgumentsBuilder {
/**
* {@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, Mode skipMode) {
wrapperName = wp.getName();
wrapper = wp.getXMLBridge();
Class wrapperType = (Class) wrapper.getTypeInfo().type;
dynamicWrapper = WrapperComposite.class.equals(wrapperType);
List<PartBuilder> parts = new ArrayList<PartBuilder>();
List<ParameterImpl> children = wp.getWrapperChildren();
for (ParameterImpl p : children) {
if (p.getMode() == skipMode) {
continue;
}
/*
if(p.isIN())
continue;
*/
QName name = p.getName();
try {
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, EndpointValueSetter.get(p)));
} else {
parts.add( new PartBuilder(
wp.getOwner().getBindingContext().getElementPropertyAccessor(
wrapperType,
name.getNamespaceURI(),
p.getName().getLocalPart()),
EndpointValueSetter.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 = parts.toArray(new PartBuilder[parts.size()]);
}
public void readRequest(Message msg, Object[] args) throws JAXBException, XMLStreamException {
if (dynamicWrapper) {
readWrappedRequest(msg, args);
} else {
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) {
part.readRequest(args,wrapperBean);
}
} 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();
}
}
}
/**
* 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 EndpointValueSetter 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, EndpointValueSetter setter) {
this.accessor = accessor;
this.setter = setter;
assert accessor!=null && setter!=null;
}
final void readRequest( Object[] args, Object wrapperBean ) {
Object obj = accessor.get(wrapperBean);
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 EndpointArgumentsBuilder {
public RpcLit(WrapperParameter wp) {
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(), EndpointValueSetter.get(p)
));
// wrapper parameter itself always bind to body, and
// so do all its children
assert p.getBinding()== ParameterBinding.BODY;
}
}
public void readRequest(Message msg, Object[] args) throws JAXBException, XMLStreamException {
readWrappedRequest(msg, args);
}
}
private static boolean isXMLMimeType(String mimeType){
return mimeType.equals("text/xml") || mimeType.equals("application/xml");
}
}

View File

@@ -0,0 +1,318 @@
/*
* 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.server.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 Jitendra Kotamraju
*/
public abstract class EndpointResponseMessageBuilder {
public abstract Message createMessage(Object[] methodArgs, Object returnValue);
public static final EndpointResponseMessageBuilder EMPTY_SOAP11 = new Empty(SOAPVersion.SOAP_11);
public static final EndpointResponseMessageBuilder EMPTY_SOAP12 = new Empty(SOAPVersion.SOAP_12);
private static final class Empty extends EndpointResponseMessageBuilder {
private final SOAPVersion soapVersion;
public Empty(SOAPVersion soapVersion) {
this.soapVersion = soapVersion;
}
public Message createMessage(Object[] methodArgs, Object returnValue) {
return Messages.createEmpty(soapVersion);
}
}
/**
* Base class for those {@link EndpointResponseMessageBuilder}s that build a {@link Message}
* from JAXB objects.
*/
private static abstract class JAXB extends EndpointResponseMessageBuilder {
/**
* This object determines the binding of the object returned
* from {@link #createMessage(Object[], Object)}
*/
private final XMLBridge bridge;
private final SOAPVersion soapVersion;
protected JAXB(XMLBridge bridge, SOAPVersion soapVersion) {
assert bridge!=null;
this.bridge = bridge;
this.soapVersion = soapVersion;
}
public final Message createMessage(Object[] methodArgs, Object returnValue) {
return JAXBMessage.create( bridge, build(methodArgs, returnValue), soapVersion );
}
/**
* Builds a JAXB object that becomes the payload.
*/
abstract Object build(Object[] methodArgs, Object returnValue);
}
/**
* Used to create a payload JAXB object just by taking
* one of the parameters.
*/
public 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 EndpointResponseMessageBuilder} from a bare parameter.
*/
public Bare(ParameterImpl p, SOAPVersion soapVersion) {
super(p.getXMLBridge(), soapVersion);
this.methodPos = p.getIndex();
this.getter = ValueGetter.get(p);
}
/**
* Picks up an object from the method arguments and uses it.
*/
Object build(Object[] methodArgs, Object returnValue) {
if (methodPos == -1) {
return returnValue;
}
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;
/**
* Used for error diagnostics.
*/
protected List<ParameterImpl> children;
protected Wrapped(WrapperParameter wp, SOAPVersion soapVersion) {
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] = ValueGetter.get(p);
}
}
/**
* Packs a bunch of arguments intoa {@link WrapperComposite}.
*/
WrapperComposite buildWrapperComposite(Object[] methodArgs, Object returnValue) {
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 v;
if (indices[i] == -1) {
v = getters[i].get(returnValue);
} else {
v = getters[i].get(methodArgs[indices[i]]);
}
if(v==null) {
throw new WebServiceException("Method Parameter: "+
children.get(i).getName() +" cannot be null. This is BP 1.1 R2211 violation.");
}
cs.values[i] = v;
}
return cs;
}
}
/**
* Used to create a payload JAXB object by wrapping
* multiple parameters into one "wrapper bean".
*/
public final static class DocLit extends Wrapped {
/**
* How does each wrapped parameter binds to XML?
*/
private final PropertyAccessor[] accessors;
//private final RawAccessor retAccessor;
/**
* Wrapper bean.
*/
private final Class wrapper;
private boolean dynamicWrapper;
/**
* Needed to get wrapper instantiation method.
*/
private BindingContext bindingContext;
/**
* Creates a {@link EndpointResponseMessageBuilder} from a {@link WrapperParameter}.
*/
public DocLit(WrapperParameter wp, SOAPVersion soapVersion) {
super(wp, soapVersion);
bindingContext = wp.getOwner().getBindingContext();
wrapper = (Class)wp.getXMLBridge().getTypeInfo().type;
dynamicWrapper = WrapperComposite.class.equals(wrapper);
children = wp.getWrapperChildren();
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] = (dynamicWrapper) ? null :
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, Object returnValue) {
if (dynamicWrapper) return buildWrapperComposite(methodArgs, returnValue);
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-- ) {
if (indices[i] == -1) {
accessors[i].set(bean, returnValue);
} else {
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!?)
*/
public final static class RpcLit extends Wrapped {
/**
* Creates a {@link EndpointResponseMessageBuilder} from a {@link WrapperParameter}.
*/
public RpcLit(WrapperParameter wp, SOAPVersion soapVersion) {
super(wp, soapVersion);
// 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();
}
/**
* Packs a bunch of arguments intoa {@link WrapperComposite}.
*/
Object build(Object[] methodArgs, Object returnValue) {
return buildWrapperComposite(methodArgs, returnValue);
}
}
}

View File

@@ -0,0 +1,123 @@
/*
* 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.server.sei;
import com.sun.xml.internal.ws.api.model.Parameter;
import com.sun.xml.internal.ws.model.ParameterImpl;
import javax.xml.ws.Holder;
/**
* 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 EndpointValueSetter} is a stateless behavior encapsulation.
*
* @author Jitendra Kotamraju
*/
public abstract class EndpointValueSetter {
private EndpointValueSetter() {}
/**
* Moves the value to the expected place.
*
* @param obj
* The unmarshalled object.
* @param args
* The arguments that need to be 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.
*
*/
abstract void put(Object obj, Object[] args);
/**
* {@link Param}s with small index numbers are used often,
* so we pool them to reduce the footprint.
*/
private static final EndpointValueSetter[] POOL = new EndpointValueSetter[16];
static {
for( int i=0; i<POOL.length; i++ )
POOL[i] = new Param(i);
}
/**
* Returns a {@link EndpointValueSetter} suitable for the given {@link Parameter}.
*/
public static EndpointValueSetter get(ParameterImpl p) {
int idx = p.getIndex();
if (p.isIN()) {
if (idx<POOL.length) {
return POOL[idx];
} else {
return new Param(idx);
}
} else {
return new HolderParam(idx);
}
}
static class Param extends EndpointValueSetter {
/**
* Index of the argument to put the value to.
*/
protected final int idx;
public Param(int idx) {
this.idx = idx;
}
void put(Object obj, Object[] args) {
if (obj != null) {
args[idx] = obj;
}
}
}
static final class HolderParam extends Param {
public HolderParam(int idx) {
super(idx);
}
@Override
void put(Object obj, Object[] args) {
Holder holder = new Holder();
if (obj != null) {
holder.value = obj;
}
args[idx] = holder;
}
}
}

View File

@@ -0,0 +1,44 @@
/*
* 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.server.sei;
import com.sun.istack.internal.NotNull;
import com.sun.xml.internal.ws.api.message.Packet;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* Hides the detail of calling into application implementations.
*
* @since 2.2.6
*/
public abstract class Invoker {
/**
* Wrapper for reflection invoke that allows containers to adapt
*/
public abstract Object invoke( @NotNull Packet p, @NotNull Method m, @NotNull Object... args ) throws InvocationTargetException, IllegalAccessException;
}

View File

@@ -0,0 +1,43 @@
/*
* 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.server.sei;
import com.sun.istack.internal.NotNull;
import com.sun.xml.internal.ws.api.message.Packet;
/**
* Interface for determining Invoker for a given request
*
* @since 2.2.6
*/
public interface InvokerSource<T extends Invoker> {
/**
* Returns Invoker for the given request
* @param request Packet for request
* @return Selected invoker
*/
public @NotNull T getInvoker(Packet request);
}

View File

@@ -0,0 +1,61 @@
/*
* 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.server.sei;
import com.sun.istack.internal.NotNull;
import com.sun.xml.internal.ws.api.message.Packet;
import com.sun.xml.internal.ws.api.pipe.TubeCloner;
import com.sun.xml.internal.ws.api.pipe.helper.AbstractTubeImpl;
/**
* Base class for {@link com.sun.xml.internal.ws.server.InvokerTube} restored
* to allow for containers to specify alternate implementations of SEI-based
* invoking.
*/
public abstract class InvokerTube<T extends Invoker>
extends AbstractTubeImpl implements InvokerSource<T> {
protected final T invoker;
protected InvokerTube(T invoker) {
this.invoker = invoker;
}
/**
* Copy constructor.
*/
protected InvokerTube(InvokerTube<T> that, TubeCloner cloner) {
cloner.add(that,this);
this.invoker = that.invoker;
}
/**
* Returns the {@link Invoker} object that serves the request.
*/
public @NotNull T getInvoker(Packet request) {
return invoker;
}
}

View File

@@ -0,0 +1,182 @@
/*
* 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.server.sei;
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;
import com.sun.xml.internal.ws.api.message.Attachment;
/**
* 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}.
*
* @author Kohsuke Kawaguchi
* @author Jitendra Kotamraju
*/
public 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}.
*/
public abstract void fillIn(Object[] methodArgs, Object returnValue, Message msg);
/**
* Adds a parameter as an MIME attachment to {@link Message}.
*/
public 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);
}
public void fillIn(Object[] methodArgs, Object returnValue, Message msg) {
String contentId = getContentId();
Object obj = (methodPos == -1) ? returnValue : getter.get(methodArgs[methodPos]);
if (obj != null) {
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);
}
public void fillIn(Object[] methodArgs, Object returnValue, Message msg) {
String contentId = getContentId();
Object obj = (methodPos == -1) ? returnValue : 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);
}
public void fillIn(Object[] methodArgs, Object returnValue, Message msg) {
String contentId = getContentId();
Object obj = (methodPos == -1) ? returnValue : getter.get(methodArgs[methodPos]);
Attachment att = new JAXBAttachment(contentId, obj, param.getXMLBridge(), mimeType);
msg.getAttachments().add(att);
}
}
/**
* Adds a parameter as an header.
*/
public static final class Header extends MessageFiller {
private final XMLBridge bridge;
private final ValueGetter getter;
public Header(int methodPos, XMLBridge bridge, ValueGetter getter) {
super(methodPos);
this.bridge = bridge;
this.getter = getter;
}
public void fillIn(Object[] methodArgs, Object returnValue, Message msg) {
Object value = (methodPos == -1) ? returnValue : 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");
}
}

View File

@@ -0,0 +1,98 @@
/*
* 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.server.sei;
import com.oracle.webservices.internal.api.databinding.JavaCallInfo;
import com.sun.istack.internal.NotNull;
import com.sun.xml.internal.ws.api.WSBinding;
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.NextAction;
import com.sun.xml.internal.ws.api.server.Invoker;
import com.sun.xml.internal.ws.client.sei.MethodHandler;
import com.sun.xml.internal.ws.model.AbstractSEIModelImpl;
import com.sun.xml.internal.ws.server.InvokerTube;
import com.sun.xml.internal.ws.wsdl.DispatchException;
import java.lang.reflect.InvocationTargetException;
/**
* This pipe is used to invoke SEI based endpoints.
*
* @author Jitendra Kotamraju
*/
public class SEIInvokerTube extends InvokerTube {
/**
* For each method on the port interface we have
* a {@link MethodHandler} that processes it.
*/
private final WSBinding binding;
private final AbstractSEIModelImpl model;
public SEIInvokerTube(AbstractSEIModelImpl model,Invoker invoker, WSBinding binding) {
super(invoker);
this.binding = binding;
this.model = model;
}
/**
* This binds the parameters for SEI endpoints and invokes the endpoint method. The
* return value, and response Holder arguments are used to create a new {@link Message}
* that traverses through the Pipeline to transport.
*/
public @NotNull NextAction processRequest(@NotNull Packet req) {
JavaCallInfo call = model.getDatabinding().deserializeRequest(req);
if (call.getException() == null) {
try {
if (req.getMessage().isOneWay(model.getPort()) && req.transportBackChannel != null) {
req.transportBackChannel.close();
}
Object ret = getInvoker(req).invoke(req, call.getMethod(), call.getParameters());
call.setReturnValue(ret);
} catch (InvocationTargetException e) {
call.setException(e);
} catch (Exception e) {
call.setException(e);
}
} else if (call.getException() instanceof DispatchException) {
DispatchException e = (DispatchException)call.getException();
return doReturnWith(req.createServerResponse(e.fault, model.getPort(), null, binding));
}
Packet res = (Packet) model.getDatabinding().serializeResponse(call);
res = req.relateServerResponse(res, req.endpoint.getPort(), model, req.endpoint.getBinding());
assert res != null;
return doReturnWith(res);
}
public @NotNull NextAction processResponse(@NotNull Packet response) {
return doReturnWith(response);
}
public @NotNull NextAction processException(@NotNull Throwable t) {
return doThrow(t);
}
}

View File

@@ -0,0 +1,336 @@
/*
* 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.server.sei;
import com.oracle.webservices.internal.api.databinding.JavaCallInfo;
import com.sun.xml.internal.ws.api.SOAPVersion;
import com.sun.xml.internal.ws.api.WSBinding;
import com.sun.xml.internal.ws.api.databinding.EndpointCallBridge;
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.message.jaxb.JAXBMessage;
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 com.sun.xml.internal.ws.wsdl.DispatchException;
import javax.jws.WebParam.Mode;
import javax.xml.bind.JAXBException;
import javax.xml.stream.XMLStreamException;
import javax.xml.ws.Holder;
import javax.xml.ws.ProtocolException;
import javax.xml.ws.WebServiceException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* <p>
* This class mainly performs the following two tasks:
* <ol>
* <li>Takes a {@link Message} that represents a request,
* and extracts the arguments (and updates {@link Holder}s.)
* <li>Accepts return value and {@link Holder} arguments for a Java method,
* and creates {@link JAXBMessage} that represents a response message.
* </ol>
*
* <h2>Creating {@link JAXBMessage}</h2>
* <p>
* At the construction time, we prepare {@link EndpointArgumentsBuilder} that knows how to create endpoint {@link Method}
* invocation arguments.
* we also prepare {@link EndpointResponseMessageBuilder} 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 Jitendra Kotamraju
* @author shih-chang.chen@oracle.com
* Refactored from EndpointMethodHandler
*/
final public class TieHandler implements EndpointCallBridge {
private final SOAPVersion soapVersion;
private final Method method;
private final int noOfArgs;
private final JavaMethodImpl javaMethodModel;
private final Boolean isOneWay;
// Converts {@link Message} --> Object[]
private final EndpointArgumentsBuilder argumentsBuilder;
// these objects together create a response message from method parameters
private final EndpointResponseMessageBuilder bodyBuilder;
private final MessageFiller[] outFillers;
protected MessageContextFactory packetFactory;
public TieHandler(JavaMethodImpl method, WSBinding binding, MessageContextFactory mcf) {
this.soapVersion = binding.getSOAPVersion();
this.method = method.getMethod();
this.javaMethodModel = method;
argumentsBuilder = createArgumentsBuilder();
List<MessageFiller> fillers = new ArrayList<MessageFiller>();
bodyBuilder = createResponseMessageBuilder(fillers);
this.outFillers = fillers.toArray(new MessageFiller[fillers.size()]);
this.isOneWay = method.getMEP().isOneWay();
this.noOfArgs = this.method.getParameterTypes().length;
packetFactory = mcf;
}
/**
* It builds EndpointArgumentsBuilder which converts request {@link Message} to endpoint method's invocation
* arguments Object[]
*
* @return EndpointArgumentsBuilder
*/
private EndpointArgumentsBuilder createArgumentsBuilder() {
EndpointArgumentsBuilder argsBuilder;
List<ParameterImpl> rp = javaMethodModel.getRequestParameters();
List<EndpointArgumentsBuilder> builders = new ArrayList<EndpointArgumentsBuilder>();
for( ParameterImpl param : rp ) {
EndpointValueSetter setter = EndpointValueSetter.get(param);
switch(param.getInBinding().kind) {
case BODY:
if(param.isWrapperStyle()) {
if(param.getParent().getBinding().isRpcLit())
builders.add(new EndpointArgumentsBuilder.RpcLit((WrapperParameter)param));
else
builders.add(new EndpointArgumentsBuilder.DocLit((WrapperParameter)param, Mode.OUT));
} else {
builders.add(new EndpointArgumentsBuilder.Body(param.getXMLBridge(),setter));
}
break;
case HEADER:
builders.add(new EndpointArgumentsBuilder.Header(soapVersion, param, setter));
break;
case ATTACHMENT:
builders.add(EndpointArgumentsBuilder.AttachmentBuilder.createAttachmentBuilder(param, setter));
break;
case UNBOUND:
builders.add(new EndpointArgumentsBuilder.NullSetter(setter,
EndpointArgumentsBuilder.getVMUninitializedValue(param.getTypeInfo().type)));
break;
default:
throw new AssertionError();
}
}
// creates {@link Holder} arguments for OUT parameters
List<ParameterImpl> resp = javaMethodModel.getResponseParameters();
for( ParameterImpl param : resp ) {
if (param.isWrapperStyle()) {
WrapperParameter wp = (WrapperParameter)param;
List<ParameterImpl> children = wp.getWrapperChildren();
for (ParameterImpl p : children) {
if (p.isOUT() && p.getIndex() != -1) {
EndpointValueSetter setter = EndpointValueSetter.get(p);
builders.add(new EndpointArgumentsBuilder.NullSetter(setter, null));
}
}
} else if (param.isOUT() && param.getIndex() != -1) {
EndpointValueSetter setter = EndpointValueSetter.get(param);
builders.add(new EndpointArgumentsBuilder.NullSetter(setter, null));
}
}
switch(builders.size()) {
case 0:
argsBuilder = EndpointArgumentsBuilder.NONE;
break;
case 1:
argsBuilder = builders.get(0);
break;
default:
argsBuilder = new EndpointArgumentsBuilder.Composite(builders);
}
return argsBuilder;
}
/**
* prepare objects for creating response {@link Message}
*/
private EndpointResponseMessageBuilder createResponseMessageBuilder(List<MessageFiller> fillers) {
EndpointResponseMessageBuilder tmpBodyBuilder = null;
List<ParameterImpl> rp = javaMethodModel.getResponseParameters();
for (ParameterImpl param : rp) {
ValueGetter getter = ValueGetter.get(param);
switch(param.getOutBinding().kind) {
case BODY:
if(param.isWrapperStyle()) {
if(param.getParent().getBinding().isRpcLit()) {
tmpBodyBuilder = new EndpointResponseMessageBuilder.RpcLit((WrapperParameter)param,
soapVersion);
} else {
tmpBodyBuilder = new EndpointResponseMessageBuilder.DocLit((WrapperParameter)param,
soapVersion);
}
} else {
tmpBodyBuilder = new EndpointResponseMessageBuilder.Bare(param, soapVersion);
}
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(soapVersion) {
case SOAP_11:
tmpBodyBuilder = EndpointResponseMessageBuilder.EMPTY_SOAP11;
break;
case SOAP_12:
tmpBodyBuilder = EndpointResponseMessageBuilder.EMPTY_SOAP12;
break;
default:
throw new AssertionError();
}
}
return tmpBodyBuilder;
}
public Object[] readRequest(Message reqMsg) {
Object[] args = new Object[noOfArgs];
try {
argumentsBuilder.readRequest(reqMsg,args);
} catch (JAXBException e) {
throw new WebServiceException(e);
} catch (XMLStreamException e) {
throw new WebServiceException(e);
}
return args;
}
public Message createResponse(JavaCallInfo call) {
Message responseMessage;
if (call.getException() == null) {
responseMessage = isOneWay ? null : createResponseMessage(call.getParameters(), call.getReturnValue());
} else {
Throwable e = call.getException();
Throwable serviceException = getServiceException(e);
if (e instanceof InvocationTargetException || serviceException != null) {
// Throwable cause = e.getCause();
//if (!(cause instanceof RuntimeException) && cause instanceof Exception) {
if (serviceException != null) {
// Service specific exception
LOGGER.log(Level.FINE, serviceException.getMessage(), serviceException);
responseMessage = SOAPFaultBuilder.createSOAPFaultMessage(soapVersion,
javaMethodModel.getCheckedException(serviceException.getClass()), serviceException);
} else {
Throwable cause = e.getCause();
if (cause instanceof ProtocolException) {
// Application code may be throwing it intentionally
LOGGER.log(Level.FINE, cause.getMessage(), cause);
} else {
// Probably some bug in application code
LOGGER.log(Level.SEVERE, cause.getMessage(), cause);
}
responseMessage = SOAPFaultBuilder.createSOAPFaultMessage(soapVersion, null, cause);
}
} else if (e instanceof DispatchException) {
responseMessage = ((DispatchException)e).fault;
} else {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
responseMessage = SOAPFaultBuilder.createSOAPFaultMessage(soapVersion, null, e);
}
}
// return req.createServerResponse(responseMessage, req.endpoint.getPort(), javaMethodModel.getOwner(), req.endpoint.getBinding());
return responseMessage;
}
Throwable getServiceException(Throwable throwable) {
if (javaMethodModel.getCheckedException(throwable.getClass()) != null) return throwable;
if (throwable.getCause() != null) {
Throwable cause = throwable.getCause();
// if (!(cause instanceof RuntimeException) && cause instanceof Exception) {
if (javaMethodModel.getCheckedException(cause.getClass()) != null) return cause;
// }
// if (javaMethodModel.getCheckedException(cause.getClass()) != null) return cause;
}
return null;
}
/**
* Creates a response {@link JAXBMessage} from method arguments, return value
*
* @return response message
*/
private Message createResponseMessage(Object[] args, Object returnValue) {
Message msg = bodyBuilder.createMessage(args, returnValue);
for (MessageFiller filler : outFillers)
filler.fillIn(args, returnValue, msg);
return msg;
}
public Method getMethod() {
return method;
}
private static final Logger LOGGER = Logger.getLogger(TieHandler.class.getName());
@Override
public JavaCallInfo deserializeRequest(Packet req) {
com.sun.xml.internal.ws.api.databinding.JavaCallInfo call = new com.sun.xml.internal.ws.api.databinding.JavaCallInfo();
call.setMethod(this.getMethod());
Object[] args = this.readRequest(req.getMessage());
call.setParameters(args);
return call;
}
@Override
public Packet serializeResponse(JavaCallInfo call) {
Message msg = this.createResponse(call);
Packet p = (msg == null) ? (Packet)packetFactory.createContext() : (Packet)packetFactory.createContext(msg);
p.setState(Packet.State.ServerResponse);
return p;
}
@Override
public JavaMethod getOperationModel() {
return javaMethodModel;
}
}

View File

@@ -0,0 +1,92 @@
/*
* 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.server.sei;
import com.sun.xml.internal.ws.model.ParameterImpl;
import com.sun.xml.internal.ws.api.model.Parameter;
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
*/
public 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() {
public 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() {
public 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.
*/
public abstract Object get(Object parameter);
/**
* Returns a {@link ValueGetter} suitable for the given {@link Parameter}.
*/
public static ValueGetter get(ParameterImpl p) {
// return value is always PLAIN
if(p.getMode() == Mode.IN || p.getIndex() == -1) {
return PLAIN;
} else {
return HOLDER;
}
}
}