[
https://issues.apache.org/jira/browse/XERCESJ-1279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12657413#action_12657413
]
Bill Michell commented on XERCESJ-1279:
---------------------------------------
A little more analysis:
The problem is with substitution groups, and appears to be related to an
oprdering issue within the schema file.
The fundamental problem is in SubstitutionGroyupHandler.java
Hashtable fSubGroupsB is used to store two different types of values. It can
either store Vectors, which hold all elements that claim to have the named
element as their affiliation or - in what seems to be an optimisation - an
array, which caches the calculated value of all elements which could be part of
the group, including indirectly affiliated members. The comments and the code
are rather conflicted about whether this array includes the effects of any
blocked elements.
The problem is that addSubstitutionGroup() assumes that the Hashtable will
always contain the raw Vector, whereas getSubGroupB will at the slightest
provocation swap any vector it finds for the calculated array.
If all the addSubstituitionGroup calls are made before the first getSubGroupB
call is made, then all proceeds normally. However, any addSubstitutionGroup
call made after the first getSubGroupB for the element concerned will always
fail with the ClassCastException.
The following change to the addSubstitutionGroup() method makes the exception
go away, but I'm really unclear about what other side effects may transpire -
particularly in regard to blocked element handling... Note that this code also
uses the new for(Object:Array) construct, which is why I haven't bothered to
prepare it as a patch...
public void addSubstitutionGroup(XSElementDecl[] elements) {
XSElementDecl subHead, element;
Vector subGroup;
// for all elements with substitution group affiliation
for (int i = elements.length-1; i >= 0; i--) {
element = elements[i];
subHead = element.fSubGroup;
// check whether this an entry for this element
Object previousEntry = fSubGroupsB.get(subHead);
if (previousEntry instanceof OneSubGroup[]) {
OneSubGroup[] previousArray=(OneSubGroup[])
previousEntry;
Vector temp=new Vector();
for (OneSubGroup group:previousArray) {
temp.add(group);
}
previousEntry=temp;
}
subGroup = (Vector)previousEntry;
if (subGroup == null) {
// if not, create a new one
subGroup = new Vector();
fSubGroupsB.put(subHead, subGroup);
}
// add to the vector
subGroup.addElement(element);
}
}
> ClassCastException in SubstitutionGroupHandler.addSubstitutionGroup() during
> Document.normalize()
> -------------------------------------------------------------------------------------------------
>
> Key: XERCESJ-1279
> URL: https://issues.apache.org/jira/browse/XERCESJ-1279
> Project: Xerces2-J
> Issue Type: Bug
> Components: XML Schema 1.0 Structures
> Affects Versions: 2.9.1
> Environment: Windows, Sun JRE 1.6.00_03
> Reporter: Bill Michell
> Assignee: Arthur De Magalhaes
> Attachments: ContentComponents.xsd, Crash.java, iCI.xsd, test.xml,
> test.xsd
>
>
> Change 319073 introduced the class SubstitutionGroupHandler$OneSubGroup and
> the Hashtable fSubGroupB
> According to the documentation, the field has the following characteristics:
> // to store substitution group information
> // the key to the hashtable is an element decl, and the value is
> // - a Vector, which contains all elements that has this element as their
> // substitution group affilication
> // - an array of OneSubGroup, which contains its substitution group
> before block.
> Unfortuntately, addSubstitutionGroup() contains the following line:
> subGroup = (Vector)fSubGroupsB.get(subHead);
> This fails with a ClassCastException if the value for the key passed turns
> out to be a OneSubGroup[]
> The following lines of getSubGroupB() appear to ensure that a OneSubGroup[]
> is in the map:
> // Convert to an array
> OneSubGroup[] ret = new OneSubGroup[newGroup.size()];
> for (int i = newGroup.size()-1; i >= 0; i--) {
> ret[i] = (OneSubGroup)newGroup.elementAt(i);
> }
> // Store the potential sub group
> fSubGroupsB.put(element, ret);
>
>
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]