Wrong handling for IdentityConstraint for key <selector xpath=".">
------------------------------------------------------------------

                 Key: XMLBEANS-339
                 URL: https://issues.apache.org/jira/browse/XMLBEANS-339
             Project: XMLBeans
          Issue Type: Bug
          Components: XmlObject
    Affects Versions:  Version 2.3
         Environment: Windows2000 on PC.
            Reporter: jackychang


This problem existed in 2.2.0 and 2.3.0. When I create a key and keyref in 
schema like
 <xsd:element name="root">
    <xsd:complexType>
      <xsd:sequence minOccurs="1" maxOccurs="1">
        <xsd:element name="AAA" type="myAAA"/>
        <xsd:element name="BBB" type="myBBB"/>
        <xsd:element name="CCC" type="xsd:string"/>
      </xsd:sequence>
      <xsd:attribute name="id" type="xsd:string" use="required"/>
    </xsd:complexType>
    <xsd:keyref name="myIdref" refer="myId">
      <xsd:selector xpath="."/>
      <xsd:field xpath="@id"/>
    </xsd:keyref>
    <xsd:key name="myId">
      <xsd:selector xpath="."/>
      <xsd:field xpath="CCC"/>
    </xsd:key>
  </xsd:element>

  <xsd:complexType name="myAAA">
    <xsd:sequence minOccurs="1">
      <xsd:element name="a" minOccurs="1" maxOccurs="unbounded">
        <xsd:complexType>
          <xsd:sequence>
             <xsd:element name="DDD" type="xsd:string"/>
          </xsd:sequence>
          <xsd:attribute name="id" type="xsd:NCName" use="required"/>
        </xsd:complexType>
      </xsd:element>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="myBBB">
    <xsd:sequence minOccurs="1">
      <xsd:element name="b" minOccurs="1" maxOccurs="unbounded">
        <xsd:complexType>
          <xsd:attribute name="idref" type="xsd:NCName" use="required"/>
        </xsd:complexType>
      </xsd:element>
    </xsd:sequence>
  </xsd:complexType>
</xsd:schema>

The Xmlbeans validator will throw an exception said like "keyref can't find the 
key value". 

But if I use the following key and keyref definition,
    <xsd:keyref name="myIdref" refer="myId">
      <xsd:selector xpath="./CCC"/>
      <xsd:field xpath="."/>
    </xsd:keyref>
    <xsd:key name="myId">
      <xsd:selector xpath="."/>
      <xsd:field xpath="@id"/>
    </xsd:key>

Everything works well. Being curious what happen in code, I open the code and 
debug it. What I found is "IdentityConstraint.java" wrongly handle the 
keyrefstat 'remove'. IdentityConstraint build a chain of selectorstate, 
fieldstat and keyrefstate. But when handling 'addKeyValues' in keyrefstat 
remove method, the selector has no any value at all in above first case. I 
can't explain why the selector can't be assigned with correct field value, but 
it happened as it. Therefore I think you must take care of it. The following 
code piece is my modification for remove method in keyrefstate.

        void remove(Event e) {
            // First check if there are any keys at the same stack level as this
            // that may contribute key values to me
 +        Set _myvalues = new LinkedHashSet(); // define a values for 
addKeyValues to keyref
            for (ConstraintState cs = _next ; cs != null && cs != 
_elementStack._savePoint ; cs = cs._next)
            {
                if (cs instanceof SelectorState)
                {
                    SelectorState sel = (SelectorState)cs;
                    if (sel._constraint == _constraint.getReferencedKey()) {
               +        if (!sel._values.isEmpty()) // if the selector has no 
value, I must use its field value instead.
                                addKeyValues(sel._values, false);
               +        else { // sometimes selector has no values, but field 
does have!
               +                for (ConstraintState cs2 = _next; cs2 !=null && 
cs2 != _elementStack._savePoint ; cs2 = cs2._next) { 
               +                        if (cs2 instanceof FieldState) {    //  
I will find the fieldstate. If this fieldstate belongs to above selector, I 
will try to put the value to keyValues.
               +                                FieldState fie = 
(FieldState)cs2;
               +                                if (fie._selector == sel) {
               +                                        
_myvalues.add(fie._value);
               +                                }
               +                        }
               +                }
               +        }
                    }
                }
            }
                +       addKeyValues(_myvalues, false);                         
                

I'm sure if this solution is OK for your project. But it seems solve my problem 
completely. I hope you can fix this bug as soon as possible.

/zhi

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