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