1 /**
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one or more
4 * contributor license agreements. See the NOTICE file distributed with
5 * this work for additional information regarding copyright ownership.
6 * The ASF licenses this file to You under the Apache License, Version 2.0
7 * (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18 package org.apache.geronimo.axis.client;
19
20 import java.lang.reflect.Method;
21 import java.rmi.RemoteException;
22 import java.util.Arrays;
23 import java.util.Iterator;
24 import java.util.Set;
25 import java.util.List;
26 import java.util.Map;
27 import javax.security.auth.Subject;
28 import javax.xml.rpc.holders.Holder;
29 import javax.wsdl.OperationType;
30
31 import net.sf.cglib.proxy.MethodInterceptor;
32 import net.sf.cglib.proxy.MethodProxy;
33 import org.apache.axis.client.Call;
34 import org.apache.axis.description.ParameterDesc;
35 import org.apache.axis.utils.JavaUtils;
36 import org.apache.geronimo.security.ContextManager;
37 import org.apache.geronimo.security.jaas.NamedUsernamePasswordCredential;
38
39 /**
40 * @version $Rev: 470597 $ $Date: 2006-11-02 15:30:55 -0800 (Thu, 02 Nov 2006) $
41 */
42 public class ServiceEndpointMethodInterceptor implements MethodInterceptor {
43
44 private final GenericServiceEndpoint stub;
45 private final OperationInfo[] operations;
46 private final String credentialsName;
47
48 public ServiceEndpointMethodInterceptor(GenericServiceEndpoint stub, OperationInfo[] operations, String credentialsName) {
49 this.stub = stub;
50 this.operations = operations;
51 this.credentialsName = credentialsName;
52 }
53
54 public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
55 int index = methodProxy.getSuperIndex();
56 OperationInfo operationInfo = operations[index];
57 if (operationInfo == null) {
58 throw new RuntimeException("Operation not mapped: " + method.getName() + " index: " + index + "\n OperationInfos: " + Arrays.asList(operations));
59 }
60 stub.checkCachedEndpoint();
61
62 Call call = stub.createCall();
63
64 operationInfo.prepareCall(call);
65
66 stub.setUpCall(call);
67 if (credentialsName != null) {
68 Subject subject = ContextManager.getNextCaller();
69 if (subject == null) {
70 throw new IllegalStateException("Subject missing but authentication turned on");
71 } else {
72 Set creds = subject.getPrivateCredentials(NamedUsernamePasswordCredential.class);
73 boolean found = false;
74 for (Iterator iterator = creds.iterator(); iterator.hasNext();) {
75 NamedUsernamePasswordCredential namedUsernamePasswordCredential = (NamedUsernamePasswordCredential) iterator.next();
76 if (credentialsName.equals(namedUsernamePasswordCredential.getName())) {
77 call.setUsername(namedUsernamePasswordCredential.getUsername());
78 call.setPassword(new String(namedUsernamePasswordCredential.getPassword()));
79 found = true;
80 break;
81 }
82 }
83 if (!found) {
84 throw new IllegalStateException("no NamedUsernamePasswordCredential found for name " + credentialsName);
85 }
86 }
87 }
88 Object response = null;
89 List parameterDescs = operationInfo.getOperationDesc().getParameters();
90 Object[] unwrapped = extractFromHolders(objects, parameterDescs, operationInfo.getOperationDesc().getNumInParams());
91 if (operationInfo.getOperationDesc().getMep() == OperationType.REQUEST_RESPONSE) {
92 try {
93 response = call.invoke(unwrapped);
94 } catch (RemoteException e) {
95 throw operationInfo.unwrapFault(e);
96 }
97
98 if (response instanceof RemoteException) {
99 throw operationInfo.unwrapFault((RemoteException) response);
100 } else {
101 stub.extractAttachments(call);
102 Map outputParameters = call.getOutputParams();
103 putInHolders(outputParameters, objects, parameterDescs);
104 Class returnType = operationInfo.getOperationDesc().getReturnClass();
105
106 if (response == null || returnType == null || returnType.isAssignableFrom(response.getClass())) {
107 return response;
108 } else {
109 return JavaUtils.convert(response, returnType);
110 }
111 }
112 } else if (operationInfo.getOperationDesc().getMep() == OperationType.ONE_WAY) {
113
114 call.invokeOneWay(unwrapped);
115 return null;
116 } else {
117 throw new RuntimeException("Invalid messaging style: " + operationInfo.getOperationDesc().getMep());
118 }
119 }
120
121 private Object[] extractFromHolders(Object[] objects, List parameterDescs, int inParameterCount) throws JavaUtils.HolderException {
122 if (objects.length != parameterDescs.size()) {
123 throw new IllegalArgumentException("Mismatch parameter count: expected: " + parameterDescs.size() + ", actual: " + objects.length);
124 }
125 Object[] unwrapped = new Object[inParameterCount];
126 int j = 0;
127 for (int i = 0; objects != null && i < objects.length; i++) {
128 Object parameter = objects[i];
129 ParameterDesc parameterDesc = (ParameterDesc) parameterDescs.get(i);
130
131 if (parameterDesc.getMode() == ParameterDesc.INOUT) {
132 unwrapped[j++] = JavaUtils.getHolderValue((Holder) parameter);
133 } else if (parameterDesc.getMode() == ParameterDesc.IN) {
134 unwrapped[j++] = parameter;
135 }
136 }
137 return unwrapped;
138 }
139
140 private void putInHolders(Map outputParameters, Object[] objects, List parameterDescs) throws JavaUtils.HolderException {
141 for (int i = 0; i < objects.length; i++) {
142 Object parameter = objects[i];
143 ParameterDesc parameterDesc = (ParameterDesc) parameterDescs.get(i);
144 if ((parameterDesc.getMode() == ParameterDesc.INOUT) ||
145 (parameterDesc.getMode() == ParameterDesc.OUT)) {
146 Object returned = outputParameters.get(parameterDesc.getQName());
147 if (returned instanceof Holder) {
148
149 returned = JavaUtils.getHolderValue(returned);
150 }
151 JavaUtils.setHolderValue((Holder) parameter, returned);
152 }
153 }
154 }
155
156 }