blob: 236ec52dd4291b0920147294d2fb18212ed4f13c [file] [log] [blame]
package groovy.net.soap;
/*
* SoapServer.java
*
* Created on 22 avril 2006, 00:10
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
//import java.util.*;
import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import org.codehaus.xfire.XFire;
import org.codehaus.xfire.XFireFactory;
import org.codehaus.xfire.server.http.XFireHttpServer;
import org.codehaus.xfire.service.Service;
import org.codehaus.xfire.service.invoker.ObjectInvoker;
import org.codehaus.xfire.service.binding.ObjectServiceFactory;
import org.codehaus.xfire.xmlbeans.XmlBeansServiceFactory;
import org.codehaus.xfire.xmlbeans.XmlBeansType;
import groovy.lang.GroovyClassLoader;
import org.apache.log4j.Logger;
/**
*
* @author Guillaume Alleon
*/
public class SoapServer {
private XFire xfire = null;
private XFireHttpServer server = null;
static private Logger logger=Logger.getLogger(SoapServer.class);
/**
* <p>Creates a new instance of SoapServer.</p>
* <p/>
*
*/
public SoapServer() {
this("localhost", 8080);
}
/**
* <p>Creates a new instance of SoapServer.</p>
* <p/>
*
* @param host the host the web container is running on.
* @param port the port used by the web container.
*/
public SoapServer(String host, Integer port) {
xfire = XFireFactory.newInstance().getXFire();
server = new XFireHttpServer();
server.setPort(port);
}
/**
* <p>Instantiate the web service using a Plain Old
* Groovy Object. Both, the interface and the implementation
* classes are generated using introspection.
* Then the implementation is delegating the call to the
* Groovy class.</p>
* <p/>
*
* @param text the prefix of the file containing the groovy class.
* @param URL the URL hosting the serviceon the server.
*/
public void setNode(String text, String URL) throws ClassNotFoundException {
GroovyClassLoader gcl = new GroovyClassLoader();
// try {
Class clazz = gcl.loadClass(text);
//} catch (ClassNotFoundException ex){
// System.err.println("Groovy file "+ text + " not found");
// throw ex;
//}
Method[] methods = clazz.getDeclaredMethods();
StringBuffer sInterface = new StringBuffer();
StringBuffer sImpl = new StringBuffer();
sInterface.append("interface ")
.append(clazz.getName())
.append("Interface {\n");
sImpl.append("class ")
.append(clazz.getName())
.append("Impl implements ")
.append(clazz.getName())
.append("Interface {\n def service = new ")
.append(clazz.getName())
.append("()\n");
boolean hasMethod = false;
for (int i=0; i<methods.length; ++i) {
if ( "getMetaClass".equals(methods[i].getName()) ||
"getProperty".equals(methods[i].getName()) ||
"getClass".equals(methods[i].getName()) ||
"setMetaClass".equals(methods[i].getName()) ||
"setProperty".equals(methods[i].getName()) ||
"invokeMethod".equals(methods[i].getName()) ||
"hashCode".equals(methods[i].getName()) ||
"equals".equals(methods[i].getName()) ||
"notify".equals(methods[i].getName()) ||
"notifyAll".equals(methods[i].getName()) ||
"toString".equals(methods[i].getName()) ||
"run".equals(methods[i].getName()) ||
"main".equals(methods[i].getName()) ||
"class$".equals(methods[i].getName()) ||
"wait".equals(methods[i].getName()) ) {
} else if (Modifier.isPublic(methods[i].getModifiers())) {
hasMethod = true;
String returnType = methods[i].getReturnType().getName();
if (returnType.startsWith("[L")) {
returnType = returnType.substring(2, returnType.length()-1);
returnType = returnType.concat("[]");
}
sInterface.append(" " + returnType)
.append(" " + methods[i].getName()+"(");
sImpl.append("\n " + returnType)
.append(" " + methods[i].getName()+"(");
Class[] params = methods[i].getParameterTypes();
int j = 0;
while (j < params.length) {
sInterface.append(params[j].getName() + " arg" + j);
sImpl.append(params[j].getName() + " arg" + j);
if (++j < params.length) {
sInterface.append(", ");
sImpl.append(", ");
}
}
sInterface.append(");\n");
sImpl.append(") {\n ");
if (methods[i].getReturnType() != void.class) {
sImpl.append("return ");
}
sImpl.append("service." + methods[i].getName() + "(");
j = 0;
while (j < params.length) {
sImpl.append("arg" + j);
if (++j < params.length) {
sImpl.append(", ");
}
}
sImpl.append(")\n }\n");
}
}
sImpl.append("}");
sInterface.append("}");
if (hasMethod == false) throw new PublicMethodNotFoundException("Groovy script should have public method");
if (logger.isDebugEnabled()) logger.debug(sImpl.toString());
if (logger.isDebugEnabled()) logger.debug(sInterface.toString());
Class interfaceClass = null;
try {
interfaceClass = gcl.parseClass(sInterface.toString());
} catch (Exception ex) {
System.err.println("Cannot parse Interface class:\n"+sInterface.toString());
ex.printStackTrace();
}
Class implClass = null;
try {
implClass = gcl.parseClass(sImpl.toString());
} catch (Exception ex) {
System.err.println("Cannot parse Implementation class:\n"+sImpl.toString());
ex.printStackTrace();
}
ObjectServiceFactory serviceFactory = new ObjectServiceFactory(xfire.getTransportManager());
Service service = serviceFactory.create(interfaceClass);
service.setProperty(ObjectInvoker.SERVICE_IMPL_CLASS, implClass);
/*
XmlBeansServiceFactory serviceFactory = new XmlBeansServiceFactory(xfire.getTransportManager());
Service service = serviceFactory.create(implClass);
service.setProperty(XmlBeansType.XMLBEANS_NAMESPACE_HACK, "true");
*/
xfire.getServiceRegistry().register(service);
}
public void setNode(String text) throws ClassNotFoundException {
this.setNode(text, "");
}
/**
* <p>Start the SoapServer.</p>
* <p/>
*
*/
public void start() {
try {
server.start();
} catch (Exception ex) {
System.err.println("Cannot start server");
}
}
/**
* <p>Stop the SoapServer.</p>
* <p/>
*
*/
public void stop() {
try {
server.stop();
} catch (Exception ex) {
System.err.println("Cannot stop server");
}
}
}