Bug fixes

This commit is contained in:
Ziver Koc 2009-05-17 18:46:05 +00:00
parent a28d2b219e
commit 553f8da549
13 changed files with 547 additions and 252 deletions

View file

@ -9,6 +9,8 @@ import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import zutil.converters.Converter;
public class Hasher {
/**

View file

@ -1,4 +1,4 @@
package zutil;
package zutil.converters;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

View file

@ -0,0 +1,48 @@
package zutil.converters;
public class WGS84Converter {
public static void main(String[] args){
System.out.println(toWGS84Decimal("N 59° 47' 43\"")+" "+toWGS84Decimal(" E 17° 42' 55\""));
System.out.println(toWGS84Decimal("55° 0' 0\"")+" "+toWGS84Decimal("68° 59' 59,999\""));
System.out.println(toWGS84Decimal("55° 0.001'")+" "+toWGS84Decimal("68° 59.999'"));
System.out.println(toWGS84Decimal("3444.0000S")+" "+toWGS84Decimal("13521.0000E"));
System.out.println(toWGS84Decimal("-44.0001")+" "+toWGS84Decimal("521.0001"));
}
/**
* Converts an WGS84 coordinate to an WGS84 decimal coordinate
*
* @param coordinate is the coordinate to convert
* @return the new coordinate in decimal degrees, returns 0 if conversions fails
*/
public static float toWGS84Decimal(String coordinate){
float deg=0, min=0, sec=0, neg=1;
coordinate = coordinate.trim().replaceAll(",", ".").toUpperCase();
if(coordinate.contains("S") || coordinate.contains("W"))
neg = -1;
// 55° 0' 68° 59,999 or 55° 0' 0" 68° 59' 59,999"
if(coordinate.matches("[NSWE ]? ?[0-9]{1,3}° [0-9]{1,2}.?[0-9]*'[ 0-9.\\\"]*")){
coordinate = coordinate.replaceAll("[NSEW°'\\\"]", "").trim();
String[] tmp = coordinate.split(" ");
deg = Float.parseFloat(tmp[0]);
min = Float.parseFloat(tmp[1]);
if(tmp.length > 2){
sec = Float.parseFloat(tmp[2]);
}
}
// 3444.0000S 13521.0000E
else if(coordinate.matches("[0-9]{4,5}.[0-9]*[NSEW]{1}")){
coordinate = coordinate.replaceAll("[NS EW]", "");
float tmpf = Float.parseFloat(coordinate);
deg = (int)(tmpf/100);
min = tmpf-(deg*100);
}
// 55.0 68.99999
else if(coordinate.matches("\\-?[0-9]{2,3}.[0-9]*")){
return Float.parseFloat(coordinate);
}
return neg*(deg + min/60 + sec/3600);
}
}

View file

@ -7,8 +7,8 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.Queue;
import zutil.Converter;
import zutil.MultiPrintStream;
import zutil.converters.Converter;
/**
* This class creates a queue that stors the

View file

@ -22,7 +22,7 @@ public interface HttpPage{
*/
public abstract void respond(HttpPrintStream out,
HashMap<String,String> client_info,
HashMap<String,String> session,
HashMap<String,Object> session,
HashMap<String,String> cookie,
HashMap<String,String> request);
}

View file

