axis-java-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gdani...@apache.org
Subject cvs commit: xml-axis/java/src/org/apache/axis/message MessageElement.java RPCParam.java SOAPEnvelope.java SOAPSAXHandler.java
Date Mon, 07 May 2001 19:56:41 GMT
gdaniels    01/05/07 12:56:40

  Modified:    java/src/org/apache/axis/encoding SerializationContext.java
                        TypeMappingRegistry.java
               java/src/org/apache/axis/message MessageElement.java
                        RPCParam.java SOAPEnvelope.java SOAPSAXHandler.java
  Log:
  Some improvements to ID/HREF serialization.
  
  Enable multi-ref outputs, triggered by the "doMultiRefs"
  swtich in the SerializationContext.  If this is on, all non-basic
  (i.e. non-string non-number) Objects will be written as hrefs,
  and the actual serializations will happen at the end of the
  body element.
  
  Move the type handling and basic deserialization knowledge
  up from RPCParam into MessageElement.
  
  Revision  Changes    Path
  1.10      +93 -1     xml-axis/java/src/org/apache/axis/encoding/SerializationContext.java
  
  Index: SerializationContext.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/encoding/SerializationContext.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- SerializationContext.java	2001/05/06 21:00:48	1.9
  +++ SerializationContext.java	2001/05/07 19:56:14	1.10
  @@ -88,6 +88,32 @@
       
       private MessageContext msgContext;
       
  +    /**
  +     * Should I write out objects as multi-refs?
  +     * 
  +     * !!! For now, this is an all-or-nothing flag.  Either ALL objects will
  +     * be written in-place as hrefs with the full serialization at the end
  +     * of the body, or we'll write everything inline (potentially repeating
  +     * serializations of identical objects).
  +     */
  +    private boolean doMultiRefs = false;
  +    
  +    /**
  +     * A place to hold objects we cache for multi-ref serialization, and
  +     * remember the IDs we assigned them.
  +     */
  +    private Hashtable multiRefValues = null;
  +    private int multiRefIndex = -1;
  +    
  +    /**
  +     * These two let us deal with multi-level object graphs for multi-ref
  +     * serialization.  Each time around the serialization loop, we'll fill
  +     * in any new objects into the secondLevelObjects vector, and then write
  +     * those out the same way the next time around.
  +     */
  +    private Object currentSer = null;
  +    private Vector secondLevelObjects = null;
  +    
       public SerializationContext(Writer writer, MessageContext msgContext)
       {
           this.writer = writer;
  @@ -134,7 +160,6 @@
               /*if ((pendingNSMappings.get(uri) != null) ||
                   (nsStack.getPrefix(uri) != null))
                   return;*/
  -            
               pendingNSMappings.put(uri, prefix);
           }
       }
  @@ -154,7 +179,74 @@
       public void serialize(QName qName, Attributes attributes, Object value)
           throws IOException
       {
  +        if (value == null)
  +            return;
  +        
  +        if (doMultiRefs && (value != currentSer) &&
  +            !(value.getClass().equals(String.class)) &&
  +            !(value instanceof Number)) {
  +            if (multiRefIndex == -1)
  +                multiRefValues = new Hashtable();
  +            
  +            String href = (String)multiRefValues.get(value);
  +            if (href == null) {
  +                multiRefIndex++;
  +                href = "id" + multiRefIndex;
  +                multiRefValues.put(value, href);
  +                
  +                /** Problem - if we're in the middle of writing out
  +                 * the multi-refs and hit another level of the
  +                 * object graph, we need to make sure this object
  +                 * will get written.  For now, add it to a list
  +                 * which we'll check each time we're done with
  +                 * outputMultiRefs().
  +                 */
  +                if (currentSer != null) {
  +                    if (secondLevelObjects == null)
  +                        secondLevelObjects = new Vector();
  +                    secondLevelObjects.addElement(value);
  +                }
  +            }
  +            
  +            AttributesImpl attrs = new AttributesImpl();
  +            if (attributes != null)
  +                attrs.setAttributes(attributes);
  +            attrs.addAttribute("", Constants.ATTR_HREF, "href",
  +                               "CDATA", "#" + href);
  +            
  +            startElement(qName, attrs);
  +            endElement();
  +            return;
  +        }
  +        
           getTypeMappingRegistry().serialize(qName, attributes, value, this);
  +    }
  +    
  +    public void outputMultiRefs() throws IOException
  +    {
  +        if (!doMultiRefs || (multiRefValues == null))
  +            return;
  +        
  +        AttributesImpl attrs = new AttributesImpl();
  +        attrs.addAttribute("","","","","");
  +        
  +        Enumeration e = multiRefValues.keys();
  +        while (e.hasMoreElements()) {
  +            while (e.hasMoreElements()) {
  +                Object val = e.nextElement();
  +                String id = (String)multiRefValues.get(val);
  +                attrs.setAttribute(0, "", Constants.ATTR_ID, "id", "CDATA",
  +                                   id);
  +                currentSer = val;
  +                serialize(new QName("","multiRef"), attrs, val);
  +            }
  +            
  +            if (secondLevelObjects != null) {
  +                e = secondLevelObjects.elements();
  +                secondLevelObjects = null;
  +            }
  +        }
  +        currentSer = null;
       }
       
       public void startElement(QName qName, Attributes attributes)
  
  
  
  1.8       +21 -0     xml-axis/java/src/org/apache/axis/encoding/TypeMappingRegistry.java
  
  Index: TypeMappingRegistry.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/encoding/TypeMappingRegistry.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- TypeMappingRegistry.java	2001/05/05 13:47:12	1.7
  +++ TypeMappingRegistry.java	2001/05/07 19:56:17	1.8
  @@ -56,12 +56,14 @@
   package org.apache.axis.encoding;
   
   import java.util.Hashtable;
  +import org.apache.axis.Constants;
   import org.apache.axis.utils.*;
   import org.apache.axis.utils.events.*;
   import org.apache.axis.message.*;
   import org.w3c.dom.Element;
   import org.w3c.dom.Document;
   import org.xml.sax.*;
  +import org.xml.sax.helpers.AttributesImpl;
   import java.io.*;
   
   /**
  @@ -188,6 +190,23 @@
           load(fis);
       }
   
  +    public Attributes setTypeAttribute(Attributes attributes, QName type,
  +                                       SerializationContext context)
  +    {
  +        if ((attributes != null) &&
  +            (attributes.getIndex(Constants.URI_CURRENT_SCHEMA_XSI,
  +                                "type") != -1))
  +            return attributes;
  +        
  +        AttributesImpl attrs = new AttributesImpl();
  +        if (attributes != null)
  +            attrs.setAttributes(attributes);
  +        
  +        attrs.addAttribute(Constants.URI_CURRENT_SCHEMA_XSI, "type",
  +                           "xsi:type", "CDATA", context.qName2String(type));
  +        return attrs;
  +    }
  +    
       public void serialize(QName name, Attributes attributes,
                             Object value, SerializationContext context)
           throws IOException
  @@ -196,6 +215,8 @@
               Class _class = value.getClass();
               Serializer ser = getSerializer(_class);
               if (ser != null) {
  +                QName type = getTypeQName(_class);
  +                attributes = setTypeAttribute(attributes, type, context);
                   ser.serialize(name, attributes, value, context);
               } else {
                   throw new IOException("No serializer found for class " + _class.getName());
  
  
  
  1.17      +112 -3    xml-axis/java/src/org/apache/axis/message/MessageElement.java
  
  Index: MessageElement.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/message/MessageElement.java,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- MessageElement.java	2001/05/05 22:16:58	1.16
  +++ MessageElement.java	2001/05/07 19:56:29	1.17
  @@ -87,6 +87,8 @@
       protected String stringRep = null;
       
       protected ElementRecorder recorder = null;
  +    protected DeserializerBase deserializer = null;
  +    protected boolean deserializing = true;
   
       /** No-arg constructor for building messages?
        */
  @@ -110,6 +112,8 @@
         if (attributes == null) {
           this.attributes = new AttributesImpl();
         } else {
  +        typeQName = context.getTypeFromAttributes(attributes);
  +
           this.attributes = new AttributesImpl(attributes);
           String rootVal = attributes.getValue(Constants.URI_SOAP_ENV, Constants.ATTR_ROOT);
           // !!! This currently defaults to false... should it default to true?
  @@ -153,13 +157,118 @@
       {
           return null;
       }
  +
  +    public Object getValue()
  +    {
  +        if (value instanceof ElementRecorder) {
  +            // !!! Lazy deserialization here... We have the SAX events,
  +            //     but haven't run them through a deserializer yet.
  +            StringWriter xml = new StringWriter();
  +            try {
  +               SerializationContext xmlContext = new SerializationContext(xml, context.getMessageContext());
  +               ((ElementRecorder)value).outputChildren(xmlContext);
  +            } catch (Exception e) {
  +               if (DEBUG_LOG) e.printStackTrace();
  +               return null;
  +            }
  +            return xml.getBuffer().toString();
  +        }
  +        
  +        if (deserializer != null) {
  +            value = deserializer.getValue();
  +            deserializer = null;
  +        }
  +        
  +        return value;
  +    }
       
  +    public void startElement(String namespace, String localName,
  +                             String qName, Attributes attributes)
  +        throws SAXException
  +    {
  +        if (DEBUG_LOG) {
  +            System.err.println("Start element in MessageElement.");
  +        }
  +        
  +        if (typeQName == null)
  +            typeQName = context.getTypeFromAttributes(attributes);
  +
  +        // !!! This check might not be complete; in the case of
  +        //     a multi-ref, we might need to check BOTH the name
  +        //     of the element with the href AND the referenced
  +        //     one.  Right now this will just check the referenced one.
  +        if (typeQName == null) {
  +            QName myQName = new QName(namespace, localName);
  +            if (myQName.equals(SOAPTypeMappingRegistry.SOAP_ARRAY)) {
  +                typeQName = SOAPTypeMappingRegistry.SOAP_ARRAY;
  +            } else if (myQName.equals(SOAPTypeMappingRegistry.SOAP_INT)) {
  +                typeQName = SOAPTypeMappingRegistry.XSD_INT;
  +            } else if (myQName.equals(SOAPTypeMappingRegistry.SOAP_BOOLEAN)) {
  +                typeQName = SOAPTypeMappingRegistry.XSD_BOOLEAN;
  +            } else if (myQName.equals(SOAPTypeMappingRegistry.SOAP_SHORT)) {
  +                typeQName = SOAPTypeMappingRegistry.XSD_SHORT;
  +            }
  +        }
  +        
  +        if (typeQName == null) {
  +            // No type inline, so check service description.
  +            ServiceDescription serviceDesc = context.getServiceDescription();
  +            if (serviceDesc != null) {
  +                setType(serviceDesc.getParamTypeByName(getEnvelope().getMessageType(),
  +                                                             name));
  +            }
  +        }
  +        
  +        /** !!! If we have a service description and this is an
  +        * explicitly-typed param, we might want to check here to
  +        * see if the xsi:type val is indeed a subtype of the type
  +        * we expect from the service description.
  +        */
  +        
  +        DeserializerBase dSer = getContentHandler();
  +        
  +        context.getSAXHandler().replaceElementHandler(dSer);
  +        
  +        if (dSer != this)
  +            dSer.startElement(namespace,localName,qName,attributes);
  +    }
  + 
       public DeserializerBase getContentHandler()
       {
  -        if (recorder == null)
  -            recorder = new ElementRecorder();
  +        if (deserializing) {
  +            // Look up type and return an appropriate deserializer
  +            if ((typeQName != null) && (deserializer == null)) {
  +                deserializer = context.getDeserializer(typeQName);
  +                if (DEBUG_LOG) {
  +                    System.err.println(typeQName + " maps to " + deserializer);
  +                }
  +            }
  +
  +            if (deserializer != null) {
  +                return deserializer;
  +            }
  +        }
  +            
  +        /** !!! Is it possible that we'll do this now, but
  +        * later on we'll figure out the type (via some OOB
  +        * means)?  In that case we want an easy way to
  +        * squirt these SAX events to a deserializer.
  +        */
  +        if (DEBUG_LOG) {
  +            System.err.println("Creating recorder for " + this.getName());
  +        }
  +        value = new ElementRecorder();
  +        recorder = (ElementRecorder)value;
  +        return (ElementRecorder)value;
  +    }
  +    
  +    public void setContentHandler(DeserializerBase handler)
  +    {
  +        if (deserializer != null) {
  +            System.err.println("Non-null deser while setting content handler?");
  +        }
           
  -        return recorder;
  +        deserializer = handler;
       }
       
       public void publishToHandler(ContentHandler handler) throws SAXException
  
  
  
  1.17      +1 -100    xml-axis/java/src/org/apache/axis/message/RPCParam.java
  
  Index: RPCParam.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/message/RPCParam.java,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- RPCParam.java	2001/05/06 16:08:17	1.16
  +++ RPCParam.java	2001/05/07 19:56:31	1.17
  @@ -71,7 +71,6 @@
   public class RPCParam extends MessageElement
   {
       private static boolean DEBUG_LOG = false;
  -    private DeserializerBase deserializer = null;
       
       // Who's your daddy?
       RPCElement myRPCElement;
  @@ -117,105 +116,7 @@
           return super.getEnvelope();
       }
       
  -    public void startElement(String namespace, String localName,
  -                             String qName, Attributes attributes)
  -        throws SAXException
  -    {
  -        if (DEBUG_LOG) {
  -            System.err.println("Start element in RPCParam.");
  -        }
  -        typeQName = context.getTypeFromAttributes(attributes);
  -
  -        // !!! This check might not be complete; in the case of
  -        //     a multi-ref, we might need to check BOTH the name
  -        //     of the element with the href AND the referenced
  -        //     one.  Right now this will just check the referenced one.
  -        if (typeQName == null) {
  -            QName myQName = new QName(namespace, localName);
  -            if (myQName.equals(SOAPTypeMappingRegistry.SOAP_ARRAY)) {
  -                typeQName = SOAPTypeMappingRegistry.SOAP_ARRAY;
  -            } else if (myQName.equals(SOAPTypeMappingRegistry.SOAP_INT)) {
  -                typeQName = SOAPTypeMappingRegistry.XSD_INT;
  -            } else if (myQName.equals(SOAPTypeMappingRegistry.SOAP_BOOLEAN)) {
  -                typeQName = SOAPTypeMappingRegistry.XSD_BOOLEAN;
  -            } else if (myQName.equals(SOAPTypeMappingRegistry.SOAP_SHORT)) {
  -                typeQName = SOAPTypeMappingRegistry.XSD_SHORT;
  -            }
  -        }
  -        
  -        if (typeQName == null) {
  -            // No type inline, so check service description.
  -            ServiceDescription serviceDesc = context.getServiceDescription();
  -            if (serviceDesc != null) {
  -                setType(serviceDesc.getParamTypeByName(getEnvelope().getMessageType(),
  -                                                             name));
  -            }
  -        }
  -        
  -        /** !!! If we have a service description and this is an
  -        * explicitly-typed param, we might want to check here to
  -        * see if the xsi:type val is indeed a subtype of the type
  -        * we expect from the service description.
  -        */
  -        
  -        DeserializerBase dSer = getContentHandler(context);
  -        
  -        context.getSAXHandler().replaceElementHandler(dSer);
  -        
  -        dSer.startElement(namespace,localName,qName,attributes);
  -    }
  -    
  -    public DeserializerBase getContentHandler(DeserializationContext context)
  -    {
  -        // Look up type and return an appropriate deserializer
  -        if (typeQName != null) {
  -            deserializer = context.getDeserializer(typeQName);
  -            if (DEBUG_LOG) {
  -                System.err.println(typeQName + " maps to " + deserializer);
  -            }
  -            if (deserializer != null) {
  -                return deserializer;
  -            }
  -        }
  -        
  -        // If we couldn't find one, just record...
  -        
  -        /** !!! Is it possible that we'll do this now, but
  -         * later on we'll figure out the type (via some OOB
  -         * means)?  In that case we want an easy way to
  -         * squirt these SAX events to a deserializer.
  -         */
  -        if (DEBUG_LOG) {
  -            System.err.println("Creating recorder for " + this.getName());
  -        }
  -        value = new ElementRecorder();
  -        return (ElementRecorder)value;
  -    }
  -    
  -    public Object getValue()
  -    {
  -        if (value instanceof ElementRecorder) {
  -            // !!! Lazy deserialization here... We have the SAX events,
  -            //     but haven't run them through a deserializer yet.
  -            StringWriter xml = new StringWriter();
  -            try {
  -               SerializationContext xmlContext = new SerializationContext(xml, context.getMessageContext());
  -               ((ElementRecorder)value).outputChildren(xmlContext);
  -            } catch (Exception e) {
  -               if (DEBUG_LOG) e.printStackTrace();
  -               return null;
  -            }
  -            return xml.getBuffer().toString();
  -        }
  -        
  -        if (deserializer != null) {
  -            value = deserializer.getValue();
  -            deserializer = null;
  -        }
  -        
  -        return value;
  -    }
  -    
  +   
       public void output(SerializationContext context) throws IOException
       {
           AttributesImpl attrs;
  
  
  
  1.24      +3 -0      xml-axis/java/src/org/apache/axis/message/SOAPEnvelope.java
  
  Index: SOAPEnvelope.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/message/SOAPEnvelope.java,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- SOAPEnvelope.java	2001/05/06 15:57:20	1.23
  +++ SOAPEnvelope.java	2001/05/07 19:56:32	1.24
  @@ -325,6 +325,9 @@
               // Output this body element.
           }
           
  +        // Output multi-refs
  +        context.outputMultiRefs();
  +        
           // Output </SOAP-ENV:Body>
           context.endElement();
           
  
  
  
  1.11      +6 -4      xml-axis/java/src/org/apache/axis/message/SOAPSAXHandler.java
  
  Index: SOAPSAXHandler.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/message/SOAPSAXHandler.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- SOAPSAXHandler.java	2001/05/06 15:57:20	1.10
  +++ SOAPSAXHandler.java	2001/05/07 19:56:34	1.11
  @@ -421,7 +421,6 @@
                   if (rec instanceof ElementRecorder) {
                       ((ElementRecorder)rec).publishToHandler(context.getSAXHandler());
                   } else {
  -                    System.out.println("Setting value to " + rec.getValue());
                       elementHandler.setValue(rec.getValue());
                   }
                   
  @@ -575,9 +574,12 @@
                       handler = context.getHandlerForID(element.getID());
                       if (handler == null) {
                           handler = element.getContentHandler();
  -                    } /* else {
  -                        System.out.println("found it " + handler);
  -                    } */
  +                    }  else {
  +                        if (DEBUG_LOG) {
  +                            System.out.println("found handler for ID " + element.getID()
+ " : " + handler);
  +                        }
  +                        element.setContentHandler(handler);
  +                    }
                   } else {
                       handler = element.getContentHandler();
                   }
  
  
  

Mime
View raw message