ReferenceDescription contains empty eReference [message #1649199] |
Wed, 04 March 2015 07:48 |
Bernd Hofner Messages: 68 Registered: July 2009 |
Member |
|
|
Hello,
here the short version of my problem:
I'm iterating through the each ReferenceDescription rd of each ResourceDescription r of my workspace.
When accessing the Reference described by the ResourceDescription, using rd.getEReference(),
I sometimes get the desired reference, but sometimes the returned reference is NULL.
Opening the affected resource file in the DSL editor remedies the problem -
so I gather its a problem when and how much of the underlying cache is filled/refreshed.
Can I somehow force the cache to be refreshed sufficiently deep to have the references of the
ReferenceDescriptions resolved? Using XtextResourceSet.getEObject(Source URI of my reference)
gets the desired result - but is painfully slow.
Note that I'm currently stuck with XText 1.0.2.
Has anyone here an idea?
Now the long version of the problem:
My DSL provides a CSS like mechanism that allows to declare and set named properties
which are then cascaded down the package hierarchy. On the way down, a property value
can be overridden by an equally named property.
Example:
package A {
Declare Property resultTable
Property resultTable= "Table A"
Rule A1 {
// no "Property resultTable" given
// => fall back to nearest value in scope: "Table A"
// scope resolution:
// -> Rule: no property "resultTable" defined
// -> contained in Package A: property "resultTable" is defined there => "Table A"
}
Rule A2 {
Property resultTable= "Table A1"
// Property "resultTable" is given, so the value "Table A" given on package level
// is overridden with "Table A1"
// scope resolution:
// -> Rule: property "resultTable" is defined => "Table A1"
}
}
Package A.B {
Property resultTable= "Table A.B"
Rule AB1 {
// no "Property resultTable" given
// => fall back to nearest value in scope: "Table A.B"
// scope resolution:
// -> Rule: no property "resultTable" defined
// -> contained in Package A.B: property "resultTable" is defined => "Table A.B"
}
}
Package A.C {
Rule AC1 {
// no "Property resultTable" given
// => fall back to nearest value in scope: "Table A"
// scope resolution:
// -> Rule: no property "resultTable" defined
// -> contained in Package A.C: no property "resultTable" defined
// -> contained in Package A: property "resultTable" is defined => "Table A"
}
}
When generating output from the DSL, I collect the properties and property values for a given "Rule" model element.
I do this by walking through the resource descriptions:
// We're looking for "Property" model elements
EClass eclsElement= DqlFactory.eINSTANCE.getDqlPackage().getProperty();
Provider<IResourceDescriptions> provider=
Access.getIResourceDescriptions();
Iterator<IResourceDescription> resourceDescs=
provider.get().getAllResourceDescriptions().iterator();
while(resourceDescs.hasNext())
{
IResourceDescription resourceDesc=
resourceDescs.next();
for(IReferenceDescription rd : resourceDesc.getReferenceDescriptions())
{
// !! rd.getEReference() == null if "reference cache" has not been refreshed !!
if(rd.getEReference() != null && eclsElement.equals(rd.getEReference().eContainer()))
{
EObject eProp= getResourceSet().getEObject(rd.getSourceEObjectUri(), true);
Property e= (Property)eEigenschaft;
// now collect the property and its value.
}
}
}
I found out that I can force the resolution of references like this:
EObject eReferer= getResourceSet().getEObject(rd.getSourceEObjectUri(), true);
if(eclsElement.equals(eReferer.eClass())) {
...
}
with:
private XtextResourceSet getResourceSet()
{
if(resourceSet == null)
resourceSet= new XtextResourceSet();
return resourceSet;
}
But this is painfully slow when iterating over a workspace with lots of resources.
Thanks in advance for any ideas,
Bernd
|
|
|
|
|
|
|
|
|
|
Re: ReferenceDescription contains empty eReference [message #1649812 is a reply to message #1649429] |
Wed, 04 March 2015 14:19 |
Bernd Hofner Messages: 68 Registered: July 2009 |
Member |
|
|
>Another Question: what is the entry point for the generation?
My *.xpt template starts from a given Rule (Regel) model element.
I can dump the code section on you, if it helps.
It's currently full of debug output and notes to help me get into the problem context again and discarded lanes of thought. Sorry about the mess:
I spit out messages when passing through resource files named "eigenschaften.dql" - by convention, I place the "Eigenschaft" definitions in these files - but for the final code, I don' want to rely on this convention.
One of the ideas I would try to pursue is to limit the resolution of the referenced URI (getResourceSet().getEObject() to the cases where the "chance" that I need it resoved (i.e. it points to the right kind of model element) is high. I haven't quite grasped if I find enough relevant data for such a distinction in the ReferenceDescription and the URIs.
public List<Eigenschaft> getProperties(Regel regel) {
System.out.println("Regel " + regel.getName());
// Alle Eigenschaften aus dem umgebenden Scope einsammeln.
PackageDeclaration regelPackage= (PackageDeclaration)regel.eContainer();
String regelPackageName= regelPackage.getName();
Provider<IResourceDescriptions> provider=
Access.getIResourceDescriptions();
provider.get().getAllResourceDescriptions();
Iterator<IResourceDescription> resourceDescs=
provider.get().getAllResourceDescriptions().iterator();
while(resourceDescs.hasNext())
{
IResourceDescription resourceDesc=
resourceDescs.next();
// Debug resolution of reference
/*
* Die TargetURI zeigt auf die Eigenschaftsdeklaration, die zufällig
* in der gleichen Resource steht.
* Wenn man den gesamten Cache durchsucht:
* a) Passende ResourceDescription finden:
* resourceDec.uri == targetEObj.uri."resourceUri()"
* b) In dieser ResourceDescription dann die exportierte EObjectDescription finden, die zur EObj-URI passt:
* eObjDesc.eFragment = targetEObj.uri.fragment()
* Wann diese eObjDesc dann eine EigenschaftsDeklaration ist, sollten wir die Referenz auflösen.
*
*/
/* -------------------------------- */
if(resourceDesc.getURI().toString().contains("eigenschaften.dql")) {
System.out.println("Eigenschaften: " + resourceDesc.getURI().toString());
for(IReferenceDescription rd : resourceDesc.getReferenceDescriptions()) {
Eigenschaft e= null;
if(rd.getEReference() == null) {
System.out.println(rd.getSourceEObjectUri()); // platform:/resource/DQ-DM-Doc/moVe/eigenschaften.dql#//@elements.0/@elements.1
System.out.println(rd.getTargetEObjectUri()); // platform:/resource/DQ-DM-Doc/moVe/eigenschaften.dql#//@elements.0/@elements.0
URI uri= rd.getSourceEObjectUri();
System.out.println(uri.fragment()); // //@elements.0/@elements.1
System.out.println(uri.path()); // /resource/DQ-DM-Doc/moVe/eigenschaften.dql
System.out.println(uri.scheme()); // platform
System.out.println(uri.toPlatformString(false)); // /DQ-DM-Doc/moVe/eigenschaften.dql
System.out.println(uri.toPlatformString(true)); // /DQ-DM-Doc/moVe/eigenschaften.dql
System.out.println(resourceDesc.getURI()); // platform:/resource/DQ-DM-Doc/moVe/eigenschaften.dql
for(IEObjectDescription ied : resourceDesc.getExportedObjects()) {
System.out.println(ied.getName());
System.out.println(ied.getEClass());
System.out.println(ied.getEObjectURI());
System.out.println(ied.getEObjectOrProxy());
if(ied.getEObjectURI().equals(rd.getTargetEObjectUri())) {
System.out.println(ied.getName()); // move.ErgebnisRelevanz
System.out.println(ied.getEClass()); // org.eclipse.emf.ecore.impl.EClassImpl@7804a579 (name: Eigenschaftsdeklaration) (instanceClassName: null) (abstract: false, interface: false)
System.out.println(ied.getEObjectURI()); // platform:/resource/DQ-DM-Doc/moVe/eigenschaften.dql#//@elements.0/@elements.0
}
}
/*
Iterator<IResourceDescription> rds=
provider.get().getAllResourceDescriptions().iterator();
while (rds.hasNext()) {
IResourceDescription r
}
*/
/*
Funktioniert nicht
IResourceDescription resDesc= provider.get().getResourceDescription(rd.getSourceEObjectUri());
for(IEObjectDescription objDesc : resDesc.getExportedObjects()) {
System.out.println(objDesc.getName());
}
*/
EObject eReferer= getResourceSet().getEObject(rd.getSourceEObjectUri(), true);
if(eclsElement.equals(eReferer.eClass())) {
e= (Eigenschaft)eReferer;
}
}
else if(eclsElement.equals(rd.getEReference().eContainer())) {
EObject eReferer= getResourceSet().getEObject(rd.getSourceEObjectUri(), true);
e= (Eigenschaft)eReferer;
}
if(e != null) {
System.out.println("Eigenschaft: " + e.getEigenschaft().getName() + "= " + e.getWert());
}
}
}
/* -------------------------------- */
for(IReferenceDescription rd : resourceDesc.getReferenceDescriptions())
{
// rd.getEReference().getEType() // EClass name: Eigenschaftsdeklaration
// rd.getEReference().eContainer() // EClass name: Eigenschaft
// System.out.println(rd.getEReference().getEReferenceType());
// System.out.println(rd.getEReference().getEReferenceType().getName());
Eigenschaft e= null;
if(rd.getEReference() == null) {
// slow
EObject eReferer= getResourceSet().getEObject(rd.getSourceEObjectUri(), true);
if(eclsElement.equals(eReferer.eClass())) {
e= (Eigenschaft)eReferer;
}
}
else if(eclsElement.equals(rd.getEReference().eContainer())) {
// quick
EObject eReferer= getResourceSet().getEObject(rd.getSourceEObjectUri(), true);
e= (Eigenschaft)eReferer;
}
if(e != null) {
/*
if(eReferer.eIsProxy()) {
eReferer= EcoreUtil.resolve(eReferer, eReferer.eResource());
}
*/
System.out.println("Eigenschaft: " + e.getEigenschaft().getName() + "= " + e.getWert());
collectEigenschaft(regelPackageName, e);
}
}
}
// Eigene Eigenschaften überschreiben ggf vorher eingesammlte Eigenschaften
for(Eigenschaft regelEigenschaft : regel.getProperties())
{
name2Prop.put(regelEigenschaft.getEigenschaft().getName(), regelEigenschaft);
}
// Sortiere nach Eigenschaftsname
List<Eigenschaft> scopedEigenschaften= new ArrayList<Eigenschaft>(name2Prop.values());
Collections.sort(
scopedEigenschaften,
new Comparator<Eigenschaft>() {
@Override
public int compare(Eigenschaft a, Eigenschaft b) {
return CollectorUtil.qualifiedName(a.getEigenschaft()).compareTo(
CollectorUtil.qualifiedName(b.getEigenschaft()));
}
}
);
return scopedEigenschaften;
}
|
|
|
Re: ReferenceDescription contains empty eReference [message #1649837 is a reply to message #1649812] |
Wed, 04 March 2015 14:30 |
|
that is i understood it.
you would want to have all
Property resultTable= "Table A"
in the index with the information where it is
e.g.
- Property resultTable in A
- Property resultTable in A.A2
- Property resultTable in A.B
and based on that information you can get the right IEobjectDescription
(if you store the value in the index as well you would not even need to resolve it at all)
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
|
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.04099 seconds