@ -12,6 +12,8 @@ import java.util.HashMap;
*
*/
public class HttpPrintStream extends PrintStream{
private Integer status_code;
private HashMap<String, String> header;
private HashMap<String, String> cookie;
private StringBuffer buffer;
private boolean buffer_enabled;
@ -19,6 +21,8 @@ public class HttpPrintStream extends PrintStream{
public HttpPrintStream(OutputStream out) {
super(out);
status_code = 0;
header = new HashMap<String, String>();
cookie = new HashMap<String, String>();
buffer = new StringBuffer();
buffer_enabled = false;
@ -28,11 +32,14 @@ public class HttpPrintStream extends PrintStream{
* Enable the buffering capability of the PrintStream.
* Nothing will be sent to the client when buffering
* is enabled until you close or flush the stream.
* This function will flush the stream if buffering is
* disabled.
*
* @param b
*/
public void enableBuffering(boolean b){
buffer_enabled = b;
if(!buffer_enabled) flush();
}
/**
@ -49,16 +56,28 @@ public class HttpPrintStream extends PrintStream{
}
/**
* Sends the given header directly to the client.
* No buffering involved.
* Adds an header value
*
* @param header is the header to send
* @param key is the header name
* @param value is the value of the header
* @throws Exception Throws exception if the header has already been sent
*/
public void sendHeader(String header) throws Exception{
if(cookie == null)
public void setHeader(String key, String value) throws Exception{
if(header == null)
throw new Exception("Header already sent!!!");
super.print(header+"\n");
header.put(key, value);
}
/**
* Sets the return status code
*
* @param code the code from 100 up to 599
* @throws Exception Throws exception if the header has already been sent
*/
public void setStatusCode(int code) throws Exception{
if(status_code == null)
throw new Exception("Header already sent!!!");
status_code = code;
}
/**
@ -83,11 +102,24 @@ public class HttpPrintStream extends PrintStream{
buffer.append(s);
}
else{
if(status_code != null){
super.print("HTTP/1.0 "+status_code+" "+getStatusString(status_code));
super.println();
status_code = null;
}
if(header != null){
for(String key : header.keySet()){
super.print(key+": "+header.get(key));
super.println();
}
header = null;
}
if(cookie != null){
for(String key : cookie.keySet()){
super.print("Set-Cookie: "+key+"="+cookie.get(key)+"; \n");
super.print("Set-Cookie: "+key+"="+cookie.get(key)+";");
super.println();
}
super.print(" \n");
super.println();
cookie = null;
}
super.print(s);
@ -104,6 +136,9 @@ public class HttpPrintStream extends PrintStream{
buffer.delete(0, buffer.length());
buffer_enabled = true;
}
else if(status_code != null || header != null || cookie != null){
printOrBuffer("");
}
super.flush();
}
@ -130,4 +165,25 @@ public class HttpPrintStream extends PrintStream{
public void print(int x){ printOrBuffer(String.valueOf(x));}
public void print(long x){ printOrBuffer(String.valueOf(x));}
public void print(Object x){ printOrBuffer(String.valueOf(x));}
/*
public void write(int b) { print((char)b);}
public void write(byte buf[], int off, int len){
print(new String(buf, off, len));}
*/
private String getStatusString(int type){
switch(type){
case 100: return "Continue";
case 200: return "OK";
case 301: return "Moved Permanently";
case 307: return "Temporary Redirect";
case 400: return "Bad Request";
case 401: return "Unauthorized";
case 403: return "Forbidden";
case 404: return "Not Found";
case 500: return "Internal Server Error";
case 501: return "Not Implemented";
default: return "";
}
}
}

View file

@ -11,12 +11,14 @@ import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.cert.CertificateException;
import java.util.HashMap;
import java.util.Timer;
import java.util.TimerTask;
import java.util.regex.Pattern;
import javax.net.ssl.SSLServerSocketFactory;
import zutil.MultiPrintStream;
/**
* A simple web server that handles both cookies and
* sessions for all the clients
@ -27,7 +29,7 @@ public class HttpServer extends Thread{
public static final boolean DEBUG = false;
public static final String SERVER_VERSION = "StaticInt HttpServer 1.0";
public static final int COOKIE_TTL = 200;
public static final int SESSION_TTL = 3600*3*1000; // in ms
public static final int SESSION_TTL = 10*60*1000; // in milliseconds
public final String server_url;
public final int server_port;
@ -36,7 +38,7 @@ public class HttpServer extends Thread{
private HashMap<String,HttpPage> pages;
private HttpPage defaultPage;
private HashMap<String,HashMap<String,String>> sessions;
private HashMap<String,HashMap<String,Object>> sessions;
private int nextSessionId;
/**
@ -65,8 +67,33 @@ public class HttpServer extends Thread{
this.keyStore = keyStore;
pages = new HashMap<String,HttpPage>();
sessions = new HashMap<String,HashMap<String,String>>();
sessions = new HashMap<String,HashMap<String,Object>>();
nextSessionId = 0;
Timer timer = new Timer();
timer.schedule(new GarbageCollector(), 0, SESSION_TTL / 2);
}
/**
* This class acts as an garbage collector that
* removes old sessions from the session HashMap
*
* @author Ziver
*/
private class GarbageCollector extends TimerTask {
public void run(){
synchronized(sessions) {
for(String key : sessions.keySet()){
HashMap<String,Object> client_session = sessions.get(key);
// Check if session is still valid
if((Long)client_session.get("ttl") < System.currentTimeMillis()){
sessions.remove(key);
if(DEBUG) MultiPrintStream.out.println("Removing Session: "+key);
}
}
}
}
}
/**
@ -155,7 +182,10 @@ public class HttpServer extends Thread{
public void run(){
String tmp = null;
int tmpi;
String[] tmpArray, tmpArray2;
Pattern colonPattern = Pattern.compile(":");
Pattern semiColonPattern = Pattern.compile(";");
Pattern equalPattern = Pattern.compile("=");
String page_url = "";
HashMap<String,String> client_info = new HashMap<String,String>();
@ -165,7 +195,7 @@ public class HttpServer extends Thread{
//**************************** REQUEST *********************************
try {
if(DEBUG)MultiPrintStream.out.println("Reciving Http Request!!!");
while(!(tmp=in.readLine()).isEmpty()){
while((tmp=in.readLine()) != null && !tmp.isEmpty()){
//System.err.println(tmp);
//*********** Handling Get variables
if(tmp.startsWith("GET")){
@ -181,28 +211,21 @@ public class HttpServer extends Thread{
}
//********* Handling Cookies
else if(tmp.startsWith("Cookie")){
tmp = tmp.substring(tmp.indexOf(':')+1, tmp.length());
while(!tmp.isEmpty()){
tmpi = ( (tmpi = tmp.indexOf(';')) == -1 ? tmp.length() : tmpi);
tmp = colonPattern.split(tmp)[1];
tmpArray = semiColonPattern.split(tmp);
for(String e : tmpArray){
tmpArray2 = equalPattern.split(e);
cookie.put(
(tmp.substring(0, tmp.indexOf('=')).trim() ), // Key
(tmp.substring(tmp.indexOf('=')+1, tmpi)).trim() ); //Value
if(tmp.indexOf(';') > 0)
tmp = tmp.substring(tmp.indexOf(';')+1, tmp.length());
else
break;
tmpArray2[0].trim(), // Key
(tmpArray2.length>1 ? tmpArray2[1] : "").trim()); //Value
}
}
//********* Handling Client info
else{
if(tmp.indexOf(':') > -1){
tmpArray = colonPattern.split(tmp);
client_info.put(
(tmp.substring(0, tmp.indexOf(':')).trim() ), // Key
(tmp.substring(tmp.indexOf(':')+1, tmp.length())).trim() ); //Value
}
else{
MultiPrintStream.out.println("Faild to parsse header: "+tmp);
}
tmpArray[0].trim(), // Key
(tmpArray.length>1 ? tmpArray[1] : "").trim()); //Value
}
}
@ -210,8 +233,7 @@ public class HttpServer extends Thread{
if(client_info.containsKey("Content-Length")){
// Reads the post data size
tmp = client_info.get("Content-Length");
int post_data_length = Integer.parseInt(
tmp.substring(tmp.indexOf(':')+1, tmp.length()).trim() );
int post_data_length = Integer.parseInt( tmp );
// read the data
StringBuffer tmpb = new StringBuffer();
// read the data
@ -234,40 +256,27 @@ public class HttpServer extends Thread{
throw new Exception("\"multipart-form-data\" Not implemented!!!");
}
}
//*****************
} catch (Exception e) {
e.printStackTrace();
try {
out.sendHeader("HTTP/1.0 500 ERROR");
} catch (Exception e1) {}
if(e.getMessage() != null)
out.println("500 Internal Error(Header: "+tmp+"): "+e.getMessage());
else{
out.println("500 Internal Error(Header: "+tmp+"): "+e.getCause().getMessage());
}
}
try {
//**************************** HANDLE REQUEST *********************************
// Get the client session or create one
HashMap<String,String> client_session;
HashMap<String, Object> client_session;
long ttl_time = System.currentTimeMillis()+SESSION_TTL;
if(cookie.containsKey("session_id") && sessions.containsKey(cookie.get("session_id"))){
client_session = sessions.get(cookie.get("session_id"));
// Check if session is still valid
if(Long.parseLong(client_session.get("ttl")) < System.currentTimeMillis()){
int session_id = Integer.parseInt(client_session.get("session_id"));
client_session = new HashMap<String,String>();
client_session.put("session_id", ""+session_id);
if((Long)client_session.get("ttl") < System.currentTimeMillis()){
int session_id = (Integer)client_session.get("session_id");
client_session = new HashMap<String, Object>();
client_session.put("session_id", session_id);
sessions.put(""+session_id, client_session);
}
// renew the session TTL
client_session.put("ttl", ""+ttl_time);
client_session.put("ttl", ttl_time);
}
else{
client_session = new HashMap<String,String>();
client_session.put("session_id", ""+nextSessionId);
client_session.put("ttl", ""+ttl_time);
client_session = new HashMap<String, Object>();
client_session.put("session_id", nextSessionId);
client_session.put("ttl", ttl_time);
sessions.put(""+nextSessionId, client_session);
nextSessionId++;
}
@ -281,10 +290,10 @@ public class HttpServer extends Thread{
}
//**************************** RESPONSE ************************************
if(DEBUG)MultiPrintStream.out.println("Sending Http Response!!!");
out.sendHeader("HTTP/1.0 200 OK");
out.sendHeader("Server: "+SERVER_VERSION);
out.sendHeader("Content-Type: text/html");
out.setCookie("session_id", client_session.get("session_id"));
out.setStatusCode(200);
out.setHeader("Server", SERVER_VERSION);
out.setHeader("Content-Type", "text/html");
out.setCookie("session_id", ""+client_session.get("session_id"));
if(!page_url.isEmpty() && pages.containsKey(page_url)){
pages.get(page_url).respond(out, client_info, client_session, cookie, request);
@ -293,13 +302,21 @@ public class HttpServer extends Thread{
defaultPage.respond(out, client_info, client_session, cookie, request);
}
else{
out.println("404 ERROR");
out.setStatusCode(404);
out.println("404 Page Not Found");
}
//********************************************************************************
} catch (Exception e) {
e.printStackTrace();
out.println("500 Internal Error: "+e.getMessage());
e.printStackTrace(MultiPrintStream.out);
try {
out.setStatusCode(500);
} catch (Exception e1) {}
if(e.getMessage() != null)
out.println("500 Internal Server Error(Header: "+tmp+"): "+e.getMessage());
else{
out.println("500 Internal Server Error(Header: "+tmp+"): "+e.getCause().getMessage());
}
}
try{
@ -308,7 +325,7 @@ public class HttpServer extends Thread{
in.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
e.printStackTrace(MultiPrintStream.out);
}
}
}

View file

@ -1,5 +1,6 @@
package zutil.network.http.soap;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
@ -16,6 +17,7 @@ import javax.wsdl.BindingOperation;
import javax.wsdl.BindingOutput;
import javax.wsdl.Definition;
import javax.wsdl.Fault;
import javax.wsdl.Import;
import javax.wsdl.Input;
import javax.wsdl.Message;
import javax.wsdl.Operation;
@ -34,6 +36,13 @@ import javax.wsdl.factory.WSDLFactory;
import javax.wsdl.xml.WSDLWriter;
import javax.xml.namespace.QName;
import zutil.network.http.HttpPage;
import zutil.network.http.HttpPrintStream;
import zutil.network.http.soap.SOAPInterface.WSDLDocumentation;
import zutil.network.http.soap.SOAPInterface.WSDLParamDocumentation;
import zutil.network.http.soap.SOAPObject.SOAPFieldName;
import zutil.MultiPrintStream;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
@ -43,18 +52,40 @@ import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.xml.sax.SAXException;
import zutil.MultiPrintStream;
import zutil.network.http.HttpPage;
import zutil.network.http.HttpPrintStream;
import zutil.network.http.soap.SOAPInterface.WSDLDocumentation;
import zutil.network.http.soap.SOAPInterface.WSDLParamDocumentation;
import zutil.network.http.soap.SOAPObject.SOAPFieldName;
import com.ibm.wsdl.extensions.PopulatedExtensionRegistry;
import com.ibm.wsdl.extensions.soap.SOAPConstants;
import com.sun.org.apache.xerces.internal.dom.DocumentImpl;
/**
* This is an HTTPPage for the HTTPServer that
* handles soap messages.
*
* TODO: Read SOAPObjects as input parameter
* TODO: Ability to have multiple arrays of same SOAPObject
*
* Features:
* Input:
* <br>-int
* <br>-double
* <br>-float
* <br>-char
* <br>-String
* <br>-byte[]
* <br>-And the Wrappers except byte
*
* Output:
* <br>-SOAPObjects
* <br>-byte[]
* <br>-int
* <br>-double
* <br>-float
* <br>-char
* <br>-String
* <br>-Arrays of Output
* <br>-And the Wrappers except byte
*
* @author Ziver
*/
public class SOAPHttpPage implements HttpPage{
// valid methods for this soap page
private HashMap<String, MethodChasch> methods;
@ -81,17 +112,20 @@ public class SOAPHttpPage implements HttpPage{
private Document wsdlType;
// the URL to this soap page
private String url;
// Session enabled
private boolean session_enabled;
public SOAPHttpPage(String url, SOAPInterface interf) throws WSDLException{
//if(!SOAPInterface.class.isAssignableFrom(interf) )
// throw new ClassCastException("Class does not implement SOAPInterface!");
this.url = url;
this.interf = interf;
this.session_enabled = false;
methods = new HashMap<String, MethodChasch>();
for(Method m : interf.getClass().getDeclaredMethods()){
// check for public methods
if(m.getModifiers() == Modifier.PUBLIC &&
if((m.getModifiers() & Modifier.PUBLIC) > 0 &&
!m.isAnnotationPresent(SOAPInterface.SOAPDisabled.class)){
MethodChasch chasch = new MethodChasch(m);
StringBuffer tmp = new StringBuffer(m.getName()+"(");
@ -150,18 +184,21 @@ public class SOAPHttpPage implements HttpPage{
}
}
public void enableSession(boolean enabled){
this.session_enabled = enabled;
}
public void respond(HttpPrintStream out,
HashMap<String, String> client_info,
HashMap<String, String> session, HashMap<String, String> cookie,
HashMap<String, Object> session, HashMap<String, String> cookie,
HashMap<String, String> request) {
try {
out.sendHeader("Content-Type: text/xml");
out.setHeader("Content-Type", "text/xml");
out.flush();
if(request.containsKey("wsdl")){
out.println("");
out.flush();
WSDLWriter writer = WSDLFactory.newInstance().newWSDLWriter();
writer.writeWSDL(wsdl, out);
}
@ -171,7 +208,15 @@ public class SOAPHttpPage implements HttpPage{
writer.write( wsdlType );
}
else{
Document document = soap( request.get("") );
SOAPInterface obj = null;
if(session_enabled && session.containsKey("SOAPInterface"))
obj = (SOAPInterface)session.get("SOAPInterface");
else{
obj = interf.getClass().newInstance();
if(session_enabled) session.put("SOAPInterface", obj);
}
Document document = soapResponse( request.get(""), obj);
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter writer = new XMLWriter( out, format );
@ -180,24 +225,35 @@ public class SOAPHttpPage implements HttpPage{
} catch (Exception e) {
e.printStackTrace(MultiPrintStream.out);
}
}
public Document soap(String xml){
/**
* Generates a soap response for the given
* @param xml is the XML request
* @return a Document with the response
*/
public Document soapResponse(String xml){
try {
return soapResponse(xml, interf.getClass().newInstance());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected Document soapResponse(String xml, SOAPInterface obj){
try {
Document document = DocumentHelper.createDocument();
Element envelope = document.addElement("soap:Envelope");
envelope.add(new Namespace("soap", "http://www.w3.org/2001/12/soap-envelope"));
envelope.addAttribute("soap:encodingStyle", "http://www.w3.org/2001/12/soap-encoding");
Element header = envelope.addElement( "soap:Header" );
Element body = envelope.addElement( "soap:Body" );
try{
Element request = getXMLRoot(xml);
Object obj = interf.getClass().newInstance();
// Header
if( request.element("Header") != null){
Element header = envelope.addElement( "soap:Header" );
prepareInvoke( obj, request.element("Header"), header );
}
@ -280,10 +336,18 @@ public class SOAPHttpPage implements HttpPage{
* @param m is the method that returned the ret
*/
private void createReturnXML(Element root, Object ret, String ename, MethodChasch m) throws IllegalArgumentException, IllegalAccessException{
if(ret == null) return;
if(byte[].class.isAssignableFrom(ret.getClass())){
Element valueE = root.addElement( ename );
valueE.addAttribute("type", "xsd:"+getClassSOAPName(ret.getClass()));
String tmp = new sun.misc.BASE64Encoder().encode((byte[])ret);
tmp = tmp.replaceAll("\\s", "");
valueE.setText(tmp);
}
// return an array
if(ret.getClass().isArray()){
else if(ret.getClass().isArray()){
Element array = root.addElement( (ename.equals("element") ? "Array" : ename) );
String arrayType = "xsd:"+ret.getClass().getSimpleName().toLowerCase();
String arrayType = "xsd:"+getClassSOAPName(ret.getClass());
arrayType = arrayType.replaceFirst("\\[\\]", "["+Array.getLength(ret)+"]");
array.addAttribute("type", "soap:Array");
@ -296,7 +360,7 @@ public class SOAPHttpPage implements HttpPage{
if(ret instanceof Element)
root.add( (Element)ret );
if(ret instanceof SOAPObject){
Element objectE = root.addElement( ret.getClass().getSimpleName().toLowerCase() );
Element objectE = root.addElement( getClassSOAPName(ret.getClass()) );
Field[] fields = ret.getClass().getFields();
for(int i=0; i<fields.length ;i++){
SOAPFieldName tmp = fields[i].getAnnotation(SOAPObject.SOAPFieldName.class);
@ -308,7 +372,7 @@ public class SOAPHttpPage implements HttpPage{
}
else {
Element valueE = root.addElement( ename );
valueE.addAttribute("type", "xsd:"+ret.getClass().getSimpleName().toLowerCase());
valueE.addAttribute("type", "xsd:"+getClassSOAPName(ret.getClass()));
valueE.addText( ""+ret );
}
}
@ -317,7 +381,7 @@ public class SOAPHttpPage implements HttpPage{
/**
* Converts an given String to a specified class
*/
private Object convertToClass(String data, Class<?> c){
protected Object convertToClass(String data, Class<?> c) throws IOException{
if(data == null || data.isEmpty())
return null;
@ -334,6 +398,8 @@ public class SOAPHttpPage implements HttpPage{
else if(c == boolean.class) return Boolean.parseBoolean(data);
else if(c == Byte.class) return Byte.parseByte(data);
else if(c == byte.class) return Byte.parseByte(data);
else if(byte[].class.isAssignableFrom(c))
return new sun.misc.BASE64Decoder().decodeBuffer(data);
return null;
}
@ -344,7 +410,7 @@ public class SOAPHttpPage implements HttpPage{
* @param params a vector with arguments
* @throws Throwable
*/
public Object invoke(Object obj, Method m, Object[] params) throws Throwable{
protected Object invoke(Object obj, Method m, Object[] params) throws Throwable{
try {
return m.invoke(obj, params );
} catch (IllegalArgumentException e) {
@ -362,7 +428,7 @@ public class SOAPHttpPage implements HttpPage{
* @param msg is the string XML
* @return the XML root Element
*/
public Element getXMLRoot(String xml) throws Exception {
private Element getXMLRoot(String xml) throws Exception {
if(xml != null && !xml.isEmpty()){
Document document = DocumentHelper.parseText(xml);
return document.getRootElement();
@ -370,6 +436,24 @@ public class SOAPHttpPage implements HttpPage{
return null;
}
private String getClassSOAPName(Class<?> c){
Class<?> cTmp = getClass(c);
if(byte[].class.isAssignableFrom(c)){
return "base64Binary";
}
else if( SOAPObject.class.isAssignableFrom(cTmp) ){
return c.getSimpleName();
}
else{
String ret = c.getSimpleName().toLowerCase();
if(cTmp == Integer.class) ret = ret.replaceAll("integer", "int");
else if(cTmp == Character.class)ret = ret.replaceAll("character", "char");
return ret;
}
}
/**
* Generates an WSDL document for the class
*
@ -378,13 +462,14 @@ public class SOAPHttpPage implements HttpPage{
private void generateWSDL() throws WSDLException{
ArrayList<Class<?>> types = new ArrayList<Class<?>>();
PopulatedExtensionRegistry extReg = new PopulatedExtensionRegistry();
WSDLFactory factory = WSDLFactory.newInstance();
String tns = url+"?wsdl";
String xsd = "http://www.w3.org/2001/XMLSchema";
String soap = "http://schemas.xmlsoap.org/wsdl/soap/";
String wsdln = "http://schemas.xmlsoap.org/wsdl/";
String td = url+"?type";
PopulatedExtensionRegistry extReg = new PopulatedExtensionRegistry();
WSDLFactory factory = WSDLFactory.newInstance();
String portTypeName = this.interf.getClass().getSimpleName()+"PortType";
wsdl = factory.newDefinition();
@ -406,12 +491,11 @@ public class SOAPHttpPage implements HttpPage{
wsdl.addMessage(exception);
// Types import
/*
Import imp = wsdl.createImport();
imp.setNamespaceURI(td);
imp.setLocationURI(td);
wsdl.addImport(imp);
*/
// PrtType
PortType portType = wsdl.createPortType();
portType.setQName(new QName(tns, portTypeName));
@ -439,7 +523,7 @@ public class SOAPHttpPage implements HttpPage{
Part part = wsdl.createPart();
part.setName(m.paramName[i]);
part.setTypeName(new QName( xsd,
m.method.getParameterTypes()[i].getSimpleName().toLowerCase()));
getClassSOAPName(m.method.getParameterTypes()[i])));
if(m.paramOptional[i])
part.getExtensionAttribute(new QName("minOccurs", "0"));
msgIn.addPart(part);
@ -462,34 +546,26 @@ public class SOAPHttpPage implements HttpPage{
// Generate new type if the object is an SOAPObject
Class<?> cTmp = getClass(m.method.getReturnType());
if(( SOAPObject.class.isAssignableFrom(cTmp) )){
// is is an array?
if(m.method.getReturnType().isArray()){
part.setTypeName(new QName(soap, "Array"));
part.setExtensionAttribute(
new QName(soap, "arrayType"),
new QName(td, m.method.getReturnType().getSimpleName().toLowerCase()));
if(byte[].class.isAssignableFrom(m.method.getReturnType())){
part.setTypeName(new QName(xsd, "base64Binary"));
}
else{ // its an Object
// is an array?
else if(m.method.getReturnType().isArray()){
part.setTypeName(new QName(td,
m.method.getReturnType().getSimpleName().toLowerCase()));
"ArrayOf"+getClassSOAPName(m.method.getReturnType()).replaceAll("[\\[\\]]", "")));
// add to type generation list
if(!types.contains(m.method.getReturnType()))
types.add(m.method.getReturnType());
}
else if( SOAPObject.class.isAssignableFrom(cTmp) ){
// its an SOAPObject
part.setTypeName(new QName(td, getClassSOAPName(m.method.getReturnType())));
// add to type generation list
if(!types.contains(cTmp))
types.add(cTmp);
}
else{
// is is an array?
if(m.method.getReturnType().isArray()){
part.setTypeName(new QName(soap, "Array"));
part.setExtensionAttribute(
new QName(soap, "arrayType"),
new QName(xsd, m.method.getReturnType().getSimpleName().toLowerCase()));
}
else{// its an Object
part.setTypeName(new QName(xsd,
m.method.getReturnType().getSimpleName().toLowerCase()));
}
part.setTypeName(new QName(xsd, getClassSOAPName(m.method.getReturnType())));
}
wsdl.addMessage(msgOut);
@ -529,7 +605,7 @@ public class SOAPHttpPage implements HttpPage{
SOAPBinding soapBinding = (SOAPBinding)extReg.createExtension(Binding.class, SOAPConstants.Q_ELEM_SOAP_BINDING);
soapBinding.setStyle("rpc");
soapBinding.setRequired(true);
//soapBinding.setRequired(true);
soapBinding.setTransportURI("http://schemas.xmlsoap.org/soap/http");
binding.addExtensibilityElement(soapBinding);
@ -588,6 +664,7 @@ public class SOAPHttpPage implements HttpPage{
port.addExtensibilityElement(addr);
Service ser = wsdl.createService();
ser.setQName(new QName(tns, interf.getClass().getSimpleName()+"Service"));
ser.addPort(port);
wsdl.addService(ser);
@ -603,17 +680,39 @@ public class SOAPHttpPage implements HttpPage{
private void generateWSDLType(ArrayList<Class<?>> types){
wsdlType = DocumentHelper.createDocument();
Element definitions = wsdlType.addElement( "wsdl:definitions" );
definitions.addNamespace("targetNamespace", url+"?type");
definitions.addAttribute("targetNamespace", url+"?type");
definitions.addNamespace("xsd", "http://www.w3.org/2001/XMLSchema");
definitions.addNamespace("wsdl", "http://schemas.xmlsoap.org/wsdl/");
definitions.addNamespace("SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/");
Element typeE = definitions.addElement("wsdl:types");
Element schema = typeE.addElement("xsd:schema");
for(int n=0; n<types.size() ;n++){
Class<?> c = types.get(n);
// Generate Array type
if(c.isArray()){
Class<?> ctmp = getClass(c);
Element type = schema.addElement("xsd:complexType");
type.addAttribute("name", c.getSimpleName().toLowerCase());
type.addAttribute("name",
"ArrayOf"+getClassSOAPName(c).replaceAll("[\\[\\]]", ""));
Element complexContent = type.addElement("complexContent");
Element restriction = complexContent.addElement("restriction");
restriction.addAttribute("base", "SOAP-ENC:Array");
Element attribute = restriction.addElement("attribute");
attribute.addAttribute("ref", "SOAP-ENC:arrayType");
attribute.addAttribute("wsdl:arrayType", "tns:"+getClassSOAPName(c));
if(!types.contains(ctmp))
types.add(ctmp);
}
// Generate SOAPObject type
else if(SOAPObject.class.isAssignableFrom(c)){
Element type = schema.addElement("xsd:complexType");
type.addAttribute("name", getClassSOAPName(c));
Element sequence = type.addElement("xsd:sequence");
@ -630,18 +729,20 @@ public class SOAPHttpPage implements HttpPage{
// Check if the object is an SOAPObject
Class<?> cTmp = getClass(fields[i].getType());
if(SOAPObject.class.isAssignableFrom(cTmp)){
element.addAttribute("type", "tns:"+cTmp.getSimpleName().toLowerCase());
element.addAttribute("type", "tns:"+getClassSOAPName(cTmp));
if(!types.contains(cTmp))
types.add(cTmp);
}
else
element.addAttribute("type", "xsd:"+cTmp.getSimpleName().toLowerCase());
else{
element.addAttribute("type", "xsd:"+getClassSOAPName(fields[i].getType()));
}
// Is the Field optional
if(tmp != null && tmp.optional())
element.addAttribute("minOccurs", "0");
}
}
}
}
private Class<?> getClass(Class<?> c){
if(c.isArray()){
@ -650,88 +751,4 @@ public class SOAPHttpPage implements HttpPage{
return c;
}
//*******************************************************************************************
//**************************** TEST *********************************************************
public static void main(String[] args){
try {
new SOAPHttpPage("http://test.se:8080/", new Test()).test();
} catch (WSDLException e) {
e.printStackTrace();
}
}
private static class TestObject2 implements SOAPObject{
public String lol = "lol11";
public String lol2 = "lol22";
}
private static class TestObject implements SOAPObject{
@SOAPFieldName(value="lolz", optional=true)
public String lol = "lol1";
@SOAPFieldName("lolx")
public String lol2 = "lol2";
public TestObject2 l = new TestObject2();
}
private static class Test implements SOAPInterface{
public Test(){}
@SOAPHeader()
@WSDLDocumentation("hello")
public void pubZ(
@SOAPParamName(value="olle", optional=true) int lol) throws Exception{
//System.out.println("Param: "+lol);
throw new Exception("Ziver is the fizle");
}
@SOAPReturnName("param")
@WSDLParamDocumentation("null is the shizzle")
public String[][] pubA (
@SOAPParamName("Ztring") String lol) throws Exception{
//System.out.println("ParamZ: "+lol);
return new String[][]{{"test","test2"},{"test3","test4"}};
}
@SOAPReturnName("zivarray")
@WSDLParamDocumentation("null is the shizzle")
public TestObject[] pubX (
@SOAPParamName("Ztring") String lol) throws Exception{
return new TestObject[]{new TestObject(), new TestObject()};
}
@SOAPDisabled()
public void privaZ(){ }
protected void protZ(){ }
}
public void test(){
// Response
try {
Document document = soap(
"<?xml version=\"1.0\"?>" +
"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" +
" <soap:Body xmlns:m=\"http://www.example.org/stock\">\n" +
//" <m:pubA>\n" +
//" <m:Ztring>IBM</m:Ztring>\n" +
//" </m:pubA>\n" +
//" <m:pubZ>\n" +
//" <m:olle>66</m:olle>\n" +
//" </m:pubZ>\n" +
" <m:pubX>\n" +
" <m:Ztring>IBM</m:Ztring>\n" +
" </m:pubX>\n" +
" </soap:Body>\n" +
"</soap:Envelope>");
System.out.println();
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter writer = new XMLWriter( System.out, format );
writer.write( document );
System.out.println();
} catch (Exception e) {
e.printStackTrace();
}
}
}

View file

@ -40,4 +40,17 @@ public interface SOAPObject{
String value();
boolean optional() default false;
}
/**
* This generates an documentation tag in the
* WSDL for the object type
*
* @author Ziver
*/
/*
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface WSDLDocumentation {
String value();
}*/
}

View file

@ -15,9 +15,9 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import zutil.Converter;
import zutil.Encrypter;
import zutil.MultiPrintStream;
import zutil.converters.Converter;
import zutil.network.nio.message.type.ResponseRequestMessage;
import zutil.network.nio.message.type.SystemMessage;
import zutil.network.nio.response.ResponseEvent;

View file

@ -7,18 +7,19 @@ import zutil.network.http.HttpPage;
import zutil.network.http.HttpPrintStream;
import zutil.network.http.HttpServer;
public class HTTPGuessTheNumber implements HttpPage{
public static void main(String[] args) throws IOException{
//HttpServer server = new HttpServer("localhost", 443, FileFinder.find("keySSL"), "rootroot");//SSL
HttpServer server = new HttpServer("localhost", 80);
HttpServer server = new HttpServer("localhost", 8080);
server.setDefaultPage(new HTTPGuessTheNumber());
server.run();
}
public void respond(HttpPrintStream out,
HashMap<String, String> client_info,
HashMap<String, String> session, HashMap<String, String> cookie,
HashMap<String, Object> session, HashMap<String, String> cookie,
HashMap<String, String> request) {
out.enableBuffering(true);
@ -27,7 +28,7 @@ public class HTTPGuessTheNumber implements HttpPage{
if(session.containsKey("random_nummber") && request.containsKey("guess")){
int guess = Integer.parseInt(request.get("guess"));
int nummber = Integer.parseInt(session.get("random_nummber"));
int nummber = (Integer)session.get("random_nummber");
try {
if(guess == nummber){
session.remove("random_nummber");
@ -54,7 +55,7 @@ public class HTTPGuessTheNumber implements HttpPage{
}
}
else{
session.put("random_nummber", ""+(int)(Math.random()*99+1));
session.put("random_nummber", (int)(Math.random()*99+1));
try {
out.setCookie("low", "0");
out.setCookie("high", "100");
@ -73,7 +74,7 @@ public class HTTPGuessTheNumber implements HttpPage{
out.println("<input type='submit' value='Guess'>");
out.println("</form>");
out.println("<script>document.all.guess.focus();</script>");
//out.println("<b>DEBUG: nummber="+session.get("random_nummber")+"</b><br>");
out.println("<b>DEBUG: nummber="+session.get("random_nummber")+"</b><br>");
out.println("</html>");
}

View file

@ -0,0 +1,37 @@
package zutil.test;
import java.io.IOException;
import java.util.HashMap;
import zutil.network.http.HttpPage;
import zutil.network.http.HttpPrintStream;
import zutil.network.http.HttpServer;
public class HTTPUploaderTest implements HttpPage{
public static void main(String[] args) throws IOException{
HttpServer server = new HttpServer("localhost", 80);
server.setDefaultPage(new HTTPUploaderTest());
server.run();
}
public void respond(HttpPrintStream out,
HashMap<String, String> client_info,
HashMap<String, Object> session, HashMap<String, String> cookie,
HashMap<String, String> request) {
if(!session.containsKey("file1")){
out.println("</html>" +
" <form enctype='multipart/form-data' method='post'>" +
" <p>Please specify a file, or a set of files:<br>" +
" <input type='file' name='datafile' size='40'>" +
" </p>" +
" <input type='submit' value='Send'>" +
" </form>" +
"</html>");
}
}
}

View file

@ -0,0 +1,104 @@
package zutil.test;
import javax.wsdl.WSDLException;
import org.dom4j.Document;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import zutil.network.http.soap.SOAPHttpPage;
import zutil.network.http.soap.SOAPInterface;
import zutil.network.http.soap.SOAPObject;
public class SOAPTest {
//*******************************************************************************************
//**************************** TEST *********************************************************
public static void main(String[] args){
try {
SOAPHttpPage soap = new SOAPHttpPage("http://test.se:8080/", new SOAPTestClass());
// Response
try {
Document document = soap.soapResponse(
"<?xml version=\"1.0\"?>" +
"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" +
" <soap:Body xmlns:m=\"http://www.example.org/stock\">\n" +
//" <m:pubA>\n" +
//" <m:Ztring>IBM</m:Ztring>\n" +
//" </m:pubA>\n" +
//" <m:pubZ>\n" +
//" <m:olle>66</m:olle>\n" +
//" </m:pubZ>\n" +
" <m:pubB>\n" +
" <m:byte>IBM</m:byte>\n" +
" </m:pubB>\n" +
" </soap:Body>\n" +
"</soap:Envelope>");
System.out.println();
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter writer = new XMLWriter( System.out, format );
writer.write( document );
System.out.println();
} catch (Exception e) {
e.printStackTrace();
}
} catch (WSDLException e) {
e.printStackTrace();
}
}
}
class SOAPTestClass3 implements SOAPObject{
public String lol = "lol11";
public String lol2 = "lol22";
}
class SOAPTestClass2 implements SOAPObject{
@SOAPFieldName(value="lolz", optional=true)
public String lol = "lol1";
@SOAPFieldName("lolx")
public String lol2 = "lol2";
public byte[] b = new byte[]{0x12, 0x23};
public SOAPTestClass3 l = new SOAPTestClass3();
}
class SOAPTestClass implements SOAPInterface{
public SOAPTestClass(){}
@SOAPHeader()
@WSDLDocumentation("hello")
public void pubZ(
@SOAPParamName(value="olle", optional=true) int lol) throws Exception{
//System.out.println("Param: "+lol);
throw new Exception("Ziver is the fizle");
}
@SOAPReturnName("param")
@WSDLParamDocumentation("null is the shizzle")
public String[][] pubA (
@SOAPParamName("Ztring") String lol) throws Exception{
//System.out.println("ParamZ: "+lol);
return new String[][]{{"test","test2"},{"test3","test4"}};
}
@SOAPReturnName("zivarray")
@WSDLParamDocumentation("null is the shizzle")
public SOAPTestClass2[] pubX (
@SOAPParamName("Ztring") String lol) throws Exception{
return new SOAPTestClass2[]{new SOAPTestClass2(), new SOAPTestClass2()};
}
@SOAPReturnName("zivarray")
@WSDLParamDocumentation("null is the shizzle")
public byte[] pubB (
@SOAPParamName("byte") String lol) throws Exception{
return new byte[]{0x12, 0x23};
}
@SOAPDisabled()
public void privaZ(){ }
protected void protZ(){ }
}