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.openejb.server.axis.client;
017:
018: import net.sf.cglib.proxy.MethodInterceptor;
019: import net.sf.cglib.proxy.MethodProxy;
020: import org.apache.axis.client.Call;
021: import org.apache.axis.description.ParameterDesc;
022: import org.apache.axis.utils.JavaUtils;
023: import org.apache.openejb.server.webservices.saaj.SaajUniverse;
024:
025: import javax.wsdl.OperationType;
026: import javax.xml.rpc.holders.Holder;
027: import java.lang.reflect.Method;
028: import java.rmi.RemoteException;
029: import java.util.Arrays;
030: import java.util.List;
031: import java.util.Map;
032:
033: public class ServiceEndpointMethodInterceptor implements
034: MethodInterceptor {
035: private final GenericServiceEndpoint stub;
036: private final OperationInfo[] operations;
037: private final String credentialsName;
038:
039: public ServiceEndpointMethodInterceptor(
040: GenericServiceEndpoint stub, OperationInfo[] operations,
041: String credentialsName) {
042: this .stub = stub;
043: this .operations = operations;
044: this .credentialsName = credentialsName;
045: }
046:
047: public Object intercept(Object o, Method method, Object[] objects,
048: MethodProxy methodProxy) throws Throwable {
049: SaajUniverse universe = new SaajUniverse();
050: universe.set(SaajUniverse.AXIS1);
051: try {
052: return doIntercept(method, objects, methodProxy);
053: } finally {
054: universe.unset();
055: }
056: }
057:
058: private Object doIntercept(Method method, Object[] objects,
059: MethodProxy methodProxy) throws Throwable {
060: int index = methodProxy.getSuperIndex();
061: OperationInfo operationInfo = operations[index];
062: if (operationInfo == null) {
063: throw new RuntimeException("Operation not mapped: "
064: + method.getName() + " index: " + index
065: + "\n OperationInfos: " + Arrays.asList(operations));
066: }
067: stub.checkCachedEndpoint();
068:
069: Call call = stub.createCall();
070:
071: operationInfo.prepareCall(call);
072:
073: stub.setUpCall(call);
074: if (credentialsName != null) {
075: throw new UnsupportedOperationException(
076: "Client side auth is not implementd");
077: // Subject subject = ContextManager.getNextCaller();
078: // if (subject == null) {
079: // throw new IllegalStateException("Subject missing but authentication turned on");
080: // } else {
081: // Set creds = subject.getPrivateCredentials(NamedUsernamePasswordCredential.class);
082: // boolean found = false;
083: // for (Iterator iterator = creds.iterator(); iterator.hasNext();) {
084: // NamedUsernamePasswordCredential namedUsernamePasswordCredential = (NamedUsernamePasswordCredential) iterator.next();
085: // if (credentialsName.equals(namedUsernamePasswordCredential.getName())) {
086: // call.setUsername(namedUsernamePasswordCredential.getUsername());
087: // call.setPassword(new String(namedUsernamePasswordCredential.getPassword()));
088: // found = true;
089: // break;
090: // }
091: // }
092: // if (!found) {
093: // throw new IllegalStateException("no NamedUsernamePasswordCredential found for name " + credentialsName);
094: // }
095: // }
096: }
097: Object response = null;
098: List parameterDescs = operationInfo.getOperationDesc()
099: .getParameters();
100: Object[] unwrapped = extractFromHolders(objects,
101: parameterDescs, operationInfo.getOperationDesc()
102: .getNumInParams());
103: if (operationInfo.getOperationDesc().getMep() == OperationType.REQUEST_RESPONSE) {
104: try {
105: response = call.invoke(unwrapped);
106: } catch (RemoteException e) {
107: throw operationInfo.unwrapFault(e);
108: }
109:
110: if (response instanceof RemoteException) {
111: throw operationInfo
112: .unwrapFault((RemoteException) response);
113: } else {
114: stub.extractAttachments(call);
115: Map outputParameters = call.getOutputParams();
116: putInHolders(outputParameters, objects, parameterDescs);
117: Class returnType = operationInfo.getOperationDesc()
118: .getReturnClass();
119: //return type should never be null... but we are not objecting if wsdl-return-value-mapping is not set.
120: if (response == null
121: || returnType == null
122: || returnType.isAssignableFrom(response
123: .getClass())) {
124: return response;
125: } else {
126: return JavaUtils.convert(response, returnType);
127: }
128: }
129: } else if (operationInfo.getOperationDesc().getMep() == OperationType.ONE_WAY) {
130: //one way
131: call.invokeOneWay(unwrapped);
132: return null;
133: } else {
134: throw new RuntimeException("Invalid messaging style: "
135: + operationInfo.getOperationDesc().getMep());
136: }
137: }
138:
139: private Object[] extractFromHolders(Object[] objects,
140: List parameterDescs, int inParameterCount)
141: throws JavaUtils.HolderException {
142: if (objects.length != parameterDescs.size()) {
143: throw new IllegalArgumentException(
144: "Mismatch parameter count: expected: "
145: + parameterDescs.size() + ", actual: "
146: + objects.length);
147: }
148: Object[] unwrapped = new Object[inParameterCount];
149: int j = 0;
150: for (int i = 0; objects != null && i < objects.length; i++) {
151: Object parameter = objects[i];
152: ParameterDesc parameterDesc = (ParameterDesc) parameterDescs
153: .get(i);
154:
155: if (parameterDesc.getMode() == ParameterDesc.INOUT) {
156: unwrapped[j++] = JavaUtils.getHolderValue(parameter);
157: } else if (parameterDesc.getMode() == ParameterDesc.IN) {
158: unwrapped[j++] = parameter;
159: }
160: }
161: return unwrapped;
162: }
163:
164: private void putInHolders(Map outputParameters, Object[] objects,
165: List parameterDescs) throws JavaUtils.HolderException {
166: for (int i = 0; i < objects.length; i++) {
167: Object parameter = objects[i];
168: ParameterDesc parameterDesc = (ParameterDesc) parameterDescs
169: .get(i);
170: if ((parameterDesc.getMode() == ParameterDesc.INOUT)
171: || (parameterDesc.getMode() == ParameterDesc.OUT)) {
172: Object returned = outputParameters.get(parameterDesc
173: .getQName());
174: if (returned instanceof Holder) {
175: //TODO this must be a bug somewhere!!!!
176: returned = JavaUtils.getHolderValue(returned);
177: }
178: JavaUtils.setHolderValue(parameter, returned);
179: }
180: }
181: }
182: }
|