Have dug into this problem some more. In
DependencyGraph.getXPathRefNodesWhat(), the list of locationPaths that
ReferenceFinder builds up during the parse of the if(......) expression
contains an unncessary copy of the entire if() expression itself
(because it contains the instance function) - I'm not sure whether this
is strictly correct/desired.
This parent if() expression causes problems down the line, because it
gets evaluated as a Pointer (DependencyGraph:188) : since it points to
nothing you end up with a xpath literal ("'xxx'"), or maybe ("''")
depending on what's inside your if(). This xpath literal then gets
thrown at instance.getModelItem() (DependencyGraph:198), which causes
the ClassCastException, because it returns a pointer to a String, not a
Node (Instance:255).
The fix is minor : it's an enhancement to Instance.existsNode(), so that
when presented with an xpath literal, it returns false.
public boolean existsNode(String path) {
return countNodeset(path) > 0;
}
becomes
public boolean existsNode(String path) {
if(path == null) {
return false;
}
if(path.startsWith("'") && path.endsWith("'")) {
return false;
}
return countNodeset(path) > 0;
}
This means getModelItem("'blah'") returns null, rather than throwing a
ClassCastException.
Arguably this change is just an ambulance at the bottom of the cliff :
it doesn't address why the if() expression ends up in the
ReferenceFinder. I would suggest that ReferenceFinder.function() &
expressionPath() be modified to only add paths which contain the
instance function at the *outer* level : there's no need to add them if
it's nested inside another function, because that will be added anyway.
Otherwise you end up with a list of paths that looks like :
<regular node>
...
instance('selected-version')
instance('selected-version')/.
if(..<regular-node>...instance('selected-version')) <-- this one causes
the problem
But the change to existsNode() is simple and it appears to work, and
arguably is an improvement in it's own right.
Adrian
> -----Original Message-----
> From: chiba-users-admin-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@xxxxxxxxxxxxxxxx
> [mailto:chiba-users-admin-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@xxxxxxxxxxxxxxxx]
> On Behalf Of
> Adrian Baker
> Sent: Wednesday, 16 March 2005 8:34 a.m.
> To: Victor Engmark
> Cc: chiba-users-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@xxxxxxxxxxxxxxxx
> Subject: RE: [Chiba-users] [ 1023227 ] misbehaviour of
> instance() function : workaround
>
>
> It seems like the problem still exists (as of 1.0 anyway),
> but is specific to instance() within an if(). The exception is :
>
> Caused by: org.chiba.xml.xforms.exception.XFormsException:
> java.lang.ClassCastException: java.lang.String
> at org.chiba.xml.xforms.Container.dispatch(Container.java:492)
> at org.chiba.xml.xforms.Model.modelConstruct(Model.java:709)
> at org.chiba.xml.xforms.Model.performDefault(Model.java:594)
> at
> org.chiba.xml.xforms.XFormsDocument.performDefault(XFormsDocum
> ent.java:1
> 72)
> at
> org.chiba.xml.xforms.XFormsDocument.dispatchEvent(XFormsDocume
> nt.java:15
> 5)
> at
> org.apache.xerces.dom.NodeImpl.dispatchEvent(NodeImpl.java:757)
> at org.chiba.xml.xforms.Container.dispatch(Container.java:470)
> at org.chiba.xml.xforms.Container.initModels(Container.java:682)
> at org.chiba.xml.xforms.Container.init(Container.java:350)
> at org.chiba.xml.xforms.ChibaBean.init(ChibaBean.java:521)
> at
> org.chiba.adapter.web.ServletAdapter.init(ServletAdapter.java:193)
> at
> com.orchestral.forms.web.adapter.chiba.ChibaDisplayAdapter.cre
> ateAdapter
> (ChibaDisplayAdapter.java:143)
> at
> com.orchestral.forms.web.adapter.chiba.ChibaDisplayAdapter.dis
> playForm(C
> hibaDisplayAdapter.java:110)
> ... 33 more
> Caused by: java.lang.ClassCastException: java.lang.String
> at org.chiba.xml.xforms.Instance.getModelItem(Instance.java:255)
> at
> org.chiba.xml.xforms.constraints.DependencyGraph.getXPathRefNo
> des(Depend
> encyGraph.java:198)
> at
> org.chiba.xml.xforms.constraints.MainDependencyGraph.addReferr
> edNodesToG
> raph(MainDependencyGraph.java:166)
> at
> org.chiba.xml.xforms.constraints.MainDependencyGraph.buildBind
> Graph(Main
> DependencyGraph.java:234)
> at org.chiba.xml.xforms.Model.rebuild(Model.java:459)
> at org.chiba.xml.xforms.Model.performDefault(Model.java:635)
> at
> org.chiba.xml.xforms.XFormsDocument.performDefault(XFormsDocum
> ent.java:1
> 72)
> at
> org.chiba.xml.xforms.XFormsDocument.dispatchEvent(XFormsDocume
> nt.java:15
> 5)
> at
> org.apache.xerces.dom.NodeImpl.dispatchEvent(NodeImpl.java:757)
> at org.chiba.xml.xforms.Container.dispatch(Container.java:470)
> ... 45 more
>
> > -----Original Message-----
> > From: Victor Engmark [mailto:victor.engmark-vJEk5272eHo@xxxxxxxxxxxxxxxx]
> > Sent: Tuesday, 15 March 2005 10:33 p.m.
> > To: Adrian Baker
> > Cc: chiba-users-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@xxxxxxxxxxxxxxxx
> > Subject: Re: [Chiba-users] [ 1023227 ] misbehaviour of
> > instance() function : workaround
> >
> >
> > Adrian Baker wrote:
> >
> > >Would anyone be able to offer a hint as to how the
> > workaround for this
> > >bug works ?
> > >
> > >From the bug summary :
> > >
> > ><quote>
> > >
> > > misbehaviour of instance() function
> > >An instance() function is only safely used at the start
> > >of a XPath
> > >expression. Anywhere else it might give errors.
> > >
> > >Example:
> > >
> > >xforms:if( portal:exists(/data/record), instance('test')/data/one,
> > >ata/two )
> > >
> > >This line gives an error: Chiba tries to strip the 1st
> > >instance() function.
> > >The code actually throws an "Index out of bounds"
> > >exception. Because it
> > >removes the text between "instance('" and ")". The
> > >first occurence of ")" is
> > >before "instance()".
> > >
> > >As a workaround: always place an extra instance()
> > >function at the start.
> > >
> > ></quote>
> > >
> > >We've got a similar expression which has an instance()
> > within an if(),
> > >which seems to trigger the problem :
> > >
> > ><xforms:bind id="versionUrl" calculate="
> > > if(not(true()),
> > >
> > >concat('sampleVersionedConsentQuestionnaireWorkflow?editable=
> > false&
> > >c
> > >onsumerId=', consentupdates/consentupdate/consumerId,
> > >'&versionNumber=',
> instance('selected-version')/selectedVersion),
> > >
> > >concat('sampleConsentQuestionnaireWorkflow?consumerId=',
> > >consentupdates/consentupdate/consumerId)
> > > )
> > > "/>
> > >
> > >I'm just not sure what "always place an extra instance()
> function at
> > >the start" means.. ?
> > >
> > >
> >
> > Hello,
> >
> > This bug
> > <http://sourceforge.net/tracker/index.php?func=detail&aid=1023
> 227&group_id=20274&atid=120274>
> was filed September last year, and it seems to have been fixed. Check
> the first comment, which was filed by me. I'm no expert, but
> I've been
> using quite a lot of instance references in my XForms, and they have
> worked fine after ironing out the XPath errors.
>
> To debug your calculation, it would be useful to know the debug
> information of Chiba relating to the error. Most importantly, which
> error do you get?
>
> --
> Victor Engmark
> "Quid quid latine dictum sit, altum viditar" - "What is said
> in latin,
> sounds profound"
>
>
> -------------------------------------------------------
> SF email is sponsored by - The IT Product Guide
> Read honest & candid reviews on hundreds of IT Products from
> real users. Discover which products truly live up to the
> hype. Start reading now.
> http://ads.osdn.com/?ad_ide95&alloc_id396&op=ick
> _______________________________________________
> Chiba-users mailing list
> Chiba-users-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@xxxxxxxxxxxxxxxx
> https://lists.sourceforge.net/lists/listinfo/chiba-users
>
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_ide95&alloc_id396&op=click
|