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.jaxws.client;
017:
018: import net.sf.cglib.proxy.MethodInterceptor;
019: import net.sf.cglib.proxy.MethodProxy;
020: import org.apache.commons.logging.Log;
021: import org.apache.commons.logging.LogFactory;
022: import org.apache.geronimo.jaxws.JAXWSUtils;
023: import org.apache.geronimo.security.ContextManager;
024: import org.apache.geronimo.security.jaas.NamedUsernamePasswordCredential;
025:
026: import javax.security.auth.Subject;
027: import javax.xml.namespace.QName;
028: import javax.xml.ws.BindingProvider;
029: import javax.xml.ws.WebEndpoint;
030: import javax.xml.ws.soap.SOAPBinding;
031:
032: import java.lang.reflect.Method;
033: import java.net.URL;
034: import java.util.Iterator;
035: import java.util.Map;
036: import java.util.Set;
037:
038: public class PortMethodInterceptor implements MethodInterceptor {
039:
040: private static final Log LOG = LogFactory
041: .getLog(PortMethodInterceptor.class);
042:
043: private Map<Object, EndpointInfo> seiInfoMap;
044:
045: public PortMethodInterceptor(Map<Object, EndpointInfo> seiInfoMap) {
046: this .seiInfoMap = seiInfoMap;
047: }
048:
049: public Object intercept(Object target, Method method,
050: Object[] arguments, MethodProxy methodProxy)
051: throws Throwable {
052: Object proxy = methodProxy.invokeSuper(target, arguments);
053:
054: if (method.getName().equals("getPort")) {
055: // it's a generic getPort() method
056: if (arguments.length == 1) {
057: // getPort(Class) called - use SEI annotation
058: setProperties((BindingProvider) proxy, JAXWSUtils
059: .getPortType((Class) arguments[0]));
060: } else if (arguments.length == 2) {
061: // getPort(QName, Class) called
062: if (arguments[0] == null) {
063: // port qname not specified - use SEI annotation
064: setProperties((BindingProvider) proxy, JAXWSUtils
065: .getPortType((Class) arguments[1]));
066: } else {
067: // port qname specified
068: setProperties((BindingProvider) proxy,
069: ((QName) arguments[0]).getLocalPart());
070: }
071: }
072: } else if (method.getName().startsWith("get")) {
073: // it's a generated get<PortName>() method
074: WebEndpoint endpoint = method
075: .getAnnotation(WebEndpoint.class);
076: setProperties((BindingProvider) proxy, endpoint.name());
077: } else if (method.getName().equals("createDispatch")) {
078: // it's one of createDispatch() methods
079: setProperties((BindingProvider) proxy,
080: ((QName) arguments[0]).getLocalPart());
081: }
082:
083: return proxy;
084: }
085:
086: private void setProperties(BindingProvider proxy, QName portType) {
087: if (portType == null) {
088: return;
089: }
090: EndpointInfo info = this .seiInfoMap.get(portType);
091: setProperties(proxy, info);
092: }
093:
094: private void setProperties(BindingProvider proxy, String portName) {
095: if (portName == null) {
096: return;
097: }
098: EndpointInfo info = this .seiInfoMap.get(portName);
099: setProperties(proxy, info);
100: }
101:
102: private void setProperties(BindingProvider proxy, EndpointInfo info) {
103: if (info == null) {
104: return;
105: }
106:
107: // set mtom
108: boolean enableMTOM = info.isMTOMEnabled();
109: if (enableMTOM && proxy.getBinding() instanceof SOAPBinding) {
110: ((SOAPBinding) proxy.getBinding())
111: .setMTOMEnabled(enableMTOM);
112: LOG.debug("Set mtom property: " + enableMTOM);
113: }
114:
115: // set address
116: URL location = info.getLocation();
117: if (location != null) {
118: proxy.getRequestContext().put(
119: BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
120: location.toString());
121: LOG.debug("Set address property: " + location);
122: }
123:
124: // set credentials
125: String credentialsName = info.getCredentialsName();
126: if (credentialsName != null) {
127: Subject subject = ContextManager.getNextCaller();
128: if (subject == null) {
129: throw new IllegalStateException(
130: "Subject missing but authentication turned on");
131: } else {
132: Set creds = subject
133: .getPrivateCredentials(NamedUsernamePasswordCredential.class);
134: boolean found = false;
135:
136: for (Iterator iterator = creds.iterator(); iterator
137: .hasNext();) {
138: NamedUsernamePasswordCredential namedUsernamePasswordCredential = (NamedUsernamePasswordCredential) iterator
139: .next();
140: if (credentialsName
141: .equals(namedUsernamePasswordCredential
142: .getName())) {
143: proxy.getRequestContext().put(
144: BindingProvider.USERNAME_PROPERTY,
145: namedUsernamePasswordCredential
146: .getUsername());
147: proxy.getRequestContext().put(
148: BindingProvider.PASSWORD_PROPERTY,
149: new String(
150: namedUsernamePasswordCredential
151: .getPassword()));
152: LOG.debug("Set username/password property: "
153: + credentialsName);
154: found = true;
155: break;
156: }
157: }
158: if (!found) {
159: throw new IllegalStateException(
160: "no NamedUsernamePasswordCredential found for name "
161: + credentialsName);
162: }
163: }
164: }
165: }
166: }
|