Hi Andreas, Thanks for the clarification. I had second thoughts about this as well. I will have this sorted.
Another question. Assume that I acquire the XMLStreamReader from an OMElement, and call next() on it. Now, when I call the toString() method I still get the whole element printed. But the WrappedMapNodeStreamReader based MapBackedOMElement doesn't allow that. It seems to me like that each call will return a new copy of the XMLStreamReader. FYI, I have added some tests in my code to test the WrappedMapNodeStreamReader implementation. And, one test (which is related to what I'm saying here) fails. What I have, maintains one single XMLStreamReader internally. Am I making any mistakes here? Also, now that I have a solid way in which the MapBackedOM can be converted into an XML representation, I believe that there also should be a way to convert an XML representation to a MapBackedOM. Are there any similar approaches, so that I can get an idea on where to start? Regards, Senaka On Sat, Nov 15, 2008 at 5:38 PM, Andreas Veithen <[EMAIL PROTECTED]>wrote: > Senaka, > > That looks very good! I think the way you construct the DataHandler is > entirely correct. > > There is still one detail: In the ValueElement constructor, you wrote > the following comment: > > // Set payload to empty string, to force getText() not > return null. > // The whole idea here is that a payload exists, but > it not necessarily > // is represented as a String. It is semantically > incorrect for one to > // request a string representation here, and > therefore, we are not doing > // the wrong thing. > > This is actually not correct. Returning a DataHandler directly is an > extension proper to AXIOM. Since AXIOM allows to access the underlying > XMLStreamReader, it could be that the WrappedMapNodeStreamReader will > be used by code that is not aware of this extension. This kind of code > would then call getText() to get the value of the element. If that > happens you should convert to Base64 pretty much as the previous > version of the code did, except that this conversion should happen > lazily in getText() rather than directly in the ValueElement > constructor. > > To summarize: > * If the XMLStreamReader implementation is used by AXIOM, the byte[] > value is retrieved as a DataHandler and getText will not be called. If > the AXIOM tree is written to a stream later, AXIOM will take care of > the Base64 encoding. > * If the XMLStreamReader is used by code that is not aware of the > AXIOM specific extension, getText will be used (if the code is > interested in the value). In that case, do the Base64 encoding in > getText(). > > Andreas > > On Thu, Nov 13, 2008 at 21:24, Senaka Fernando <[EMAIL PROTECTED]> > wrote: > > Hi Andreas, > > > > I have added DataHandler related logic to [1] , please do let me know > > whether I've taken the correct approach. There seems to be several ways > in > > which I can create a DataHandler, and to be on the safe side, I chose, > the > > [2] based implementation. > > > > [1] > > > http://sci-flex.googlecode.com/svn/sci-flex/trunk/java/axiom/src/main/java/org/apache/axiom/om/util/WrappedMapNodeStreamReader.java > < > http://sci-flex.googlecode.com/svn/sci-flex/trunk/java/axiom/src/main/java/org/apache/axiom/om/util/WrappedMapNodeStreamReader.java > > > > [2] > > > http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/attachments/utils/DataHandlerUtils.java > > > > Thanks, > > Senaka > > > > On Tue, Nov 11, 2008 at 10:31 PM, Senaka Fernando <[EMAIL PROTECTED] > >wrote: > > > >> Thanks for the clarification. Yes, this sounds a perfect scheme. I will > >> have this implementation added shortly. > >> > >> Regards, > >> Senaka > >> > >> > >> On Tue, Nov 11, 2008 at 10:23 PM, Andreas Veithen < > >> [EMAIL PROTECTED]> wrote: > >> > >>> I mean output a DataHandler from the XMLStreamReader. In that case > >>> next() would still return a CHARACTERS event. > >>> > >>> What AXIOM does for CHARACTERS events is to call getProperty (on your > >>> XMLStreamReader) with property name OMConstants.IS_BINARY. If the > >>> value is false, it simply calls getText(). If it is true, it calls > >>> getProperty again with OMConstants.DATA_HANDLER (instead of calling > >>> getText), giving you a chance to return a DataHandler object. Note > >>> that your XMLStreamReader also needs to recognize the > >>> OMConstants.IS_DATA_HANDLERS_AWARE property and return true to enable > >>> this mechanism in AXIOM. > >>> > >>> Andreas > >>> > >>> On Mon, Nov 10, 2008 at 18:35, Senaka Fernando <[EMAIL PROTECTED]> > >>> wrote: > >>> > Hi Andreas, > >>> > > >>> > Thanks for the pointer, however, I'd still like to make one > >>> clarification. > >>> > Do you mean here to internally maintain a DataHandler? or to output a > >>> > DataHandler from the XMLStreamReader? > >>> > > >>> > If you mean the latter, what would the call to next return from the > >>> states > >>> > in [1]. And, if you mean the former, I'd like to know why is it > >>> necessary to > >>> > maintain a DataHandler when you already got the Map with the byte[]? > >>> > > >>> > [1] > >>> > > >>> > http://java.sun.com/javase/6/docs/api/javax/xml/stream/XMLStreamConstants.html > >>> > > >>> > Regards, > >>> > Senaka > >>> > > >>> > On Mon, Nov 10, 2008 at 10:34 PM, Andreas Veithen < > >>> [EMAIL PROTECTED] > >>> >> wrote: > >>> > > >>> >> Senaka, > >>> >> > >>> >> I think for efficiency, it should be the other way round: The > >>> >> XMLStreamReader should produce a DataHandler, which is a thin layer > on > >>> >> top of the byte[]. AXIOM will then convert to Base64 on demand. A > look > >>> >> at OMStAXWrapper#getProperty might help to understand how this can > be > >>> >> achieved. > >>> >> > >>> >> Andreas > >>> >> > >>> >> On Mon, Nov 10, 2008 at 16:26, Senaka Fernando <[EMAIL PROTECTED] > > > >>> >> wrote: > >>> >> > Hi Andreas, > >>> >> > > >>> >> > I have added code to handle byte[] data as well, at [1]. As far as > I > >>> >> > understood, normally Axiom will store data as text, unless a > >>> DataHandler > >>> >> is > >>> >> > created and attached to a tree, and the DataHandler can be > extracted > >>> from > >>> >> > the text (the DataHandler is created on-demand). For this to > happen > >>> the > >>> >> text > >>> >> > must be Base64 encoded. This is the same procedure that takes > place > >>> when > >>> >> the > >>> >> > Axis2 engine receives a XML payload having binary content embedded > as > >>> >> Base64 > >>> >> > encoded text. Also, since I'm dealing with an XMLStreamReader, I > >>> believe > >>> >> > that this approach sounds logical. WDYT? > >>> >> > > >>> >> > I have also moved the char[] based code to use Strings as > suggested. > >>> >> > > >>> >> > [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 Mon, Nov 10, 2008 at 12:22 AM, Senaka Fernando < > >>> [EMAIL PROTECTED] > >>> >> >wrote: > >>> >> > > >>> >> >> Hi Andreas, > >>> >> >> > >>> >> >> I did some modifications to the source and committed it minutes > ago. > >>> My > >>> >> >> previous post to the thread shows a sample output. Seems that > your > >>> last > >>> >> post > >>> >> >> and my last post were sent almost at the same time. :-).. So in > >>> addition > >>> >> to > >>> >> >> what I've said in the previous post, i have added some comments > to > >>> this > >>> >> >> post, inline. > >>> >> >> > >>> >> >> On Mon, Nov 10, 2008 at 12:06 AM, Andreas Veithen < > >>> >> >> [EMAIL PROTECTED]> wrote: > >>> >> >> > >>> >> >>> Senaka, > >>> >> >>> > >>> >> >>> I didn't execute the code yet, but I did a quick review and it > >>> looks > >>> >> >>> already very good. I would like to make the following comments > to > >>> >> >>> improve this still further: > >>> >> >>> > >>> >> >> > >>> >> >> Thanks, and I will add some tests for this code, shortly. I > tweaked > >>> the > >>> >> >> present test source to observe the sample output, which I have > not > >>> >> >> committed. > >>> >> >> > >>> >> >>> > >>> >> >>> * In WrappedTextNodeStreamReader, the character data is returned > in > >>> >> >>> chunks in order to avoid loading the entire data into memory > >>> >> >>> (typically the data comes from a temporary file). I don't think > >>> that > >>> >> >>> this is necessary for the map values, and could even introduce > >>> >> >>> unnecessary overhead. They should simply be converted to a > String > >>> and > >>> >> >>> returned as a single chunk. Getting rid of the java.io.Reader > would > >>> >> >>> also simplify the code. > >>> >> >> > >>> >> >> > >>> >> >> Sounds logical. But, what made me go for this approach is that I > >>> assumed > >>> >> >> that at times a typical Map MIGHT have data that is too large to > fit > >>> in > >>> >> >> memory. WDYT? > >>> >> >> > >>> >> >>> > >>> >> >>> * The right way to represent a byte[] value is to produce a > >>> >> >>> DataHandler (which is equivalent to having the binary data > encoded > >>> as > >>> >> >>> Base64). Note that this is not directly supported by the StAX > API, > >>> but > >>> >> >>> rather an extension introduced by AXIOM to handle binary data > >>> >> >>> efficiently. Please have a look at > >>> >> >>> StAXBuilder#createOMText(OMContainer, int) to see how this magic > >>> >> >>> works. > >>> >> >> > >>> >> >> > >>> >> >> Thanks for the pointer, I will try to add this logic as well. > >>> >> >> > >>> >> >>> > >>> >> >>> * For the moment the key of a map entry is represented using a > >>> "key" > >>> >> >>> attribute but also used for the element name. I guess this is a > >>> >> >>> mistake. Since a map key is not necessarily a valid XML element > >>> name, > >>> >> >>> I think we should prefer the representation using an attribute. > >>> >> >> > >>> >> >> > >>> >> >> I corrected this. Now, element names are "value", and the key is > an > >>> >> >> attribute. The logic limits Map keys to types that can be > >>> represented as > >>> >> >> Strings, and an exception is thrown if it is of any other type. > >>> >> >> > >>> >> >> Regards, > >>> >> >> Senaka > >>> >> >> > >>> >> >>> > >>> >> >>> Regards, > >>> >> >>> > >>> >> >>> Andreas > >>> >> >>> > >>> >> >>> On Sun, Nov 9, 2008 at 11:40, 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/ > >>> >> >>> >> > >>> >> >>> > > >>> >> >>> > >>> >> >> > >>> >> >> > >>> >> > > >>> >> > >>> > > >>> > >> > >> > > >
