[ 
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]

Reply via email to