You are viewing a plain text version of this content. The canonical link for it is here.
Posted to j-dev@xerces.apache.org by Mukul Gandhi <ga...@gmail.com> on 2009/05/30 13:06:48 UTC

SchemaGrammar.addGlobalTypeDecl gives NPE for anonymous types

Hi all,
   I am trying to enhance the Xerces XML Schema 1.1 assertions
implementation as per the latest suggestions from Khaled on the JIRA
issue, XERCESJ-1365.

While making some enhancements, I have bumped into a little problem,
for which I need help..

Below is the description of the problem, my analysis why Xerces gives
an exception (a NPE as stated below), and my questions..

I have got an element declaration as following:

<xs:element name="phonebill">
   <xs:complexType>
     <xs:sequence>
       <xs:element name="plan" type="xs:string" />
       <xs:element name="rent" type="xs:integer" />
     </xs:sequence>
     <xs:attribute name="custId" type="xs:string" />
     <xs:assert test="starts-with(@custId, 'XYZTelecom')" />
     <xs:assert test="(plan = 'A' and rent = 500) or
	              (plan = 'B' and rent = 650) or
		      (plan = 'C' and rent = 1000)" />
   </xs:complexType>
</xs:element>

You could see, that the complex type of the element, "phonebill" is anonymous.

After debugging the execution, I could see, that
Xerces generates internally the name, "#AnonType_phonebill" for this
anonymous complex type.

I am trying to create a local XSModel object for an element's content
model (not of the full schema, but am trying to build the XSModel for
this single element - phonebill in this case).

for this, I have written a code like below:

SchemaGrammar schemaGrammar = new SchemaGrammar(null, null, null,
Constants.SCHEMA_VERSION_1_1);

schemaGrammar.addGlobalElementDecl((XSElementDecl)elementPSVI.getElementDeclaration());
schemaGrammar.addGlobalTypeDecl(elementPSVI.getTypeDefinition()); //
[1] a java.lang.NullPointerException comes here
XSNotationDeclaration notationDecl = elementPSVI.getNotation();
if (notationDecl != null) {
  schemaGrammar.addGlobalNotationDecl((XSNotationDecl) notationDecl);
}

XSModel xsModel = new XSModelImpl(new SchemaGrammar[] { schemaGrammar
}); // this is the object, that I need to create

(elementPSVI is of type ElementPSVI and is populated correctly, which
is passed from the class XMLSchemaValidator.java)

When I run this code, I get a null pointer exception at location [1]
stated above.

When I further debugged the code, I could find following cause of the
null pointer exception:

null pointer exception is produced by the call,
schemaGrammar.addGlobalTypeDecl as stated above. When I look the
implementation of method, addGlobalTypeDecl in SchemaGrammar.java, I
can see that NPE is coming in the function call:

fGlobalTypeDecls.put(decl.getName(), decl);

decl.getName() in this case is null (because, we have an anonymous
type). The implementation of decl.getName() is as following:

public String getName() {
  return getAnonymous() ? null : fName;
}

(you could see, that null is returned if the type is an anonymous type)

decl.getName() being null, the call fGlobalTypeDecls.put fails

put is being implemented as follows:

public void put(Object key, Object value) {
  int bucket = (key.hashCode() & 0x7FFFFFFF) % fTableSize;

since the 'key' is null, we get a NPE (I think at the call, key.hashCode).

I need help to understand this behaviour, and want to create the
SchemaGrammar above (without NPE..)

I can think of following options:

1. I cannot do,
schemaGrammar.addGlobalTypeDecl(elementPSVI.getTypeDefinition());
if the type is an anonymous type.

It seem, *I need to do this* to have a fully populated schema.

2. To solve this issue, the implementation of getName() above could have been:

public String getName() {
  return fName;
}

So the getName call would have returned "#AnonType_phonebill" in this case.

Is the change 2. feasible to be implemented in Xerces? Does it affect
other places of Xerces code?

I have following questions:
1) Am I building the SchemaGrammar correctly? If not, what's the correct way?
2) If yes, then how do I avoid NPE in this case?


-- 
Regards,
Mukul Gandhi

