ohair@286: /* ohair@286: * Copyright (c) 1997, 2011, 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.namespace.QName; ohair@286: import javax.xml.ws.WebServiceFeature; ohair@286: ohair@286: import com.sun.xml.internal.org.jvnet.ws.message.MessageContext; ohair@286: ohair@286: import com.sun.xml.internal.ws.api.databinding.EndpointCallBridge; ohair@286: import com.sun.xml.internal.ws.api.databinding.JavaCallInfo; 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; 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; 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.util.QNameMap; 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: */ ohair@286: public class DatabindingImpl implements Databinding, com.sun.xml.internal.org.jvnet.ws.databinding.Databinding { ohair@286: ohair@286: AbstractSEIModelImpl seiModel; ohair@286: Map stubHandlers; ohair@286: QNameMap wsdlOpMap = new QNameMap(); ohair@286: Map tieHandlers = new HashMap(); ohair@286: OperationDispatcher operationDispatcher; ohair@286: OperationDispatcher operationDispatcherNoWsdl; ohair@286: boolean clientConfig = false; ohair@286: Codec codec; ohair@286: ohair@286: public DatabindingImpl(DatabindingProviderImpl p, DatabindingConfig config) { ohair@286: RuntimeModeler modeler = new RuntimeModeler(config); ohair@286: modeler.setClassLoader(config.getClassLoader()); ohair@286: seiModel = modeler.buildRuntimeModel(); ohair@286: WSDLPort wsdlport = config.getWsdlPort(); ohair@286: clientConfig = isClientConfig(config); ohair@286: if ( clientConfig ) initStubHandlers(); ohair@286: seiModel.setDatabinding(this); ohair@286: if (wsdlport != null) freeze(wsdlport); ohair@286: if (operationDispatcher == null) operationDispatcherNoWsdl = new OperationDispatcher(null, seiModel.getWSBinding(), seiModel); ohair@286: // if(!clientConfig) { ohair@286: for(JavaMethodImpl jm: seiModel.getJavaMethods()) if (!jm.isAsync()) { ohair@286: TieHandler th = new TieHandler(jm, seiModel.getWSBinding()); ohair@286: wsdlOpMap.put(jm.getOperationQName(), th); ohair@286: tieHandlers.put(th.getMethod(), th); ohair@286: } ohair@286: // } ohair@286: } ohair@286: ohair@286: //TODO isClientConfig ohair@286: private boolean isClientConfig(DatabindingConfig config) { ohair@286: if (config.getContractClass() == null) return false; ohair@286: if (!config.getContractClass().isInterface()) return false; ohair@286: return (config.getEndpointClass() == null || config.getEndpointClass().isInterface()); ohair@286: } ohair@286: //TODO fix freeze ohair@286: public synchronized void freeze(WSDLPort port) { ohair@286: if (clientConfig) return; ohair@286: if (operationDispatcher != null) return; ohair@286: operationDispatcher = (port == null) ? null : new OperationDispatcher(port, seiModel.getWSBinding(), seiModel); ohair@286: } ohair@286: ohair@286: public SEIModel getModel() { ohair@286: return seiModel; ohair@286: } ohair@286: //Refactored from SEIStub ohair@286: private void initStubHandlers() { ohair@286: 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) { ohair@286: StubHandler handler = new StubHandler(m); 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(); ohair@286: StubAsyncHandler handler = new StubAsyncHandler(jm, sync); ohair@286: stubHandlers.put(m, handler); ohair@286: } ohair@286: } ohair@286: } ohair@286: ohair@286: public QName resolveOperationQName(Packet req) throws DispatchException { ohair@286: return (operationDispatcher != null)? ohair@286: operationDispatcher.getWSDLOperationQName(req): ohair@286: operationDispatcherNoWsdl.getWSDLOperationQName(req); ohair@286: } ohair@286: ohair@286: public JavaCallInfo deserializeRequest(Packet req) { ohair@286: JavaCallInfo call = new JavaCallInfo(); ohair@286: try { ohair@286: QName wsdlOp = resolveOperationQName(req); ohair@286: TieHandler tie = wsdlOpMap.get(wsdlOp); ohair@286: call.setMethod(tie.getMethod()); ohair@286: Object[] args = tie.readRequest(req.getMessage()); ohair@286: call.setParameters(args); ohair@286: } catch (DispatchException e) { ohair@286: call.setException(e); ohair@286: } ohair@286: return call; ohair@286: } ohair@286: ohair@286: 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: } ohair@286: } ohair@286: ohair@286: public WebServiceFeature[] getFeatures() { ohair@286: // TODO Auto-generated method stub ohair@286: return null; ohair@286: } ohair@286: ohair@286: public Packet serializeRequest(JavaCallInfo call) { ohair@286: StubHandler stubHandler = stubHandlers.get(call.getMethod()); ohair@286: return stubHandler.createRequestPacket(call); ohair@286: } ohair@286: ohair@286: public Packet serializeResponse(JavaCallInfo call) { ohair@286: Method method = call.getMethod(); ohair@286: Message message = null; ohair@286: if (method != null) { ohair@286: TieHandler th = tieHandlers.get(method); ohair@286: if (th != null) { ohair@286: return th.serializeResponse(call); ohair@286: } ohair@286: } ohair@286: if (call.getException() instanceof DispatchException) { ohair@286: message = ((DispatchException)call.getException()).fault; ohair@286: } ohair@286: Packet response = new Packet(); ohair@286: response.setMessage(message); ohair@286: return response; ohair@286: } ohair@286: ohair@286: public ClientCallBridge getClientBridge(Method method) { ohair@286: return stubHandlers.get(method); ohair@286: } ohair@286: ohair@286: ohair@286: public void generateWSDL(WSDLGenInfo info) { ohair@286: com.sun.xml.internal.ws.wsdl.writer.WSDLGenerator wsdlGen = new com.sun.xml.internal.ws.wsdl.writer.WSDLGenerator( ohair@286: seiModel, ohair@286: info.getWsdlResolver(), ohair@286: seiModel.getWSBinding(), ohair@286: info.getContainer(), seiModel.getEndpointClass(), ohair@286: info.isInlineSchemas(), ohair@286: info.getExtensions()); ohair@286: wsdlGen.doGeneration(); ohair@286: } ohair@286: ohair@286: public EndpointCallBridge getEndpointBridge(Packet req) throws DispatchException { ohair@286: QName wsdlOp = resolveOperationQName(req); ohair@286: return wsdlOpMap.get(wsdlOp); ohair@286: } ohair@286: ohair@286: ohair@286: Codec getCodec() { ohair@286: if (codec == null) codec = ((BindingImpl)seiModel.getWSBinding()).createCodec(); ohair@286: return codec; ohair@286: } ohair@286: ohair@286: public ContentType encode( Packet packet, OutputStream out ) throws IOException { ohair@286: return getCodec().encode(packet, out); ohair@286: } ohair@286: ohair@286: public void decode( InputStream in, String ct, Packet p ) throws IOException{ ohair@286: getCodec().decode(in, ct, p); ohair@286: } ohair@286: ohair@286: public com.sun.xml.internal.org.jvnet.ws.databinding.JavaCallInfo createJavaCallInfo(Method method, Object[] args) { ohair@286: return new JavaCallInfo(method, args); ohair@286: } ohair@286: ohair@286: public MessageContext serializeRequest(com.sun.xml.internal.org.jvnet.ws.databinding.JavaCallInfo call) { ohair@286: return serializeRequest((JavaCallInfo)call); ohair@286: } ohair@286: ohair@286: public com.sun.xml.internal.org.jvnet.ws.databinding.JavaCallInfo deserializeResponse( ohair@286: MessageContext message, com.sun.xml.internal.org.jvnet.ws.databinding.JavaCallInfo call) { ohair@286: return deserializeResponse((Packet)message, (JavaCallInfo)call); ohair@286: } ohair@286: ohair@286: public com.sun.xml.internal.org.jvnet.ws.databinding.JavaCallInfo deserializeRequest(MessageContext message) { ohair@286: return deserializeRequest((Packet)message); ohair@286: } ohair@286: ohair@286: public MessageContext serializeResponse(com.sun.xml.internal.org.jvnet.ws.databinding.JavaCallInfo call) { ohair@286: return serializeResponse((JavaCallInfo)call); ohair@286: } ohair@286: }