I made this post to the user group. I thought you guys might be interested
in what I did to make serialization work for objects declared as interfaces
or abstract classes. As I said below, if this has not been corrected in 2.2,
maybe you can use the code! (i'VE not included any code in this mail that i
wrote for the inheritance thing...)
-----


I was able to write a single class that converts any java bean to SOAP XML
and does not include all the bulky envelope stuff. I did have to modify a
few of the the soap classes as well to overload some methods.

here's how (note that that obviously you will have to modify the main to
serialize classes other than the ones I am serializing). If anyone is really
interested in using this stuff, we are using it in a production database to
serialize and deserialize very complex hierarchical objects and it works
great. I could post up all the classes if there is interest.

Another thing I did was create an interface serialize. this was needed
because often objects are declared as marker interfaces or abstract classes.
of course apache soap chokes when it tries to instantiate these since they
are not instantiable.

So I have also made the apache code completely able to deal with
inheritance, etc.
I made all these changes to the soap 2.1 code base. Maybe this was fixed by
somebody else in 2.2 release, but I needed this stuff fixed and 2.2 wasn't
out at the time.

Like I said, if there is interest I would like to see this code pushed into
future releases of apache soap (the inheritance stuff I mean).

this is just :


 
import java.beans.*;
import java.lang.reflect.*;
import org.apache.soap.util.xml.*;
import org.apache.soap.encoding.soapenc.*;
import org.apache.soap.rpc.*;
import org.apache.soap.*;
import java.io.*;
import com.grvt8.leap.util.*;
import org.apache.log4j.*;
import org.apache.soap.server.*;
import org.apache.soap.encoding.*;
import java.util.*;
import org.apache.soap.util.*;
import org.apache.soap.util.xml.*;
import org.w3c.dom.*;
import com.grvt8.leap.api.clouds.*;

/**
 * <code>XMLBeanSerializer</code> marshals and unmarshals Beans. Designed
 * to read and write XML from a database.
 * @author <a href="mailto:[EMAIL PROTECTED]";>Geoff Hendrey</a>
 * @see BeanSerializer
 */

public class XMLBeanSerializer extends BeanSerializer
{

        private final static String inScopeEncStyle =
Constants.NS_URI_SOAP_ENC;
        private static final Category cat =
Category.getInstance(XMLBeanSerializer.class.getName());
        private XMLJavaMappingRegistry xjmr = null;
        
        public XMLBeanSerializer()
        {
                //empty constructor for java bean 
                //Don't use this constructor.
        }
        /**
        * Use this constructor, not the default constructor.
        * @param ddFileName java.lang.String - full path to the
DeploymentDescriptor.xml
        */      
        public XMLBeanSerializer(String ddFileName)
        {

                super();
                try
                {
                        xjmr = getSMR(ddFileName);
                }catch(Exception e)
                {
                        cat.fatal(e);           
                }
                        
        }       
        
        /**
        * converts a java bean into xml.
        * The goal is to use the Apache XML Bean serialization code, without
        * creating superfluous envelopes that are used for SOAP transport,
but
        * are not needed for database storage.
        * @param src java.lang.Object - the java bean.
        * @param context java.lang.String - the instance name of the java
bean. For example
        * if marshalling a RequestProcessor instance, context might be
"requestProcessor2".
        * @param writer java.io.writer - the xml gets written to this sink.
        * @param beanNameSpaceURI - a namespace is defined for all of our
Gravitate classes 
        * that we want to marshal. This namespace is defined in
DeploymentDescriptor.xml. 
        * At the moment, we name it "urn:RemoteRequestManagerTypes"
        */              

