FYI,
The payload for:
Map map = new TreeMap();
map.put("intro", 5);
map.put("next", (float)5.5);
map.put("more", "five");
Map nestedMap1 = new TreeMap();
Map nestedMap2 = new TreeMap();
nestedMap1.put("ink", 100);
nestedMap1.put("def", (float)2.0);
nestedMap2.put("str", "ten");
nestedMap1.put("fested", nestedMap2);
nestedMap1.put("dub", (double)100);
map.put("nested", nestedMap1);
is:
<map xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><value
key="intro" xsi:type="int">5</value><value key="more"
xsi:type="string">five</value><value key="nested" type="map"><value
key="def" xsi:type="float">2.0</value><value key="dub"
xsi:type="double">100.0</value><value key="fested" type="map"><value
key="str" xsi:type="string">ten</value></value><value key="ink"
xsi:type="int">100</value></value><value key="next"
xsi:type="float">5.5</value></map>
Regards,
Senaka
On Sun, Nov 9, 2008 at 4:10 PM, Senaka Fernando <[EMAIL PROTECTED]> wrote:
> Andreas,
>
> I did go through your suggested implementation, and [1]'s what I'm planning
> to do. Please do let me know whether I've made the correct choices. As of
> now, the getElementText() method is perhaps not quite correct and I have not
> yet added a mechanism to represent a byte[].
>
> [1]
> http://sci-flex.googlecode.com/svn/sci-flex/trunk/java/axiom/src/main/java/org/apache/axiom/om/util/WrappedMapNodeStreamReader.java
>
> Regards,
> Senaka
>
>
> On Sat, Nov 8, 2008 at 1:36 AM, Sanjiva Weerawarana <[EMAIL PROTECTED]
> > wrote:
>
>> +1 Andreas. This should be written so that the OM is created IFF XML
>> navigation is done. Otherwise the map message should remain in Java and then
>> just get piped thru - that's critical for Synapse performance.
>>
>> Sanjiva.
>>
>>
>> Andreas Veithen 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
>>>>>>>>>>
>>>>>>>>>>
>>
>> --
>> Sanjiva Weerawarana, Ph.D.
>> Founder & Director; Lanka Software Foundation; http://www.opensource.lk/
>> Founder, Chairman & CEO; WSO2, Inc.; http://www.wso2.com/
>> Member; Apache Software Foundation; http://www.apache.org/
>> Visiting Lecturer; University of Moratuwa; http://www.cse.mrt.ac.lk/
>>
>> Blog: http://sanjiva.weerawarana.org/
>>
>
>