ReferenceDescription contains empty eReference [message #1649199] |
Wed, 04 March 2015 02:48  |
Eclipse User |
|
|
|
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 09:19   |
Eclipse User |
|
|
|
>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 #1654214 is a reply to message #1651282] |
Fri, 06 March 2015 10:38  |
Eclipse User |
|
|
|
I soved the problem now using the following quick and dirty approach:
Iterate over the ResourceDescriptions and collect the EObjectURI of all exported objects of the "type" "Deklariere Eigenschaft" in a hashset.
Iterate over the ResourceDescriptions, collecting the contained IResourceDescriptions that have a targetEObjectUri that is in the previously collected hashmap.
The sourceEObjectUri of such a IResourceDescription then points to an Eigenschaft model element.
This works reasonably fast and reliable.
Nevertheless I'll have a look how to enrich the index with the desired user data.
|
|
|
Powered by
FUDForum. Page generated in 0.24548 seconds