aoqi@0: /* aoqi@0: * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. Oracle designates this aoqi@0: * particular file as subject to the "Classpath" exception as provided aoqi@0: * by Oracle in the LICENSE file that accompanied this code. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: */ aoqi@0: aoqi@0: package com.sun.xml.internal.ws.db; aoqi@0: aoqi@0: import java.io.IOException; aoqi@0: import java.io.InputStream; aoqi@0: import java.io.OutputStream; aoqi@0: import java.lang.reflect.Method; aoqi@0: import java.util.HashMap; aoqi@0: import java.util.Map; aoqi@0: aoqi@0: import javax.xml.ws.WebServiceFeature; aoqi@0: aoqi@0: import com.oracle.webservices.internal.api.databinding.JavaCallInfo; aoqi@0: import com.oracle.webservices.internal.api.message.MessageContext; aoqi@0: import com.sun.xml.internal.ws.api.databinding.EndpointCallBridge; aoqi@0: import com.sun.xml.internal.ws.api.databinding.WSDLGenInfo; aoqi@0: import com.sun.xml.internal.ws.api.databinding.Databinding; aoqi@0: import com.sun.xml.internal.ws.api.databinding.DatabindingConfig; aoqi@0: import com.sun.xml.internal.ws.api.databinding.ClientCallBridge; aoqi@0: import com.sun.xml.internal.ws.api.message.Message; aoqi@0: import com.sun.xml.internal.ws.api.message.MessageContextFactory; aoqi@0: import com.sun.xml.internal.ws.api.message.Packet; aoqi@0: import com.sun.xml.internal.ws.api.model.MEP; aoqi@0: import com.sun.xml.internal.ws.api.model.SEIModel; aoqi@0: import com.sun.xml.internal.ws.api.model.WSDLOperationMapping; aoqi@0: import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort; aoqi@0: import com.sun.xml.internal.ws.api.pipe.Codec; aoqi@0: import com.sun.xml.internal.ws.api.pipe.ContentType; aoqi@0: import com.sun.xml.internal.ws.binding.BindingImpl; aoqi@0: import com.sun.xml.internal.ws.client.sei.StubAsyncHandler; aoqi@0: import com.sun.xml.internal.ws.client.sei.StubHandler; aoqi@0: import com.sun.xml.internal.ws.model.AbstractSEIModelImpl; aoqi@0: import com.sun.xml.internal.ws.model.JavaMethodImpl; aoqi@0: import com.sun.xml.internal.ws.model.RuntimeModeler; aoqi@0: import com.sun.xml.internal.ws.server.sei.TieHandler; aoqi@0: import com.sun.xml.internal.ws.wsdl.ActionBasedOperationSignature; aoqi@0: import com.sun.xml.internal.ws.wsdl.DispatchException; aoqi@0: import com.sun.xml.internal.ws.wsdl.OperationDispatcher; aoqi@0: aoqi@0: /** aoqi@0: * WsRuntimeImpl is the databinding processor built on SEIModel aoqi@0: * aoqi@0: * @author shih-chang.chen@oracle.com aoqi@0: */ aoqi@0: public final class DatabindingImpl implements Databinding { aoqi@0: aoqi@0: AbstractSEIModelImpl seiModel; aoqi@0: Map stubHandlers; aoqi@0: // QNameMap wsdlOpMap = new QNameMap(); aoqi@0: Map wsdlOpMap = new HashMap(); aoqi@0: Map tieHandlers = new HashMap(); aoqi@0: OperationDispatcher operationDispatcher; aoqi@0: OperationDispatcher operationDispatcherNoWsdl; aoqi@0: boolean clientConfig = false; aoqi@0: Codec codec; aoqi@0: MessageContextFactory packetFactory = null; aoqi@0: aoqi@0: public DatabindingImpl(DatabindingProviderImpl p, DatabindingConfig config) { aoqi@0: RuntimeModeler modeler = new RuntimeModeler(config); aoqi@0: modeler.setClassLoader(config.getClassLoader()); aoqi@0: seiModel = modeler.buildRuntimeModel(); aoqi@0: WSDLPort wsdlport = config.getWsdlPort(); aoqi@0: packetFactory = new MessageContextFactory(seiModel.getWSBinding().getFeatures()); aoqi@0: clientConfig = isClientConfig(config); aoqi@0: if (clientConfig) { aoqi@0: initStubHandlers(); aoqi@0: } aoqi@0: seiModel.setDatabinding(this); aoqi@0: if (wsdlport != null) { aoqi@0: freeze(wsdlport); aoqi@0: } aoqi@0: if (operationDispatcher == null) { aoqi@0: operationDispatcherNoWsdl = new OperationDispatcher(null, seiModel.getWSBinding(), seiModel); aoqi@0: } aoqi@0: // if(!clientConfig) { aoqi@0: for (JavaMethodImpl jm : seiModel.getJavaMethods()) { aoqi@0: if (!jm.isAsync()) { aoqi@0: TieHandler th = new TieHandler(jm, seiModel.getWSBinding(), packetFactory); aoqi@0: wsdlOpMap.put(jm, th); aoqi@0: tieHandlers.put(th.getMethod(), th); aoqi@0: } aoqi@0: } aoqi@0: // } aoqi@0: } aoqi@0: aoqi@0: //TODO isClientConfig aoqi@0: private boolean isClientConfig(DatabindingConfig config) { aoqi@0: if (config.getContractClass() == null) { aoqi@0: return false; aoqi@0: } aoqi@0: if (!config.getContractClass().isInterface()) { aoqi@0: return false; aoqi@0: } aoqi@0: return (config.getEndpointClass() == null || config.getEndpointClass().isInterface()); aoqi@0: } aoqi@0: //TODO fix freeze aoqi@0: aoqi@0: public void freeze(WSDLPort port) { aoqi@0: if (clientConfig) { aoqi@0: return; aoqi@0: } aoqi@0: synchronized(this) { aoqi@0: if (operationDispatcher == null) { aoqi@0: operationDispatcher = (port == null) ? null : new OperationDispatcher(port, seiModel.getWSBinding(), seiModel); aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: public SEIModel getModel() { aoqi@0: return seiModel; aoqi@0: } aoqi@0: //Refactored from SEIStub aoqi@0: aoqi@0: private void initStubHandlers() { aoqi@0: stubHandlers = new HashMap(); aoqi@0: Map syncs = new HashMap(); aoqi@0: // fill in methodHandlers. aoqi@0: // first fill in sychronized versions aoqi@0: for (JavaMethodImpl m : seiModel.getJavaMethods()) { aoqi@0: if (!m.getMEP().isAsync) { aoqi@0: StubHandler handler = new StubHandler(m, packetFactory); aoqi@0: syncs.put(m.getOperationSignature(), m); aoqi@0: stubHandlers.put(m.getMethod(), handler); aoqi@0: } aoqi@0: } aoqi@0: for (JavaMethodImpl jm : seiModel.getJavaMethods()) { aoqi@0: JavaMethodImpl sync = syncs.get(jm.getOperationSignature()); aoqi@0: if (jm.getMEP() == MEP.ASYNC_CALLBACK || jm.getMEP() == MEP.ASYNC_POLL) { aoqi@0: Method m = jm.getMethod(); aoqi@0: StubAsyncHandler handler = new StubAsyncHandler(jm, sync, packetFactory); aoqi@0: stubHandlers.put(m, handler); aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: JavaMethodImpl resolveJavaMethod(Packet req) throws DispatchException { aoqi@0: WSDLOperationMapping m = req.getWSDLOperationMapping(); aoqi@0: if (m == null) { aoqi@0: synchronized (this) { aoqi@0: m = (operationDispatcher != null) aoqi@0: ? operationDispatcher.getWSDLOperationMapping(req) aoqi@0: : operationDispatcherNoWsdl.getWSDLOperationMapping(req); aoqi@0: } aoqi@0: } aoqi@0: return (JavaMethodImpl) m.getJavaMethod(); aoqi@0: } aoqi@0: aoqi@0: public JavaCallInfo deserializeRequest(Packet req) { aoqi@0: com.sun.xml.internal.ws.api.databinding.JavaCallInfo call = new com.sun.xml.internal.ws.api.databinding.JavaCallInfo(); aoqi@0: try { aoqi@0: JavaMethodImpl wsdlOp = resolveJavaMethod(req); aoqi@0: TieHandler tie = wsdlOpMap.get(wsdlOp); aoqi@0: call.setMethod(tie.getMethod()); aoqi@0: Object[] args = tie.readRequest(req.getMessage()); aoqi@0: call.setParameters(args); aoqi@0: } catch (DispatchException e) { aoqi@0: call.setException(e); aoqi@0: } aoqi@0: return call; aoqi@0: } aoqi@0: aoqi@0: public JavaCallInfo deserializeResponse(Packet res, JavaCallInfo call) { aoqi@0: StubHandler stubHandler = stubHandlers.get(call.getMethod()); aoqi@0: try { aoqi@0: return stubHandler.readResponse(res, call); aoqi@0: } catch (Throwable e) { aoqi@0: call.setException(e); aoqi@0: return call; aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: public WebServiceFeature[] getFeatures() { aoqi@0: // TODO Auto-generated method stub aoqi@0: return null; aoqi@0: } aoqi@0: aoqi@0: @Override aoqi@0: public Packet serializeRequest(JavaCallInfo call) { aoqi@0: StubHandler stubHandler = stubHandlers.get(call.getMethod()); aoqi@0: Packet p = stubHandler.createRequestPacket(call); aoqi@0: p.setState(Packet.State.ClientRequest); aoqi@0: return p; aoqi@0: } aoqi@0: aoqi@0: @Override aoqi@0: public Packet serializeResponse(JavaCallInfo call) { aoqi@0: Method method = call.getMethod(); aoqi@0: Message message = null; aoqi@0: if (method != null) { aoqi@0: TieHandler th = tieHandlers.get(method); aoqi@0: if (th != null) { aoqi@0: return th.serializeResponse(call); aoqi@0: } aoqi@0: } aoqi@0: if (call.getException() instanceof DispatchException) { aoqi@0: message = ((DispatchException) call.getException()).fault; aoqi@0: } aoqi@0: Packet p = (Packet) packetFactory.createContext(message); aoqi@0: p.setState(Packet.State.ServerResponse); aoqi@0: return p; aoqi@0: } aoqi@0: aoqi@0: @Override aoqi@0: public ClientCallBridge getClientBridge(Method method) { aoqi@0: return stubHandlers.get(method); aoqi@0: } aoqi@0: aoqi@0: @Override aoqi@0: public void generateWSDL(WSDLGenInfo info) { aoqi@0: com.sun.xml.internal.ws.wsdl.writer.WSDLGenerator wsdlGen = new com.sun.xml.internal.ws.wsdl.writer.WSDLGenerator( aoqi@0: seiModel, aoqi@0: info.getWsdlResolver(), aoqi@0: seiModel.getWSBinding(), aoqi@0: info.getContainer(), seiModel.getEndpointClass(), aoqi@0: info.isInlineSchemas(), aoqi@0: info.isSecureXmlProcessingDisabled(), aoqi@0: info.getExtensions()); aoqi@0: wsdlGen.doGeneration(); aoqi@0: } aoqi@0: aoqi@0: @Override aoqi@0: public EndpointCallBridge getEndpointBridge(Packet req) throws DispatchException { aoqi@0: JavaMethodImpl wsdlOp = resolveJavaMethod(req); aoqi@0: return wsdlOpMap.get(wsdlOp); aoqi@0: } aoqi@0: aoqi@0: Codec getCodec() { aoqi@0: if (codec == null) { aoqi@0: codec = ((BindingImpl) seiModel.getWSBinding()).createCodec(); aoqi@0: } aoqi@0: return codec; aoqi@0: } aoqi@0: aoqi@0: @Override aoqi@0: public ContentType encode(Packet packet, OutputStream out) throws IOException { aoqi@0: return getCodec().encode(packet, out); aoqi@0: } aoqi@0: aoqi@0: @Override aoqi@0: public void decode(InputStream in, String ct, Packet p) throws IOException { aoqi@0: getCodec().decode(in, ct, p); aoqi@0: } aoqi@0: aoqi@0: @Override aoqi@0: public com.oracle.webservices.internal.api.databinding.JavaCallInfo createJavaCallInfo(Method method, Object[] args) { aoqi@0: return new com.sun.xml.internal.ws.api.databinding.JavaCallInfo(method, args); aoqi@0: } aoqi@0: aoqi@0: @Override aoqi@0: public com.oracle.webservices.internal.api.databinding.JavaCallInfo deserializeResponse( aoqi@0: MessageContext message, com.oracle.webservices.internal.api.databinding.JavaCallInfo call) { aoqi@0: return deserializeResponse((Packet) message, (JavaCallInfo) call); aoqi@0: } aoqi@0: aoqi@0: @Override aoqi@0: public com.oracle.webservices.internal.api.databinding.JavaCallInfo deserializeRequest(MessageContext message) { aoqi@0: return deserializeRequest((Packet) message); aoqi@0: } aoqi@0: aoqi@0: @Override aoqi@0: public MessageContextFactory getMessageContextFactory() { aoqi@0: return packetFactory; aoqi@0: } aoqi@0: }