1 /* 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.xml.internal.ws.db; 27 28 import java.io.IOException; 29 import java.io.InputStream; 30 import java.io.OutputStream; 31 import java.lang.reflect.Method; 32 import java.util.HashMap; 33 import java.util.Map; 34 35 import javax.xml.ws.WebServiceFeature; 36 37 import com.oracle.webservices.internal.api.databinding.JavaCallInfo; 38 import com.oracle.webservices.internal.api.message.MessageContext; 39 import com.sun.xml.internal.ws.api.databinding.EndpointCallBridge; 40 import com.sun.xml.internal.ws.api.databinding.WSDLGenInfo; 41 import com.sun.xml.internal.ws.api.databinding.Databinding; 42 import com.sun.xml.internal.ws.api.databinding.DatabindingConfig; 43 import com.sun.xml.internal.ws.api.databinding.ClientCallBridge; 44 import com.sun.xml.internal.ws.api.message.Message; 45 import com.sun.xml.internal.ws.api.message.MessageContextFactory; 46 import com.sun.xml.internal.ws.api.message.Packet; 47 import com.sun.xml.internal.ws.api.model.MEP; 48 import com.sun.xml.internal.ws.api.model.SEIModel; 49 import com.sun.xml.internal.ws.api.model.WSDLOperationMapping; 50 import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort; 51 import com.sun.xml.internal.ws.api.pipe.Codec; 52 import com.sun.xml.internal.ws.api.pipe.ContentType; 53 import com.sun.xml.internal.ws.binding.BindingImpl; 54 import com.sun.xml.internal.ws.client.sei.StubAsyncHandler; 55 import com.sun.xml.internal.ws.client.sei.StubHandler; 56 import com.sun.xml.internal.ws.model.AbstractSEIModelImpl; 57 import com.sun.xml.internal.ws.model.JavaMethodImpl; 58 import com.sun.xml.internal.ws.model.RuntimeModeler; 59 import com.sun.xml.internal.ws.server.sei.TieHandler; 60 import com.sun.xml.internal.ws.wsdl.ActionBasedOperationSignature; 61 import com.sun.xml.internal.ws.wsdl.DispatchException; 62 import com.sun.xml.internal.ws.wsdl.OperationDispatcher; 63 64 /** 65 * WsRuntimeImpl is the databinding processor built on SEIModel 66 * 67 * @author shih-chang.chen@oracle.com 68 */ 69 public final class DatabindingImpl implements Databinding { 70 71 AbstractSEIModelImpl seiModel; 72 Map<Method, StubHandler> stubHandlers; 73 // QNameMap<TieHandler> wsdlOpMap = new QNameMap<TieHandler>(); 74 Map<JavaMethodImpl, TieHandler> wsdlOpMap = new HashMap<JavaMethodImpl, TieHandler>(); 75 Map<Method, TieHandler> tieHandlers = new HashMap<Method, TieHandler>(); 76 OperationDispatcher operationDispatcher; 77 OperationDispatcher operationDispatcherNoWsdl; 78 boolean clientConfig = false; 79 Codec codec; 80 MessageContextFactory packetFactory = null; 81 82 public DatabindingImpl(DatabindingProviderImpl p, DatabindingConfig config) { 83 RuntimeModeler modeler = new RuntimeModeler(config); 84 modeler.setClassLoader(config.getClassLoader()); 85 seiModel = modeler.buildRuntimeModel(); 86 WSDLPort wsdlport = config.getWsdlPort(); 87 packetFactory = new MessageContextFactory(seiModel.getWSBinding().getFeatures()); 88 clientConfig = isClientConfig(config); 89 if (clientConfig) { 90 initStubHandlers(); 91 } 92 seiModel.setDatabinding(this); 93 if (wsdlport != null) { 94 freeze(wsdlport); 95 } 96 if (operationDispatcher == null) { 97 operationDispatcherNoWsdl = new OperationDispatcher(null, seiModel.getWSBinding(), seiModel); 98 } 99 // if(!clientConfig) { 100 for (JavaMethodImpl jm : seiModel.getJavaMethods()) { 101 if (!jm.isAsync()) { 102 TieHandler th = new TieHandler(jm, seiModel.getWSBinding(), packetFactory); 103 wsdlOpMap.put(jm, th); 104 tieHandlers.put(th.getMethod(), th); 105 } 106 } 107 // } 108 } 109 110 //TODO isClientConfig 111 private boolean isClientConfig(DatabindingConfig config) { 112 if (config.getContractClass() == null) { 113 return false; 114 } 115 if (!config.getContractClass().isInterface()) { 116 return false; 117 } 118 return (config.getEndpointClass() == null || config.getEndpointClass().isInterface()); 119 } 120 //TODO fix freeze 121 122 public void freeze(WSDLPort port) { 123 if (clientConfig) { 124 return; 125 } 126 synchronized(this) { 127 if (operationDispatcher == null) { 128 operationDispatcher = (port == null) ? null : new OperationDispatcher(port, seiModel.getWSBinding(), seiModel); 129 } 130 } 131 } 132 133 public SEIModel getModel() { 134 return seiModel; 135 } 136 //Refactored from SEIStub 137 138 private void initStubHandlers() { 139 stubHandlers = new HashMap<Method, StubHandler>(); 140 Map<ActionBasedOperationSignature, JavaMethodImpl> syncs = new HashMap<ActionBasedOperationSignature, JavaMethodImpl>(); 141 // fill in methodHandlers. 142 // first fill in sychronized versions 143 for (JavaMethodImpl m : seiModel.getJavaMethods()) { 144 if (!m.getMEP().isAsync) { 145 StubHandler handler = new StubHandler(m, packetFactory); 146 syncs.put(m.getOperationSignature(), m); 147 stubHandlers.put(m.getMethod(), handler); 148 } 149 } 150 for (JavaMethodImpl jm : seiModel.getJavaMethods()) { 151 JavaMethodImpl sync = syncs.get(jm.getOperationSignature()); 152 if (jm.getMEP() == MEP.ASYNC_CALLBACK || jm.getMEP() == MEP.ASYNC_POLL) { 153 Method m = jm.getMethod(); 154 StubAsyncHandler handler = new StubAsyncHandler(jm, sync, packetFactory); 155 stubHandlers.put(m, handler); 156 } 157 } 158 } 159 160 JavaMethodImpl resolveJavaMethod(Packet req) throws DispatchException { 161 WSDLOperationMapping m = req.getWSDLOperationMapping(); 162 if (m == null) { 163 synchronized (this) { 164 m = (operationDispatcher != null) 165 ? operationDispatcher.getWSDLOperationMapping(req) 166 : operationDispatcherNoWsdl.getWSDLOperationMapping(req); 167 } 168 } 169 return (JavaMethodImpl) m.getJavaMethod(); 170 } 171 172 public JavaCallInfo deserializeRequest(Packet req) { 173 com.sun.xml.internal.ws.api.databinding.JavaCallInfo call = new com.sun.xml.internal.ws.api.databinding.JavaCallInfo(); 174 try { 175 JavaMethodImpl wsdlOp = resolveJavaMethod(req); 176 TieHandler tie = wsdlOpMap.get(wsdlOp); 177 call.setMethod(tie.getMethod()); 178 Object[] args = tie.readRequest(req.getMessage()); 179 call.setParameters(args); 180 } catch (DispatchException e) { 181 call.setException(e); 182 } 183 return call; 184 } 185 186 public JavaCallInfo deserializeResponse(Packet res, JavaCallInfo call) { 187 StubHandler stubHandler = stubHandlers.get(call.getMethod()); 188 try { 189 return stubHandler.readResponse(res, call); 190 } catch (Throwable e) { 191 call.setException(e); 192 return call; 193 } 194 } 195 196 public WebServiceFeature[] getFeatures() { 197 // TODO Auto-generated method stub 198 return null; 199 } 200 201 @Override 202 public Packet serializeRequest(JavaCallInfo call) { 203 StubHandler stubHandler = stubHandlers.get(call.getMethod()); 204 Packet p = stubHandler.createRequestPacket(call); 205 p.setState(Packet.State.ClientRequest); 206 return p; 207 } 208 209 @Override 210 public Packet serializeResponse(JavaCallInfo call) { 211 Method method = call.getMethod(); 212 Message message = null; 213 if (method != null) { 214 TieHandler th = tieHandlers.get(method); 215 if (th != null) { 216 return th.serializeResponse(call); 217 } 218 } 219 if (call.getException() instanceof DispatchException) { 220 message = ((DispatchException) call.getException()).fault; 221 } 222 Packet p = (Packet) packetFactory.createContext(message); 223 p.setState(Packet.State.ServerResponse); 224 return p; 225 } 226 227 @Override 228 public ClientCallBridge getClientBridge(Method method) { 229 return stubHandlers.get(method); 230 } 231 232 @Override 233 public void generateWSDL(WSDLGenInfo info) { 234 com.sun.xml.internal.ws.wsdl.writer.WSDLGenerator wsdlGen = new com.sun.xml.internal.ws.wsdl.writer.WSDLGenerator( 235 seiModel, 236 info.getWsdlResolver(), 237 seiModel.getWSBinding(), 238 info.getContainer(), seiModel.getEndpointClass(), 239 info.isInlineSchemas(), 240 info.isSecureXmlProcessingDisabled(), 241 info.getExtensions()); 242 wsdlGen.doGeneration(); 243 } 244 245 @Override 246 public EndpointCallBridge getEndpointBridge(Packet req) throws DispatchException { 247 JavaMethodImpl wsdlOp = resolveJavaMethod(req); 248 return wsdlOpMap.get(wsdlOp); 249 } 250 251 Codec getCodec() { 252 if (codec == null) { 253 codec = ((BindingImpl) seiModel.getWSBinding()).createCodec(); 254 } 255 return codec; 256 } 257 258 @Override 259 public ContentType encode(Packet packet, OutputStream out) throws IOException { 260 return getCodec().encode(packet, out); 261 } 262 263 @Override 264 public void decode(InputStream in, String ct, Packet p) throws IOException { 265 getCodec().decode(in, ct, p); 266 } 267 268 @Override 269 public com.oracle.webservices.internal.api.databinding.JavaCallInfo createJavaCallInfo(Method method, Object[] args) { 270 return new com.sun.xml.internal.ws.api.databinding.JavaCallInfo(method, args); 271 } 272 273 @Override 274 public com.oracle.webservices.internal.api.databinding.JavaCallInfo deserializeResponse( 275 MessageContext message, com.oracle.webservices.internal.api.databinding.JavaCallInfo call) { 276 return deserializeResponse((Packet) message, (JavaCallInfo) call); 277 } 278 279 @Override 280 public com.oracle.webservices.internal.api.databinding.JavaCallInfo deserializeRequest(MessageContext message) { 281 return deserializeRequest((Packet) message); 282 } 283 284 @Override 285 public MessageContextFactory getMessageContextFactory() { 286 return packetFactory; 287 } 288 }