001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.geronimo.axis.client;
017:
018: import java.io.Serializable;
019: import java.lang.reflect.InvocationTargetException;
020: import java.math.BigInteger;
021: import java.net.MalformedURLException;
022: import java.net.URI;
023: import java.net.URL;
024: import java.rmi.Remote;
025: import java.util.Iterator;
026: import java.util.List;
027:
028: import javax.xml.namespace.QName;
029: import javax.xml.rpc.ServiceException;
030: import javax.xml.rpc.handler.HandlerChain;
031:
032: import net.sf.cglib.core.Signature;
033: import net.sf.cglib.proxy.Callback;
034: import net.sf.cglib.proxy.Enhancer;
035: import net.sf.cglib.proxy.MethodInterceptor;
036: import net.sf.cglib.proxy.MethodProxy;
037: import net.sf.cglib.proxy.NoOp;
038: import net.sf.cglib.reflect.FastClass;
039: import net.sf.cglib.reflect.FastConstructor;
040: import org.apache.axis.AxisEngine;
041: import org.apache.axis.Constants;
042: import org.apache.axis.client.Service;
043: import org.apache.axis.constants.Use;
044: import org.apache.axis.description.TypeDesc;
045: import org.apache.axis.encoding.TypeMapping;
046: import org.apache.axis.encoding.TypeMappingRegistry;
047: import org.apache.axis.encoding.ser.SimpleDeserializerFactory;
048: import org.apache.axis.encoding.ser.SimpleSerializerFactory;
049: import org.apache.axis.handlers.HandlerInfoChainFactory;
050:
051: /**
052: * @version $Rev: 548434 $ $Date: 2007-06-18 11:27:34 -0700 (Mon, 18 Jun 2007) $
053: */
054: public class SEIFactoryImpl implements SEIFactory, Serializable {
055:
056: private final QName serviceName;
057: private final QName portQName;
058: private final String serviceEndpointClassName;
059: private final OperationInfo[] operationInfos;
060: private transient FastConstructor constructor;
061: private Object serviceImpl;
062: private final List typeInfo;
063: private final URL location;
064: private final List handlerInfos;
065: private final String credentialsName;
066: private transient HandlerInfoChainFactory handlerInfoChainFactory;
067: private transient OperationInfo[] sortedOperationInfos;
068: private Class serviceEndpointClass;
069:
070: public SEIFactoryImpl(QName serviceName, String portName,
071: String serviceEndpointClassName,
072: OperationInfo[] operationInfos, List typeInfo,
073: URL location, List handlerInfos, String credentialsName) {
074: this .serviceName = serviceName;
075: this .portQName = new QName("", portName);
076: this .serviceEndpointClassName = serviceEndpointClassName;
077: this .operationInfos = operationInfos;
078: this .typeInfo = typeInfo;
079: this .location = location;
080: this .handlerInfos = handlerInfos;
081: this .credentialsName = credentialsName;
082: }
083:
084: void initialize(Object serviceImpl, ClassLoader classLoader)
085: throws ClassNotFoundException {
086: this .serviceImpl = serviceImpl;
087: Class serviceEndpointBaseClass = classLoader
088: .loadClass(serviceEndpointClassName);
089: serviceEndpointClass = enhanceServiceEndpointInterface(
090: serviceEndpointBaseClass, classLoader);
091: Class[] constructorTypes = new Class[] { classLoader
092: .loadClass(GenericServiceEndpoint.class.getName()) };
093: this .constructor = FastClass.create(serviceEndpointClass)
094: .getConstructor(constructorTypes);
095: this .handlerInfoChainFactory = new HandlerInfoChainFactory(
096: handlerInfos);
097: sortedOperationInfos = new OperationInfo[FastClass.create(
098: serviceEndpointClass).getMaxIndex() + 1];
099: String encodingStyle = "";
100: for (int i = 0; i < operationInfos.length; i++) {
101: OperationInfo operationInfo = operationInfos[i];
102: Signature signature = operationInfo.getSignature();
103: MethodProxy methodProxy = MethodProxy.find(
104: serviceEndpointClass, signature);
105: if (methodProxy == null) {
106: throw new RuntimeException(
107: "No method proxy for operationInfo "
108: + signature);
109: }
110: int index = methodProxy.getSuperIndex();
111: sortedOperationInfos[index] = operationInfo;
112: if (operationInfo.getOperationDesc().getUse() == Use.ENCODED) {
113: encodingStyle = org.apache.axis.Constants.URI_SOAP11_ENC;
114: }
115: }
116: //register our type descriptors
117: Service service = ((ServiceImpl) serviceImpl).getService();
118: AxisEngine axisEngine = service.getEngine();
119: TypeMappingRegistry typeMappingRegistry = axisEngine
120: .getTypeMappingRegistry();
121: TypeMapping typeMapping = typeMappingRegistry
122: .getOrMakeTypeMapping(encodingStyle);
123: typeMapping.register(BigInteger.class,
124: Constants.XSD_UNSIGNEDLONG,
125: new SimpleSerializerFactory(BigInteger.class,
126: Constants.XSD_UNSIGNEDLONG),
127: new SimpleDeserializerFactory(BigInteger.class,
128: Constants.XSD_UNSIGNEDLONG));
129: typeMapping.register(URI.class, Constants.XSD_ANYURI,
130: new SimpleSerializerFactory(URI.class,
131: Constants.XSD_ANYURI),
132: new SimpleDeserializerFactory(URI.class,
133: Constants.XSD_ANYURI));
134: //It is essential that the types be registered before the typeInfos create the serializer/deserializers.
135: for (Iterator iter = typeInfo.iterator(); iter.hasNext();) {
136: TypeInfo info = (TypeInfo) iter.next();
137: TypeDesc.registerTypeDescForClass(info.getClazz(), info
138: .buildTypeDesc());
139: }
140: TypeInfo.register(typeInfo, typeMapping);
141: }
142:
143: private Class enhanceServiceEndpointInterface(
144: Class serviceEndpointInterface, ClassLoader classLoader) {
145: Enhancer enhancer = new Enhancer();
146: enhancer.setClassLoader(classLoader);
147: enhancer.setSuperclass(GenericServiceEndpointWrapper.class);
148: enhancer
149: .setInterfaces(new Class[] { serviceEndpointInterface });
150: enhancer.setCallbackFilter(new NoOverrideCallbackFilter(
151: GenericServiceEndpointWrapper.class));
152: enhancer.setCallbackTypes(new Class[] { NoOp.class,
153: MethodInterceptor.class });
154: enhancer.setUseFactory(false);
155: enhancer.setUseCache(false);
156:
157: return enhancer.createClass();
158: }
159:
160: public Remote createServiceEndpoint() throws ServiceException {
161: //TODO figure out why this can't be called in readResolve!
162: // synchronized (this) {
163: // if (!initialized) {
164: // initialize();
165: // initialized = true;
166: // }
167: // }
168: Service service = ((ServiceImpl) serviceImpl).getService();
169: GenericServiceEndpoint serviceEndpoint = new GenericServiceEndpoint(
170: portQName, service, location);
171: Callback callback = new ServiceEndpointMethodInterceptor(
172: serviceEndpoint, sortedOperationInfos, credentialsName);
173: Callback[] callbacks = new Callback[] {
174: SerializableNoOp.INSTANCE, callback };
175: Enhancer.registerCallbacks(serviceEndpointClass, callbacks);
176: try {
177: return (Remote) constructor
178: .newInstance(new Object[] { serviceEndpoint });
179: } catch (InvocationTargetException e) {
180: throw (ServiceException) new ServiceException(
181: "Could not construct service instance", e
182: .getTargetException()).initCause(e);
183: }
184: }
185:
186: public HandlerChain createHandlerChain() {
187: return handlerInfoChainFactory.createHandlerChain();
188: }
189:
190: // private Object readResolve() throws ObjectStreamException {
191: // SEIFactoryImpl seiFactory = new SEIFactoryImpl(serviceName, portQName.getLocalPart(), serviceEndpointClassName, operationInfos, typeInfo, location, handlerInfos, credentialsName);
192: // seiFactory.initialize();
193: // return seiFactory;
194: // }
195:
196: public OperationInfo[] getOperationInfos() {
197: return operationInfos;
198: }
199:
200: public QName getPortQName() {
201: return portQName;
202: }
203:
204: public QName getServiceName() {
205: return serviceName;
206: }
207:
208: public URL getWSDLDocumentLocation() {
209: try {
210: return new URL(location.toExternalForm() + "?wsdl");
211: } catch (MalformedURLException e) {
212: return null;
213: }
214: }
215: }
|