[ http://issues.apache.org/jira/browse/XMLBEANS-228?page=all ]

Lawrence Jones updated XMLBEANS-228:
------------------------------------

    Attachment: xmlbeans228.patch

I'm attaching a patch which I think fixes this problem. However that's the good 
news. The bad news is that this patch is not consistent with a chat I had with 
one of the committers and therefore it may not get applied.

My solution keeps an extra QName on every Xobj. It is null except in the case 
where you are substituting for some other element in which case it is the QName 
of the element you are substituting for. (You then make decisions at 
appropriate times pretty much as mentioned in the comments above.)

The original plan we came up with wanted to (rightly I believe) create a new 
class, SubstituteElementXobj, derived from ElementXobj and make it so that only 
that class has the extra QName on it to avoid the memory burden on _every_ 
Xobj. Unfortunately the way XmlBeans does substitution at the moment (the 
XmlObjectBase.substitute() method) is kind of like a "rename" of the underlying 
Xobj. In order for the SubstituteElementXobj approach to work, whenever you 
substitute you need to create a new SubstituteElementXobj and use it to 
_replace_ (not just "rename") the existing Xobj.

Unfortunately there are lots of links to the existing Xobj which all then need 
to be updated. I'm not convinced I can even get to all of them. I tried to get 
it to work but basically I was trying to swap out some Xobj, call it xobj1, 
from within xobj1 itself and it seemed like I'd be making changes to Xobj and 
Cur which could have huge consequences. Also I've run out of time for being 
able to work on this (I need to get back to my day job ;). So I'm attaching the 
work I've done so far in case it's useful. I think I need someone with a lot 
more experience with the store code to take a look at it and decide:

a) to apply this patch and put up with the possible memory consequences, or
b) to use the above work and generate a better solution based on the 
SubstituteElementXobj approach (or something new)


> Element order is mixed up on document creation after calling substitute()
> -------------------------------------------------------------------------
>
>          Key: XMLBEANS-228
>          URL: http://issues.apache.org/jira/browse/XMLBEANS-228
>      Project: XMLBeans
>         Type: Bug
>   Components: XmlObject
>     Versions: Version 2, Version 2.1
>  Environment: N/A
>     Reporter: Andreas Loew
>      Fix For: Version 2, Version 2.1
>  Attachments: SubstitutionGroupTest.java, substGroupTests.xsd, 
> substitutionGroupFix.patch, substitutionGroupInSequence.xsd, 
> xmlbeans228.patch, xmlbeans228_QNameSet.patch
>
> When trying to create XML documents with XMLBeans 2.x using xmlText() or 
> save() that use substitution groups, usage of the substitute() method will 
> mix up the order of the XML document (the order will remain correct when 
> substitute() will not be called).
> We have attached a test case (schema XSD, JUnit test) that demonstrates the 
> failure and also attached a patch against plain XMLBeans 2.0.0 that shows 
> where the problem is and what is needed to fix problem (although currently at 
> the cost of a quite severe perfomance penalty, as I am not an expert in 
> XMLBeans internals):
> For the test case, XMLBeans 2.0.0 as well as the current SVN snapshot both 
> fail as they return
> <?xml version="1.0" encoding="UTF-8"?>
> <Person 
> xmlns="urn:www-apache-org:SubstitutionGroup/substitutionGroupInSequence">
>   <FirstCommentElement>ThirdElement</FirstCommentElement>
>   <FirstName>FirstElement</FirstName>
>   <LastName>SecondElement</LastName>
> </Person>
> instead of
> <?xml version="1.0" encoding="UTF-8"?>
> <Person 
> xmlns="urn:www-apache-org:SubstitutionGroup/substitutionGroupInSequence">
>   <FirstName>FirstElement</FirstName>
>   <LastName>SecondElement</LastName>
>   <FirstCommentElement>ThirdElement</FirstCommentElement>
> </Person>
> as would be correct (and will be returned after applying the patches 
> provided).
> Basically, the main problem is that  
> XmlObjectBase#getElementEndingDelimiters() after having called 
> SchemaProperty#getJavaSetterDelimiter(), does not take into account that the 
> QNameSet returned by getJavaSetterDelimiter() does not yet include the "alias 
> names" - i.e. possible substitutions - of those elements that happen to be 
> heads of substitution groups.
> The patch for XmlObjectBase adds the missing substitutions to this QNameSet. 
> This will fix the base problem, but so far at the cost of performance: In 
> order to simulate a (non-existing) QNameSet iterator on the set of 
> JavaSetterDelimiters, we have not been able to find a more intelligent 
> solution than to iterate over the complete array of SchemaGlobalElements and 
> check each head of a substitution group for inclusion in the QNameSet (using 
> QNameSet#contains()). This definitely is suboptimal and should be replaced by 
> an optimized implementation done by somebody who is familiar with the 
> internals of XMLBeans. (Sorry!)
> Unfortunately, while creating the first fix, we ran into a second (small) 
> issue:
> The static method QNameSet#forArray() does mistakenly pass null instead of 
> new HashSet() to the private constructor, which results in a 
> NullPointerException. The second fix (also included in the patch) will fix 
> this problem.
> Please get back to me in case you need any additional details.
> Thanks & best regards,
> Andreas Loew & Patrik Streicher

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to