|
Hi Ed,
Many thanks for your comments and suggestions. I
have attached a partial project containing a schema that illustrates the kind of
keyref patterns that I have encountered - they are a fairly simple
subset.
I was originally thinking in terms of a
metamodel-driven implementation (generative or reflective) but given
your suggestions I did try overriding the
Resource.getURIFragment(EObject) and InternalEObject.eResolveProxy(InternalEObject)
methods to store/resolve the specific keys. The attached code just about
works but it turned into the most hideous kludge ;-(
It's hard to state categorically what a usable
subset of key/keyref functionality might be in the general sense but it does
seem to me that EReference.eKeys() might do the trick if there was an option to
tell it to use a single bare key value for same-doc references rather than a
hierarchical URI fragment path. BTW given the experience of writing the attached
code I rather suspect that the issue would be resolving key values rather
than computing them.
Renewed thanks, and best regards,
Adrian.
Adrian,
Comments
below.
Adrian Price wrote:
Good day,
First, my apologies for the length of this posting; I've tried to be
concise.
People often accuse me of being to verbose, but I figure
it's good to cover all the important details.
My last two EMF consulting engagements have involved the use of EMF in
conjunction with published application schemas bearing XSD unique/key-keyref
constraints on non-containment references, which EMF does not currently
support. Use of xsd:ID would have imposed an unacceptably restrictive
document-wide key uniqueness constraint. The net result is a rather
less-than-usable generated model API with such references represented as
string-type EAttributes rather than typesafe EReferences. Consequently,
clients require hand-cranked key<-->object accessor/lookup code and JFace
viewers, data binding support, etc. cannot readily be used.
The problem is that the full generality of this
constructs in schema don't map well into simple concepts...
Now, you can add ecore:reference attributes to the schema xsd:attribute,
which causes XSD2Ecore to import the attribute as an EReference, but that
does not solve the problem because EMF still uses the positional URI
fragment segment syntax. Adding ecore:keys attributes doesn't help either,
because EMF's //@<feature>[<key>='<value>'] syntax differs from the plain
key value syntax implied by XSD keyref@field. Yes, the value
for a keyref is really more like an ID with a more localized scope.
I could not find an easy way
to override fragment generation or lookup (because neither Resource
getURIFragment(EObject) nor getEObject(String) pass the EReference context).
Yep. That's why we can't produce "relative fragment
paths either".
Also, JET2 has a fully functional XPath implementation that can navigate EMF
models. It seems to need ExtendedMetaData annotations in the domain
meta-model to map the XPath element and attribute references to Ecore
EReferences or EAttributes (XSD2Ecore imports these annotations
automatically). I saw this as a potential basis for evaluating key scopes to
support key lookup and validation.
There are callbacks on the owner of the proxy, so that
potentially a hook at which to resolve such proxies relative to the owner.
public EObject eResolveProxy(InternalEObject
proxy) { return EcoreUtil.resolve(proxy,
this); }
And you could specialize
Resource.getURIFragment with the assumption that the reference objects will
only be referenced in a way that can use some local attributes as the key.
Ed Merks stated in dnu9m6$c4e$1@xxxxxxxxxxxxxxxx (Dec' 05):
Yes, there is no support for key/keyref and no short term plans to add
it. There really aren't even long term plans to add it. The whole
design is just so XML-centric and maps so very poorly at the metadata
level. There's very little you can do with the fully general XPath
expressions until you have instance data to match it against. I.e.,
there is no requirement that the referenced ElementB has an @AttrA in
the schema, only that the instances have such an attribute, but each
instance could be a different complex type instance with a different
version of @AttrA of a different type even. It's kind of a mess, in my
opinion...
Ed's comments seem to suggest that it would not be possible for EMF codegen
to generate key-keyref constraints into 'minimally reflective' methods. Even
so, I'm wondering whether a reflective/interpretive approach might be
feasible given the existence of JET2's EMF XPath support. My guess is that
the performance hit on load/save would be an acceptable tradeoff against the
enhanced client API.
Finally, my research turned up the following reference:
http://www.priorartdatabase.com/IPCOM/000157944/ ("Modeling XSD:key and
XSD:keyref Using EMF"). From the (incomplete) text it looks as if someone at
IBM has looked at the issue and actually come up with at least a design, if
not an implementation. Does anyone have any information on this?
No one ever discussed writing a disclosure with me.
Of course I help folks all the time and I'm never sure what they go off and do
with the information I share freely.
I'd be interested if anyone has thoughts on this topic.
Given that there is a decent hook for which "relative
fragment" paths could be evaluated (both in BasicEObject and perhaps in in the
EcoreUtil method I suspect the trickiest issue is how get XML serialization to
generate such a thing. It would be interesting to see some real
world examples (or facsimiles there of) of scenarios you've encountered.
As I said before, the full generality is kind of a little much, but I'll bet
the real world use cases are far simpler and might be supportable with a few
simple annotations. So if you would care to share some
examples/scenarios, I could give some thought to how such patterns might be
supported. Perhaps open a bugzilla feature request and attach examples
there and we can discuss some possible approaches.
Thanks,
Adrian Price
TIBCO Software, Inc.
|