Java tutorial
/* * Copyright (c) 2008-2011, Martijn Brinkers, Djigzo. * * This file is part of Djigzo email encryption. * * Djigzo is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License * version 3, 19 November 2007 as published by the Free Software * Foundation. * * Djigzo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public * License along with Djigzo. If not, see <http://www.gnu.org/licenses/> * * Additional permission under GNU AGPL version 3 section 7 * * If you modify this Program, or any covered work, by linking or * combining it with saaj-api-1.3.jar, saaj-impl-1.3.jar, * wsdl4j-1.6.1.jar (or modified versions of these libraries), * containing parts covered by the terms of Common Development and * Distribution License (CDDL), Common Public License (CPL) the * licensors of this Program grant you additional permission to * convey the resulting work. */ package mitm.common.ws; import java.lang.reflect.ParameterizedType; import java.net.URL; import java.util.HashMap; import java.util.Map; import javax.xml.namespace.QName; import javax.xml.ws.BindingProvider; import javax.xml.ws.Service; import org.apache.commons.lang.time.DateUtils; import org.apache.cxf.endpoint.Client; import org.apache.cxf.endpoint.Endpoint; import org.apache.cxf.frontend.ClientProxy; import org.apache.cxf.transport.http.HTTPConduit; import org.apache.cxf.transports.http.configuration.HTTPClientPolicy; import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor; import org.apache.ws.security.handler.WSHandlerConstants; /** * Base class for Webservice factories. This class is abstract because it must not be instantiated * but only extended. This is required because we need the class for the webservice * (see persistentClass). * * @author Martijn Brinkers * * @param <T> */ public abstract class AbstractWSProxyFactory<T> implements WSProxyFactory<T> { private final static long DEFAULT_RECEIVE_TIMEOUT = 5 * DateUtils.MILLIS_PER_MINUTE; private final static long DEFAULT_CONNECT_TIMEOUT = 30 * DateUtils.MILLIS_PER_SECOND; private final static String PASSWORD_FIELD = "password"; private final Class<T> persistentClass; /* * URL of the WSDL. */ private final URL wsdlURL; /* * Namespace of the service */ private final String nsURI; /* * Local part of the service */ private final String localPart; /* * SOAP receive timeout */ private long receiveTimeOut = DEFAULT_RECEIVE_TIMEOUT; /* * SOAP connection timeout */ private long connectTimeOut = DEFAULT_CONNECT_TIMEOUT; /* * The SOAP password mode to use */ private SOAPPasswordMode passwordMode = SOAPPasswordMode.DIGEST; private T proxy; @SuppressWarnings("unchecked") public AbstractWSProxyFactory(URL wsdlURL, String nsURI, String localPart) { this.wsdlURL = wsdlURL; this.nsURI = nsURI; this.localPart = localPart; this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()) .getActualTypeArguments()[0]; } private T internalCreateProxy() { QName SERVICE_NAME = new QName(nsURI, localPart); Service service = Service.create(wsdlURL, SERVICE_NAME); T proxy = service.getPort(persistentClass); /* * Make request context multithread safe. See http://markmail.org/message/lgldei2zt4trlyr6 */ ((BindingProvider) proxy).getRequestContext().put("thread.local.request.context", Boolean.TRUE); Client client = ClientProxy.getClient(proxy); HTTPConduit http = (HTTPConduit) client.getConduit(); HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy(); httpClientPolicy.setConnectionTimeout(connectTimeOut); httpClientPolicy.setReceiveTimeout(receiveTimeOut); http.setClient(httpClientPolicy); Endpoint endpoint = client.getEndpoint(); Map<String, Object> outProps = new HashMap<String, Object>(); outProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN); outProps.put(WSHandlerConstants.PASSWORD_TYPE, passwordMode.getMode()); WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps); endpoint.getOutInterceptors().add(wssOut); return proxy; } @Override public synchronized T createProxy(Credential credential) throws WSProxyFactoryException { if (proxy == null) { proxy = internalCreateProxy(); } if (!(proxy instanceof BindingProvider)) { throw new WSProxyFactoryException("The proxy does not implement BindingProvider"); } Map<String, Object> requestContext = ((BindingProvider) proxy).getRequestContext(); /* * Make request context multithread safe. See http://markmail.org/message/lgldei2zt4trlyr6. * I'm not sure if I have to call it for every invocation but according to this post it * should: * http://www.nabble.com/Re%3A-Need-help-on-OutInterceptors%2C-authentiction-and-multiple-threads-p17866587.html */ requestContext.put("thread.local.request.context", Boolean.TRUE); requestContext.put(WSHandlerConstants.USER, credential.getUsername()); requestContext.put(PASSWORD_FIELD, credential.getPassword()); return proxy; } public SOAPPasswordMode getPasswordMode() { return passwordMode; } public void setPasswordMode(SOAPPasswordMode passwordMode) { this.passwordMode = passwordMode; } }