/*
 * 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.db;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import javax.xml.ws.WebServiceFeature;

import com.oracle.webservices.internal.api.databinding.JavaCallInfo;
import com.oracle.webservices.internal.api.message.MessageContext;
import com.sun.xml.internal.ws.api.databinding.EndpointCallBridge;
import com.sun.xml.internal.ws.api.databinding.WSDLGenInfo;
import com.sun.xml.internal.ws.api.databinding.Databinding;
import com.sun.xml.internal.ws.api.databinding.DatabindingConfig;
import com.sun.xml.internal.ws.api.databinding.ClientCallBridge;
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.MEP;
import com.sun.xml.internal.ws.api.model.SEIModel;
import com.sun.xml.internal.ws.api.model.WSDLOperationMapping;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort;
import com.sun.xml.internal.ws.api.pipe.Codec;
import com.sun.xml.internal.ws.api.pipe.ContentType;
import com.sun.xml.internal.ws.binding.BindingImpl;
import com.sun.xml.internal.ws.client.sei.StubAsyncHandler;
import com.sun.xml.internal.ws.client.sei.StubHandler;
import com.sun.xml.internal.ws.model.AbstractSEIModelImpl;
import com.sun.xml.internal.ws.model.JavaMethodImpl;
import com.sun.xml.internal.ws.model.RuntimeModeler;
import com.sun.xml.internal.ws.server.sei.TieHandler;
import com.sun.xml.internal.ws.wsdl.ActionBasedOperationSignature;
import com.sun.xml.internal.ws.wsdl.DispatchException;
import com.sun.xml.internal.ws.wsdl.OperationDispatcher;

WsRuntimeImpl is the databinding processor built on SEIModel
Author:shih-chang.chen@oracle.com
/** * WsRuntimeImpl is the databinding processor built on SEIModel * * @author shih-chang.chen@oracle.com */
public final class DatabindingImpl implements Databinding { AbstractSEIModelImpl seiModel; Map<Method, StubHandler> stubHandlers; // QNameMap<TieHandler> wsdlOpMap = new QNameMap<TieHandler>(); Map<JavaMethodImpl, TieHandler> wsdlOpMap = new HashMap<JavaMethodImpl, TieHandler>(); Map<Method, TieHandler> tieHandlers = new HashMap<Method, TieHandler>(); OperationDispatcher operationDispatcher; OperationDispatcher operationDispatcherNoWsdl; boolean clientConfig = false; Codec codec; MessageContextFactory packetFactory = null; public DatabindingImpl(DatabindingProviderImpl p, DatabindingConfig config) { RuntimeModeler modeler = new RuntimeModeler(config); modeler.setClassLoader(config.getClassLoader()); seiModel = modeler.buildRuntimeModel(); WSDLPort wsdlport = config.getWsdlPort(); Object facProp = config.properties().get("com.sun.xml.internal.ws.api.message.MessageContextFactory"); packetFactory = (facProp != null && facProp instanceof MessageContextFactory)? (MessageContextFactory)facProp : new MessageContextFactory(seiModel.getWSBinding().getFeatures()); clientConfig = isClientConfig(config); if (clientConfig) { initStubHandlers(); } seiModel.setDatabinding(this); if (wsdlport != null) { freeze(wsdlport); } if (operationDispatcher == null) { operationDispatcherNoWsdl = new OperationDispatcher(null, seiModel.getWSBinding(), seiModel); } // if(!clientConfig) { for (JavaMethodImpl jm : seiModel.getJavaMethods()) { if (!jm.isAsync()) { TieHandler th = new TieHandler(jm, seiModel.getWSBinding(), packetFactory); wsdlOpMap.put(jm, th); tieHandlers.put(th.getMethod(), th); } } // } } //TODO isClientConfig private boolean isClientConfig(DatabindingConfig config) { if (config.getContractClass() == null) { return false; } if (!config.getContractClass().isInterface()) { return false; } return (config.getEndpointClass() == null || config.getEndpointClass().isInterface()); } //TODO fix freeze public void freeze(WSDLPort port) { if (clientConfig) { return; } synchronized(this) { if (operationDispatcher == null) { operationDispatcher = (port == null) ? null : new OperationDispatcher(port, seiModel.getWSBinding(), seiModel); } } } public SEIModel getModel() { return seiModel; } //Refactored from SEIStub private void initStubHandlers() { stubHandlers = new HashMap<Method, StubHandler>(); Map<ActionBasedOperationSignature, JavaMethodImpl> syncs = new HashMap<ActionBasedOperationSignature, JavaMethodImpl>(); // fill in methodHandlers. // first fill in sychronized versions for (JavaMethodImpl m : seiModel.getJavaMethods()) { if (!m.getMEP().isAsync) { StubHandler handler = new StubHandler(m, packetFactory); syncs.put(m.getOperationSignature(), m); stubHandlers.put(m.getMethod(), handler); } } for (JavaMethodImpl jm : seiModel.getJavaMethods()) { JavaMethodImpl sync = syncs.get(jm.getOperationSignature()); if (jm.getMEP() == MEP.ASYNC_CALLBACK || jm.getMEP() == MEP.ASYNC_POLL) { Method m = jm.getMethod(); StubAsyncHandler handler = new StubAsyncHandler(jm, sync, packetFactory); stubHandlers.put(m, handler); } } } JavaMethodImpl resolveJavaMethod(Packet req) throws DispatchException { WSDLOperationMapping m = req.getWSDLOperationMapping(); if (m == null) { synchronized (this) { m = (operationDispatcher != null) ? operationDispatcher.getWSDLOperationMapping(req) : operationDispatcherNoWsdl.getWSDLOperationMapping(req); } } return (JavaMethodImpl) m.getJavaMethod(); } public JavaCallInfo deserializeRequest(Packet req) { com.sun.xml.internal.ws.api.databinding.JavaCallInfo call = new com.sun.xml.internal.ws.api.databinding.JavaCallInfo(); try { JavaMethodImpl wsdlOp = resolveJavaMethod(req); TieHandler tie = wsdlOpMap.get(wsdlOp); call.setMethod(tie.getMethod()); Object[] args = tie.readRequest(req.getMessage()); call.setParameters(args); } catch (DispatchException e) { call.setException(e); } return call; } public JavaCallInfo deserializeResponse(Packet res, JavaCallInfo call) { StubHandler stubHandler = stubHandlers.get(call.getMethod()); try { return stubHandler.readResponse(res, call); } catch (Throwable e) { call.setException(e); return call; } } public WebServiceFeature[] getFeatures() { // TODO Auto-generated method stub return null; } @Override public Packet serializeRequest(JavaCallInfo call) { StubHandler stubHandler = stubHandlers.get(call.getMethod()); Packet p = stubHandler.createRequestPacket(call); p.setState(Packet.State.ClientRequest); return p; } @Override public Packet serializeResponse(JavaCallInfo call) { Method method = call.getMethod(); Message message = null; if (method != null) { TieHandler th = tieHandlers.get(method); if (th != null) { return th.serializeResponse(call); } } if (call.getException() instanceof DispatchException) { message = ((DispatchException) call.getException()).fault; } Packet p = (Packet) packetFactory.createContext(message); p.setState(Packet.State.ServerResponse); return p; } @Override public ClientCallBridge getClientBridge(Method method) { return stubHandlers.get(method); } @Override public void generateWSDL(WSDLGenInfo info) { com.sun.xml.internal.ws.wsdl.writer.WSDLGenerator wsdlGen = new com.sun.xml.internal.ws.wsdl.writer.WSDLGenerator( seiModel, info.getWsdlResolver(), seiModel.getWSBinding(), info.getContainer(), seiModel.getEndpointClass(), info.isInlineSchemas(), info.isSecureXmlProcessingDisabled(), info.getExtensions()); wsdlGen.doGeneration(); } @Override public EndpointCallBridge getEndpointBridge(Packet req) throws DispatchException { JavaMethodImpl wsdlOp = resolveJavaMethod(req); return wsdlOpMap.get(wsdlOp); } Codec getCodec() { if (codec == null) { codec = ((BindingImpl) seiModel.getWSBinding()).createCodec(); } return codec; } @Override public ContentType encode(Packet packet, OutputStream out) throws IOException { return getCodec().encode(packet, out); } @Override public void decode(InputStream in, String ct, Packet p) throws IOException { getCodec().decode(in, ct, p); } @Override public com.oracle.webservices.internal.api.databinding.JavaCallInfo createJavaCallInfo(Method method, Object[] args) { return new com.sun.xml.internal.ws.api.databinding.JavaCallInfo(method, args); } @Override public com.oracle.webservices.internal.api.databinding.JavaCallInfo deserializeResponse( MessageContext message, com.oracle.webservices.internal.api.databinding.JavaCallInfo call) { return deserializeResponse((Packet) message, (JavaCallInfo) call); } @Override public com.oracle.webservices.internal.api.databinding.JavaCallInfo deserializeRequest(MessageContext message) { return deserializeRequest((Packet) message); } @Override public MessageContextFactory getMessageContextFactory() { return packetFactory; } }