RE: KVM-serialize my own dataype

"Mike Jones" <[email protected]> Wed, 9 Jul 2003 10:06:13 -0700
Newsgroups gmane.comp.java.enhydra.ksoap
Message-ID <!~!UENERkVCMDkAAQACAAAAAAAAAAAAAAAAABgAAAAAAAAAq5r+Gdo6e0SOWnHo8vu74qKCAAAQAAAAdy/f7MkbBEKZMHMZzj/[email protected]>
Frank,

What I did was create a custom marshaler that could deal with floats and
integers and other simple types.

The only problem I am having is compatibility issues with .Net. See my
thread on that. So far, no one has answered that mail, and I have not
taken the time to dig into the Soap spec to solve it.

Mike

---------------CODE BEGIN ----------

This class is the parent class to classes I want to serialize:

package serializationPackage;

public class Command
{
	public Command ()
	{
		foo1 = 4;
		foo2 = 8;
		foo3 = true;
		foo4 = "My or my!";
		foo5 = 9.4;
	}
	
	public int foo1;
	public long foo2;
	public boolean foo3;
	public String foo4;
	public double foo5;

}

This class is the marshaler class for it:

package org.ksoap;

import java.io.IOException;
import java.lang.reflect.Field;

import org.kobjects.serialization.ElementType;

public class CommandMarshal implements Marshal 
{
	private boolean debug = false;
	
