| [news.eclipse.tools.emf] Re: Complex EMF Query for a "Simple Query" |
Hello Christian,
Thanks a lot.
I managed to reduce some of my condition objects based on your input. The code now looks like this (and as you said - simple)
EObjectCondition authorCondition = new EObjectCondition() {
@Override
public boolean isSatisfied(EObject object) {
//Removed reflection for simplicity
if (object instanceof Writer)
if (((Writer) object).getBooks().size() > 10)
return true;return false; } };
SELECT select = new SELECT(new FROM(selectedEObjects), new WHERE( authorCondition));
Thanks Nirmal
Hi, Nirmal,
You're right, it shouldn't have to be so complicated, and I don't think it actually is.
I think you can do this query with two one objects. Create a subclass of the EObjectStructuralFeatureCondition. By default, this condition matches objects that have the feature (meaning not that they have values for the feature, but that the feature is available/defined for their EClasses). In your subclass, extend the isSatisfied(EObject) method to check the size of the feature's value list (by extend, I mean do your additional check if super returns true).
That should do it.
Your scenario raises a good point: the API currently is missing a framework for aggregate functions on multi-valued features. It would have been nice to be able to create an EObjectReferenceValueCondition with a COUNT aggregate function object. The current EObjectReferenceValueCondition (like EObjectAttributeValueCondition) only knows how to evaluate a condition on the individual collection elements with a "forAll" or "exists" quantifier. COUNT would mix nicely with the NumberCondition class ...
That would make a great contribution :-D
Cheers,
Christian
On Thu, 2009-05-07 at 07:43 +0000, Nirmal Sasidharan wrote:Hello,
I am playing around with EMF Query currently. I wanted to write a simple query based on the Extended Library Model.
SELECT Authors FROM Library WHERE COUNT(Authors.Books) > 10
I ended up writing a query like this. Would like to know if there is a simpler way of doing this.
EObjectCondition adaptedCondition = new EObjectCondition(){
@Override
public boolean isSatisfied(EObject object) {
if (object.eClass().equals(EXTLibraryPackage.eINSTANCE.getWriter())) {
if (((EList)object.eGet(EXTLibraryPackage.eINSTANCE.getWriter_Books())).size() > 10)
return true;
}
return false;
}
};
EObjectCondition contextCondition = new EObjectTypeRelationCondition( EXTLibraryPackage.eINSTANCE.getWriter());
EObjectCondition valueCondition = new EObjectReferenceValueCondition( EXTLibraryPackage.eINSTANCE.getBook_Author(), adaptedCondition);
EObjectCondition masterCondition = new EObjectReferenceValueCondition(
contextCondition,
EXTLibraryPackage.eINSTANCE.getWriter_Books(), valueCondition);
What I find funny is the fact that, I started with Writer as the context (because this is what I want to return). Then I get the Books of the Writer, then the Writer of the Books, then the Books of the writer again. Arrrrg.... Has to be a better way.
Thanks in advance,
Nirmal