This discussion will be continued in the thread [1].
[1] http://markmail.org/message/txqutv7o4eo4lzo3
Regards,
Senaka
On Fri, Oct 31, 2008 at 2:57 AM, Andreas Veithen
<[EMAIL PROTECTED]>wrote:
> Senaka,
>
> The AXIOM tree is built twice because of the following piece of code:
>
> public XMLStreamReader getReader() throws XMLStreamException {
> return getUnderlyingElement().getXMLStreamReader();
> }
>
> The getUnderlyingElement method will build an AXIOM tree representing
> the Map(Message), but when the OMSourcedElement is expanded, AXIOM
> will build another tree based on the events pulled from the
> XMLStreamReader. There are two options then:
>
> 1. One considers that in the vast majority of cases, the content will
> be accessed anyway. Then it would make more sense to construct the
> AXIOM tree directly when the message is received (i.e. no need for an
> OMSourcedElement).
> 2. Don't build an AXIOM tree inside the OMDataSource but construct an
> XMLStreamReader implementation that returns the sequence of StAX
> events corresponding to the desired XML representation.
>
> I used the technique behind option 2 in the following piece of code:
>
>
> http://svn.apache.org/repos/asf/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/util/WrappedTextNodeStreamReader.java
>
> The XMLStreamReader implementation shown in this link is used to
> transform character data (provided by a java.io.Reader) into an
> OMSourcedElement that wraps this data, i.e. the resulting tree would
> be an element with a text node as child. That doesn't sound very
> useful at first glance, but in case of very long character data, it
> allows to stream the data almost directly from the source to the
> destination without ever building the OMText nodes (which would
> consume a large amount of memory).
>
> Given that reading the data source is non destructive, option 2 has
> the advantage that the AXIOM tree
> * will be built exactly once if somebody queries the child OMNodes;
> * will not be built at all when somebody serializes the content into a
> byte stream.
>
> While this is the optimal solution, it is also much more difficult to
> implement. It is certainly an interesting challenge to do that.
>
> Finally, for the type problem, it is indeed sufficient to add a "type"
> attribute to the element that represents the key-value pair:
>
> <price type="double">12.456</price>
>
> Andreas
>
> On Thu, Oct 30, 2008 at 10:34, Senaka Fernando <[EMAIL PROTECTED]>
> wrote:
> > Hi Andreas,
> > I agree with your observations here. Also, I would like to understand
> what
> > you mean by "it will build the AXIOM tree twice when the content
> > is accessed", can this be corrected? As far as Map Messages found in the
> jms
> > transport are concerned, the key is of type string, and the value is a
> > primitive java type, I believe that a slight modification option 2
> discussed
> > here should work. WDYT?
> >
> > Regards,
> > Senaka
> >
> > On Thu, Oct 30, 2008 at 2:10 AM, Andreas Veithen
> > <[EMAIL PROTECTED]>wrote:
> >
> >> Having alternative strategies that map between MapMessages and XML
> >> might be interesting, but to start with we should have at least one
> >> implementation that meets all of the following requirements:
> >>
> >> 1. Highly optimized and having the least possible overhead (even if
> >> the AXIOM tree is build).
> >> 2. The XML representation must be simple so that it can be easily used
> >> with XSLT and XPath.
> >> 3. The mapping must be two way and lossless. That is important if you
> >> want to switch from JMS to another protocol and then back again to
> >> JMS.
> >>
> >> In my opinion, the XMLEncoder based solution doesn't satisfy the first
> >> two requirements, but will meet the last one.
> >>
> >> The other implementation you propose
> >> - partially satisfies requirement 1 (partially because - as far as I
> >> can see - it will build the AXIOM tree twice when the content is
> >> accessed);
> >> - satisfies requirement 2;
> >> - doesn't satisfy requirement 3 because it looses information about
> >> the property types, i.e. you will not be able to recreate an
> >> equivalent MapMessage from the XML representation.
> >>
> >> Andreas
> >>
> >>
> >> On Tue, Oct 28, 2008 at 04:44, Senaka Fernando <[EMAIL PROTECTED]>
> >> wrote:
> >> > Hi Andreas,
> >> >
> >> > The scenario here was to have an implementation that will support Map
> >> > Messages "as well as" hierarchical Maps, and any generic use of Maps
> with
> >> > OM. And as you have mentioned here Map Messages can only have
> primitive
> >> > types on it. Therefore, in theory MapMessage support would only
> require a
> >> > subset of provisions made by this implementation.
> >> >
> >> > Also, if you have tried the implementation I have at the moment, it
> >> supports
> >> > alternative strategies (so you may use whatever type of serializer you
> >> > want).
> >> >
> >> > Regards,
> >> > Senaka
> >> >
> >> > On Tue, Oct 28, 2008 at 5:34 AM, Andreas Veithen
> >> > <[EMAIL PROTECTED]>wrote:
> >> >
> >> >> Senaka,
> >> >>
> >> >> How does your question actually relate to the MapMessage support you
> >> >> are working on? AFAIK MapMessages can't contain arbitrary Java
> >> >> objects.
> >> >>
> >> >> Andreas
> >> >>
> >> >> On Sun, Oct 26, 2008 at 22:19, Senaka Fernando <[EMAIL PROTECTED]>
> >> >> wrote:
> >> >> > Hi Andreas,
> >> >> >
> >> >> > Here you go:
> >> >> >
> >> >> > <map>
> >> >> > <java version="1.6.0_06" class="java.beans.XMLDecoder">
> >> >> > <object class="java.util.TreeMap">
> >> >> > <void method="put">
> >> >> > <string>KeyStr</string>
> >> >> > <string>five</string>
> >> >> > </void>
> >> >> > <void method="put">
> >> >> > <string>Test</string>
> >> >> > <float>5.5</float>
> >> >> > </void>
> >> >> > <void method="put">
> >> >> > <string>SomeKey</string>
> >> >> > <int>5</int>
> >> >> > </void>
> >> >> > <void method="put">
> >> >> > <string>nested</string>
> >> >> > <object class="java.util.TreeMap">
> >> >> > <void method="put">
> >> >> > <string>me</string>
> >> >> > <float>2.0</float>
> >> >> > </void>
> >> >> > <void method="put">
> >> >> > <string>more</string>
> >> >> > <int>100</int>
> >> >> > </void>
> >> >> > <void method="put">
> >> >> > <string>moreNested</string>
> >> >> > <object class="java.util.TreeMap">
> >> >> > <void method="put">
> >> >> > <string>String</string>
> >> >> > <string>ten</string>
> >> >> > </void>
> >> >> > </object>
> >> >> > </void>
> >> >> > </object>
> >> >> > </void>
> >> >> > </object>
> >> >> > </java>
> >> >> > </map>
> >> >> >
> >> >> > This is the serialization for a TreeMap having {<KeyStr, five>,
> <Test,
> >> >> 5.5>,
> >> >> > <someKey, 5>, <nested, {<me, 2.0>, <more, 100>, <moreNested,
> {<String,
> >> >> > ten>}>}>}
> >> >> >
> >> >> > Regards,
> >> >> > Senaka
> >> >> >
> >> >> > On Mon, Oct 27, 2008 at 1:52 AM, Andreas Veithen
> >> >> > <[EMAIL PROTECTED]>wrote:
> >> >> >
> >> >> >> Senaka,
> >> >> >>
> >> >> >> Just a quick question: what does the serialization of a Map looks
> >> like
> >> >> >> with XMLEncoder?
> >> >> >>
> >> >> >> Andreas
> >> >> >>
> >> >> >> On Sat, Oct 25, 2008 at 20:01, Senaka Fernando <
> [EMAIL PROTECTED]>
> >> >> >> wrote:
> >> >> >> > Hi all,
> >> >> >> >
> >> >> >> > I'm working on a mechanism to attach a java.util.Map onto an
> Axiom
> >> >> Tree.
> >> >> >> So
> >> >> >> > far, I have been able to attach the java.util.Map onto the OM
> Tree
> >> >> with
> >> >> >> the
> >> >> >> > help of a specialized data source I have created. This
> >> implementation
> >> >> >> > features on-demand building of the XML payload and I believe the
> >> >> broader
> >> >> >> > usefulness of this would be to serve as a mechanism to store a
> >> >> >> java.util.Map
> >> >> >> > as a part of the OM Tree and perform XML operations (ex:- XPath)
> to
> >> >> >> extract
> >> >> >> > data if needed. However, there can be situations where one would
> >> >> require
> >> >> >> to
> >> >> >> > serialize the internal Map payload and obtain an XML
> >> representation.
> >> >> This
> >> >> >> > can be achieved either through a custom serializer or through a
> >> >> built-in
> >> >> >> > serializer that will convert the Map into an XML representation.
> I
> >> >> have
> >> >> >> as
> >> >> >> > of present added two serializers to the implementation.
> >> >> >> >
> >> >> >> > 1. A simple serializer i I wrote that can handle primitive
> types,
> >> and
> >> >> >> Maps
> >> >> >> > (supports hierarchical maps)
> >> >> >> > 2. The Java XML encoder/decoder for beans java.beans.XMLEncoder
> /
> >> >> >> > java.beans.XMLDecoder (Apache Harmony has an implementation of
> this
> >> if
> >> >> >> you
> >> >> >> > are interested in digging deeper into what happens, [1], [2])
> >> >> >> >
> >> >> >> > Now, after having a word with Paul on this setup I decided to
> make
> >> >> this
> >> >> >> > implementation more generic, and capable of supporting any type
> of
> >> >> object
> >> >> >> > attached to the Map, which eventually drops the 1st
> implementation
> >> >> above.
> >> >> >> > The second works fine, but, is a highly Java specific way of
> doing
> >> >> things
> >> >> >> > (but there is another point here, java.util.Map is Java anyway
> so
> >> this
> >> >> >> might
> >> >> >> > not be an issue) and make no sense in a non-Java context, and
> can
> >> also
> >> >> be
> >> >> >> > memory consuming and inefficient.
> >> >> >> >
> >> >> >> > I have investigated the possibility to make use of,
> >> >> >> >
> >> >> >> > 3. org.apache.axis2.databinding.utils.BeanUtil
> >> >> >> > - This is a sample source code portion that i used,
> >> >> >> >
> >> >> >> > XMLStreamReader xtr = BeanUtil.getPullParser(map);
> >> >> >> > StAXOMBuilder builder = new StAXOMBuilder(xtr);
> >> >> >> > OMElement ele = builder.getDocumentElement();
> >> >> >> >
> >> >> >> > However, for some reason this doesn't work and I run into an
> NPE.
> >> >> >> >
> >> >> >> > org.apache.axiom.om.OMException: java.lang.NullPointerException
> >> >> >> > at
> >> >> >> >
> >> >> >>
> >> >>
> >>
> org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:251)
> >> >> >> > at
> >> >> >> >
> >> >> >>
> >> >>
> >>
> org.apache.axiom.om.impl.llom.OMDocumentImpl.getOMDocumentElement(OMDocumentImpl.java:132)
> >> >> >> > at
> >> >> >> >
> >> >> >>
> >> >>
> >>
> org.apache.axiom.om.impl.builder.StAXOMBuilder.getDocumentElement(StAXOMBuilder.java:526)
> >> >> >> > at my.package.MyClass.myMethod(MyClass.java:127)
> >> >> >> > Caused by: java.lang.NullPointerException
> >> >> >> > at
> >> >> >> >
> >> >> >>
> >> >>
> >>
> org.apache.axiom.om.impl.builder.StAXOMBuilder.endElement(StAXOMBuilder.java:508)
> >> >> >> > at
> >> >> >> >
> >> >> >>
> >> >>
> >>
> org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:222)
> >> >> >> > ... 35 more
> >> >> >> >
> >> >> >> > I spoke to Chinthaka on this matter, and was told that there
> >> might
> >> >> be
> >> >> >> an
> >> >> >> > assumption that the BeanUtil can only handle Bean Classes, or
> >> Classes
> >> >> >> that
> >> >> >> > are not Maps, which might have lead to this situation. I believe
> it
> >> >> wont
> >> >> >> be
> >> >> >> > easy to fix these issues. This is the rationale: I might be able
> to
> >> >> get
> >> >> >> this
> >> >> >> > to work for java.util.Map, but the whole idea is to make use of
> it
> >> to
> >> >> >> > serialize any type of object, where I can't anticipate the
> >> stability.
> >> >> >> >
> >> >> >> > 4. PayloadHelper in Apache Synapse
> >> >> >> > This is a robust implementation that will work for primitive
> Maps
> >> >> (based
> >> >> >> > on org.apache.synapse.util.SimpleMap) like option 1. above.
> >> However,
> >> >> it
> >> >> >> > lacks some aspects.
> >> >> >> > a. It is still a part of Synapse and needs to be ported to
> Axiom
> >> >> (this
> >> >> >> > is do-able as the system has clear and loosely coupled
> interfaces).
> >> >> >> > b. It is an extension of HashMap and thus will not work with
> >> other
> >> >> Map
> >> >> >> > types, such as TreeMap which can be an issue when element
> ordering
> >> >> comes
> >> >> >> > into play.
> >> >> >> > c. It wont support Hierarchical Maps (please correct me if I
> >> made a
> >> >> >> > mistake here).
> >> >> >> > d. It still doesn't serve the purpose of supporting more
> generic
> >> >> Maps
> >> >> >> > with any types of objects in it.
> >> >> >> >
> >> >> >> > 5. A serialization/de-serialization mechanism found in Axis1
> seems
> >> >> >> > interesting as well.
> >> >> >> > - test/soap12/TestDeser.java, test/soap12/TestSer.java
> explains
> >> >> this
> >> >> >> > fact.
> >> >> >> >
> >> >> >> > In here, we have several advantages
> >> >> >> > a. Uniform representation of any primitive type as well as
> >> complex
> >> >> >> types
> >> >> >> > as composites of primitive types
> >> >> >> > b. Good performance
> >> >> >> > c. Ability to nest
> >> >> >> > d. Highly customizable
> >> >> >> >
> >> >> >> > But, there are disadvantages
> >> >> >> > a. This scheme is not capable of storing information about
> the
> >> >> >> > underlying object unless it being explicitly told. Thus, unless
> we
> >> >> know
> >> >> >> what
> >> >> >> > is going on, the Vector class or an extension of a Vector class
> is
> >> >> >> > represented in the very same way. This is not the case in the
> java
> >> >> >> > serializer mechanism as object type information is automatically
> >> >> encoded.
> >> >> >> > b. Assume that we came up with a modification to this scheme
> >> that
> >> >> >> makes
> >> >> >> > it possible to encode object types, still the implementor will
> have
> >> to
> >> >> >> > perhaps write his own Type Table for a type that we did not
> >> >> anticipate.
> >> >> >> > c. Implementation can be complicated as the complexity of the
> >> types
> >> >> of
> >> >> >> > objects representable increases
> >> >> >> > d. Additional maintenance overhead
> >> >> >> >
> >> >> >> > Therefore, each scheme seem to have pros and cons, and are not
> >> >> perfectly
> >> >> >> > fitting in. IMHO, the Java serializer might be the best scheme
> if
> >> we
> >> >> are
> >> >> >> to
> >> >> >> > consider a single scheme. However, modifications to a certain
> >> scheme
> >> >> to
> >> >> >> have
> >> >> >> > a combination of schemes to yield a useful result can prove to
> be
> >> >> >> > advantages. Also, I might have missed some other possibilities.
> >> Your
> >> >> >> input
> >> >> >> > is highly appreciated, and will serve as means for the approach
> I
> >> >> should
> >> >> >> be
> >> >> >> > taking.
> >> >> >> >
> >> >> >> > The current implementation is not as yet a part of Axiom and is
> >> >> available
> >> >> >> > at, [3]. The source includes a maven build system, and please
> note
> >> >> that
> >> >> >> if
> >> >> >> > you may run into some test failures due to an issue in the Axiom
> >> >> >> forceExpand
> >> >> >> > logic. I'm looking forward to have this fixed on the Axiom
> trunk.
> >> >> >> >
> >> >> >> > [1]
> >> >> >> >
> >> >> >>
> >> >>
> >>
> http://svn.apache.org/repos/asf/harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/XMLEncoder.java
> >> >> >> > [2]
> >> >> >> >
> >> >> >>
> >> >>
> >>
> http://svn.apache.org/repos/asf/harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/XMLDeccoder.java
> >> >> >> > [3]
> http://sci-flex.googlecode.com/svn/sci-flex/trunk/java/axiom
> >> >> >> >
> >> >> >> > Thanks,
> >> >> >> > Senaka
> >> >> >> >
> >> >> >>
> >> >> >
> >> >>
> >> >
> >>
> >
>