1 /**
2 *
3 * Copyright 2003-2004 The Apache Software Foundation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.geronimo.axis.client;
18
19 import java.io.Serializable;
20 import java.lang.reflect.InvocationTargetException;
21 import java.math.BigInteger;
22 import java.net.MalformedURLException;
23 import java.net.URI;
24 import java.net.URL;
25 import java.rmi.Remote;
26 import java.util.Iterator;
27 import java.util.List;
28
29 import javax.xml.namespace.QName;
30 import javax.xml.rpc.ServiceException;
31 import javax.xml.rpc.handler.HandlerChain;
32
33 import net.sf.cglib.core.Signature;
34 import net.sf.cglib.proxy.Callback;
35 import net.sf.cglib.proxy.Enhancer;
36 import net.sf.cglib.proxy.MethodInterceptor;
37 import net.sf.cglib.proxy.MethodProxy;
38 import net.sf.cglib.proxy.NoOp;
39 import net.sf.cglib.reflect.FastClass;
40 import net.sf.cglib.reflect.FastConstructor;
41 import org.apache.axis.AxisEngine;
42 import org.apache.axis.Constants;
43 import org.apache.axis.client.Service;
44 import org.apache.axis.constants.Use;
45 import org.apache.axis.description.TypeDesc;
46 import org.apache.axis.encoding.TypeMapping;
47 import org.apache.axis.encoding.TypeMappingRegistry;
48 import org.apache.axis.encoding.ser.SimpleDeserializerFactory;
49 import org.apache.axis.encoding.ser.SimpleSerializerFactory;
50 import org.apache.axis.handlers.HandlerInfoChainFactory;
51
52 /**
53 * @version $Rev: 394442 $ $Date: 2006-04-16 01:08:12 -0700 (Sun, 16 Apr 2006) $
54 */
55 public class SEIFactoryImpl implements SEIFactory, Serializable {
56
57 private final QName serviceName;
58 private final QName portQName;
59 private final String serviceEndpointClassName;
60 private final OperationInfo[] operationInfos;
61 private transient FastConstructor constructor;
62 private Object serviceImpl;
63 private final List typeInfo;
64 private final URL location;
65 private final List handlerInfos;
66 private final String credentialsName;
67 private transient HandlerInfoChainFactory handlerInfoChainFactory;
68 private transient OperationInfo[] sortedOperationInfos;
69 private Class serviceEndpointClass;
70
71 public SEIFactoryImpl(QName serviceName, String portName, String serviceEndpointClassName, OperationInfo[] operationInfos, List typeInfo, URL location, List handlerInfos, String credentialsName) {
72 this.serviceName = serviceName;
73 this.portQName = new QName("", portName);
74 this.serviceEndpointClassName = serviceEndpointClassName;
75 this.operationInfos = operationInfos;
76 this.typeInfo = typeInfo;
77 this.location = location;
78 this.handlerInfos = handlerInfos;
79 this.credentialsName = credentialsName;
80 }
81
82 void initialize(Object serviceImpl, ClassLoader classLoader) throws ClassNotFoundException {
83 this.serviceImpl = serviceImpl;
84 Class serviceEndpointBaseClass = classLoader.loadClass(serviceEndpointClassName);
85 serviceEndpointClass = enhanceServiceEndpointInterface(serviceEndpointBaseClass, classLoader);
86 Class[] constructorTypes = new Class[]{classLoader.loadClass(GenericServiceEndpoint.class.getName())};
87 this.constructor = FastClass.create(serviceEndpointClass).getConstructor(constructorTypes);
88 this.handlerInfoChainFactory = new HandlerInfoChainFactory(handlerInfos);
89 sortedOperationInfos = new OperationInfo[FastClass.create(serviceEndpointClass).getMaxIndex() + 1];
90 String encodingStyle = "";
91 for (int i = 0; i < operationInfos.length; i++) {
92 OperationInfo operationInfo = operationInfos[i];
93 Signature signature = operationInfo.getSignature();
94 MethodProxy methodProxy = MethodProxy.find(serviceEndpointClass, signature);
95 if (methodProxy == null) {
96 throw new RuntimeException("No method proxy for operationInfo " + signature);
97 }
98 int index = methodProxy.getSuperIndex();
99 sortedOperationInfos[index] = operationInfo;
100 if (operationInfo.getOperationDesc().getUse() == Use.ENCODED) {
101 encodingStyle = org.apache.axis.Constants.URI_SOAP11_ENC;
102 }
103 }
104
105 Service service = ((ServiceImpl) serviceImpl).getService();
106 AxisEngine axisEngine = service.getEngine();
107 TypeMappingRegistry typeMappingRegistry = axisEngine.getTypeMappingRegistry();
108 TypeMapping typeMapping = typeMappingRegistry.getOrMakeTypeMapping(encodingStyle);
109 typeMapping.register(BigInteger.class,
110 Constants.XSD_UNSIGNEDLONG,
111 new SimpleSerializerFactory(BigInteger.class, Constants.XSD_UNSIGNEDLONG),
112 new SimpleDeserializerFactory(BigInteger.class, Constants.XSD_UNSIGNEDLONG));
113 typeMapping.register(URI.class,
114 Constants.XSD_ANYURI,
115 new SimpleSerializerFactory(URI.class, Constants.XSD_ANYURI),
116 new SimpleDeserializerFactory(URI.class, Constants.XSD_ANYURI));
117
118 for (Iterator iter = typeInfo.iterator(); iter.hasNext();) {
119 TypeInfo info = (TypeInfo) iter.next();
120 TypeDesc.registerTypeDescForClass(info.getClazz(), info.buildTypeDesc());
121 }
122 TypeInfo.register(typeInfo, typeMapping);
123 }
124
125 private Class enhanceServiceEndpointInterface(Class serviceEndpointInterface, ClassLoader classLoader) {
126 Enhancer enhancer = new Enhancer();
127 enhancer.setClassLoader(classLoader);
128 enhancer.setSuperclass(GenericServiceEndpointWrapper.class);
129 enhancer.setInterfaces(new Class[]{serviceEndpointInterface});
130 enhancer.setCallbackFilter(new NoOverrideCallbackFilter(GenericServiceEndpointWrapper.class));
131 enhancer.setCallbackTypes(new Class[]{NoOp.class, MethodInterceptor.class});
132 enhancer.setUseFactory(false);
133 enhancer.setUseCache(false);
134
135 return enhancer.createClass();
136 }
137 public Remote createServiceEndpoint() throws ServiceException {
138
139
140
141
142
143
144
145 Service service = ((ServiceImpl) serviceImpl).getService();
146 GenericServiceEndpoint serviceEndpoint = new GenericServiceEndpoint(portQName, service, location);
147 Callback callback = new ServiceEndpointMethodInterceptor(serviceEndpoint, sortedOperationInfos, credentialsName);
148 Callback[] callbacks = new Callback[]{SerializableNoOp.INSTANCE, callback};
149 Enhancer.registerCallbacks(serviceEndpointClass, callbacks);
150 try {
151 return (Remote) constructor.newInstance(new Object[]{serviceEndpoint});
152 } catch (InvocationTargetException e) {
153 e.getTargetException().printStackTrace();
154 throw new ServiceException("Could not construct service instance", e.getTargetException());
155 }
156 }
157
158 public HandlerChain createHandlerChain() {
159 return handlerInfoChainFactory.createHandlerChain();
160 }
161
162
163
164
165
166
167
168 public OperationInfo[] getOperationInfos() {
169 return operationInfos;
170 }
171
172 public QName getPortQName() {
173 return portQName;
174 }
175
176 public QName getServiceName() {
177 return serviceName;
178 }
179
180 public URL getWSDLDocumentLocation() {
181 try {
182 return new URL(location.toExternalForm() + "?wsdl");
183 } catch (MalformedURLException e) {
184 return null;
185 }
186 }
187 }