	public Object readInstance(SoapParser parser, String namespace,
String name, ElementType expected) throws IOException 
	{
		if (debug) System.out.println("Process readInstance:
Namespace: " + namespace + " Name: " + name);
		if (debug) System.out.flush();
		parser.parser.read(); // read start tag

		if (name.equals("Command"))
		{
			if (debug) System.out.println("Found command");
			if (debug) System.out.flush();
			Object instance;
			try {
				Class classDefinition =
Class.forName("serializationPackage.Command");
				instance =
classDefinition.newInstance();
			} 
			catch (Exception e)
			{
				if (debug) e.printStackTrace();
				return null;
			}

			if (debug) System.out.println("Process
fields...");
			Field[] fields =
instance.getClass().getDeclaredFields();
			for (int i = 0; i < fields.length; i++)
			{
				if (debug) System.out.println("\tField "
+ i + ": " + fields[i].getName());
				if (debug) System.out.flush();
				Object p = parser.parser.read(); // end
line
				try 
				{
					Object o =
fields[i].get(instance);
					String typeName =
o.getClass().getName();
					String fieldName =
fields[i].getName();
					if (debug)
System.out.println("\t\t Field Name:" + fieldName + " FieldType:" +
typeName);
					if
(typeName.equals("java.lang.Double"))
					{
						if (debug)
System.out.println("Read Double");
						if (debug)
System.out.flush();
	
fields[i].setDouble(instance, ((Double) parser.read(null, i, namespace,
fieldName, new ElementType(Double.class))).doubleValue());
					}
					else if
(typeName.equals("java.lang.Integer"))
					{
						if (debug)
System.out.println("Read Integer");
						if (debug)
System.out.flush();
	
fields[i].setInt(instance, ((Integer) parser.read(null, i, namespace,
fieldName, new ElementType(ElementType.INTEGER_CLASS))).intValue());
					}
					else if
(typeName.equals("java.lang.Boolean"))
					{
						if (debug)
System.out.println("Read Boolean");
						if (debug)
System.out.flush();
	
fields[i].setBoolean(instance, ((Boolean) parser.read(null, i,
namespace, fieldName, new
ElementType(ElementType.BOOLEAN_CLASS))).booleanValue());
					}
					else if
(typeName.equals("java.lang.Long"))
					{
						if (debug)
System.out.println("Read Lone");
						if (debug)
System.out.flush();
	
fields[i].setLong(instance,((Long) parser.read(null, i, namespace,
fieldName, new ElementType(ElementType.LONG_CLASS))).longValue());
					}
					else if
(typeName.equals("java.lang.String"))
					{
						if (debug)
System.out.println("Read String");
						if (debug)
System.out.flush();
						fields[i].set(instance,
parser.read(null, i, namespace, fieldName, new
ElementType(ElementType.STRING_CLASS)));
					}
				}
				catch (Exception e)
				{
					if (debug) e.printStackTrace();
					if (debug) System.out.flush();
					return null;
				}
			}
			return instance;
		}
		else
		{
			if (debug) System.out.println("Found primative
Field: " + name);
			String text = parser.parser.readText ();
			Object p = parser.parser.read (); // read end
tag
			switch (name.charAt (0)) {
				case 's': return text;
				case 'i': return new Integer
(Integer.parseInt (text));
				case 'l': return new Long
(Long.parseLong (text));
				case 'b': return new Boolean
(Soap.stringToBoolean (text));
				case 'd': return new Double
(Double.valueOf(text).doubleValue());
				default:
					throw new RuntimeException ();
			}
		}
	}

	public void writeInstance(SoapWriter writer, Object instance)
throws IOException 
	{
		if (debug) System.out.println("Process writeInstance");

		// This could use reflection to find each field and call
write.
		if
(instance.getClass().getName().equals("serializationPackage.Command"))
		{
			if (debug) System.out.println("Found command");

			if (debug) System.out.println("Process
fields...");
			if (debug) System.out.flush();
			Field[] fields =
instance.getClass().getDeclaredFields();
			for (int i = 0; i < fields.length; i++)
			{
				if (debug) System.out.println("\tField "
+ i + ": " + fields[i].getName());
				if (debug) System.out.flush();
				try 
				{
					Object o =
fields[i].get(instance);
					String typeName =
o.getClass().getName();
					String fieldName =
fields[i].getName();
					if (debug)
System.out.println("\t\t Field Name:" + fieldName + " FieldType:" +
typeName);
					if
(typeName.equals("java.lang.Double"))
					{
						if (debug)
System.out.println("\t\tWrite Double");
						if (debug)
System.out.flush();
						writer.writer.startTag
(fieldName);
						writer.writeProperty(o,
new ElementType(Double.class));
						writer.writer.endTag();
						if (debug)
System.out.println("\t\tDone");
						if (debug)
System.out.flush();
					}
					else if
(typeName.equals("java.lang.Integer"))
					{
						if (debug)
System.out.println("\t\tWrite Integer");
						if (debug)
System.out.flush();
						writer.writer.startTag
(fieldName);
						writer.writeProperty(o,
new ElementType(ElementType.INTEGER_CLASS));
						writer.writer.endTag();
						if (debug)
System.out.println("\t\tDone");
						if (debug)
System.out.flush();
					}
					else if
(typeName.equals("java.lang.Boolean"))
					{
						if (debug)
System.out.println("\t\tWrite Boolean");
						if (debug)
System.out.flush();
						writer.writer.startTag
(fieldName);
						writer.writeProperty(o,
new ElementType(ElementType.BOOLEAN_CLASS));
						writer.writer.endTag();
						if (debug)
System.out.println("\t\tDone");
						if (debug)
System.out.flush();
					}
					else if
(typeName.equals("java.lang.Long"))
					{
						if (debug)
System.out.println("\t\tWrite Long");
						if (debug)
System.out.flush();
						writer.writer.startTag
(fieldName);
						writer.writeProperty(o,
new ElementType(ElementType.LONG_CLASS));
						writer.writer.endTag();
						if (debug)
System.out.println("\t\tDone");
						if (debug)
System.out.flush();
					}
					else if
(typeName.equals("java.lang.String"))
					{
						if (debug)
System.out.println("\t\tWrite String");
						if (debug)
System.out.flush();
						writer.writer.startTag
(fieldName);
						writer.writeProperty(o,
new ElementType(ElementType.STRING_CLASS));
						writer.writer.endTag();
						if (debug)
System.out.println("\t\tDone");
						if (debug)
System.out.flush();
					}
					if (debug)
System.out.println("Done with Fields");
					if (debug) System.out.flush();
				}
				catch (Exception e)
				{
					if (debug)
System.out.println("Exception in field writing: " + e.getMessage());
					if (debug) e.printStackTrace();
					if (debug) System.out.flush();
				}
			}
		}
		else
			writer.writer.write (instance.toString ());	

	}

	public void register(ClassMap cm) 
	{
		cm.addMapping (cm.xsd, "int", ElementType.INTEGER_CLASS,
this); 
		cm.addMapping (cm.xsd, "long", ElementType.LONG_CLASS,
this); 
		cm.addMapping (cm.xsd, "string",
ElementType.STRING_CLASS, this); 
		cm.addMapping (cm.xsd, "boolean",
ElementType.BOOLEAN_CLASS, this); 		
		cm.addMapping (cm.xsd, "double", Double.class, this);
	}

}

Some example code using it:

package serializationPackage;

import java.io.*;

import org.kxml.io.*;
import org.kxml.parser.AbstractXmlParser;
import org.kxml.parser.XmlParser;
import org.ksoap.*;

/**
 * @author mike_jones
 *
 * To change the template for this generated type comment go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
public class MainClass {
	
	private static boolean debug = false;
	
	public static void main(String[] args) 
	{
		System.out.println("Start");
		Writer writer = new StringWriter();
		AbstractXmlWriter xmlWriter = new XmlWriter(writer);
		ClassMap classMap = new ClassMap();
		Marshal marshal = new CommandMarshal();
		marshal.register(classMap);
		classMap.addMapping(classMap.xsd, "Command",
Command.class, marshal);
		SoapWriter soapWriter = new SoapWriter(xmlWriter,
classMap);
		
		Command c = new Command();
		try 
		{
			soapWriter.write(c);
		}
		catch (IOException e)
		{
			
		}
		
		String output = writer.toString();
		System.out.println(output);
		
		String data = writer.toString();
		

		try
		{
			for (int i = 0; i < 300; i++)
			{
				// C# generated soap xml string
//				Reader reader = new
StringReader("<a1:Command id=\"ref-1\"
xmlns:a1=\"http://schemas.microsoft.com/clr/nsassem/SoapExperiment/SoapE
xperiment\"><foo1 xsi:type=\"xsd:int\">4</foo1><foo2
xsi:type=\"xsd:long\">8</foo2><foo3
xsi:type=\"xsd:boolean\">true</foo3><foo4 xsi:type=\"xsd:string\">My or
my!</foo4></a1:Command>");

				Reader reader = new StringReader(data);
				AbstractXmlParser xmlParser = new
XmlParser(reader);
				SoapParser soapParser = new
SoapParser(xmlParser, classMap);
				System.out.println(i);
				c = null;
				c = (Command) soapParser.read();
			}
			System.out.println(c.foo5);
		}
		catch (IOException e)
		{
			if (debug) System.out.println("Exception in
field application: " + e.getMessage());
			if (debug) e.printStackTrace();
		}
		System.out.println("Done");
	}
}

---------------CODE END ----------



-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf
Of [email protected]
Sent: Wednesday, July 09, 2003 4:28 AM
To: [email protected]
Subject: Ksoap: KVM-serialize my own dataype

Hey,
I'm searching for an easy way to kvm-serialize my own datatype. Can
anybody give me an example. How must I define the interface-methods?

Thanx,
Frank

_______________________________________________
Ksoap mailing list
[email protected] http://www.enhydra.org/mailman/listinfo.cgi/ksoap