        public void marshall(Object src, String context, Writer sink, String
beanNameSpaceURI)
    throws IllegalArgumentException, IOException
        {
                try
                {


                        SOAPContext ctx = new SOAPContext();
                        NSStack nsStack = new NSStack();
                        Class javaType = src.getClass();
                         
                        //push scope for the namespaces that would otherwise
go in the envelope
                        nsStack.pushScope();
                        //since there is no Envelope used for serializing
Beans to the 
                        //database, we must push the scopes manually that
would have been
                        //in the envelope 
                        declareEnvelopeNamespaces(nsStack);
                        
                        //we must also add a namespace declaration for our
Beans that are listed
                        //in the deployment descriptor.
                        nsStack.addNSDeclaration(beanNameSpaceURI);

                        //push scope for this bean we are serializing
                        nsStack.pushScope();

                        //because we have no envelope, we put the attributes
that we pushed onto envelope's scope
                        //into the attributes of the first tag.
                        String beanNSPrefix =
nsStack.getPrefixFromURI(beanNameSpaceURI, sink);
                        
                        String attributes = " " + Constants.NS_PRE_XMLNS +
":"+Constants.NS_PRE_SCHEMA_XSI+
                        "=\""+Constants.NS_URI_SCHEMA_XSI+"\" "+
        
Constants.NS_PRE_XMLNS+":"+Constants.NS_PRE_SCHEMA_XSD+"=\""+Constants.NS_UR
I_SCHEMA_XSD+
                        "\" "+ Constants.NS_PRE_XMLNS +
":"+beanNSPrefix+"=\""+ beanNameSpaceURI+"\"";

                        //This is a new utility method that will put
additional attributes
                        //in the first tag of the bean we are marshalling.
We need to put the
                        //namespaces that would otherwise have been in the
envelope into the tag.

        
SoapEncUtils.generateStructureHeaderWithAttributes(inScopeEncStyle,
                                         javaType,
                                         context,
                                         sink,
                                         nsStack,
                                         xjmr,null,null,false,attributes);

                        //from here down it's simply a cut and paste from
this point in super.marshall()
                        //This will have to be maintained if the stuff in
super.marshall()    
                        //changes in the future. Nothing I can do about it
though, because 
                        //the code in super.marshall() is pretty monolithic.
                        
        
sink.write(org.apache.soap.util.StringUtils.lineSeparator);
        
                    PropertyDescriptor[] properties =
getPropertyDescriptors(javaType);

                    for (int i = 0; i < properties.length; i++)
                {
                        propName = properties[i].getName();
                        propType = properties[i].getPropertyType();

                        // Serialize every property except the "class"
property.
                        if (!propType.equals(Class.class))
                        {
                                Method propReadMethod =
properties[i].getReadMethod();

        // Only serialize readable properties.
        if (propReadMethod != null)
        {
          propValue = null;

          // Get the property's value.
          try
          {
            if (src != null)
            {
              propValue = propReadMethod.invoke(src, new Object[]{});
            }
          }
          catch (Exception e)
          {
            throw new IllegalArgumentException("Unable to retrieve '" +
                                               propName + "' property " +
                                               "value: " + e.getMessage() +
                                               '.');
          }

          // Serialize the property.

          Parameter param = new Parameter(propName, propType, propValue,
null);

          xjmr.marshall(inScopeEncStyle, Parameter.class, param, null,
                        sink, nsStack, ctx);

          sink.write(org.apache.soap.util.StringUtils.lineSeparator);
        }
      }
    }

    sink.write("</" + context + '>');

    nsStack.popScope(); 

                        
                }
                catch(Exception e)
                {
                        System.out.println(e);
                                
                }

                }
                
                
        private void declareEnvelopeNamespaces(NSStack nsStack)
        {
                nsStack.addNSDeclaration(Constants.NS_PRE_SCHEMA_XSI,
Constants.NS_URI_SCHEMA_XSI);
                nsStack.addNSDeclaration(Constants.NS_PRE_SCHEMA_XSD,
Constants.NS_URI_SCHEMA_XSD);
                
        }               
                
        /**
        * converts xml into java bean
        * @param elementType org.apache.soap.util.xml.QName. - for example,
Bean bean =new QName("urn:RemoteRequestManagerTypes", "Profile")
        * @param xmlReader java.io.Reader - the xml gets read from here.
        */
  public Bean unmarshall(QName elementType, Reader xmlReader)
        {
                XercesParserLiaison xpl = new XercesParserLiaison();
                Document doc = null;
                Node src = null;
                try
                {
                        doc = xpl.read("usless string", xmlReader);
                        src = (Node) doc.getDocumentElement();
                }
                catch(Exception e)
                {
                        System.out.println(e);          
                }
                        
                SOAPContext ctx = new SOAPContext();
                NSStack nsStack = new NSStack();
                return super.unmarshall(inScopeEncStyle, elementType, src,
xjmr,ctx);              
        }
        

