View Javadoc

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         //register our type descriptors
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         //It is essential that the types be registered before the typeInfos create the serializer/deserializers.
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         //TODO figure out why this can't be called in readResolve!
139 //        synchronized (this) {
140 //            if (!initialized) {
141 //                initialize();
142 //                initialized = true;
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 //    private Object readResolve() throws ObjectStreamException {
163 //            SEIFactoryImpl seiFactory =  new SEIFactoryImpl(serviceName, portQName.getLocalPart(), serviceEndpointClassName, operationInfos, typeInfo, location, handlerInfos, credentialsName);
164 //            seiFactory.initialize();
165 //            return seiFactory;
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 }