/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* http://glassfish.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.xml.ws.sdo;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.URL;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.jws.WebService;
import javax.xml.namespace.QName;
import javax.xml.ws.WebServiceFeature;
import org.eclipse.persistence.sdo.helper.SDOHelperContext;
import org.eclipse.persistence.sdo.helper.SDOXSDHelper;
import junit.framework.TestCase;
import com.oracle.webservices.api.databinding.DatabindingModeFeature;
import com.oracle.webservices.api.databinding.ExternalMetadataFeature;
import com.oracle.webservices.api.databinding.JavaCallInfo;
import com.sun.xml.ws.api.BindingID;
import com.sun.xml.ws.api.ComponentFeature;
import com.sun.xml.ws.api.WSBinding;
import com.sun.xml.ws.api.databinding.Databinding;
import com.sun.xml.ws.api.databinding.DatabindingConfig;
import com.sun.xml.ws.api.databinding.DatabindingFactory;
import com.sun.xml.ws.api.databinding.WSDLGenInfo;
import com.sun.xml.ws.api.message.Packet;
import com.sun.xml.ws.api.model.wsdl.WSDLModel;
import com.sun.xml.ws.api.model.wsdl.WSDLPort;
import com.sun.xml.ws.api.pipe.ClientTubeAssemblerContext;
import com.sun.xml.ws.api.pipe.Codec;
import com.sun.xml.ws.api.pipe.ContentType;
import com.sun.xml.ws.api.pipe.NextAction;
import com.sun.xml.ws.api.pipe.TransportTubeFactory;
import com.sun.xml.ws.api.pipe.Tube;
import com.sun.xml.ws.api.pipe.TubeCloner;
import com.sun.xml.ws.api.pipe.helper.AbstractTubeImpl;
import com.sun.xml.ws.api.server.Container;
import com.sun.xml.ws.api.server.SDDocumentSource;
import com.sun.xml.ws.api.server.WSEndpoint;
import com.sun.xml.ws.api.wsdl.parser.WSDLParserExtension;
import com.sun.xml.ws.api.wsdl.writer.WSDLGeneratorExtension;
import com.sun.xml.ws.binding.WebServiceFeatureList;
import com.sun.xml.ws.db.sdo.HelperContextResolver;
import com.sun.xml.ws.db.sdo.SchemaInfo;
import com.sun.xml.ws.util.ServiceFinder;
import com.sun.xml.ws.util.xml.XmlUtil;
import com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser;
import commonj.sdo.helper.HelperContext;
/**
* WsDatabindingTestBase
*
* @author shih-chang.chen@oracle.com
*/
abstract public class SDODatabindingTestBase extends TestCase {
static public DatabindingFactory factory = DatabindingFactory.newInstance();
static public <T> T createProxy(Class<T> proxySEI, Class<?> endpointClass, String db, boolean debug) throws Exception {
DatabindingConfig srvConfig = new DatabindingConfig();
srvConfig.setEndpointClass(endpointClass);
DatabindingModeFeature dbf = new DatabindingModeFeature(db);
WebServiceFeatureList wsfeatures = new WebServiceFeatureList(endpointClass);
WebServiceFeature[] f = { dbf };
// config.setFeatures(wsfeatures.toArray());
srvConfig.setFeatures(f);
DatabindingConfig cliConfig = new DatabindingConfig();
cliConfig.setContractClass(proxySEI);
cliConfig.setFeatures(f);
return createProxy(proxySEI, srvConfig, cliConfig, debug);
}
static public <T> T createProxy(Class<T> proxySEI, DatabindingConfig srvConfig, DatabindingConfig cliConfig, boolean debug) throws Exception {
Class<?> endpointClass = srvConfig.getEndpointClass();
//TODO default BindingID
if (srvConfig.getMappingInfo().getBindingID() == null)
srvConfig.getMappingInfo().setBindingID(BindingID.parse(endpointClass));
Databinding srvDb = (Databinding)factory.createRuntime(srvConfig);
InVmWSDLResolver result = new InVmWSDLResolver();
WSDLGenInfo wsdlGenInfo = new WSDLGenInfo();
wsdlGenInfo.setWsdlResolver(result);
// wsdlGenInfo.setContainer(container);
wsdlGenInfo.setExtensions(ServiceFinder.find(WSDLGeneratorExtension.class).toArray());
wsdlGenInfo.setInlineSchemas(true);
srvDb.generateWSDL(wsdlGenInfo);
if (debug) result.print();
WSDLModel wsdl = RuntimeWSDLParser.parse(
result.getWsdlSource(), result.getEntityResolver(), false, null, new WSDLParserExtension[0]);
QName serviceName = wsdl.getFirstServiceName();
WSDLPort wsdlPort = wsdl.getService(serviceName).getFirstPort();
// ((AbstractSEIModelImpl)((DatabindingImpl)srvDb).getModel()).freeze((WSDLPortImpl)wsdlPort);
cliConfig.setWsdlPort(wsdlPort);
cliConfig.getMappingInfo().setServiceName(serviceName);
Databinding cliDb = (Databinding)factory.createRuntime(cliConfig);
Class<?>[] intf = { proxySEI };
WsDatabindingTestFacade h = new WsDatabindingTestFacade(cliDb, srvDb, endpointClass);
h.wireLog = debug;
Object proxy = Proxy.newProxyInstance(proxySEI.getClassLoader(), intf, h);
return proxySEI.cast(proxy);
}
static public class WsDatabindingTestFacade implements InvocationHandler {
Databinding cli;
Databinding srv;
Class<?> serviceBeanType;
public Object serviceBeanInstance;
public boolean wireLog = false;
public boolean keepWireMessage = false;
public boolean keepMessageObject = false;
public String request;
public String response;
public Packet requestMessage;
public Packet responseMessage;
WsDatabindingTestFacade(Databinding client, Databinding server, Class endpoint) {
cli = client;
srv = server;
serviceBeanType = endpoint;
try {
serviceBeanInstance = serviceBeanType.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// JavaCallInfo cliCall = new JavaCallInfo();
// cliCall.setMethod(method);
// cliCall.setParameters(args);
JavaCallInfo cliCall = cli.createJavaCallInfo(method, args);
// Packet cliSoapReq = clientBridge.createRequestPacket(cliCall);
Packet cliSoapReq = (Packet)cli.serializeRequest(cliCall);
//Transmit to Server
ByteArrayOutputStream cliBo = new ByteArrayOutputStream();
ContentType cliCt = cli.encode(cliSoapReq, cliBo);
if (wireLog) {
System.out.println("Request Message: " + cliCt.getContentType() + " " + cliCt.getSOAPActionHeader() );
System.out.println(new String(cliBo.toByteArray()));
}
if (keepMessageObject) {
requestMessage = cliSoapReq;
}
if (keepWireMessage) {
request = new String(cliBo.toByteArray());
}
ByteArrayInputStream srvBi = new ByteArrayInputStream(cliBo.toByteArray());
Packet srvSoapReq = new Packet();
// packet.soapAction = fixQuotesAroundSoapAction(con.getRequestHeader("SOAPAction"));
srv.decode(srvBi, cliCt.getContentType(), srvSoapReq);
// Message srvSoapReq = tie.getMessageFactory().createMessage(srcReq, cliSoapReq.transportHeaders(), null);
// EndpointCallBridge endpointBridge = srv.getEndpointBridge(srvSoapReq);
JavaCallInfo srcCall = srv.deserializeRequest(srvSoapReq);
Method intfMethod = srcCall.getMethod();
Method implMethod = serviceBeanType.getMethod(intfMethod.getName(), intfMethod.getParameterTypes());
try {
Object ret = implMethod.invoke(serviceBeanInstance, srcCall.getParameters());
srcCall.setReturnValue(ret);
} catch (Exception e) {
srcCall.setException(e);
}
Packet srvSoapRes = (Packet)srv.serializeResponse(srcCall);
// Packet srvSoapRes = srvSoapReq.createResponse(srvSoapResMsg);
//Transmit to Client
ByteArrayOutputStream srvBo = new ByteArrayOutputStream();
ContentType srvCt = srv.encode(srvSoapRes, srvBo);
if (wireLog) {
System.out.println("Response Message: " + srvCt.getContentType());
System.out.println(new String(srvBo.toByteArray()));
}
if (keepMessageObject) {
responseMessage = srvSoapRes;
}
if (keepWireMessage) {
response = new String(srvBo.toByteArray());
}
ByteArrayInputStream cliBi = new ByteArrayInputStream(srvBo.toByteArray());
Packet cliSoapRes = new Packet();
cli.decode(cliBi, srvCt.getContentType(), cliSoapRes);
// cliCall = clientBridge.readResponse(cliSoapRes, cliCall);
cliCall = cli.deserializeResponse(cliSoapRes, cliCall);
if (cliCall.getException() != null) {
throw cliCall.getException();
}
return cliCall.getReturnValue();
}
}
static public void assertEqualList(List<?> list1, List<?> list2) {
assertTrue(list1.size() == list2.size());
for (int i = 0; i < list1.size(); i++) {
assertEquals(list1.get(i), list2.get(i));
}
}
static public void assertEqualCollection(Collection<?> c1, Collection<?> c2) {
assertTrue(c1.size() == c2.size());
for (Iterator i = c1.iterator(); i.hasNext();) {
assertTrue(c2.contains(i.next()));
}
}
static public void assertEqualArray(Object a1, Object a2) {
assertTrue(Array.getLength(a1) == Array.getLength(a2));
for (int i = 0; i < Array.getLength(a1); i++) {
assertEquals(Array.get(a1, i), Array.get(a2, i));
}
}
static public boolean equalsMap(Map<?,?> req, Map<?,?> res) {
if (req.size() != res.size()) return false;
for(Object k : req.keySet()) if(!req.get(k).equals(res.get(k))) return false;
return true;
}
static public URL getResource(String str) throws Exception {
return Thread.currentThread().getContextClassLoader().getResource("etc/"+str);
}
static protected class SDOConfig {
HelperContext context;
HelperContextResolver resolver;
}
protected SDOConfig sdoConfig(Set<SchemaInfo> schemas, boolean server) {
final SDOConfig config = new SDOConfig();
config.context = server ?
SDOHelperContext.getHelperContext("server"):
SDOHelperContext.getHelperContext();//SDODatabindingContext.getLocalHelperContext();
config.resolver = new HelperContextResolver() {
public HelperContext getHelperContext(boolean isClient, QName serviceName, Map<String, Object> properties) {
return config.context;
}
};
for (SchemaInfo xi : schemas) ((SDOXSDHelper) config.context.getXSDHelper()).define(xi.getSchemaSource(), null);
return config;
}
protected WebServiceFeature[] invmSetup(final URL wsdlURL, final Class sei, final Class seb, final QName serviceName, final QName portName) {
DatabindingModeFeature dbmf = new DatabindingModeFeature("eclipselink.sdo");
Class implementorClass = seb;
boolean handlersSetInDD = false;
Container container = Container.NONE;
Map<String, SDDocumentSource> docs = new HashMap<String, SDDocumentSource>();
SDDocumentSource primaryWSDL = SDDocumentSource.create(wsdlURL);
docs.put(wsdlURL.toString(), primaryWSDL);
ExternalMetadataFeature exm = ExternalMetadataFeature.builder().setReader( new com.sun.xml.ws.model.ReflectAnnotationReader() {
public <A extends Annotation> A getAnnotation(final Class<A> annType, final Class<?> cls) {
if (WebService.class.equals(annType)) {
final WebService ws = cls.getAnnotation(WebService.class);
return (A)new javax.jws.WebService() {
public Class<? extends Annotation> annotationType() {
return WebService.class;
}
@Override
public String endpointInterface() {
return sei.getName();
}
@Override
public String name() {
return (ws != null)? ws.name() : null;
}
@Override
public String portName() {
return (ws != null)? ws.portName() : null;
}
@Override
public String serviceName() {
return (ws != null)? ws.serviceName() : null;
}
@Override
public String targetNamespace() {
return (ws != null)? ws.targetNamespace() : null;
}
@Override
public String wsdlLocation() {
return (ws != null)? ws.wsdlLocation() : null;
}
};
}
return cls.getAnnotation(annType);
}
}).build();
BindingID bindingID = BindingID.parse(implementorClass);
WSBinding binding = bindingID.createBinding(dbmf, exm);
final WSEndpoint<?> endpoint = WSEndpoint.create(
implementorClass, !handlersSetInDD,
null,
serviceName, portName, container, binding,
primaryWSDL, docs.values(), XmlUtil.createEntityResolver(null), false
);
ComponentFeature cf = new ComponentFeature( new com.sun.xml.ws.api.Component() {
public <S> S getSPI(Class<S> spiType) {
if (TransportTubeFactory.class.equals(spiType)) return (S) new TransportTubeFactory() {
public Tube doCreate( ClientTubeAssemblerContext context) {
return new InVmTransportTube(context.getCodec(), context.getBinding(), wsdlURL, endpoint);
}
};
return null;
}
});
WebServiceFeature[] f = {dbmf, cf};
return f;
}
static public class InVmTransportTube extends AbstractTubeImpl {
Codec clientCodec;
WSBinding clientBinding;
WSEndpoint<?> endpoint;
Codec endpointCodec;
InVmTransportTube(Codec codec, WSBinding b, URL wsdlURL, WSEndpoint<?> e) {
clientCodec = codec;
clientBinding = b;
endpoint = e;
endpointCodec = endpoint.createCodec();;
}
@Override
public NextAction processRequest(Packet request) {
ByteArrayOutputStream os1 = new ByteArrayOutputStream();
ContentType ctReq = clientCodec.getStaticContentType(request);
Packet response = null;
try {
clientCodec.encode(request, os1);
Packet requestOnServer = new Packet();
endpointCodec.decode(new ByteArrayInputStream(os1.toByteArray()), ctReq.getContentType(), requestOnServer);
Packet responseOnServer = endpoint.createPipeHead().process(requestOnServer, null, null);
ByteArrayOutputStream os2 = new ByteArrayOutputStream();
ContentType ctRes = endpointCodec.encode(responseOnServer, os2);
response = new Packet();
clientCodec.decode(new ByteArrayInputStream(os2.toByteArray()), ctRes.getContentType(), response);
} catch (IOException e) {
e.printStackTrace();
}
NextAction na = new NextAction();
na.returnWith(response);
return na;
}
@Override
public NextAction processResponse(Packet response) {
System.out.println("InVmTransportTube.processResponse " + response);
return null;
}
@Override
public NextAction processException(Throwable t) { return null; }
@Override
public void preDestroy() {}
@Override
public AbstractTubeImpl copy(TubeCloner cloner) { return null; }
}
}