/* ===============================================================================
*
* Part of the InfoGlue Content Management Platform (www.infoglue.org)
*
* ===============================================================================
*
* Copyright (C)
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 2, as published by the
* Free Software Foundation. See the file LICENSE.html for more information.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY, including the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc. / 59 Temple
* Place, Suite 330 / Boston, MA 02111-1307 / USA.
*
* ===============================================================================
*/
package org.infoglue.deliver.util.webservices;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;
import org.apache.axis.encoding.ser.BeanDeserializerFactory;
import org.apache.axis.encoding.ser.BeanSerializerFactory;
import org.apache.log4j.Logger;
import org.infoglue.cms.security.InfoGluePrincipal;
/**
*
*/
class Parameter
{
public final String name;
public final QName type;
public Parameter(final String name, final QName type)
{
this.name = name;
this.type = type;
}
}
/**
*
*/
public class DynamicWebservice
{
/**
* The class logger.
*/
private final static Logger logger = Logger.getLogger(DynamicWebservice.class.getName());
/**
*
*/
private static final String PRINCIPAL_ARGUMENT_NAME = "principal";
/**
*
*/
private static final String DEFAULT_NAMESPACE_URI = "http://soapinterop.org/";
/**
*
*/
private String targetEndpointAddress;
/**
*
*/
private String operationName;
/**
*
*/
private QName returnType;
/**
*
*/
private final List parameters = new ArrayList();
/**
*
*/
private final List arguments = new ArrayList();
/**
*
*/
private final Map mappings = new HashMap(); // <Class> -> <QName>
/**
*
*/
private final Map standardMappings = new HashMap(); // <Class> -> <QName>
/**
*
*/
private Service service;
/**
*
*/
private Call call;
/**
*
*/
private Object result;
/**
*
*/
private DynamicWebserviceSerializer serializer;
/**
*
*/
public DynamicWebservice(final InfoGluePrincipal remotePrincipal)
{
super();
configureStandardMappings();
serializer = new DynamicWebserviceSerializer(standardMappings);
addArgument(PRINCIPAL_ARGUMENT_NAME, remotePrincipal.getName());
}
/**
*
*/
public void callService()
{
try
{
service = new Service();
call = (Call) service.createCall();
configureBasic();
configureMappings();
configureParameters();
result = call.invoke(arguments.toArray());
}
catch (Exception e)
{
e.printStackTrace();
}
}
/**
*
*/
private void configureStandardMappings()
{
standardMappings.put(Boolean.class, XMLType.XSD_BASE64);
standardMappings.put(Boolean.class, XMLType.XSD_BOOLEAN);
standardMappings.put(Double.class, XMLType.XSD_DOUBLE);
standardMappings.put(Float.class, XMLType.XSD_FLOAT);
standardMappings.put(Integer.class, XMLType.XSD_INT);
standardMappings.put(Long.class, XMLType.XSD_LONG);
standardMappings.put(String.class, XMLType.XSD_STRING);
}
/**
*
*/
private void configureBasic()
{
call.setTimeout(30000);
call.setTargetEndpointAddress(targetEndpointAddress);
call.setOperationName(new QName(DEFAULT_NAMESPACE_URI, operationName));
call.setEncodingStyle(Call.ENCODINGSTYLE_URI_PROPERTY);
call.setReturnType(returnType);
}
/**
*
*/
private void configureParameters()
{
for(final Iterator i = parameters.iterator(); i.hasNext(); )
{
final Parameter parameter = (Parameter) i.next();
call.addParameter(parameter.name, parameter.type, ParameterMode.IN);
}
}
/**
*
*/
private void configureMappings()
{
for(final Iterator i = mappings.keySet().iterator(); i.hasNext(); )
{
final Class clazz = (Class) i.next();
final QName type = (QName) mappings.get(clazz);
call.registerTypeMapping(clazz, type, BeanSerializerFactory.class, BeanDeserializerFactory.class);
}
}
/**
*
*/
public Object getResult()
{
return result;
}
/**
*
*/
public void setTargetEndpointAddress(final String targetEndpointAddress)
{
logger.debug("targetEndpointAddress=[" + targetEndpointAddress + "]");
this.targetEndpointAddress = targetEndpointAddress;
}
/**
*
*/
public void setOperationName(final String operationName)
{
logger.debug("operationName=[" + operationName + "]");
this.operationName = operationName;
}
/**
*
*/
public void setReturnType(final Class c)
{
logger.debug("returnType=[" + (c==null ? "null" : getClassName(c)) + "]");
returnType = mappingForClass(c); // null is ok
}
/**
*
*/
public void setReturnType(final Class c, QName type)
{
logger.debug("returnType=[" + (c==null ? "null" : type.getLocalPart()) + "]");
this.mappings.put(c, type);
returnType = mappingForClass(c); // null is ok
}
/**
*
*/
public void addArgument(final String name, final Object value)
{
assertNameNotNull(name);
logger.debug("addArgument=[" + name + "," + value + "]");
addArgument(name, mappingForClass(value.getClass()), value);
}
/**
*
*/
public void addArgument(final String name, final Map value)
{
assertNameNotNull(name);
logger.debug("addArgument=[" + name + "," + value + "] (Map)");
addArgument(name, XMLType.SOAP_ARRAY, serializer.serializeMap(value).toArray());
}
/**
*
*/
public void addArgument(final String name, final Collection value)
{
assertNameNotNull(name);
logger.debug("addArgument=[" + name + "," + value + "] (Collection)");
addArgument(name, XMLType.SOAP_ARRAY, serializer.serializeCollection(value).toArray());
}
/**
*
*/
public void addArgument(final String name, final Collection value, final Class[] objectClass)
{
assertNameNotNull(name);
logger.debug("addArgument=[" + name + "," + value + "] (Collection)");
for(int i=0; i<objectClass.length; i++)
{
this.mappings.put(objectClass[i], new QName("infoglue", getClassName(objectClass[i])));
mappingForClass(objectClass[i], "infoglue");
}
addArgument(name, XMLType.SOAP_ARRAY, serializer.serializeCollection(value).toArray());
}
/**
*
*/
public void addArgument(final String name, final Map value, final Class[] objectClass)
{
assertNameNotNull(name);
logger.debug("addArgument=[" + name + "," + value + "] (Map)");
for(int i=0; i<objectClass.length; i++)
{
this.mappings.put(objectClass[i], new QName("infoglue", getClassName(objectClass[i])));
mappingForClass(objectClass[i], "infoglue");
}
addArgument(name, XMLType.SOAP_ARRAY, serializer.serializeMap(value).toArray());
}
/**
*
*/
public void addNonSerializedArgument(final String name, final Collection value)
{
assertNameNotNull(name);
logger.debug("addArgument=[" + name + "," + value + "] (Collection)");
addArgument(name, XMLType.SOAP_ARRAY, value);
}
/**
*
*/
private void assertNameNotNull(final String argument)
{
if(argument == null)
{
throw new IllegalArgumentException("A parameter name can't be null.");
}
}
/**
*
*/
private void addArgument(final String name, final QName type, final Object value)
{
parameters.add(new Parameter(name, type));
arguments.add(value);
}
/**
*
*/
private QName mappingForClass(final Class c)
{
if(c == null)
{
return null;
}
if(standardMappings.containsKey(c))
{
return (QName) standardMappings.get(c);
}
if(mappings.containsKey(c))
{
return (QName) mappings.get(c);
}
return addMapping(c);
}
/**
*
*/
private QName mappingForClass(final Class c, final String namespace)
{
if(c == null)
{
return null;
}
if(standardMappings.containsKey(c))
{
return (QName) standardMappings.get(c);
}
if(mappings.containsKey(c))
{
return (QName) mappings.get(c);
}
return addMapping(c, namespace);
}
/**
*
*/
private QName addMapping(final Class c) {
final String className = getClassName(c);
final QName type = new QName(DEFAULT_NAMESPACE_URI + className, className);
mappings.put(c, type);
logger.debug("addMapping=[" + c.getName() + "," + type + "]");
return type;
}
/**
*
*/
private QName addMapping(final Class c, String namespace) {
final String className = getClassName(c);
final QName type = new QName(namespace + className, className);
mappings.put(c, type);
logger.debug("addMapping=[" + c.getName() + "," + type + "]");
return type;
}
/**
*
*/
public String getClassName(final Class c)
{
final int firstChar = c.getName().lastIndexOf('.') + 1;
return (firstChar > 0) ? c.getName().substring(firstChar) : c.getName();
}
}