[292939] Improve the performance of metadata query
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/IMetaDataModelMergeAssistant.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/IMetaDataModelMergeAssistant.java
index d579a63..0a6a341 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/IMetaDataModelMergeAssistant.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/IMetaDataModelMergeAssistant.java
@@ -30,10 +30,10 @@
* Method that will first check to see if an entity with the same id exists in the merged model.
* If not, it will add it. The entities includeGroups are then also merged.
* @param entity
- * @return flag indicating whether or not the entity was new and therefore added to the merged model
+ * @return the merged model entity
*
*/
- public boolean addEntity(Entity entity);
+ public Entity addEntity(Entity entity);
/**
* Method will add an entity if not already existing in the merged model, and then check for an existing trait by id on the merged model's entity.
* @param entity
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/MetaDataModelMergeAssistantImpl.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/MetaDataModelMergeAssistantImpl.java
index 49f9aa4..0c53521 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/MetaDataModelMergeAssistantImpl.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/MetaDataModelMergeAssistantImpl.java
@@ -51,7 +51,7 @@
* Constructor. Queries with search control limited to first found.
* @param model
*/
- public MetaDataModelMergeAssistantImpl(MetaDataModel model) {
+ public MetaDataModelMergeAssistantImpl(final MetaDataModel model) {
this.mergedModel = model;
entityVisitor = new SimpleEntityQueryVisitorImpl(new HierarchicalSearchControl(1,
HierarchicalSearchControl.SCOPE_ALL_LEVELS));
@@ -72,7 +72,7 @@
return provider;
}
- public void setSourceModelProvider(IMetaDataSourceModelProvider provider) {
+ public void setSourceModelProvider(final IMetaDataSourceModelProvider provider) {
this.provider = provider;
}
@@ -80,8 +80,8 @@
/* (non-Javadoc)
* @see org.eclipse.jst.jsf.common.metadata.internal.IMetaDataModelMergeAssistant#addEntityGroup(org.eclipse.jst.jsf.common.metadata.EntityGroup)
*/
- public void addEntityGroup(EntityGroup entityGroup) {
- Model model = (Model)getMergedModel().getRoot();
+ public void addEntityGroup(final EntityGroup entityGroup) {
+ final Model model = (Model)getMergedModel().getRoot();
if (!isExistingEntityGroup(model, entityGroup)){
model.getEntityGroups().add(entityGroup);
}
@@ -90,17 +90,17 @@
/* (non-Javadoc)
* @see org.eclipse.jst.jsf.common.metadata.internal.IMetaDataModelMergeAssistant#addEntity(org.eclipse.jst.jsf.common.metadata.Entity)
*/
- public boolean addEntity(final Entity entity) {
+ public Entity addEntity(final Entity entity) {
Entity mmEntity = getMergedEntity(entity);
if (mmEntity == null){
- addEntityAsNecessary((Entity)entity.eContainer(), entity);
- return true;
+ mmEntity = addEntityAsNecessary((Entity)entity.eContainer(), entity);
+ return mmEntity;
}
addIncludeGroupsAsNecessary(mmEntity, entity);
- return false;
+ return mmEntity;
}
- public Entity getMergedEntity(Entity queryRoot, String entityKey){
+ public Entity getMergedEntity(final Entity queryRoot, final String entityKey){
Entity ret = null;
SimpleResultSet rs = (SimpleResultSet)entityVisitor.findEntities(queryRoot, entityKey);
try {
@@ -113,11 +113,11 @@
return ret;
}
private void addIncludeGroupsAsNecessary(final Entity mmEntity, final Entity entity) {
- for (Iterator it=entity.getIncludeGroups().iterator();it.hasNext();){
- IncludeEntityGroup grp = (IncludeEntityGroup)it.next();
+ for (final Iterator it=entity.getIncludeGroups().iterator();it.hasNext();){
+ final IncludeEntityGroup grp = (IncludeEntityGroup)it.next();
boolean found = false;
for (Iterator it2=mmEntity.getIncludeGroups().iterator();it2.hasNext();){
- IncludeEntityGroup grp2 = (IncludeEntityGroup)it2.next();
+ final IncludeEntityGroup grp2 = (IncludeEntityGroup)it2.next();
if (grp2.equals(grp)){
found = true;
break;
@@ -154,9 +154,9 @@
return mmEntity;
}
- private boolean isExistingEntityGroup(Model model, EntityGroup entityGroup) {
+ private boolean isExistingEntityGroup(final Model model, final EntityGroup entityGroup) {
boolean found = false;
- for(Iterator it=model.getEntityGroups().iterator();it.hasNext();){
+ for(final Iterator it=model.getEntityGroups().iterator();it.hasNext();){
if (entityGroup.getId().equals(((EntityGroup)it.next()).getId()))
return true;
}
@@ -164,8 +164,8 @@
}
private Entity getExistingChildEntity(final Entity parent, final Entity entity) {
- for(Iterator it=parent.getChildEntities().iterator();it.hasNext();){
- Entity foundEntity = (Entity)it.next();
+ for(final Iterator it=parent.getChildEntities().iterator();it.hasNext();){
+ final Entity foundEntity = (Entity)it.next();
if (entity.getId().equals(foundEntity.getId()))
return foundEntity;
}
@@ -173,8 +173,8 @@
}
private /*synchronized*/ Entity addEntityInternal(final Entity parent, final Entity entity) {
- Copier copier = new Copier();
- Entity mmEntity =(Entity)copier.copy(entity);
+ final Copier copier = new Copier();
+ final Entity mmEntity =(Entity)copier.copy(entity);
copier.copyReferences();
parent.getChildEntities().add(mmEntity);
return mmEntity;
@@ -183,8 +183,8 @@
/* (non-Javadoc)
* @see org.eclipse.jst.jsf.common.metadata.internal.IMetaDataModelMergeAssistant#addTrait(org.eclipse.jst.jsf.common.metadata.Entity, org.eclipse.jst.jsf.common.metadata.Trait)
*/
- public boolean addTrait(Entity entity, Trait trait) {
- Entity returnedEntity = getMergedEntity(entity);
+ public boolean addTrait(final Entity entity, final Trait trait) {
+ final Entity returnedEntity = getMergedEntity(entity);
if (returnedEntity != null){
return addTraitAsNecessary(returnedEntity, trait);
}
@@ -193,7 +193,7 @@
private boolean addTraitAsNecessary(Entity mergedEntity, Trait trait) {
- Trait mmTrait = getMergedTrait(mergedEntity, trait);
+ final Trait mmTrait = getMergedTrait(mergedEntity, trait);
if (mmTrait == null){
addTraitInternal(mergedEntity, trait);
return true;
@@ -206,7 +206,7 @@
* @see org.eclipse.jst.jsf.common.metadata.internal.IMetaDataModelMergeAssistant#setMergeComplete()
*/
public void setMergeComplete() {
- Model model = (Model)getMergedModel().getRoot();
+ final Model model = (Model)getMergedModel().getRoot();
if (model != null){
StandardModelFactory.debug(">> Begin processIncludeGroups for: "+getMergedModel().getModelKey(),StandardModelFactory.DEBUG_MD_LOAD); //$NON-NLS-1$
@@ -226,8 +226,8 @@
* @return merged Trait
*/
private Trait addTraitInternal(final Entity parent, final Trait trait) {
- Copier copier = new Copier();
- Trait mmTrait =(Trait)copier.copy(trait);
+ final Copier copier = new Copier();
+ final Trait mmTrait =(Trait)copier.copy(trait);
copier.copyReferences();
parent.getTraits().add(mmTrait);
//set the model key to know from where the trait came
@@ -242,13 +242,13 @@
* @param entity
* @return merged entity
*/
- private Entity getMergedEntity(Entity entity){
+ private Entity getMergedEntity(final Entity entity){
if (entity instanceof Model)
return (Entity)mergedModel.getRoot();
Entity ret = null;
- String entityKey = getIdRelativeToRoot(entity);
- SimpleResultSet rs = (SimpleResultSet)entityVisitor.findEntities((Entity)mergedModel.getRoot(), entityKey);
+ final String entityKey = getIdRelativeToRoot(entity);
+ final SimpleResultSet rs = (SimpleResultSet)entityVisitor.findEntities((Entity)mergedModel.getRoot(), entityKey);
try {
if (! rs.getResults().isEmpty())
ret = (Entity)rs.getResults().get(0);
@@ -261,7 +261,7 @@
private String getIdRelativeToRoot(final Entity entity) {
Entity e = entity;
- StringBuffer buf = new StringBuffer();
+ final StringBuffer buf = new StringBuffer();
while (e.eContainer() != null){
buf.insert(0, e.getId());
if (e.eContainer()!=null && e.eContainer().eContainer() != null)
@@ -279,8 +279,8 @@
* @param trait
* @return merged Trait
*/
- public Trait getMergedTrait(Entity entity, Trait trait){
- SimpleResultSet rs = (SimpleResultSet)traitVisitor.findTraits(entity, trait.getId());
+ public Trait getMergedTrait(final Entity entity, final Trait trait){
+ final SimpleResultSet rs = (SimpleResultSet)traitVisitor.findTraits(entity, trait.getId());
Trait ret = null;
try {
if (! rs.getResults().isEmpty())
@@ -305,14 +305,14 @@
private void doIncludes(final Entity entity){
for (int j=0, groupsSize=entity.getIncludeGroups().size();j<groupsSize; j++){
- IncludeEntityGroup include = (IncludeEntityGroup)entity.getIncludeGroups().get(j);
+ final IncludeEntityGroup include = (IncludeEntityGroup)entity.getIncludeGroups().get(j);
if (include.getId() != null){
//is this a local merge?
if (include.getModelUri() == null||
(include.getModelUri()
.equals(getMergedModel()
.getModelKey().getUri())) ){
- EntityGroup eg = ((Model)getMergedModel().getRoot()).findIncludeGroup(include.getId());
+ final EntityGroup eg = ((Model)getMergedModel().getRoot()).findIncludeGroup(include.getId());
addIncludeRefs(entity, eg);
} else //external model include
addIncludeRefs(entity, include);
@@ -325,15 +325,15 @@
* @param include
*/
private void addIncludeRefs(final Entity entity, final IncludeEntityGroup include) {
- ITaglibDomainMetaDataModelContext modelContext = new TaglibDomainMetaDataModelContextImpl(
+ final ITaglibDomainMetaDataModelContext modelContext = new TaglibDomainMetaDataModelContextImpl(
getMergedModel().getModelKey().getDomain(),
getMergedModel().getModelKey().getProject(),
include.getModelUri()
);
- Model externalModel = TaglibDomainMetaDataQueryHelper.getModel(modelContext);
+ final Model externalModel = TaglibDomainMetaDataQueryHelper.getModel(modelContext);
if (externalModel != null){
- EntityGroup entityGroup = externalModel.findIncludeGroup(include.getId());
+ final EntityGroup entityGroup = externalModel.findIncludeGroup(include.getId());
addIncludeRefs(entity, entityGroup);
}
else {
@@ -362,15 +362,15 @@
}
private void traverseAndAddIncludes(final Entity parent, final Entity entity){
- Entity mergedEntity = addIncludedEntityAsNecessary(parent, entity);
+ final Entity mergedEntity = addIncludedEntityAsNecessary(parent, entity);
for (final Iterator/*<Trait>*/ it=entity.getTraits().iterator();it.hasNext();){
- Trait trait = (Trait)it.next();
+ final Trait trait = (Trait)it.next();
addTraitAsNecessary(mergedEntity, trait);
}
for (final Iterator/*<EntityKey>*/ it=entity.getChildEntities().iterator();it.hasNext();){
- Entity e = (Entity)it.next();
+ final Entity e = (Entity)it.next();
traverseAndAddIncludes(mergedEntity, e);//add as normal
}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/StandardMetaDataFilesTranslator.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/StandardMetaDataFilesTranslator.java
index f9869ff..6695ec5 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/StandardMetaDataFilesTranslator.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/StandardMetaDataFilesTranslator.java
@@ -29,25 +29,25 @@
*/
public class StandardMetaDataFilesTranslator implements IMetaDataTranslator {
- public boolean canTranslate(IMetaDataSourceModelProvider modelProvider) {
+ public boolean canTranslate(final IMetaDataSourceModelProvider modelProvider) {
if (modelProvider instanceof StandardMetaDataFilesProvider)
return true;
return false;
}
- public void translate(IMetaDataModelMergeAssistant assistant) {//TODO: throw proper errors
+ public void translate(final IMetaDataModelMergeAssistant assistant) {//TODO: throw proper errors
//null translate - sourceModel object are already Entities and traits
//traverse the tree and add to model
//temp - throw proper errors
//assert assistant.getSourceModel() instanceof ModelKeyDescriptor;
- MetaDataModel mm = assistant.getMergedModel();
- Model mk = (Model)assistant.getSourceModelProvider().getSourceModel();
+ final MetaDataModel mm = assistant.getMergedModel();
+ final Model mk = (Model)assistant.getSourceModelProvider().getSourceModel();
if (mm.getRoot() == null) {
//create copy, otherwise source model becomes merged model because of reference
- Copier copier = new Copier();
- Model newModel = (Model)copier.copy(mk.getModel());
+ final Copier copier = new Copier();
+ final Model newModel = (Model)copier.copy(mk.getModel());
copier.copyReferences();
mm.setRoot(newModel);
}
@@ -66,23 +66,23 @@
* @param assistant
* @param entity
*/
- protected void traverseAndAdd(IMetaDataModelMergeAssistant assistant, final Entity entity){
- assistant.addEntity(entity);
+ protected void traverseAndAdd(final IMetaDataModelMergeAssistant assistant, final Entity entity){
+ final Entity mmEntity = assistant.addEntity(entity);
if (entity instanceof Model){
- Model model = (Model)entity;
+ final Model model = (Model)entity;
for (final Iterator/*EntityGroup*/ it=model.getEntityGroups().iterator();it.hasNext();){
assistant.addEntityGroup((EntityGroup)it.next());
}
}
for (final Iterator/*<Trait>*/ it=entity.getTraits().iterator();it.hasNext();){
- Trait trait = (Trait)it.next();
- assistant.addTrait(entity, trait);
+ final Trait trait = (Trait)it.next();
+ assistant.addTrait(mmEntity, trait);
}
for (final Iterator/*<EntityKey>*/ it=entity.getChildEntities().iterator();it.hasNext();){
- Entity e = (Entity)it.next();
+ final Entity e = (Entity)it.next();
traverseAndAdd(assistant, e);
}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/impl/EntityImpl.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/impl/EntityImpl.java
index da0f6ee..ab8247d 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/impl/EntityImpl.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/impl/EntityImpl.java
@@ -2,7 +2,7 @@
* <copyright>
* </copyright>
*
- * $Id: EntityImpl.java,v 1.7 2008/11/18 22:24:39 gkessler Exp $
+ * $Id: EntityImpl.java,v 1.8 2010/01/27 23:54:32 gkessler Exp $
*/
package org.eclipse.jst.jsf.common.metadata.internal.impl;
@@ -26,6 +26,7 @@
import org.eclipse.jst.jsf.common.metadata.Model;
import org.eclipse.jst.jsf.common.metadata.Trait;
import org.eclipse.jst.jsf.common.metadata.query.IEntityVisitor;
+import org.eclipse.jst.jsf.common.metadata.query.internal.IHierarchicalEntityVisitor;
/**
* <!-- begin-user-doc -->
@@ -231,36 +232,52 @@
* <!-- end-user-doc -->
* @generated NOT
*/
- public void accept(IEntityVisitor visitor) {
- if (visitor.stopVisiting())
- return;
- visitor.visit(this);
-
+ private boolean accept(final IHierarchicalEntityVisitor visitor) {
+ if (visitor.visitEnter( this )) {
+ acceptChildren(visitor);
+ }
+ return visitor.visitLeave(this);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated NOT
+ */
+ public void accept(final IEntityVisitor visitor) {
+ if (visitor instanceof IHierarchicalEntityVisitor) {
+ accept((IHierarchicalEntityVisitor)visitor);
+ }
+ else {
+ if (visitor.stopVisiting())
+ return;
+
+ visitor.visit(this);
+ if (visitor.stopVisiting())
+ return;
+
+ acceptChildren(visitor);
+
+ visitor.visitCompleted(this);
+ }
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated NOT
+ */
+ private void acceptChildren(final IEntityVisitor visitor) {
if (!getChildEntities().isEmpty()){
- for (Iterator/*<Entity>*/ it = getChildEntities().iterator(); it.hasNext();){
- Entity k = (Entity)it.next();
+ for (final Iterator/*<Entity>*/ it = getChildEntities().iterator(); it.hasNext();){
+ final Entity k = (Entity)it.next();
k.accept(visitor);
if (visitor.stopVisiting())
return;
}
}
-// if (!getIncludeGroups().isEmpty()){
-// for (Iterator/*<IncludeEntityGroup>*/ it = getIncludeGroups().iterator(); it.hasNext();){
-// IncludeEntityGroup entityGroup = (IncludeEntityGroup)it.next();
-// Model m = getModel(entityGroup);
-// if (m != null){
-// Entity k = m.findIncludeGroup(entityGroup.getId());
-// if (k != null){
-// k.accept(visitor);
-// if (visitor.stopVisiting())
-// return;
-// }
-// }
-// }
-// }
- visitor.visitCompleted(this);
}
-
+
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/impl/ModelImpl.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/impl/ModelImpl.java
index ab3c51c..cfbb83e 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/impl/ModelImpl.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/impl/ModelImpl.java
@@ -2,7 +2,7 @@
* <copyright>
* </copyright>
*
- * $Id: ModelImpl.java,v 1.7 2008/11/18 22:24:39 gkessler Exp $
+ * $Id: ModelImpl.java,v 1.8 2010/01/27 23:54:32 gkessler Exp $
*/
package org.eclipse.jst.jsf.common.metadata.internal.impl;
@@ -12,7 +12,6 @@
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.util.EObjectResolvingEList;
-import org.eclipse.jst.jsf.common.metadata.Entity;
import org.eclipse.jst.jsf.common.metadata.EntityGroup;
import org.eclipse.jst.jsf.common.metadata.MetadataPackage;
import org.eclipse.jst.jsf.common.metadata.Model;
@@ -221,26 +220,15 @@
}
/**
* <!-- begin-user-doc -->
+ * Due to a mistake in the EMF model, Model is not inheriting accept method from Entity. This should be fixed.
* <!-- end-user-doc -->
* @generated NOT
*/
public void accept(IEntityVisitor visitor) {
- if (visitor.stopVisiting())
- return;
- visitor.visit(this);
-
- if (!getChildEntities().isEmpty()){
- for (Iterator/*<Entity>*/ it = getChildEntities().iterator(); it.hasNext();){
- Entity k = (Entity)it.next();
- k.accept(visitor);
- if (visitor.stopVisiting())
- return;
- }
- }
-
- visitor.visitCompleted(this);
+ super.accept(visitor);
}
+
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/internal/IHierarchicalEntityVisitor.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/internal/IHierarchicalEntityVisitor.java
new file mode 100644
index 0000000..b91fd9e
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/internal/IHierarchicalEntityVisitor.java
@@ -0,0 +1,24 @@
+package org.eclipse.jst.jsf.common.metadata.query.internal;
+
+import org.eclipse.jst.jsf.common.metadata.Entity;
+import org.eclipse.jst.jsf.common.metadata.query.IEntityVisitor;
+
+/**
+ * Provides the necessary hierarchical visitor interface methods to
+ * provide conditional navigation of the entity hierarchy
+ *
+ */
+public interface IHierarchicalEntityVisitor extends IEntityVisitor {
+ /**
+ * @param entity
+ * @return true if children should be traversed
+ */
+ boolean visitEnter(Entity entity);
+ /**
+ * @param entity
+ * @return true when coming out of a branch
+ */
+ boolean visitLeave(Entity entity);
+
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/internal/SimpleEntityQueryVisitorImpl.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/internal/SimpleEntityQueryVisitorImpl.java
index 19c8e6a..ea68a01 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/internal/SimpleEntityQueryVisitorImpl.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/internal/SimpleEntityQueryVisitorImpl.java
@@ -13,27 +13,28 @@
import java.util.ArrayList;
import java.util.List;
-import java.util.Stack;
+import java.util.StringTokenizer;
import org.eclipse.jst.jsf.common.metadata.Entity;
-import org.eclipse.jst.jsf.common.metadata.EntityGroup;
import org.eclipse.jst.jsf.common.metadata.query.AbstractEntityQueryVisitor;
import org.eclipse.jst.jsf.common.metadata.query.IResultSet;
/**
- * A simple metadata query visitor implementing {@link org.eclipse.jst.jsf.common.metadata.query.IEntityQueryVisitor} and {@link org.eclipse.jst.jsf.common.metadata.query.ITraitQueryVisitor}.
- * - simple find entity and traits by id only
- * - Does not allow for wild card searchs
- *
+ * A simple metadata query visitor implementing {@link org.eclipse.jst.jsf.common.metadata.query.IEntityQueryVisitor} and {@link org.eclipse.jst.jsf.common.metadata.query.ITraitQueryVisitor}.<p>
+ * - simple find entity and traits by id only <br>
+ * - does not allow for wild card searchs<br>
+ * <p>
* TODO - fix for case-sensitivity https://bugs.eclipse.org/bugs/show_bug.cgi?id=212794
+ *
*/
-public class SimpleEntityQueryVisitorImpl extends AbstractEntityQueryVisitor {
+public class SimpleEntityQueryVisitorImpl extends AbstractEntityQueryVisitor implements IHierarchicalEntityVisitor {
private HierarchicalSearchControl control;
private boolean _stop;
- private EntityQueryComparator entityComparator;
+ private EntityQueryFilterVisitor entityQuery;
private List/*<Entity>*/ _entityResults;
+ private Entity initialEntityContext;
/**
* Constructor that also creates a default SearchControl
@@ -47,7 +48,7 @@
* Constructor
* @param control
*/
- public SimpleEntityQueryVisitorImpl(HierarchicalSearchControl control) {
+ public SimpleEntityQueryVisitorImpl(final HierarchicalSearchControl control) {
super();
this.control = control;
}
@@ -55,14 +56,15 @@
/* (non-Javadoc)
* @see org.eclipse.jst.jsf.common.metadata.query.IEntityQueryVisitor#findEntities(org.eclipse.jst.jsf.common.metadata.Entity, java.lang.String)
*/
- public IResultSet/*<Entity>*/ findEntities(Entity initialEntityContext,
- String entityKey) {
+ public IResultSet/*<Entity>*/ findEntities(final Entity initialEntity,
+ final String entityKey) {
resetQuery();
- if (initialEntityContext != null){
- entityComparator = new EntityQueryComparator(entityKey);
- initialEntityContext.accept(this);
+ if (initialEntity != null){
+ this.initialEntityContext = initialEntity;
+ entityQuery = new EntityQueryFilterVisitor(initialEntity.getId(), entityKey);
+ initialEntity.accept(this);
}
return new SimpleResultSet(getInternalEntityResults());
@@ -80,25 +82,31 @@
return _entityResults;
}
+
+ public boolean visitEnter(final Entity entity) {
+
+ if (entity == initialEntityContext)
+ return true;
+
+ entityQuery.pushLevel();
+ if (entityQuery.canVisit(entity))
+ return entityQuery.visit(entity);
+
+ return false;
+ }
+
+ public boolean visitLeave(Entity entity) {
+ checkShouldStopVisitingEntities();
+ if (entity != initialEntityContext)
+ entityQuery.popLevel();
+ return true;
+ }
+
/* (non-Javadoc)
* @see org.eclipse.jst.jsf.common.metadata.query.IEntityVisitor#visit(org.eclipse.jst.jsf.common.metadata.Entity)
*/
- public void visit(Entity key) {
- switch (entityComparator.compareTo(key)){
- case 0:
- getInternalEntityResults().add(key);
- break;
- default:
- break;
-
- }
- checkShouldStopVisitingEntities();
- }
- /* (non-Javadoc)
- * @see org.eclipse.jst.jsf.common.metadata.query.IEntityVisitor#visitCompleted(Entity entity)
- */
- public void visitCompleted(Entity entity) {
- entityComparator.popContext();
+ public void visit(final Entity key) {
+ //do nothing... all work now done in visitEnter/visitLeave
}
/* (non-Javadoc)
@@ -110,72 +118,87 @@
private void checkShouldStopVisitingEntities(){
//implement how to set stop to signal to the entity accept() to skip visiting
- if (control.getCountLimit()== getInternalEntityResults().size() && control.getCountLimit() != SearchControl.COUNT_LIMIT_NONE )
+ if (_stop == false
+ && control.getCountLimit()== getInternalEntityResults().size()
+ && control.getCountLimit() != SearchControl.COUNT_LIMIT_NONE )
+
_stop = true;
}
/**
- * Simple comparator that compares that an entity's id for with another.
- * Case-insensitive compare
- *
+ * Visitor that filters and acts upon hierarchical data that compares that an entity's id for with another with case-insensitive compare
*/
- private class EntityQueryComparator implements Comparable/*<Entity>*/{
+ private class EntityQueryFilterVisitor {
- private String entityKey;
- private EntityStack stack;
-
+ private String entityId;
+ private List<String> entityQueue;
+ private int curLevel = 0;
+
/**
* Constructor
- * @param entityKey
+ * @param initialContextId - Entity id from which the query is rooted
+ * @param queryKey - query key which may be compound ("A/B/C")
*/
- public EntityQueryComparator(String entityKey){
- this.entityKey = entityKey.toUpperCase();
- stack = new EntityStack();
+ public EntityQueryFilterVisitor(final String initialContextId, final String queryKey){
+ init(initialContextId, queryKey);
}
- public int compareTo(Object entity) {
- stack.push(entity);
- return entityKey.compareTo(getRelativeId().toUpperCase());
- }
-
- /**
- * Pop stack
- */
- public void popContext(){
- stack.pop();
- }
-
- private String getRelativeId(){
- int size = stack.size();
- int i = 1;
- StringBuffer buf = new StringBuffer();
- while(i < size){
- Entity e = (Entity)stack.elementAt(i);
- if (!(e instanceof EntityGroup)){
- if (buf.length()>0)
- buf.append("/"); //$NON-NLS-1$
- buf.append(e.getId());
- }
- i++;
+ private void init(final String initialContextId, final String key) {
+ entityQueue = new ArrayList<String>(3);
+ addLevel(initialContextId);
+ if (key == null || key.trim().equals("") || key.trim().equals("/")){ //$NON-NLS-1$ //$NON-NLS-2$
+ addLevel(""); //$NON-NLS-1$
}
- return buf.toString();
+ else {
+ final StringTokenizer st = new StringTokenizer(key, "/"); //$NON-NLS-1$
+ String partialKey = st.nextToken();
+ addLevel(partialKey);
+ while (st.hasMoreElements()){
+ partialKey = st.nextToken();
+ addLevel(partialKey);
+ }
+ }
}
- }
-
- /**
- * Stack used for determining relative key of an entity from the initial context.
- */
- private class EntityStack extends Stack/*<Entity>*/ {
- /**
- *
- */
- private static final long serialVersionUID = -6010267544968175003L;
- /**
- * Constructor
- */
- public EntityStack(){
- super();
+ /**
+ * @param entity
+ * @return flag indicating that filter was passed and children may be visited
+ */
+ public boolean canVisit(final Entity entity) {
+ // only one filter rule... does this entity id match the current level's entity id (case-insensitive)
+ return entityId.compareTo(entity.getId().toUpperCase()) == 0;
+ }
+
+ /**
+ * Operates on passed entity and determines if it should be part of the query results
+ * @param entity
+ * @return true if children of entity should be visited
+ */
+ public boolean visit(final Entity entity) {
+ //one operation... if we have found the leaf-most entity in the query, add it to the results and go no deeper
+ if (curLevel == entityQueue.size() - 1) {
+ getInternalEntityResults().add(entity);
+ return false;
+ }
+ return true;
+ }
+
+ private void addLevel(final String key) {
+ entityQueue.add(key.toUpperCase());
+ }
+
+ /**
+ * Move up one level in the query
+ */
+ public void popLevel(){
+ entityId = entityQueue.get(--curLevel);
+ }
+
+ /**
+ * Move down one level in the query
+ */
+ public void pushLevel() {
+ entityId = entityQueue.get(++curLevel);
}
}