        private SOAPMappingRegistry getSMR(String ddFileName) throws
Exception {
                cat.debug("Creating Soap Mapping Registry from
DeploymentDescriptor");
                File f= new File(ddFileName);
                FileReader fr = new FileReader(f);
                DeploymentDescriptor dd = DeploymentDescriptor.fromXML(fr);
                cat.debug("deployment descriptor read from " + ddFileName +
": " + dd);
                SOAPMappingRegistry smr =
DeploymentDescriptor.buildSOAPMappingRegistry (dd);
                return smr;
        }

        public static void main(String[] args)
        {
                FileWriter fw = null;
                XMLBeanSerializer ser = null;
                XercesParserLiaison xpl = new XercesParserLiaison();
                FileReader fr = null;
                Document doc = null;
                try
                {

                 fw = new FileWriter("c:/TEMP/test.xml");
                 IDevice iDevice = new Device("PHONE","555-1212");
                 Profile prof = new Profile();
                 prof.setValue("SOME STRING I SET");
                 ListNearbyUsersRequest list = new ListNearbyUsersRequest();
                 
                 ser = new
XMLBeanSerializer("c:/TEMP/DeploymentDescriptor.xml");

                 fw.flush();
                 //ser.marshall((Object)phone,"Phone",(Writer)fw);
                 //XMLJavaMappingRegistry xjmr =
ser.getSMR("c:/TEMP/DeploymentDescriptor.xml");
                 //ser.marshall((Object)prof,"profile",(Writer)fw,
"urn:RemoteRequestManagerTypes");
        
ser.marshall((Object)list,"ListNearbyUsersRequest",(Writer)fw,
"urn:RemoteRequestManagerTypes");

                 fw.flush();
                 cat.info("closing FileWriter");

                 fr = new FileReader("c:/TEMP/test.xml");
                 //Bean bean = ser.unmarshall(new
QName("urn:RemoteRequestManagerTypes", "Profile"),fr);
                 //Profile prof2 = (Profile) bean.value;
                 //System.out.println(prof2.getValue());
                 Bean bean = ser.unmarshall(new
QName("urn:RemoteRequestManagerTypes", "ListNearbyUsersRequest"),fr);
                 list = (ListNearbyUsersRequest) bean.value;
                 System.out.println(list.getFindMaxUsers());
/*
                 Bean bean = ser.unmarshall(new
QName("urn:RemoteRequestManagerTypes", "Phone"),fr);
                 Phone phone2 = (Phone) bean.value;
        
System.out.println(phone2.getProtocol()+":"+phone2.getValue());
*/
                }catch(Exception e)
                {
                
                        System.out.println(e);
                
                }


        }



-----Original Message-----
From: graham glass [mailto:[EMAIL PROTECTED]]
Sent: Friday, August 10, 2001 11:49 PM
To: [EMAIL PROTECTED]; [EMAIL PROTECTED]
Subject: RE: Converting Java objects to XML using SOAP utilities


the GLUE java/xml facility is independent of SOAP
and will soon be available as a separate standalone package.

cheers,
graham

http://www.themindelectric.com

-----Original Message-----
From: Kartheek Hirode [mailto:[EMAIL PROTECTED]]
Sent: Friday, August 10, 2001 5:22 PM
To: [EMAIL PROTECTED]
Subject: RE: Converting Java objects to XML using SOAP utilities


1) Look at http://castor.exolab.org/
2) Keep your eyes on http://java.sun.com/xml/jaxb/index.html for
implementations from Javasoft.
Using SOAP for Java-to-XML would be like using a hammer to turn a screw.
Regards,
--KH


-----Original Message-----
From: wen xie [mailto:[EMAIL PROTECTED]]
Sent: Thursday, August 09, 2001 1:21 PM
To: [EMAIL PROTECTED]
Subject: Converting Java objects to XML using SOAP utilities


Hi,

I am trying to use SOAP utilities to convert Java objects to XML format
since I know that SOAP embeds objects to XML messages. I did some searches
but so far no good. I don't need to invoke RPCs or communicate between
client and server. Simply I just want to know how I can convert Java objects
to XML using SOAP. Could someone give me a hint about this?

Thanks a lot.

Wen

_________________________________________________________________
Get your FREE download of MSN Explorer at http://explorer.msn.com/intl.asp




-    GEOFF HENDREY    -
Chief Technology Officer

Gravitate, Inc.
713 Linden Avenue
South San Francisco, CA  94080

Office  650-873-4373 x101
Mobile  650-270-7020
Fax     650-873-4393

Reply via email to