---------------------------------------------------------------------
To unsubscribe, e-mail: j-dev-unsubscribe@xerces.apache.org
For additional commands, e-mail: j-dev-help@xerces.apache.org


Re: SchemaGrammar.addGlobalTypeDecl gives NPE for anonymous types

Posted by Mukul Gandhi <ga...@gmail.com>.
Hi Michael,
   Thanks for your reply.

   In XMLSchemaValidator, in handleEndElement method I am writing code
like following, for assertions processing:

ElementPSVImpl assertPSVI = new ElementPSVImpl();
assertPSVI.fDeclaration = fCurrentElemDecl;
assertPSVI.fTypeDecl = fCurrentType;
assertPSVI.fNotation = fNotation;

// set grammar ??

// construct the augmentations object for assertions.
// store assertPSVI into the augmentations
AugmentationsImpl assertAugs = new AugmentationsImpl();
assertAugs.putItem(Constants.ELEMENT_PSVI, assertPSVI);
assertionProcessor.endElement(element, assertAugs);

Then in XMLAssertPsychopathImpl (which is assertionProcessor) I do:

public void endElement(QName element, Augmentations augs) .. {
  ...

  ElementPSVI elemPSVI = (ElementPSVI)augs.getItem(Constants.ELEMENT_PSVI);
  ((PSVIElementNSImpl)currentAssertDomNode).setPSVI(elemPSVI);

  // now I need XSModel at this point

  If I do:
  XSModel fSchema =
((PSVIElementNSImpl)currentAssertDomNode).getSchemaInformation();

I can get fSchema as null, because currentAssertDomNode may not be the
root node of the XML document.

I need the XSModel for the "content model" of any element in the
original XML tree, which would be having assertion definitions. So my
grammar root may change depending where assertions are there.

It seems, as per your suggestion at,
http://markmail.org/message/zq3hrqiygu24euwi I can something like:

assertPSVI.fGrammars = fGrammarBucket.getGrammars();

at the location, // set grammar ?? above.

This *does* set the grammar. But I can see, that this is the global
grammar object (represeting the whole XML document). I cannot use it
for assertions processing, because I need the XSModel for some local
element (which could be some descendant in the XML tree).

For this, I was trying to construct a grammar from scratch as
following (as I wrote in my original mail in this thread):
// XX
SchemaGrammar schemaGrammar = new SchemaGrammar(null, null, null,
Constants.SCHEMA_VERSION_1_1);
...
...

But you are advising against this approach.

What do you suggest further to achieve, what I have described?

I have one other question please:

When I create SchemaGrammar from scratch for an element (as stated at
// XX above), I only set three things as follows:

schemaGrammar.addGlobalElementDecl (..
schemaGrammar.addGlobalTypeDecl (.. // only if the type is not anonymous
schemaGrammar.addGlobalNotationDecl (..

Do you think, these three calls are enough to complete create the
grammar for an element? Or do we need to set some other things as
well, on schemaGrammar?

On Sun, May 31, 2009 at 1:11 AM, Michael Glavassevich
<mr...@ca.ibm.com> wrote:
> Hi Mukul,
>
> Mukul Gandhi <ga...@gmail.com> wrote on 05/30/2009 07:20:37 AM:
>
>> On Sat, May 30, 2009 at 4:36 PM, Mukul Gandhi <ga...@gmail.com>
>> wrote:
>> > 1. I cannot do,
>> > schemaGrammar.addGlobalTypeDecl(elementPSVI.getTypeDefinition());
>> > if the type is an anonymous type.
>> >
>> > It seem, *I need to do this* to have a fully populated schema.
>>
>> It seems I have found the workaround (as below):
>>
>> I can do,
>>
>> XSTypeDefinition typeDef = elementPSVI.getTypeDefinition();
>> if (!typeDef.getAnonymous()) {
>>    schemaGrammar.addGlobalTypeDecl(elementPSVI.getTypeDefinition());
>> }
>>
>> So, I do .addGlobalTypeDecl only if the type is not anonymous.
>
> Right. By definition anonymous types are never global.
>
>> So in this case, an XSElementDecl has all the necessary information.
>> Therefore, the following call is sufficient for this example:
>>
>> schemaGrammar.addGlobalElementDecl((XSElementDecl)elementPSVI.
>> getElementDeclaration());
>>
>> It seems, my problem is solved. But any comments on the approach I am
>> following would be great..
>
> Well, I didn't think you need to create a new SchemaGrammar. See my note [1]
> on this from earlier in the month.
>
>> --
>> Regards,
>> Mukul Gandhi
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: j-dev-unsubscribe@xerces.apache.org
>> For additional commands, e-mail: j-dev-help@xerces.apache.org
>
> Thanks.
>
> [1] http://markmail.org/message/zq3hrqiygu24euwi
>
> Michael Glavassevich
> XML Parser Development
> IBM Toronto Lab
> E-mail: mrglavas@ca.ibm.com
> E-mail: mrglavas@apache.org
>



-- 
Regards,
Mukul Gandhi

---------------------------------------------------------------------
To unsubscribe, e-mail: j-dev-unsubscribe@xerces.apache.org
For additional commands, e-mail: j-dev-help@xerces.apache.org


Re: SchemaGrammar.addGlobalTypeDecl gives NPE for anonymous types

Posted by Michael Glavassevich <mr...@ca.ibm.com>.
Hi Mukul,

Mukul Gandhi <ga...@gmail.com> wrote on 05/30/2009 07:20:37 AM:

> On Sat, May 30, 2009 at 4:36 PM, Mukul Gandhi <ga...@gmail.com>
wrote:
> > 1. I cannot do,
> > schemaGrammar.addGlobalTypeDecl(elementPSVI.getTypeDefinition());
> > if the type is an anonymous type.
> >
> > It seem, *I need to do this* to have a fully populated schema.
>
> It seems I have found the workaround (as below):
>
> I can do,
>
> XSTypeDefinition typeDef = elementPSVI.getTypeDefinition();
> if (!typeDef.getAnonymous()) {
>    schemaGrammar.addGlobalTypeDecl(elementPSVI.getTypeDefinition());
> }
>
> So, I do .addGlobalTypeDecl only if the type is not anonymous.

Right. By definition anonymous types are never global.

> So in this case, an XSElementDecl has all the necessary information.
> Therefore, the following call is sufficient for this example:
>
> schemaGrammar.addGlobalElementDecl((XSElementDecl)elementPSVI.
> getElementDeclaration());
>
> It seems, my problem is solved. But any comments on the approach I am
> following would be great..

Well, I didn't think you need to create a new SchemaGrammar. See my note
[1] on this from earlier in the month.

> --
> Regards,
> Mukul Gandhi
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: j-dev-unsubscribe@xerces.apache.org
> For additional commands, e-mail: j-dev-help@xerces.apache.org

Thanks.>

[1] http://markmail.org/message/zq3hrqiygu24euwi

Michael Glavassevich
XML Parser Development
IBM Toronto Lab
E-mail: mrglavas@ca.ibm.com
E-mail: mrglavas@apache.org

Re: SchemaGrammar.addGlobalTypeDecl gives NPE for anonymous types

Posted by Mukul Gandhi <ga...@gmail.com>.
On Sat, May 30, 2009 at 4:36 PM, Mukul Gandhi <ga...@gmail.com> wrote:
> 1. I cannot do,
> schemaGrammar.addGlobalTypeDecl(elementPSVI.getTypeDefinition());
> if the type is an anonymous type.
>
> It seem, *I need to do this* to have a fully populated schema.

It seems I have found the workaround (as below):

I can do,

XSTypeDefinition typeDef = elementPSVI.getTypeDefinition();
if (!typeDef.getAnonymous()) {
   schemaGrammar.addGlobalTypeDecl(elementPSVI.getTypeDefinition());
}

So, I do .addGlobalTypeDecl only if the type is not anonymous.

So in this case, an XSElementDecl has all the necessary information.
Therefore, the following call is sufficient for this example:

schemaGrammar.addGlobalElementDecl((XSElementDecl)elementPSVI.getElementDeclaration());

It seems, my problem is solved. But any comments on the approach I am
following would be great..


-- 
Regards,
Mukul Gandhi

---------------------------------------------------------------------
To unsubscribe, e-mail: j-dev-unsubscribe@xerces.apache.org
For additional commands, e-mail: j-dev-help@xerces.apache.org