diff --git a/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/adapter/BaseGeneratedDatabindingAdapter.java b/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/adapter/BaseGeneratedDatabindingAdapter.java index 15831b42..ea28b7fa 100644 --- a/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/adapter/BaseGeneratedDatabindingAdapter.java +++ b/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/adapter/BaseGeneratedDatabindingAdapter.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.databinding.runtime.adapter; - +package org.eclipse.incquery.databinding.runtime.adapter; + import java.util.Map; import org.eclipse.core.databinding.observable.value.IObservableValue; @@ -19,28 +19,28 @@ import org.eclipse.incquery.runtime.api.IPatternMatch; import com.google.common.base.Preconditions; - -public class BaseGeneratedDatabindingAdapter extends DatabindingAdapter { - - protected Map parameterMap; - - @Override - public String[] getParameterNames() { - return parameterMap.keySet().toArray(new String[parameterMap.keySet().size()]); - } - - @Override - public IObservableValue getObservableParameter(T match, String parameterName) { - if (parameterMap.size() > 0) { - String expression = parameterMap.get(parameterName); - return IncQueryObservables.getObservableValue(match, expression); - } - return null; - } + +public class BaseGeneratedDatabindingAdapter extends DatabindingAdapter { + + protected Map parameterMap; + + @Override + public String[] getParameterNames() { + return parameterMap.keySet().toArray(new String[parameterMap.keySet().size()]); + } + + @Override + public IObservableValue getObservableParameter(T match, String parameterName) { + if (parameterMap.size() > 0) { + String expression = parameterMap.get(parameterName); + return IncQueryObservables.getObservableValue(match, expression); + } + return null; + } public IValueProperty getProperty(String parameterName) { Preconditions.checkArgument(parameterMap.containsKey(parameterName), "Invalid parameter name"); return new MatcherProperty(parameterMap.get(parameterName)); - } - -} + } + +} diff --git a/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/adapter/DatabindingAdapter.java b/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/adapter/DatabindingAdapter.java index 45154a80..7b6c419c 100644 --- a/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/adapter/DatabindingAdapter.java +++ b/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/adapter/DatabindingAdapter.java @@ -9,8 +9,8 @@ * Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.databinding.runtime.adapter; - +package org.eclipse.incquery.databinding.runtime.adapter; + import org.eclipse.core.databinding.observable.Realm; import org.eclipse.core.databinding.observable.value.IObservableValue; import org.eclipse.core.databinding.property.value.ValueProperty; @@ -18,16 +18,17 @@ import org.eclipse.incquery.runtime.api.IPatternMatch; import com.google.common.base.Preconditions; - -/** - * The class is used to observe given parameters of a pattern. - * - * @author Tamas Szabo - * - * @param the type parameter of the match - */ -public abstract class DatabindingAdapter { - + +/** + * The class is used to observe given parameters of a pattern. + * + * @author Tamas Szabo + * + * @param + * the type parameter of the match + */ +public abstract class DatabindingAdapter { + protected class MatcherProperty extends ValueProperty { private String expression; @@ -60,20 +61,22 @@ public IObservableValue observe(Realm realm, Object source) { } } - - /** - * Returns the array of observable values. - * - * @return the array of values - */ - public abstract String[] getParameterNames(); - - /** - * Returns an observable value for the given match and parameterName. - * - * @param match the match object - * @param parameterName the parameter name - * @return an observable value - */ - public abstract IObservableValue getObservableParameter(T match, String parameterName); -} + + /** + * Returns the array of observable values. + * + * @return the array of values + */ + public abstract String[] getParameterNames(); + + /** + * Returns an observable value for the given match and parameterName. + * + * @param match + * the match object + * @param parameterName + * the parameter name + * @return an observable value + */ + public abstract IObservableValue getObservableParameter(T match, String parameterName); +} diff --git a/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/adapter/DatabindingAdapterUtil.java b/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/adapter/DatabindingAdapterUtil.java index 949f384e..823b20b3 100644 --- a/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/adapter/DatabindingAdapterUtil.java +++ b/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/adapter/DatabindingAdapterUtil.java @@ -9,8 +9,8 @@ * Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.databinding.runtime.adapter; - +package org.eclipse.incquery.databinding.runtime.adapter; + import java.util.List; import java.util.Map; @@ -30,116 +30,122 @@ import com.google.common.base.Preconditions; import com.google.common.collect.ListMultimap; import com.google.common.collect.Maps; - + public class DatabindingAdapterUtil { - - public static final String OBSERVABLEVALUE_ANNOTATION = "ObservableValue"; - - private DatabindingAdapterUtil() {} - - /** - * Returns an IObservableValue for the given match based on the given expression. - * If an attribute is not present in the expression than it tries with the 'name' attribute. - * If it is not present the returned value will be null. + + public static final String OBSERVABLEVALUE_ANNOTATION = "ObservableValue"; + + private DatabindingAdapterUtil() { + } + + /** + * Returns an IObservableValue for the given match based on the given expression. If an attribute is not present in + * the expression than it tries with the 'name' attribute. If it is not present the returned value will be null. * - * @param match the match object - * @param expression the expression - * @return IObservableValue instance or null + * @param match + * the match object + * @param expression + * the expression + * @return IObservableValue instance or null * @deprecated Use {@link IncQueryObservables#getObservableValue(IPatternMatch,String)} instead */ @Deprecated public static IObservableValue getObservableValue(IPatternMatch match, String expression) { return IncQueryObservables.getObservableValue(match, expression); - } - - /** - * Registers the given changeListener for the appropriate features of the given signature. - * The features will be computed based on the message parameter. + } + + /** + * Registers the given changeListener for the appropriate features of the given signature. The features will be + * computed based on the message parameter. * - * @param signature the signature instance - * @param changeListener the changle listener - * @param message the message which can be found in the appropriate PatternUI annotation + * @param signature + * the signature instance + * @param changeListener + * the changle listener + * @param message + * the message which can be found in the appropriate PatternUI annotation * @return the list of IObservableValue instances for which the IValueChangeListener was registered * @deprecated Use {@link IncQueryObservables#observeFeatures(IPatternMatch,IValueChangeListener,String)} instead */ @Deprecated - public static List observeFeatures(IPatternMatch match, IValueChangeListener changeListener, String message) { + public static List observeFeatures(IPatternMatch match, IValueChangeListener changeListener, + String message) { return IncQueryObservables.observeFeatures(match, changeListener, message); - } - - /** - * Registers the given change listener on the given object's all accessible fields. - * This function uses Java Reflection. + } + + /** + * Registers the given change listener on the given object's all accessible fields. This function uses Java + * Reflection. * - * @param changeListener the changle listener - * @param object the observed object + * @param changeListener + * the changle listener + * @param object + * the observed object * @return the list of IObservableValue instances for which the IValueChangeListener was registered * @deprecated Use {@link IncQueryObservables#observeAllAttributes(IValueChangeListener,Object)} instead */ @Deprecated public static List observeAllAttributes(IValueChangeListener changeListener, Object object) { return IncQueryObservables.observeAllAttributes(changeListener, object); - } - - /** - * Get the structural feature with the given name of the given object. - * - * @param o the object (must be an EObject) - * @param featureName the name of the feature - * @return the EStructuralFeature of the object or null if it can not be found - */ - public static EStructuralFeature getFeature(Object o, String featureName) { - if (o instanceof EObject) { - EStructuralFeature feature = ((EObject) o).eClass().getEStructuralFeature(featureName); - return feature; - } - return null; - } - - public static String getMessage(IPatternMatch match, String message) { - String[] tokens = message.split("\\$"); - StringBuilder newText = new StringBuilder(); - - for (int i = 0;i 0) { - Object o = null; - EStructuralFeature feature = null; - - if (objectTokens.length == 1) { - o = match.get(objectTokens[0]); - feature = DatabindingAdapterUtil.getFeature(o, "name"); - } - if (objectTokens.length == 2) { - o = match.get(objectTokens[0]); - feature = DatabindingAdapterUtil.getFeature(o, objectTokens[1]); - } - - if (o != null && feature != null) { - Object value = ((EObject) o).eGet(feature); - if (value != null) { - newText.append(value.toString()); - } - else { - newText.append("null"); - } - } - else if (o != null) { - newText.append(o.toString()); - } - } - else { - newText.append("[no such parameter]"); - } - } - } - - return newText.toString(); - } + } + + /** + * Get the structural feature with the given name of the given object. + * + * @param o + * the object (must be an EObject) + * @param featureName + * the name of the feature + * @return the EStructuralFeature of the object or null if it can not be found + */ + public static EStructuralFeature getFeature(Object o, String featureName) { + if (o instanceof EObject) { + EStructuralFeature feature = ((EObject) o).eClass().getEStructuralFeature(featureName); + return feature; + } + return null; + } + + public static String getMessage(IPatternMatch match, String message) { + String[] tokens = message.split("\\$"); + StringBuilder newText = new StringBuilder(); + + for (int i = 0; i < tokens.length; i++) { + if (i % 2 == 0) { + newText.append(tokens[i]); + } else { + String[] objectTokens = tokens[i].split("\\."); + if (objectTokens.length > 0) { + Object o = null; + EStructuralFeature feature = null; + + if (objectTokens.length == 1) { + o = match.get(objectTokens[0]); + feature = DatabindingAdapterUtil.getFeature(o, "name"); + } + if (objectTokens.length == 2) { + o = match.get(objectTokens[0]); + feature = DatabindingAdapterUtil.getFeature(o, objectTokens[1]); + } + + if (o != null && feature != null) { + Object value = ((EObject) o).eGet(feature); + if (value != null) { + newText.append(value.toString()); + } else { + newText.append("null"); + } + } else if (o != null) { + newText.append(o.toString()); + } + } else { + newText.append("[no such parameter]"); + } + } + } + + return newText.toString(); + } /** * @param pattern @@ -152,7 +158,7 @@ public static Map calculateObservableValues(Pattern pattern) { } for (Annotation annotation : CorePatternLanguageHelper .getAnnotationsByName(pattern, OBSERVABLEVALUE_ANNOTATION)) { - + ListMultimap parameterMap = CorePatternLanguageHelper .getAnnotationParameters(annotation); List nameAttributes = parameterMap.get("name"); @@ -170,7 +176,7 @@ public static Map calculateObservableValues(Pattern pattern) { propertyMap.put(key, value); } } - } + } return propertyMap; - } -} + } +} diff --git a/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/adapter/GenericDatabindingAdapter.java b/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/adapter/GenericDatabindingAdapter.java index adf1c7be..f297698e 100644 --- a/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/adapter/GenericDatabindingAdapter.java +++ b/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/adapter/GenericDatabindingAdapter.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.databinding.runtime.adapter; - +package org.eclipse.incquery.databinding.runtime.adapter; + import java.util.Map; import org.eclipse.core.databinding.observable.value.IObservableValue; @@ -20,36 +20,36 @@ import org.eclipse.incquery.runtime.api.IPatternMatch; import com.google.common.base.Preconditions; - -public class GenericDatabindingAdapter extends DatabindingAdapter { - - private final Map parameterMap; - + +public class GenericDatabindingAdapter extends DatabindingAdapter { + + private final Map parameterMap; + public GenericDatabindingAdapter(Map parameterMap) { - this.parameterMap = parameterMap; - } + this.parameterMap = parameterMap; + } public GenericDatabindingAdapter(Pattern pattern) { this.parameterMap = DatabindingAdapterUtil.calculateObservableValues(pattern); - } - - @Override - public String[] getParameterNames() { - return parameterMap.keySet().toArray(new String[parameterMap.keySet().size()]); - } - - @Override - public IObservableValue getObservableParameter(IPatternMatch match, String parameterName) { - if (parameterMap.size() > 0) { - String expression = parameterMap.get(parameterName); - return IncQueryObservables.getObservableValue(match, expression); - } - return null; - } + } + + @Override + public String[] getParameterNames() { + return parameterMap.keySet().toArray(new String[parameterMap.keySet().size()]); + } + + @Override + public IObservableValue getObservableParameter(IPatternMatch match, String parameterName) { + if (parameterMap.size() > 0) { + String expression = parameterMap.get(parameterName); + return IncQueryObservables.getObservableValue(match, expression); + } + return null; + } public IValueProperty getProperty(String parameterName) { Preconditions.checkArgument(parameterMap.containsKey(parameterName), "Invalid parameter name"); return new MatcherProperty(parameterMap.get(parameterName)); - } - -} + } + +} diff --git a/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/api/IncQueryObservables.java b/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/api/IncQueryObservables.java index b5e6f6a0..b5f870c6 100644 --- a/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/api/IncQueryObservables.java +++ b/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/api/IncQueryObservables.java @@ -29,11 +29,10 @@ import org.eclipse.incquery.runtime.api.IncQueryMatcher; /** - * Utility class for observing EMF-IncQuery related objects, such as match sets, - * match parameters. + * Utility class for observing EMF-IncQuery related objects, such as match sets, match parameters. * * @author Abel Hegedus - * + * */ public class IncQueryObservables { @@ -41,120 +40,135 @@ public class IncQueryObservables { * Hidden constructor for utility class */ private IncQueryObservables() { - + } - + /** * Create an observable list of the match set of the given query on the selected notifier. * - *

The matches are ordered by appearance, so a new match is always put on the end of the list. + *

+ * The matches are ordered by appearance, so a new match is always put on the end of the list. * - *

Use the generated matcher factories for initialization, in the generic case, you may have to - * accept an unchecked invocation (or use the Generic classes if you are sure). + *

+ * Use the generated matcher factories for initialization, in the generic case, you may have to accept an unchecked + * invocation (or use the Generic classes if you are sure). * - * @param factory the matcher factory for the query to observe - * @param notifier the notifier to use for the matcher + * @param factory + * the matcher factory for the query to observe + * @param notifier + * the notifier to use for the matcher * @return an observable list of matches */ - public static > IObservableList observeMatchesAsList(IMatcherFactory factory, Notifier notifier) { + public static > IObservableList observeMatchesAsList( + IMatcherFactory factory, Notifier notifier) { return new ObservablePatternMatchList(factory, notifier); } - + /** * Create an observable set of the match set of the given query on the selected notifier. * - *

Use the generated matcher factories for initialization, in the generic case, you may have to - * accept an unchecked invocation (or use the Generic classes if you are sure). + *

+ * Use the generated matcher factories for initialization, in the generic case, you may have to accept an unchecked + * invocation (or use the Generic classes if you are sure). * - * @param factory the matcher factory for the query to observe - * @param notifier the notifier to use for the matcher + * @param factory + * the matcher factory for the query to observe + * @param notifier + * the notifier to use for the matcher * @return an observable set of matches */ - public static > IObservableSet observeMatchesAsSet(IMatcherFactory factory, Notifier notifier) { + public static > IObservableSet observeMatchesAsSet( + IMatcherFactory factory, Notifier notifier) { return new ObservablePatternMatchSet(factory, notifier); } /** - * Registers the given changeListener for the appropriate features of the given signature. - * The features will be computed based on the message parameter. + * Registers the given changeListener for the appropriate features of the given signature. The features will be + * computed based on the message parameter. * - * @param signature the signature instance - * @param changeListener the changle listener - * @param message the message which can be found in the appropriate PatternUI annotation + * @param signature + * the signature instance + * @param changeListener + * the changle listener + * @param message + * the message which can be found in the appropriate PatternUI annotation * @return the list of IObservableValue instances for which the IValueChangeListener was registered */ - public static List observeFeatures(IPatternMatch match, IValueChangeListener changeListener, String message) { - List affectedValues = new ArrayList(); - if (message != null) { - String[] tokens = message.split("\\$"); - - for (int i = 0; i < tokens.length; i++) { - - //odd tokens - if (i % 2 != 0) { - IObservableValue value = IncQueryObservables.getObservableValue(match, tokens[i]); - if (value != null) { - value.addValueChangeListener(changeListener); - affectedValues.add(value); - } - } - } - } - return affectedValues; + public static List observeFeatures(IPatternMatch match, IValueChangeListener changeListener, + String message) { + List affectedValues = new ArrayList(); + if (message != null) { + String[] tokens = message.split("\\$"); + + for (int i = 0; i < tokens.length; i++) { + + // odd tokens + if (i % 2 != 0) { + IObservableValue value = IncQueryObservables.getObservableValue(match, tokens[i]); + if (value != null) { + value.addValueChangeListener(changeListener); + affectedValues.add(value); + } + } + } + } + return affectedValues; } /** - * Registers the given change listener on the given object's all accessible fields. - * This function uses Java Reflection. + * Registers the given change listener on the given object's all accessible fields. This function uses Java + * Reflection. * - * @param changeListener the changle listener - * @param object the observed object + * @param changeListener + * the changle listener + * @param object + * the observed object * @return the list of IObservableValue instances for which the IValueChangeListener was registered */ public static List observeAllAttributes(IValueChangeListener changeListener, Object object) { - List affectedValues = new ArrayList(); - if (object instanceof EObject) { - for (EStructuralFeature feature : ((EObject) object).eClass().getEAllStructuralFeatures()) { - IObservableValue val = EMFProperties.value(feature).observe(object); - affectedValues.add(val); - val.addValueChangeListener(changeListener); - } - } - return affectedValues; + List affectedValues = new ArrayList(); + if (object instanceof EObject) { + for (EStructuralFeature feature : ((EObject) object).eClass().getEAllStructuralFeatures()) { + IObservableValue val = EMFProperties.value(feature).observe(object); + affectedValues.add(val); + val.addValueChangeListener(changeListener); + } + } + return affectedValues; } /** - * Returns an IObservableValue for the given match based on the given expression. - * If an attribute is not present in the expression than it tries with the 'name' attribute. - * If it is not present the returned value will be null. + * Returns an IObservableValue for the given match based on the given expression. If an attribute is not present in + * the expression than it tries with the 'name' attribute. If it is not present the returned value will be null. * - * @param match the match object - * @param expression the expression - * @return IObservableValue instance or null + * @param match + * the match object + * @param expression + * the expression + * @return IObservableValue instance or null */ public static IObservableValue getObservableValue(IPatternMatch match, String expression) { - IObservableValue val = null; - String[] objectTokens = expression.split("\\."); - - if (objectTokens.length > 0) { - Object o = null; - EStructuralFeature feature = null; - - if (objectTokens.length == 2) { - o = match.get(objectTokens[0]); - feature = DatabindingAdapterUtil.getFeature(o, objectTokens[1]); - } - if (objectTokens.length == 1) { - o = match.get(objectTokens[0]); - feature = DatabindingAdapterUtil.getFeature(o, "name"); - } - if (o != null && feature != null) { - val = EMFProperties.value(feature).observe(o); - } - } - - return val; + IObservableValue val = null; + String[] objectTokens = expression.split("\\."); + + if (objectTokens.length > 0) { + Object o = null; + EStructuralFeature feature = null; + + if (objectTokens.length == 2) { + o = match.get(objectTokens[0]); + feature = DatabindingAdapterUtil.getFeature(o, objectTokens[1]); + } + if (objectTokens.length == 1) { + o = match.get(objectTokens[0]); + feature = DatabindingAdapterUtil.getFeature(o, "name"); + } + if (o != null && feature != null) { + val = EMFProperties.value(feature).observe(o); + } + } + + return val; } - - + } diff --git a/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/collection/IObservablePatternMatchCollection.java b/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/collection/IObservablePatternMatchCollection.java index 7fd2ec7c..59caf67d 100644 --- a/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/collection/IObservablePatternMatchCollection.java +++ b/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/collection/IObservablePatternMatchCollection.java @@ -13,26 +13,28 @@ import org.eclipse.incquery.runtime.api.IPatternMatch; /** - * Common interface for observable pattern match collections (e.g. - * {@link ObservablePatternMatchList} and {@link ObservablePatternMatchSet}). + * Common interface for observable pattern match collections (e.g. {@link ObservablePatternMatchList} and + * {@link ObservablePatternMatchSet}). * * @author Abel Hegedus - * + * */ -public interface IObservablePatternMatchCollection{ +public interface IObservablePatternMatchCollection { /** * Can be called to indicate that a match appeared and should be added to the collection. * - * @param match the new match + * @param match + * the new match */ void addMatch(Match match); /** * Can be called to indicate that a match disappeared and should be removed from the collection. - * - * @param match the disappered match + * + * @param match + * the disappered match */ void removeMatch(Match match); - + } diff --git a/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/collection/ObservableCollectionHelper.java b/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/collection/ObservableCollectionHelper.java index 36ee1780..9af8da6b 100644 --- a/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/collection/ObservableCollectionHelper.java +++ b/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/collection/ObservableCollectionHelper.java @@ -21,11 +21,11 @@ import org.eclipse.incquery.runtime.triggerengine.firing.AutomaticFiringStrategy; /** - * Utility class to prepare a rule in an agenda for an observable collection. - * For use cases, see {@link ObservablePatternMatchSet} and {@link ObservablePatternMatchList}. + * Utility class to prepare a rule in an agenda for an observable collection. For use cases, see + * {@link ObservablePatternMatchSet} and {@link ObservablePatternMatchList}. * * @author Abel Hegedus - * + * */ public class ObservableCollectionHelper { @@ -35,18 +35,25 @@ public class ObservableCollectionHelper { private ObservableCollectionHelper() { // TODO Auto-generated constructor stub } - + /** - * Creates the rule used for updating the results in the given agenda. + * Creates the rule used for updating the results in the given agenda. * - * @param observableCollection the observable collection to handle - * @param factory the {@link IMatcherFactory} used to create the rule - * @param agenda an existing {@link Agenda} where the rule is created + * @param observableCollection + * the observable collection to handle + * @param factory + * the {@link IMatcherFactory} used to create the rule + * @param agenda + * an existing {@link Agenda} where the rule is created */ - public static > void createRuleInAgenda(IObservablePatternMatchCollection observableCollection, IMatcherFactory factory, IAgenda agenda) { + public static > void createRuleInAgenda( + IObservablePatternMatchCollection observableCollection, IMatcherFactory factory, + IAgenda agenda) { IRule rule = agenda.createRule(factory, false, true); - ObservableCollectionProcessor insertProc = new ObservableCollectionProcessor(Direction.INSERT, observableCollection); - ObservableCollectionProcessor deleteProc = new ObservableCollectionProcessor(Direction.DELETE, observableCollection); + ObservableCollectionProcessor insertProc = new ObservableCollectionProcessor(Direction.INSERT, + observableCollection); + ObservableCollectionProcessor deleteProc = new ObservableCollectionProcessor(Direction.DELETE, + observableCollection); rule.setStateChangeProcessor(ActivationState.APPEARED, insertProc); rule.setStateChangeProcessor(ActivationState.DISAPPEARED, deleteProc); AutomaticFiringStrategy firingStrategy = new AutomaticFiringStrategy(agenda.newActivationMonitor(true)); diff --git a/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/collection/ObservableCollectionProcessor.java b/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/collection/ObservableCollectionProcessor.java index 1e13a7e9..568dbe60 100644 --- a/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/collection/ObservableCollectionProcessor.java +++ b/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/collection/ObservableCollectionProcessor.java @@ -31,8 +31,10 @@ public class ObservableCollectionProcessor implemen /** * Creates a processor with the given direction and observable collection. * - * @param direction the {@link Direction} of updates that are handled - * @param collection the {@link IObservablePatternMatchCollection} to manage + * @param direction + * the {@link Direction} of updates that are handled + * @param collection + * the {@link IObservablePatternMatchCollection} to manage */ public ObservableCollectionProcessor(Direction direction, IObservablePatternMatchCollection collection) { this.direction = direction; diff --git a/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/collection/ObservablePatternMatchList.java b/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/collection/ObservablePatternMatchList.java index 21b95002..edc6a434 100644 --- a/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/collection/ObservablePatternMatchList.java +++ b/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/collection/ObservablePatternMatchList.java @@ -30,75 +30,99 @@ import org.eclipse.incquery.runtime.triggerengine.api.RuleEngine; /** - * Observable view of a match set for a given {@link IncQueryMatcher} on a model - * (match sets of an {@link IncQueryMatcher} are ordered by the order of their appearance). - * - *

This implementation uses the {@link RuleEngine} to get notifications for match set changes, - * and can be instantiated using either an existing {@link IncQueryMatcher}, or an {@link IMatcherFactory} and - * either a {@link Notifier}, {@link IncQueryEngine} or {@link Agenda}. + * Observable view of a match set for a given {@link IncQueryMatcher} on a model (match sets of an + * {@link IncQueryMatcher} are ordered by the order of their appearance). + * + *

+ * This implementation uses the {@link RuleEngine} to get notifications for match set changes, and can be instantiated + * using either an existing {@link IncQueryMatcher}, or an {@link IMatcherFactory} and either a {@link Notifier}, + * {@link IncQueryEngine} or {@link Agenda}. * * @author Abel Hegedus - * + * */ -public class ObservablePatternMatchList extends AbstractObservableList implements IObservablePatternMatchCollection { +public class ObservablePatternMatchList extends AbstractObservableList implements + IObservablePatternMatchCollection { private final List cache = Collections.synchronizedList(new ArrayList()); - + /** * Creates an observable view of the match set of the given {@link IncQueryMatcher}. * - *

Consider using {@link IncQueryObservables#observeMatchesAsList} instead! + *

+ * Consider using {@link IncQueryObservables#observeMatchesAsList} instead! * - * @param matcher the {@link IncQueryMatcher} to use as the source of the observable list + * @param matcher + * the {@link IncQueryMatcher} to use as the source of the observable list */ @SuppressWarnings("unchecked") public > ObservablePatternMatchList(Matcher matcher) { super(); - IMatcherFactory matcherFactory = (IMatcherFactory) MatcherFactoryRegistry.getOrCreateMatcherFactory(matcher.getPattern()); - ObservableCollectionHelper.createRuleInAgenda(this, matcherFactory, RuleEngine.getInstance().getOrCreateAgenda(matcher.getEngine())); + IMatcherFactory matcherFactory = (IMatcherFactory) MatcherFactoryRegistry + .getOrCreateMatcherFactory(matcher.getPattern()); + ObservableCollectionHelper.createRuleInAgenda(this, matcherFactory, + RuleEngine.getInstance().getOrCreateAgenda(matcher.getEngine())); } - + /** - * Creates an observable view of the match set of the given {@link IMatcherFactory} initialized on the given {@link Notifier}. + * Creates an observable view of the match set of the given {@link IMatcherFactory} initialized on the given + * {@link Notifier}. * - *

Consider using {@link IncQueryObservables#observeMatchesAsList} instead! + *

+ * Consider using {@link IncQueryObservables#observeMatchesAsList} instead! * - * @param factory the {@link IMatcherFactory} used to create a matcher - * @param notifier the {@link Notifier} on which the matcher is created + * @param factory + * the {@link IMatcherFactory} used to create a matcher + * @param notifier + * the {@link Notifier} on which the matcher is created */ - public > ObservablePatternMatchList(IMatcherFactory factory, Notifier notifier) { + public > ObservablePatternMatchList(IMatcherFactory factory, + Notifier notifier) { this(factory, RuleEngine.getInstance().getOrCreateAgenda(notifier)); } - + /** - * Creates an observable view of the match set of the given {@link IMatcherFactory} initialized on the given {@link IncQueryEngine}. + * Creates an observable view of the match set of the given {@link IMatcherFactory} initialized on the given + * {@link IncQueryEngine}. * - *

Consider using {@link IncQueryObservables#observeMatchesAsList} instead! + *

+ * Consider using {@link IncQueryObservables#observeMatchesAsList} instead! * - * @param factory the {@link IMatcherFactory} used to create a matcher - * @param engine the {@link IncQueryEngine} on which the matcher is created + * @param factory + * the {@link IMatcherFactory} used to create a matcher + * @param engine + * the {@link IncQueryEngine} on which the matcher is created */ - public > ObservablePatternMatchList(IMatcherFactory factory, IncQueryEngine engine) { + public > ObservablePatternMatchList(IMatcherFactory factory, + IncQueryEngine engine) { this(factory, RuleEngine.getInstance().getOrCreateAgenda(engine)); } - + /** - * Creates an observable view of the match set of the given {@link IMatcherFactory} initialized on the given {@link Agenda}. + * Creates an observable view of the match set of the given {@link IMatcherFactory} initialized on the given + * {@link Agenda}. * - *

Consider using {@link IncQueryObservables#observeMatchesAsList} instead! + *

+ * Consider using {@link IncQueryObservables#observeMatchesAsList} instead! * - *

Note, that no firing strategy will be added to the {@link Agenda}! + *

+ * Note, that no firing strategy will be added to the {@link Agenda}! * - * @param factory the {@link IMatcherFactory} used to create a matcher - * @param agenda an existing {@link Agenda} that specifies the used model + * @param factory + * the {@link IMatcherFactory} used to create a matcher + * @param agenda + * an existing {@link Agenda} that specifies the used model */ - public > ObservablePatternMatchList(IMatcherFactory factory, IAgenda agenda) { + public > ObservablePatternMatchList(IMatcherFactory factory, + IAgenda agenda) { super(); ObservableCollectionHelper.createRuleInAgenda(this, factory, agenda); - + } - - /* (non-Javadoc) + + /* + * (non-Javadoc) + * * @see org.eclipse.core.databinding.observable.list.IObservableList#getElementType() */ @Override @@ -106,7 +130,9 @@ public Object getElementType() { return IPatternMatch.class; } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see org.eclipse.core.databinding.observable.list.AbstractObservableList#doGetSize() */ @Override @@ -114,7 +140,9 @@ protected int doGetSize() { return cache.size(); } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see java.util.AbstractList#get(int) */ @Override diff --git a/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/collection/ObservablePatternMatchSet.java b/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/collection/ObservablePatternMatchSet.java index 3e63cd00..87f11451 100644 --- a/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/collection/ObservablePatternMatchSet.java +++ b/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/collection/ObservablePatternMatchSet.java @@ -31,71 +31,94 @@ import com.google.common.collect.Sets; /** - * Observable view of a match set for a given {@link IncQueryMatcher} on a model - * (match sets of an {@link IncQueryMatcher} are not ordered by default). - * - *

This implementation uses the {@link RuleEngine} to get notifications for match set changes, - * and can be instantiated using either an existing {@link IncQueryMatcher}, or an {@link IMatcherFactory} and - * either a {@link Notifier}, {@link IncQueryEngine} or {@link Agenda}. + * Observable view of a match set for a given {@link IncQueryMatcher} on a model (match sets of an + * {@link IncQueryMatcher} are not ordered by default). + * + *

+ * This implementation uses the {@link RuleEngine} to get notifications for match set changes, and can be instantiated + * using either an existing {@link IncQueryMatcher}, or an {@link IMatcherFactory} and either a {@link Notifier}, + * {@link IncQueryEngine} or {@link Agenda}. * * @author Abel Hegedus - * + * */ -public class ObservablePatternMatchSet extends AbstractObservableSet implements IObservablePatternMatchCollection { +public class ObservablePatternMatchSet extends AbstractObservableSet implements + IObservablePatternMatchCollection { private final Set cache = Collections.synchronizedSet(new HashSet()); - + /** * Creates an observable view of the match set of the given {@link IncQueryMatcher}. * - *

Consider using {@link IncQueryObservables#observeMatchesAsSet} instead! + *

+ * Consider using {@link IncQueryObservables#observeMatchesAsSet} instead! * - * @param matcher the {@link IncQueryMatcher} to use as the source of the observable set + * @param matcher + * the {@link IncQueryMatcher} to use as the source of the observable set */ @SuppressWarnings("unchecked") public > ObservablePatternMatchSet(Matcher matcher) { - IMatcherFactory matcherFactory = (IMatcherFactory) MatcherFactoryRegistry.getOrCreateMatcherFactory(matcher.getPattern()); - ObservableCollectionHelper.createRuleInAgenda(this, matcherFactory, RuleEngine.getInstance().getOrCreateAgenda(matcher.getEngine())); + IMatcherFactory matcherFactory = (IMatcherFactory) MatcherFactoryRegistry + .getOrCreateMatcherFactory(matcher.getPattern()); + ObservableCollectionHelper.createRuleInAgenda(this, matcherFactory, + RuleEngine.getInstance().getOrCreateAgenda(matcher.getEngine())); } - + /** - * Creates an observable view of the match set of the given {@link IMatcherFactory} initialized on the given {@link Notifier}. + * Creates an observable view of the match set of the given {@link IMatcherFactory} initialized on the given + * {@link Notifier}. * - *

Consider using {@link IncQueryObservables#observeMatchesAsSet} instead! + *

+ * Consider using {@link IncQueryObservables#observeMatchesAsSet} instead! * - * @param factory the {@link IMatcherFactory} used to create a matcher - * @param notifier the {@link Notifier} on which the matcher is created + * @param factory + * the {@link IMatcherFactory} used to create a matcher + * @param notifier + * the {@link Notifier} on which the matcher is created */ - public > ObservablePatternMatchSet(IMatcherFactory factory, Notifier notifier) { + public > ObservablePatternMatchSet(IMatcherFactory factory, + Notifier notifier) { this(factory, RuleEngine.getInstance().getOrCreateAgenda(notifier)); } - + /** - * Creates an observable view of the match set of the given {@link IMatcherFactory} initialized on the given {@link IncQueryEngine}. + * Creates an observable view of the match set of the given {@link IMatcherFactory} initialized on the given + * {@link IncQueryEngine}. * - *

Consider using {@link IncQueryObservables#observeMatchesAsSet} instead! + *

+ * Consider using {@link IncQueryObservables#observeMatchesAsSet} instead! * - * @param factory the {@link IMatcherFactory} used to create a matcher - * @param engine the {@link IncQueryEngine} on which the matcher is created + * @param factory + * the {@link IMatcherFactory} used to create a matcher + * @param engine + * the {@link IncQueryEngine} on which the matcher is created */ - public > ObservablePatternMatchSet(IMatcherFactory factory, IncQueryEngine engine) { + public > ObservablePatternMatchSet(IMatcherFactory factory, + IncQueryEngine engine) { this(factory, RuleEngine.getInstance().getOrCreateAgenda(engine)); } - + /** - * Creates an observable view of the match set of the given {@link IMatcherFactory} initialized on the given {@link IncQueryEngine}. + * Creates an observable view of the match set of the given {@link IMatcherFactory} initialized on the given + * {@link IncQueryEngine}. * - *

Consider using {@link IncQueryObservables#observeMatchesAsSet} instead! + *

+ * Consider using {@link IncQueryObservables#observeMatchesAsSet} instead! * - * @param factory the {@link IMatcherFactory} used to create a matcher - * @param agenda an existing {@link Agenda} that specifies the used model + * @param factory + * the {@link IMatcherFactory} used to create a matcher + * @param agenda + * an existing {@link Agenda} that specifies the used model */ - public > ObservablePatternMatchSet(IMatcherFactory factory, IAgenda agenda) { + public > ObservablePatternMatchSet(IMatcherFactory factory, + IAgenda agenda) { super(); ObservableCollectionHelper.createRuleInAgenda(this, factory, agenda); } - - /* (non-Javadoc) + + /* + * (non-Javadoc) + * * @see org.eclipse.core.databinding.observable.list.IObservableList#getElementType() */ @Override @@ -103,7 +126,9 @@ public Object getElementType() { return IPatternMatch.class; } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see org.eclipse.core.databinding.observable.set.AbstractObservableSet#getWrappedSet() */ @Override diff --git a/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/util/PatternToMatchMultimap.java b/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/util/PatternToMatchMultimap.java index 0d302581..f3f703a9 100644 --- a/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/util/PatternToMatchMultimap.java +++ b/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/util/PatternToMatchMultimap.java @@ -21,32 +21,36 @@ * Multimap for managing multiple patterns and related matches for a given notifier. * * @author Abel Hegedus - * + * */ -public class PatternToMatchMultimap extends TriggeredQueryResultMultimap { +public class PatternToMatchMultimap extends + TriggeredQueryResultMultimap { /** * Creates a new multimap for the given agenda. * - * @param agenda the agenda to use + * @param agenda + * the agenda to use */ public PatternToMatchMultimap(Agenda agenda) { super(agenda); } - + /** * Creates a new multimap for the given engine. * - * @param engine the engine to use + * @param engine + * the engine to use */ public PatternToMatchMultimap(IncQueryEngine engine) { super(engine); } - + /** * Creates a new multimap for the given notifier * - * @param notifier the notifier to use + * @param notifier + * the notifier to use */ public PatternToMatchMultimap(Notifier notifier) { super(notifier); diff --git a/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/util/validation/ObservableValuePatternValidator.java b/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/util/validation/ObservableValuePatternValidator.java index 4dd07863..8dfce178 100644 --- a/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/util/validation/ObservableValuePatternValidator.java +++ b/plugins/org.eclipse.incquery.databinding.runtime/src/org/eclipse/incquery/databinding/runtime/util/validation/ObservableValuePatternValidator.java @@ -57,6 +57,7 @@ public void executeAdditionalValidation(Annotation annotation, IIssueCallback va validateParameterExpression(pattern, ref, value, validator); } } + /** * @param pattern * @param ref @@ -68,8 +69,8 @@ private void validateParameterExpression(Pattern pattern, ValueReference ref, St String[] tokens = expression.split("\\."); String featureName = ""; if (expression.isEmpty() || tokens.length == 0) { - validator.error("Expression must not be empty.", ref, - PatternLanguagePackage.Literals.STRING_VALUE__VALUE, GENERAL_ISSUE_CODE); + validator.error("Expression must not be empty.", ref, PatternLanguagePackage.Literals.STRING_VALUE__VALUE, + GENERAL_ISSUE_CODE); return; } else if (tokens.length == 1) { featureName = "name"; @@ -95,9 +96,8 @@ private void validateParameterExpression(Pattern pattern, ValueReference ref, St } EClass classDef = (EClass) classifier; if (classDef.getEStructuralFeature(featureName) == null) { - validator.error( - String.format("Invalid feature type %s in EClass %s", featureName, classifier.getName()), ref, - PatternLanguagePackage.Literals.STRING_VALUE__VALUE, UNKNOWN_ATTRIBUTE_CODE); + validator.error(String.format("Invalid feature type %s in EClass %s", featureName, classifier.getName()), + ref, PatternLanguagePackage.Literals.STRING_VALUE__VALUE, UNKNOWN_ATTRIBUTE_CODE); } } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/EMFPatternLanguageUIActivator.java b/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/EMFPatternLanguageUIActivator.java index c8b7c5ea..a10c9efe 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/EMFPatternLanguageUIActivator.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/EMFPatternLanguageUIActivator.java @@ -18,13 +18,13 @@ public class EMFPatternLanguageUIActivator extends EMFPatternLanguageActivator { - @Override - protected Module getRuntimeModule(String grammar) { - if (ORG_ECLIPSE_INCQUERY_PATTERNLANGUAGE_EMF_EMFPATTERNLANGUAGE.equals(grammar)) { - return IncQueryGeneratorPlugin.INSTANCE.getRuntimeModule(); - } - - throw new IllegalArgumentException(grammar); - } + @Override + protected Module getRuntimeModule(String grammar) { + if (ORG_ECLIPSE_INCQUERY_PATTERNLANGUAGE_EMF_EMFPATTERNLANGUAGE.equals(grammar)) { + return IncQueryGeneratorPlugin.INSTANCE.getRuntimeModule(); + } + + throw new IllegalArgumentException(grammar); + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/EMFPatternLanguageUiModule.java b/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/EMFPatternLanguageUiModule.java index d8390ec2..f1e2712d 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/EMFPatternLanguageUiModule.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/EMFPatternLanguageUiModule.java @@ -47,85 +47,83 @@ * Use this class to register components to be used within the IDE. */ public class EMFPatternLanguageUiModule extends AbstractEMFPatternLanguageUiModule { - private static final String loggerRoot = "org.eclipse.incquery"; - - public EMFPatternLanguageUiModule(AbstractUIPlugin plugin) { - super(plugin); - } - - @Provides - @Singleton - Logger provideLoggerImplementation() { - Logger logger = Logger.getLogger(loggerRoot); - logger.setAdditivity(false); - logger.addAppender(new ConsoleAppender()); - logger.addAppender(new EclipseLogAppender()); - return logger; - } - - @Override - public void configure(Binder binder) { - super.configure(binder); - binder.bind(String.class) - .annotatedWith( - Names.named(XtextContentAssistProcessor.COMPLETION_AUTO_ACTIVATION_CHARS)) - .toInstance(".,"); - } - - /* - * Registering model inferrer from the tooling.generator project - */ - public Class bindIJvmModelInferrer() { - return EMFPatternLanguageJvmModelInferrer.class; - } - - @Override - public Class bindIXtextBuilderParticipant() { - return EMFPatternLanguageBuilderParticipant.class; - } - - @Override - public Class bindISemanticHighlightingCalculator() { - return EMFPatternLanguageHighlightingCalculator.class; - } - - @Override - public Class bindIHighlightingConfiguration() { - return EMFPatternLanguageHighlightingConfiguration.class; - } - - public Class bindIMetamodelProvider() { - return GenModelMetamodelProviderService.class; - } - - public Class bindIEiqGenmodelProvider() { - return GenModelMetamodelProviderService.class; - } - - public Class bindITypeProvider() { - return GenModelBasedTypeProvider.class; - } - - @Override - public Class bindIEObjectHoverDocumentationProvider() { - return EMFPatternLanguageHoverDocumentationProvider.class; - } - - public Class bindIErrorFeedback(){ - return GeneratorMarkerFeedback.class; - } - - - public Class bindILogicalContainerProvider() { - return EMFPatternJvmModelAssociator.class; - } - - public Class bindJvmModelAssociator() { - return EMFPatternJvmModelAssociator.class; - } - - @SingletonBinding(eager = true) - public Class bindEMFPatternLanguageJavaValidator() { - return GenmodelBasedEMFPatternLanguageJavaValidator.class; - } + private static final String loggerRoot = "org.eclipse.incquery"; + + public EMFPatternLanguageUiModule(AbstractUIPlugin plugin) { + super(plugin); + } + + @Provides + @Singleton + Logger provideLoggerImplementation() { + Logger logger = Logger.getLogger(loggerRoot); + logger.setAdditivity(false); + logger.addAppender(new ConsoleAppender()); + logger.addAppender(new EclipseLogAppender()); + return logger; + } + + @Override + public void configure(Binder binder) { + super.configure(binder); + binder.bind(String.class) + .annotatedWith(Names.named(XtextContentAssistProcessor.COMPLETION_AUTO_ACTIVATION_CHARS)) + .toInstance(".,"); + } + + /* + * Registering model inferrer from the tooling.generator project + */ + public Class bindIJvmModelInferrer() { + return EMFPatternLanguageJvmModelInferrer.class; + } + + @Override + public Class bindIXtextBuilderParticipant() { + return EMFPatternLanguageBuilderParticipant.class; + } + + @Override + public Class bindISemanticHighlightingCalculator() { + return EMFPatternLanguageHighlightingCalculator.class; + } + + @Override + public Class bindIHighlightingConfiguration() { + return EMFPatternLanguageHighlightingConfiguration.class; + } + + public Class bindIMetamodelProvider() { + return GenModelMetamodelProviderService.class; + } + + public Class bindIEiqGenmodelProvider() { + return GenModelMetamodelProviderService.class; + } + + public Class bindITypeProvider() { + return GenModelBasedTypeProvider.class; + } + + @Override + public Class bindIEObjectHoverDocumentationProvider() { + return EMFPatternLanguageHoverDocumentationProvider.class; + } + + public Class bindIErrorFeedback() { + return GeneratorMarkerFeedback.class; + } + + public Class bindILogicalContainerProvider() { + return EMFPatternJvmModelAssociator.class; + } + + public Class bindJvmModelAssociator() { + return EMFPatternJvmModelAssociator.class; + } + + @SingletonBinding(eager = true) + public Class bindEMFPatternLanguageJavaValidator() { + return GenmodelBasedEMFPatternLanguageJavaValidator.class; + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/EclipseLogAppender.java b/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/EclipseLogAppender.java index 6fa43c66..08df5f0d 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/EclipseLogAppender.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/EclipseLogAppender.java @@ -20,6 +20,7 @@ /** * Updated Eclipse LogAppender based on the implementation in org.eclipse.xtext.logger bundle. + * * @author Peter Friese - Initial contribution and API * @author Sven Efftinge * @author Knut Wannheden - Refactored handling when used in non OSGi environment @@ -27,83 +28,83 @@ */ public class EclipseLogAppender extends AppenderSkeleton { - private static final String LOG_PATTERN = "%m%n"; - - private static final String BUNDLE_NAME = EMFPatternLanguageUIActivator.getInstance().getBundle().getSymbolicName(); - - private boolean initialized; - private ILog log; - - public EclipseLogAppender() { - super(); - layout = new PatternLayout(LOG_PATTERN); - } - - public EclipseLogAppender(boolean isActive) { - super(isActive); - layout = new PatternLayout(LOG_PATTERN); - } - - private synchronized void ensureInitialized() { - if (!initialized) { - log = Platform.getLog(Platform.getBundle(BUNDLE_NAME)); - initialized = true; - } - } - - private ILog getLog() { - ensureInitialized(); - return log; - } - - @Override - protected void append(LoggingEvent event) { - if (isDoLog(event.getLevel())) { - String logString = layout.format(event); - - ILog myLog = getLog(); - if (myLog != null) { - String loggerName = event.getLoggerName(); - int severity = mapLevel(event.getLevel()); - final Throwable throwable = event.getThrowableInformation() != null ? event.getThrowableInformation() - .getThrowable() : null; - IStatus status = createStatus(severity, loggerName, logString, throwable); - getLog().log(status); - } - } - } - - private boolean isDoLog(Level level) { - return level.toInt() >= Priority.WARN_INT; - } - - private int mapLevel(Level level) { - switch (level.toInt()) { - case Priority.DEBUG_INT: - case Priority.INFO_INT: - return IStatus.INFO; - - case Priority.WARN_INT: - return IStatus.WARNING; - - case Priority.ERROR_INT: - case Priority.FATAL_INT: - return IStatus.ERROR; - - default: - return IStatus.INFO; - } - } - - private IStatus createStatus(int severity, String loggerName, String message, Throwable throwable) { - return new Status(severity, BUNDLE_NAME, message, throwable); - } - - public void close() { - } - - public boolean requiresLayout() { - return true; - } + private static final String LOG_PATTERN = "%m%n"; + + private static final String BUNDLE_NAME = EMFPatternLanguageUIActivator.getInstance().getBundle().getSymbolicName(); + + private boolean initialized; + private ILog log; + + public EclipseLogAppender() { + super(); + layout = new PatternLayout(LOG_PATTERN); + } + + public EclipseLogAppender(boolean isActive) { + super(isActive); + layout = new PatternLayout(LOG_PATTERN); + } + + private synchronized void ensureInitialized() { + if (!initialized) { + log = Platform.getLog(Platform.getBundle(BUNDLE_NAME)); + initialized = true; + } + } + + private ILog getLog() { + ensureInitialized(); + return log; + } + + @Override + protected void append(LoggingEvent event) { + if (isDoLog(event.getLevel())) { + String logString = layout.format(event); + + ILog myLog = getLog(); + if (myLog != null) { + String loggerName = event.getLoggerName(); + int severity = mapLevel(event.getLevel()); + final Throwable throwable = event.getThrowableInformation() != null ? event.getThrowableInformation() + .getThrowable() : null; + IStatus status = createStatus(severity, loggerName, logString, throwable); + getLog().log(status); + } + } + } + + private boolean isDoLog(Level level) { + return level.toInt() >= Priority.WARN_INT; + } + + private int mapLevel(Level level) { + switch (level.toInt()) { + case Priority.DEBUG_INT: + case Priority.INFO_INT: + return IStatus.INFO; + + case Priority.WARN_INT: + return IStatus.WARNING; + + case Priority.ERROR_INT: + case Priority.FATAL_INT: + return IStatus.ERROR; + + default: + return IStatus.INFO; + } + } + + private IStatus createStatus(int severity, String loggerName, String message, Throwable throwable) { + return new Status(severity, BUNDLE_NAME, message, throwable); + } + + public void close() { + } + + public boolean requiresLayout() { + return true; + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/UiPluginInjectorProvider.java b/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/UiPluginInjectorProvider.java index 1c253e16..115ff803 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/UiPluginInjectorProvider.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/UiPluginInjectorProvider.java @@ -17,9 +17,10 @@ public class UiPluginInjectorProvider implements IInjectorProvider { - @Override - public Injector getInjector() { - return EMFPatternLanguageUIActivator.getInstance().getInjector(EMFPatternLanguageUIActivator.ORG_ECLIPSE_INCQUERY_PATTERNLANGUAGE_EMF_EMFPATTERNLANGUAGE); - } + @Override + public Injector getInjector() { + return EMFPatternLanguageUIActivator.getInstance().getInjector( + EMFPatternLanguageUIActivator.ORG_ECLIPSE_INCQUERY_PATTERNLANGUAGE_EMF_EMFPATTERNLANGUAGE); + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/contentassist/EMFPatternLanguageProposalProvider.java b/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/contentassist/EMFPatternLanguageProposalProvider.java index 131a0525..bf34f154 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/contentassist/EMFPatternLanguageProposalProvider.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/contentassist/EMFPatternLanguageProposalProvider.java @@ -56,193 +56,195 @@ import com.google.common.base.Predicates; import com.google.common.collect.Sets; import com.google.inject.Inject; + /** * see http://www.eclipse.org/Xtext/documentation/latest/xtext.html#contentAssist on how to customize content assistant */ public class EMFPatternLanguageProposalProvider extends AbstractEMFPatternLanguageProposalProvider { - - private static final Set FILTERED_KEYWORDS = Sets.newHashSet("pattern"); - - @Inject - IScopeProvider scopeProvider; - @Inject - ReferenceProposalCreator crossReferenceProposalCreator; - - public static class ClassifierPrefixMatcher extends PrefixMatcher { - private final PrefixMatcher delegate; - - private final IQualifiedNameConverter qualifiedNameConverter; - - - public ClassifierPrefixMatcher(PrefixMatcher delegate, IQualifiedNameConverter qualifiedNameConverter) { - this.delegate = delegate; - this.qualifiedNameConverter = qualifiedNameConverter; - } - - @Override - public boolean isCandidateMatchingPrefix(String name, String prefix) { - if (delegate.isCandidateMatchingPrefix(name, prefix)) - return true; - QualifiedName qualifiedName = qualifiedNameConverter.toQualifiedName(name); - QualifiedName qualifiedPrefix = qualifiedNameConverter.toQualifiedName(prefix); - if (qualifiedName.getSegmentCount() > 1) { - if (qualifiedPrefix.getSegmentCount() == 1) - return delegate.isCandidateMatchingPrefix(qualifiedName.getSegment(1), - qualifiedPrefix.getFirstSegment()); - if (!delegate.isCandidateMatchingPrefix(qualifiedName.getFirstSegment(), - qualifiedPrefix.getFirstSegment())) - return false; - return delegate.isCandidateMatchingPrefix(qualifiedName.getSegment(1), qualifiedPrefix.getSegment(1)); - } - return false; - } - - } - - /* (non-Javadoc) - * @see org.eclipse.xtext.xbase.ui.contentassist.XbaseProposalProvider#completeKeyword(org.eclipse.xtext.Keyword, org.eclipse.xtext.ui.editor.contentassist.ContentAssistContext, org.eclipse.xtext.ui.editor.contentassist.ICompletionProposalAcceptor) - */ - @Override - public void completeKeyword(Keyword keyword, - ContentAssistContext contentAssistContext, - ICompletionProposalAcceptor acceptor) { - // ignore keywords in FILTERED set - if (FILTERED_KEYWORDS.contains(keyword.getValue())) { - return; - } - super.completeKeyword(keyword, contentAssistContext, acceptor); - } - - @Override - public void complete_ValueReference(EObject model, RuleCall ruleCall, - ContentAssistContext context, ICompletionProposalAcceptor acceptor) { - super.complete_ValueReference(model, ruleCall, context, acceptor); - if (model instanceof PathExpressionHead) { - PathExpressionHead head = (PathExpressionHead) model; - try { - //XXX The following code re-specifies scoping instead of reusing the scope provider - EClassifier typeClassifier = EMFPatternLanguageScopeHelper.calculateExpressionType(head); - if (typeClassifier instanceof EEnum) { - //In case of EEnums add Enum Literal constants - EEnum type = (EEnum) typeClassifier; - for (EEnumLiteral literal : type.getELiterals()) { - acceptor.accept(createCompletionProposal( - "::" + literal.getName(), type.getName() + "::" + literal.getName(), - null, context)); - } - } - //XXX The following code re-specifies scoping instead of reusing the scope provider - // Always refer to existing variables - PatternBody body = (PatternBody) head.eContainer()/*PathExpression*/.eContainer()/*PatternBody*/; - for (Variable var : body.getVariables()) { - acceptor.accept(createCompletionProposal(var.getName(), context)); - } - Pattern pattern = (Pattern) body.eContainer(); - for (Variable var : pattern.getParameters()) { - acceptor.accept(createCompletionProposal(var.getName(), context)); - } - } catch (ResolutionException e) { - //If resolution fails, simply don't return anything - } - } - } - - @Override - public void completeType_Typename(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { - PatternModel pModel = null; - EObject root = getRootContainer(model); - if (root instanceof PatternModel){ - pModel = (PatternModel) root; - } - ContentAssistContext.Builder myContextBuilder = context.copy(); - myContextBuilder.setMatcher(new ClassifierPrefixMatcher(context.getMatcher(), getQualifiedNameConverter())); - ClassType type = null; - if (model instanceof Variable) { - type = (ClassType) ((Variable) model).getType(); - } else { - return; - } - - ICompositeNode node = NodeModelUtils.getNode(type); - int offset = node.getOffset(); - Region replaceRegion = new Region(offset, context.getReplaceRegion() - .getLength() + context.getReplaceRegion().getOffset() - offset); - myContextBuilder.setReplaceRegion(replaceRegion); - myContextBuilder.setLastCompleteNode(node); - StringBuilder availablePrefix = new StringBuilder(4); - for (ILeafNode leaf : node.getLeafNodes()) { - if (leaf.getGrammarElement() != null && !leaf.isHidden()) { - if ((leaf.getTotalLength() + leaf.getTotalOffset()) < context - .getOffset()) - availablePrefix.append(leaf.getText()); - else - availablePrefix.append(leaf.getText().substring(0, - context.getOffset() - leaf.getTotalOffset())); - } - if (leaf.getTotalOffset() >= context.getOffset()) - break; - } - myContextBuilder.setPrefix(availablePrefix.toString()); - - ContentAssistContext myContext = myContextBuilder.toContext(); - for (PackageImport declaration : pModel.getImportPackages()) { - if (declaration.getEPackage() != null) { - createClassifierProposals(declaration, model, myContext, acceptor); - } - } - } - - private void createClassifierProposals(PackageImport declaration, EObject model, - ContentAssistContext context, ICompletionProposalAcceptor acceptor) { - //String alias = declaration.getAlias(); - //QualifiedName prefix = (!Strings.isEmpty(alias)) - // ? QualifiedName.create(getValueConverter().toString(alias,"ID")) - // : null; - boolean createDatatypeProposals = modelOrContainerIs(model, Variable.class); - boolean createEnumProposals = modelOrContainerIs(model, EnumRule.class); - boolean createClassProposals = modelOrContainerIs(model, Variable.class); - Function factory = getProposalFactory(null, context); - for (EClassifier classifier : declaration.getEPackage().getEClassifiers()) { - if (classifier instanceof EDataType && createDatatypeProposals || classifier instanceof EEnum - && createEnumProposals || classifier instanceof EClass && createClassProposals) { - String classifierName = getValueConverter().toString(classifier.getName(), "ID"); - QualifiedName proposalQualifiedName = /*(prefix != null) ? prefix.append(classifierName) :*/ QualifiedName - .create(classifierName); - IEObjectDescription description = EObjectDescription.create(proposalQualifiedName, classifier); - ConfigurableCompletionProposal proposal = (ConfigurableCompletionProposal) factory.apply(description); - if (proposal != null) { - /*if (prefix != null) - proposal.setDisplayString(classifier.getName() + " - " + alias);*/ - proposal.setPriority(proposal.getPriority() * 2); - } - acceptor.accept(proposal); - } - } - } - - private boolean modelOrContainerIs(EObject model, Class... types) { - for (Class type : types) { - if (type.isInstance(model) || type.isInstance(model.eContainer())) - return true; - } - return false; - } - - public void complete_RefType(PathExpressionElement model, RuleCall ruleCall, - ContentAssistContext context, ICompletionProposalAcceptor acceptor) { - IScope scope = scopeProvider.getScope(model.getTail(), - EMFPatternLanguagePackage.Literals.REFERENCE_TYPE__REFNAME); - crossReferenceProposalCreator.lookupCrossReference(scope, model, - EMFPatternLanguagePackage.Literals.REFERENCE_TYPE__REFNAME, - acceptor, Predicates. alwaysTrue(), - getProposalFactory(ruleCall.getRule().getName(), context)); - } - - @Override - public void completeRefType_Refname(EObject model, Assignment assignment, - ContentAssistContext context, ICompletionProposalAcceptor acceptor) { - // This method is deliberately empty. - // This override prohibits the content assist to suggest incorrect parameters. - } - + + private static final Set FILTERED_KEYWORDS = Sets.newHashSet("pattern"); + + @Inject + IScopeProvider scopeProvider; + @Inject + ReferenceProposalCreator crossReferenceProposalCreator; + + public static class ClassifierPrefixMatcher extends PrefixMatcher { + private final PrefixMatcher delegate; + + private final IQualifiedNameConverter qualifiedNameConverter; + + public ClassifierPrefixMatcher(PrefixMatcher delegate, IQualifiedNameConverter qualifiedNameConverter) { + this.delegate = delegate; + this.qualifiedNameConverter = qualifiedNameConverter; + } + + @Override + public boolean isCandidateMatchingPrefix(String name, String prefix) { + if (delegate.isCandidateMatchingPrefix(name, prefix)) + return true; + QualifiedName qualifiedName = qualifiedNameConverter.toQualifiedName(name); + QualifiedName qualifiedPrefix = qualifiedNameConverter.toQualifiedName(prefix); + if (qualifiedName.getSegmentCount() > 1) { + if (qualifiedPrefix.getSegmentCount() == 1) + return delegate.isCandidateMatchingPrefix(qualifiedName.getSegment(1), + qualifiedPrefix.getFirstSegment()); + if (!delegate.isCandidateMatchingPrefix(qualifiedName.getFirstSegment(), + qualifiedPrefix.getFirstSegment())) + return false; + return delegate.isCandidateMatchingPrefix(qualifiedName.getSegment(1), qualifiedPrefix.getSegment(1)); + } + return false; + } + + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.xtext.xbase.ui.contentassist.XbaseProposalProvider#completeKeyword(org.eclipse.xtext.Keyword, + * org.eclipse.xtext.ui.editor.contentassist.ContentAssistContext, + * org.eclipse.xtext.ui.editor.contentassist.ICompletionProposalAcceptor) + */ + @Override + public void completeKeyword(Keyword keyword, ContentAssistContext contentAssistContext, + ICompletionProposalAcceptor acceptor) { + // ignore keywords in FILTERED set + if (FILTERED_KEYWORDS.contains(keyword.getValue())) { + return; + } + super.completeKeyword(keyword, contentAssistContext, acceptor); + } + + @Override + public void complete_ValueReference(EObject model, RuleCall ruleCall, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { + super.complete_ValueReference(model, ruleCall, context, acceptor); + if (model instanceof PathExpressionHead) { + PathExpressionHead head = (PathExpressionHead) model; + try { + // XXX The following code re-specifies scoping instead of reusing the scope provider + EClassifier typeClassifier = EMFPatternLanguageScopeHelper.calculateExpressionType(head); + if (typeClassifier instanceof EEnum) { + // In case of EEnums add Enum Literal constants + EEnum type = (EEnum) typeClassifier; + for (EEnumLiteral literal : type.getELiterals()) { + acceptor.accept(createCompletionProposal("::" + literal.getName(), type.getName() + "::" + + literal.getName(), null, context)); + } + } + // XXX The following code re-specifies scoping instead of reusing the scope provider + // Always refer to existing variables + PatternBody body = (PatternBody) head.eContainer()/* PathExpression */.eContainer()/* PatternBody */; + for (Variable var : body.getVariables()) { + acceptor.accept(createCompletionProposal(var.getName(), context)); + } + Pattern pattern = (Pattern) body.eContainer(); + for (Variable var : pattern.getParameters()) { + acceptor.accept(createCompletionProposal(var.getName(), context)); + } + } catch (ResolutionException e) { + // If resolution fails, simply don't return anything + } + } + } + + @Override + public void completeType_Typename(EObject model, Assignment assignment, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { + PatternModel pModel = null; + EObject root = getRootContainer(model); + if (root instanceof PatternModel) { + pModel = (PatternModel) root; + } + ContentAssistContext.Builder myContextBuilder = context.copy(); + myContextBuilder.setMatcher(new ClassifierPrefixMatcher(context.getMatcher(), getQualifiedNameConverter())); + ClassType type = null; + if (model instanceof Variable) { + type = (ClassType) ((Variable) model).getType(); + } else { + return; + } + + ICompositeNode node = NodeModelUtils.getNode(type); + int offset = node.getOffset(); + Region replaceRegion = new Region(offset, context.getReplaceRegion().getLength() + + context.getReplaceRegion().getOffset() - offset); + myContextBuilder.setReplaceRegion(replaceRegion); + myContextBuilder.setLastCompleteNode(node); + StringBuilder availablePrefix = new StringBuilder(4); + for (ILeafNode leaf : node.getLeafNodes()) { + if (leaf.getGrammarElement() != null && !leaf.isHidden()) { + if ((leaf.getTotalLength() + leaf.getTotalOffset()) < context.getOffset()) + availablePrefix.append(leaf.getText()); + else + availablePrefix.append(leaf.getText().substring(0, context.getOffset() - leaf.getTotalOffset())); + } + if (leaf.getTotalOffset() >= context.getOffset()) + break; + } + myContextBuilder.setPrefix(availablePrefix.toString()); + + ContentAssistContext myContext = myContextBuilder.toContext(); + for (PackageImport declaration : pModel.getImportPackages()) { + if (declaration.getEPackage() != null) { + createClassifierProposals(declaration, model, myContext, acceptor); + } + } + } + + private void createClassifierProposals(PackageImport declaration, EObject model, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { + // String alias = declaration.getAlias(); + // QualifiedName prefix = (!Strings.isEmpty(alias)) + // ? QualifiedName.create(getValueConverter().toString(alias,"ID")) + // : null; + boolean createDatatypeProposals = modelOrContainerIs(model, Variable.class); + boolean createEnumProposals = modelOrContainerIs(model, EnumRule.class); + boolean createClassProposals = modelOrContainerIs(model, Variable.class); + Function factory = getProposalFactory(null, context); + for (EClassifier classifier : declaration.getEPackage().getEClassifiers()) { + if (classifier instanceof EDataType && createDatatypeProposals || classifier instanceof EEnum + && createEnumProposals || classifier instanceof EClass && createClassProposals) { + String classifierName = getValueConverter().toString(classifier.getName(), "ID"); + QualifiedName proposalQualifiedName = /* (prefix != null) ? prefix.append(classifierName) : */QualifiedName + .create(classifierName); + IEObjectDescription description = EObjectDescription.create(proposalQualifiedName, classifier); + ConfigurableCompletionProposal proposal = (ConfigurableCompletionProposal) factory.apply(description); + if (proposal != null) { + /* + * if (prefix != null) proposal.setDisplayString(classifier.getName() + " - " + alias); + */ + proposal.setPriority(proposal.getPriority() * 2); + } + acceptor.accept(proposal); + } + } + } + + private boolean modelOrContainerIs(EObject model, Class... types) { + for (Class type : types) { + if (type.isInstance(model) || type.isInstance(model.eContainer())) + return true; + } + return false; + } + + public void complete_RefType(PathExpressionElement model, RuleCall ruleCall, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { + IScope scope = scopeProvider.getScope(model.getTail(), + EMFPatternLanguagePackage.Literals.REFERENCE_TYPE__REFNAME); + crossReferenceProposalCreator.lookupCrossReference(scope, model, + EMFPatternLanguagePackage.Literals.REFERENCE_TYPE__REFNAME, acceptor, + Predicates. alwaysTrue(), + getProposalFactory(ruleCall.getRule().getName(), context)); + } + + @Override + public void completeRefType_Refname(EObject model, Assignment assignment, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { + // This method is deliberately empty. + // This override prohibits the content assist to suggest incorrect parameters. + } + } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/feedback/GeneratorMarkerFeedback.java b/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/feedback/GeneratorMarkerFeedback.java index 5d309135..878edae8 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/feedback/GeneratorMarkerFeedback.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/feedback/GeneratorMarkerFeedback.java @@ -31,75 +31,74 @@ import com.google.inject.Inject; public class GeneratorMarkerFeedback implements IErrorFeedback { - - @Inject - private MarkerCreator markerCreator; - @Inject - private ILocationInFileProvider locationProvider; - @Inject - private Logger logger; - @Override - public void reportError(EObject ctx, String message, String errorCode, Severity severity, String markerType) { - try { - Resource res = ctx.eResource(); - if (res != null && res.getURI().isPlatformResource()) { - ITextRegion region = locationProvider - .getSignificantTextRegion(ctx); - IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); - IFile file = root.getFile(new Path(res.getURI() - .toPlatformString(true))); - createMarker(message, errorCode, markerType, file, region, severity); - } - } catch (CoreException e) { - logger.error("Error while creating error marker", e); - } - } + @Inject + private MarkerCreator markerCreator; + @Inject + private ILocationInFileProvider locationProvider; + @Inject + private Logger logger; - @Override - public void reportErrorNoLocation(EObject ctx, String message, String errorCode, Severity severity, String markerType) { - try { - Resource res = ctx.eResource(); - if (res != null && res.getURI().isPlatformResource()) { - ITextRegion region = ITextRegion.EMPTY_REGION; - IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); - IFile file = root.getFile(new Path(res.getURI() - .toPlatformString(true))); - createMarker(message, errorCode, markerType, file, region, severity); - } - } catch (CoreException e) { - logger.error("Error while creating error marker", e); - } - } + @Override + public void reportError(EObject ctx, String message, String errorCode, Severity severity, String markerType) { + try { + Resource res = ctx.eResource(); + if (res != null && res.getURI().isPlatformResource()) { + ITextRegion region = locationProvider.getSignificantTextRegion(ctx); + IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); + IFile file = root.getFile(new Path(res.getURI().toPlatformString(true))); + createMarker(message, errorCode, markerType, file, region, severity); + } + } catch (CoreException e) { + logger.error("Error while creating error marker", e); + } + } - @Override - public void reportError(IFile file, String message, String errorCode, Severity severity, String markerType) { - try { - ITextRegion region = ITextRegion.EMPTY_REGION; - createMarker(message, errorCode, markerType, file, region, severity); - } catch (CoreException e) { - logger.error("Error while creating error marker", e); - } - } - - private void createMarker(String message, String errorCode, String markerType, IFile file, - ITextRegion region, Severity severity) throws CoreException { - Issue.IssueImpl issue = new Issue.IssueImpl(); - issue.setOffset(region.getOffset()); - issue.setLength(region.getLength()); - issue.setMessage(message); - issue.setCode(errorCode); - issue.setSeverity(severity); - issue.setType(CheckType.EXPENSIVE); - markerCreator.createMarker(issue, file, markerType); - } - @Override - public void clearMarkers(IResource resource, String markerType) { - try { - resource.deleteMarkers(markerType, true, IResource.DEPTH_INFINITE); - } catch (CoreException e) { - logger.error("Error while clearing markers", e); - } - } + @Override + public void reportErrorNoLocation(EObject ctx, String message, String errorCode, Severity severity, + String markerType) { + try { + Resource res = ctx.eResource(); + if (res != null && res.getURI().isPlatformResource()) { + ITextRegion region = ITextRegion.EMPTY_REGION; + IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); + IFile file = root.getFile(new Path(res.getURI().toPlatformString(true))); + createMarker(message, errorCode, markerType, file, region, severity); + } + } catch (CoreException e) { + logger.error("Error while creating error marker", e); + } + } + + @Override + public void reportError(IFile file, String message, String errorCode, Severity severity, String markerType) { + try { + ITextRegion region = ITextRegion.EMPTY_REGION; + createMarker(message, errorCode, markerType, file, region, severity); + } catch (CoreException e) { + logger.error("Error while creating error marker", e); + } + } + + private void createMarker(String message, String errorCode, String markerType, IFile file, ITextRegion region, + Severity severity) throws CoreException { + Issue.IssueImpl issue = new Issue.IssueImpl(); + issue.setOffset(region.getOffset()); + issue.setLength(region.getLength()); + issue.setMessage(message); + issue.setCode(errorCode); + issue.setSeverity(severity); + issue.setType(CheckType.EXPENSIVE); + markerCreator.createMarker(issue, file, markerType); + } + + @Override + public void clearMarkers(IResource resource, String markerType) { + try { + resource.deleteMarkers(markerType, true, IResource.DEPTH_INFINITE); + } catch (CoreException e) { + logger.error("Error while clearing markers", e); + } + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/highlight/EMFPatternLanguageHighlightingCalculator.java b/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/highlight/EMFPatternLanguageHighlightingCalculator.java index dcd92b23..67e9053e 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/highlight/EMFPatternLanguageHighlightingCalculator.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/highlight/EMFPatternLanguageHighlightingCalculator.java @@ -33,65 +33,55 @@ import com.google.inject.Inject; @SuppressWarnings("restriction") -public class EMFPatternLanguageHighlightingCalculator extends - XbaseHighlightingCalculator { +public class EMFPatternLanguageHighlightingCalculator extends XbaseHighlightingCalculator { - @Inject - private PatternAnnotationProvider annotationProvider; + @Inject + private PatternAnnotationProvider annotationProvider; - @Override - protected void searchAndHighlightElements(XtextResource resource, IHighlightedPositionAcceptor acceptor) { - TreeIterator iterator = resource.getAllContents(); - while (iterator.hasNext()) { - EObject object = iterator.next(); - if (object instanceof XAbstractFeatureCall) { - computeFeatureCallHighlighting((XAbstractFeatureCall) object, acceptor); - } else if (object instanceof XNumberLiteral) { - // Handle XAnnotation in a special way because we want the @ highlighted too - highlightNumberLiterals((XNumberLiteral) object, acceptor); - } else if (object instanceof XAnnotation) { - highlightAnnotation((XAnnotation) object, acceptor); - } else if (object instanceof ClassType || object instanceof ReferenceType) { - ICompositeNode node = NodeModelUtils.findActualNodeFor(object); - highlightNode(node, EMFPatternLanguageHighlightingConfiguration.METAMODEL_REFERENCE, acceptor); - } else if (object instanceof Annotation - && annotationProvider.isDeprecated((Annotation) object)) { - Annotation annotation = (Annotation) object; - ICompositeNode compositeNode = NodeModelUtils - .findActualNodeFor(annotation); - INode node = null; - for (ILeafNode leafNode : compositeNode.getLeafNodes()) { - if (leafNode.getText().equals(annotation.getName())) { - node = leafNode; - break; - } - } - node = (node == null) ? compositeNode : node; - highlightNode(node, - XbaseHighlightingConfiguration.DEPRECATED_MEMBERS, - acceptor); - } else if (object instanceof AnnotationParameter - && annotationProvider - .isDeprecated((AnnotationParameter) object)) { - ICompositeNode compositeNode = NodeModelUtils - .findActualNodeFor(object); - INode node = null; - for (ILeafNode leafNode : compositeNode.getLeafNodes()) { - if (leafNode.getText().equals(((AnnotationParameter)object).getName())) { - node = leafNode; - break; - } + @Override + protected void searchAndHighlightElements(XtextResource resource, IHighlightedPositionAcceptor acceptor) { + TreeIterator iterator = resource.getAllContents(); + while (iterator.hasNext()) { + EObject object = iterator.next(); + if (object instanceof XAbstractFeatureCall) { + computeFeatureCallHighlighting((XAbstractFeatureCall) object, acceptor); + } else if (object instanceof XNumberLiteral) { + // Handle XAnnotation in a special way because we want the @ highlighted too + highlightNumberLiterals((XNumberLiteral) object, acceptor); + } else if (object instanceof XAnnotation) { + highlightAnnotation((XAnnotation) object, acceptor); + } else if (object instanceof ClassType || object instanceof ReferenceType) { + ICompositeNode node = NodeModelUtils.findActualNodeFor(object); + highlightNode(node, EMFPatternLanguageHighlightingConfiguration.METAMODEL_REFERENCE, acceptor); + } else if (object instanceof Annotation && annotationProvider.isDeprecated((Annotation) object)) { + Annotation annotation = (Annotation) object; + ICompositeNode compositeNode = NodeModelUtils.findActualNodeFor(annotation); + INode node = null; + for (ILeafNode leafNode : compositeNode.getLeafNodes()) { + if (leafNode.getText().equals(annotation.getName())) { + node = leafNode; + break; + } + } + node = (node == null) ? compositeNode : node; + highlightNode(node, XbaseHighlightingConfiguration.DEPRECATED_MEMBERS, acceptor); + } else if (object instanceof AnnotationParameter + && annotationProvider.isDeprecated((AnnotationParameter) object)) { + ICompositeNode compositeNode = NodeModelUtils.findActualNodeFor(object); + INode node = null; + for (ILeafNode leafNode : compositeNode.getLeafNodes()) { + if (leafNode.getText().equals(((AnnotationParameter) object).getName())) { + node = leafNode; + break; + } + } + node = (node == null) ? compositeNode : node; + + highlightNode(node, XbaseHighlightingConfiguration.DEPRECATED_MEMBERS, acceptor); + } else { + computeReferencedJvmTypeHighlighting(acceptor, object); + } } - node = (node == null) ? compositeNode : node; - - - highlightNode(node, - XbaseHighlightingConfiguration.DEPRECATED_MEMBERS, - acceptor); - } else { - computeReferencedJvmTypeHighlighting(acceptor, object); - } - } - } - + } + } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/highlight/EMFPatternLanguageHighlightingConfiguration.java b/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/highlight/EMFPatternLanguageHighlightingConfiguration.java index 2e8cb87a..f1c5ea4d 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/highlight/EMFPatternLanguageHighlightingConfiguration.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/highlight/EMFPatternLanguageHighlightingConfiguration.java @@ -18,22 +18,21 @@ import org.eclipse.xtext.xbase.ui.highlighting.XbaseHighlightingConfiguration; @SuppressWarnings("restriction") -public class EMFPatternLanguageHighlightingConfiguration extends - XbaseHighlightingConfiguration { +public class EMFPatternLanguageHighlightingConfiguration extends XbaseHighlightingConfiguration { - public static final String METAMODEL_REFERENCE = "incquery.metamodel.reference"; - - @Override - public void configure(IHighlightingConfigurationAcceptor acceptor) { - acceptor.acceptDefaultHighlighting(METAMODEL_REFERENCE, "EMF type reference", metamodelReference()); - - super.configure(acceptor); - } + public static final String METAMODEL_REFERENCE = "incquery.metamodel.reference"; - public TextStyle metamodelReference(){ - TextStyle textStyle = defaultTextStyle().copy(); - textStyle.setStyle(SWT.BOLD); - textStyle.setColor(new RGB(0, 26, 171)); - return textStyle; - } + @Override + public void configure(IHighlightingConfigurationAcceptor acceptor) { + acceptor.acceptDefaultHighlighting(METAMODEL_REFERENCE, "EMF type reference", metamodelReference()); + + super.configure(acceptor); + } + + public TextStyle metamodelReference() { + TextStyle textStyle = defaultTextStyle().copy(); + textStyle.setStyle(SWT.BOLD); + textStyle.setColor(new RGB(0, 26, 171)); + return textStyle; + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/labeling/EMFPatternLanguageDescriptionLabelProvider.java b/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/labeling/EMFPatternLanguageDescriptionLabelProvider.java index 17d81c4b..427aa89c 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/labeling/EMFPatternLanguageDescriptionLabelProvider.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/labeling/EMFPatternLanguageDescriptionLabelProvider.java @@ -19,16 +19,12 @@ */ public class EMFPatternLanguageDescriptionLabelProvider extends DefaultDescriptionLabelProvider { -/* - //Labels and icons can be computed like this: - - String text(IEObjectDescription ele) { - return "my "+ele.getName(); - } - - String image(IEObjectDescription ele) { - return ele.getEClass().getName() + ".gif"; - } -*/ + /* + * //Labels and icons can be computed like this: + * + * String text(IEObjectDescription ele) { return "my "+ele.getName(); } + * + * String image(IEObjectDescription ele) { return ele.getEClass().getName() + ".gif"; } + */ } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/labeling/EMFPatternLanguageHoverDocumentationProvider.java b/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/labeling/EMFPatternLanguageHoverDocumentationProvider.java index 40359ac1..c24c39b0 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/labeling/EMFPatternLanguageHoverDocumentationProvider.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/labeling/EMFPatternLanguageHoverDocumentationProvider.java @@ -29,76 +29,68 @@ /** * @author Zoltan Ujhelyi - * + * */ @SuppressWarnings("restriction") -public class EMFPatternLanguageHoverDocumentationProvider extends - XbaseHoverDocumentationProvider { +public class EMFPatternLanguageHoverDocumentationProvider extends XbaseHoverDocumentationProvider { + + @Inject + private IEiqGenmodelProvider genmodelProvider; + @Inject + private PatternAnnotationProvider annotationProvider; + @Inject + private ITypeProvider typeProvider; + @Inject + private IEMFTypeProvider emfTypeProvider; - @Inject - private IEiqGenmodelProvider genmodelProvider; - @Inject - private PatternAnnotationProvider annotationProvider; - @Inject - private ITypeProvider typeProvider; - @Inject - private IEMFTypeProvider emfTypeProvider; - - @Override - public String computeDocumentation(EObject object) { - if (object instanceof Annotation) { - String description = annotationProvider.getDescription((Annotation) object); - if (annotationProvider.isDeprecated((Annotation) object)) { - return "@deprecated

" + description; - } else { - return description; - } - } else if (object instanceof AnnotationParameter) { - String description = annotationProvider.getDescription((AnnotationParameter)object); - if (annotationProvider.isDeprecated((AnnotationParameter) object)) { - return "@deprecated

" + description; - } else { - return description; - } - } else if (object instanceof PackageImport) { - PackageImport packageImport = (PackageImport) object; - GenPackage genPackage = genmodelProvider.findGenPackage( - packageImport, packageImport.getEPackage()); - if (genPackage != null) { - return String.format( - "Genmodel found: %s
Package uri: %s", - genPackage.eResource().getURI().toString(), genPackage - .getEcorePackage().eResource().getURI() - .toString()); - } - } else if (object instanceof Variable) { - Variable variable = (Variable) object; - return calculateVariableHover(variable); - } else if (object instanceof VariableReference) { - VariableReference reference = (VariableReference) object; - return calculateVariableHover(reference.getVariable()); - } - return super.computeDocumentation(object); - } + @Override + public String computeDocumentation(EObject object) { + if (object instanceof Annotation) { + String description = annotationProvider.getDescription((Annotation) object); + if (annotationProvider.isDeprecated((Annotation) object)) { + return "@deprecated

" + description; + } else { + return description; + } + } else if (object instanceof AnnotationParameter) { + String description = annotationProvider.getDescription((AnnotationParameter) object); + if (annotationProvider.isDeprecated((AnnotationParameter) object)) { + return "@deprecated

" + description; + } else { + return description; + } + } else if (object instanceof PackageImport) { + PackageImport packageImport = (PackageImport) object; + GenPackage genPackage = genmodelProvider.findGenPackage(packageImport, packageImport.getEPackage()); + if (genPackage != null) { + return String.format("Genmodel found: %s
Package uri: %s", genPackage.eResource() + .getURI().toString(), genPackage.getEcorePackage().eResource().getURI().toString()); + } + } else if (object instanceof Variable) { + Variable variable = (Variable) object; + return calculateVariableHover(variable); + } else if (object instanceof VariableReference) { + VariableReference reference = (VariableReference) object; + return calculateVariableHover(reference.getVariable()); + } + return super.computeDocumentation(object); + } - /** - * @param variable - * @return - */ - private String calculateVariableHover(Variable variable) { - JvmTypeReference type = typeProvider.getTypeForIdentifiable(variable); - EClassifier emfType = emfTypeProvider - .getClassifierForVariable(variable); - String javaTypeString = type.getQualifiedName(); - String emfTypeString; - if (emfType == null) { - emfTypeString = "Not applicable"; - } else { - emfTypeString = String.format("%s (%s)", emfType.getName(), - emfType.getEPackage().getNsURI()); - } - return String.format("EMF Type: %s
Java Type: %s", - emfTypeString, javaTypeString); - } + /** + * @param variable + * @return + */ + private String calculateVariableHover(Variable variable) { + JvmTypeReference type = typeProvider.getTypeForIdentifiable(variable); + EClassifier emfType = emfTypeProvider.getClassifierForVariable(variable); + String javaTypeString = type.getQualifiedName(); + String emfTypeString; + if (emfType == null) { + emfTypeString = "Not applicable"; + } else { + emfTypeString = String.format("%s (%s)", emfType.getName(), emfType.getEPackage().getNsURI()); + } + return String.format("EMF Type: %s
Java Type: %s", emfTypeString, javaTypeString); + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/labeling/EMFPatternLanguageLabelProvider.java b/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/labeling/EMFPatternLanguageLabelProvider.java index c65899eb..4f673437 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/labeling/EMFPatternLanguageLabelProvider.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/labeling/EMFPatternLanguageLabelProvider.java @@ -55,138 +55,132 @@ */ public class EMFPatternLanguageLabelProvider extends DefaultEObjectLabelProvider { - @Inject - public EMFPatternLanguageLabelProvider(AdapterFactoryLabelProvider delegate) { - super(delegate); - } - - String text(PatternModel model) { - return "Pattern Model"; - } - - String text(PackageImport ele) { - String name = (ele.getEPackage() != null) ? ele.getEPackage().getName() : "«package»"; - return String.format("import %s", name); - } - - String text(Pattern pattern) { - return String.format("pattern %s/%d", pattern.getName(), pattern.getParameters().size()); - } - - String text(PatternBody ele) { - return String.format("body #%d", ((Pattern)ele.eContainer()).getBodies().indexOf(ele) + 1); - } - - String text(EClassifierConstraint constraint) { - String typename = ((ClassType)constraint.getType()).getClassname().getName(); - return String.format("%s (%s)", typename, constraint.getVar().getVar()); - } - - String text(CompareConstraint constraint) { - CompareFeature feature = constraint.getFeature(); - String op = feature.equals(CompareFeature.EQUALITY) ? "==" : - feature.equals(CompareFeature.INEQUALITY) ? "!=" : - ""; - String left = getValueText(constraint.getLeftOperand()); - String right = getValueText(constraint.getRightOperand()); - return String.format("%s %s %s", left, op, right); - } - - String text(PatternCompositionConstraint constraint) { - String modifiers = (constraint.isNegative()) ? "neg " : ""; - return String.format("%s%s", modifiers, text(constraint.getCall())); - } - - String text(PatternCall call) { - String transitiveOp = call.isTransitive() ? "+" : ""; - final String name = call.getPatternRef() == null ? "" : call.getPatternRef().getName(); - return String.format("find %s/%d%s", name, call.getParameters().size(), transitiveOp); - } - - String text(PathExpressionConstraint constraint) { - String typename = ((ClassType)constraint.getHead().getType()).getClassname().getName(); - String varName = (constraint.getHead().getSrc() != null) ? constraint.getHead().getSrc().getVar() : "«type»"; - return String.format("%s (%s)", typename, varName); - } - - String text(CheckConstraint constraint) { - return String.format("check()"); - } - - String text(AggregatedValue aggregate) { - String aggregator = getAggregatorText(aggregate.getAggregator()); - String call = text(aggregate.getCall()); - return String.format(/*"aggregate %s %s"*/"%s %s", aggregator, call); - } - - String text(PathExpressionTail tail) { - EStructuralFeature refname = ((ReferenceType)tail.getType()).getRefname(); - String type = (refname != null) ? refname.getName() : "«type»"; - String varName = ""; - if (tail.getTail() == null) { - PathExpressionHead head = EMFPatternLanguageScopeHelper.getExpressionHead(tail); - varName = String.format("(%s)",getValueText(head.getDst())); - } - return String.format("%s %s",type, varName); - } - - -// String text(ComputationValue computation) { -// -// } - - private String getAggregatorText(AggregatorExpression aggregator) { - if (aggregator instanceof CountAggregator) { - return String.format("count"); - } - else return aggregator.toString(); - } - - String getValueText(ValueReference ref) { - if (ref instanceof VariableValue) { - return ((VariableValue) ref).getValue().getVar(); - } else if (ref instanceof IntValue) { - return Integer.toString(((IntValue) ref).getValue()); - } else if (ref instanceof BoolValue) { - return Boolean.toString(((BoolValue) ref).isValue()); - } else if (ref instanceof DoubleValue) { - return Double.toString(((DoubleValue) ref).getValue()); - } else if (ref instanceof ListValue) { - EList values = ((ListValue) ref).getValues(); - List valueStrings = new ArrayList(); - for (ValueReference valueReference : values) { - valueStrings.add(getValueText(valueReference)); - } - return "{" + Strings.concat(", ", valueStrings)+ "}"; - } else if (ref instanceof StringValue) { - return "\"" + ((StringValue) ref).getValue() + "\""; - } else if (ref instanceof EnumValue) { - EnumValue enumVal = (EnumValue) ref; - if (enumVal.getLiteral() == null || enumVal.getLiteral().getLiteral() == null) { - return ""; - } - String enumName; - if (enumVal.getEnumeration() != null) { - enumName = enumVal.getEnumeration().getName(); - } else { - enumName = enumVal.getLiteral().getEEnum().getName(); - } - return enumName + "::" + enumVal.getLiteral().getLiteral(); - } else if (ref instanceof AggregatedValue) { - return text((AggregatedValue)ref); - } - return null; - } - -/* - //Labels and icons can be computed like this: - - String text(MyModel ele) { - return "my "+ele.getName(); - } - - String image(MyModel ele) { - return "MyModel.gif"; + @Inject + public EMFPatternLanguageLabelProvider(AdapterFactoryLabelProvider delegate) { + super(delegate); } -*/ + + String text(PatternModel model) { + return "Pattern Model"; + } + + String text(PackageImport ele) { + String name = (ele.getEPackage() != null) ? ele.getEPackage().getName() : "«package»"; + return String.format("import %s", name); + } + + String text(Pattern pattern) { + return String.format("pattern %s/%d", pattern.getName(), pattern.getParameters().size()); + } + + String text(PatternBody ele) { + return String.format("body #%d", ((Pattern) ele.eContainer()).getBodies().indexOf(ele) + 1); + } + + String text(EClassifierConstraint constraint) { + String typename = ((ClassType) constraint.getType()).getClassname().getName(); + return String.format("%s (%s)", typename, constraint.getVar().getVar()); + } + + String text(CompareConstraint constraint) { + CompareFeature feature = constraint.getFeature(); + String op = feature.equals(CompareFeature.EQUALITY) ? "==" : feature.equals(CompareFeature.INEQUALITY) ? "!=" + : ""; + String left = getValueText(constraint.getLeftOperand()); + String right = getValueText(constraint.getRightOperand()); + return String.format("%s %s %s", left, op, right); + } + + String text(PatternCompositionConstraint constraint) { + String modifiers = (constraint.isNegative()) ? "neg " : ""; + return String.format("%s%s", modifiers, text(constraint.getCall())); + } + + String text(PatternCall call) { + String transitiveOp = call.isTransitive() ? "+" : ""; + final String name = call.getPatternRef() == null ? "" : call.getPatternRef().getName(); + return String.format("find %s/%d%s", name, call.getParameters().size(), transitiveOp); + } + + String text(PathExpressionConstraint constraint) { + String typename = ((ClassType) constraint.getHead().getType()).getClassname().getName(); + String varName = (constraint.getHead().getSrc() != null) ? constraint.getHead().getSrc().getVar() : "«type»"; + return String.format("%s (%s)", typename, varName); + } + + String text(CheckConstraint constraint) { + return String.format("check()"); + } + + String text(AggregatedValue aggregate) { + String aggregator = getAggregatorText(aggregate.getAggregator()); + String call = text(aggregate.getCall()); + return String.format(/* "aggregate %s %s" */"%s %s", aggregator, call); + } + + String text(PathExpressionTail tail) { + EStructuralFeature refname = ((ReferenceType) tail.getType()).getRefname(); + String type = (refname != null) ? refname.getName() : "«type»"; + String varName = ""; + if (tail.getTail() == null) { + PathExpressionHead head = EMFPatternLanguageScopeHelper.getExpressionHead(tail); + varName = String.format("(%s)", getValueText(head.getDst())); + } + return String.format("%s %s", type, varName); + } + + // String text(ComputationValue computation) { + // + // } + + private String getAggregatorText(AggregatorExpression aggregator) { + if (aggregator instanceof CountAggregator) { + return String.format("count"); + } else + return aggregator.toString(); + } + + String getValueText(ValueReference ref) { + if (ref instanceof VariableValue) { + return ((VariableValue) ref).getValue().getVar(); + } else if (ref instanceof IntValue) { + return Integer.toString(((IntValue) ref).getValue()); + } else if (ref instanceof BoolValue) { + return Boolean.toString(((BoolValue) ref).isValue()); + } else if (ref instanceof DoubleValue) { + return Double.toString(((DoubleValue) ref).getValue()); + } else if (ref instanceof ListValue) { + EList values = ((ListValue) ref).getValues(); + List valueStrings = new ArrayList(); + for (ValueReference valueReference : values) { + valueStrings.add(getValueText(valueReference)); + } + return "{" + Strings.concat(", ", valueStrings) + "}"; + } else if (ref instanceof StringValue) { + return "\"" + ((StringValue) ref).getValue() + "\""; + } else if (ref instanceof EnumValue) { + EnumValue enumVal = (EnumValue) ref; + if (enumVal.getLiteral() == null || enumVal.getLiteral().getLiteral() == null) { + return ""; + } + String enumName; + if (enumVal.getEnumeration() != null) { + enumName = enumVal.getEnumeration().getName(); + } else { + enumName = enumVal.getLiteral().getEEnum().getName(); + } + return enumName + "::" + enumVal.getLiteral().getLiteral(); + } else if (ref instanceof AggregatedValue) { + return text((AggregatedValue) ref); + } + return null; + } + + /* + * //Labels and icons can be computed like this: + * + * String text(MyModel ele) { return "my "+ele.getName(); } + * + * String image(MyModel ele) { return "MyModel.gif"; } + */ } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/outline/EMFPatternLanguageOutlineTreeProvider.java b/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/outline/EMFPatternLanguageOutlineTreeProvider.java index 316a810a..767886aa 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/outline/EMFPatternLanguageOutlineTreeProvider.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/outline/EMFPatternLanguageOutlineTreeProvider.java @@ -32,70 +32,68 @@ * * @author Mark Czotter */ -public class EMFPatternLanguageOutlineTreeProvider extends - DefaultOutlineTreeProvider { +public class EMFPatternLanguageOutlineTreeProvider extends DefaultOutlineTreeProvider { - protected void _createChildren(DocumentRootNode parentNode, - PatternModel model) { - // adding a structuralfeaturenode for ecore package imports - createEStructuralFeatureNode( - parentNode, - model, - EMFPatternLanguagePackage.Literals.PATTERN_MODEL__IMPORT_PACKAGES, - _image(model), "import declarations", false); - // adding patterns to the default DocumentRootNode - for (EObject element : model.getPatterns()) { - createNode(parentNode, element); - } - } - - protected void _createChildren(IOutlineNode parentNode, Pattern model) { - if (model.getBodies().size() == 1) { - _createChildren(parentNode, model.getBodies().get(0)); - } else { - for (PatternBody body : model.getBodies()) { - createNode(parentNode, body); - } - } - } - - protected void _createChildren(IOutlineNode parentNode, EClassifierConstraint constraint) { - // By leaving this method empty, the EClass Constraint will not have any children in the outline view - } - - protected void _createChildren(IOutlineNode parentNode, PathExpressionConstraint constraint) { - PathExpressionHead head = constraint.getHead(); - if (head.getTail() != null) { - createNode(parentNode, head.getTail()); - } - } - - protected void _createChildren(IOutlineNode parentNode, PathExpressionTail tail) { - if (tail.getTail() != null) { - createNode(parentNode, tail.getTail()); - } - } - - protected void _createChildren(IOutlineNode parentNode, PatternCompositionConstraint constraint) { - // By leaving this method empty, the Pattern Composition Constraint will not have any children in the outline view - } - - /** - * Simple text styling for {@link Pattern}. - * @param pattern - * @return - */ - protected String _text(Pattern pattern) { - StringBuilder result = new StringBuilder(); - result.append(pattern.getName()); - result.append("("); - for (Iterator iter = pattern.getParameters().iterator();iter.hasNext();) { - result.append(iter.next().getName()); - if (iter.hasNext()) { - result.append(","); - } - } - result.append(")"); - return result.toString(); - } + protected void _createChildren(DocumentRootNode parentNode, PatternModel model) { + // adding a structuralfeaturenode for ecore package imports + createEStructuralFeatureNode(parentNode, model, + EMFPatternLanguagePackage.Literals.PATTERN_MODEL__IMPORT_PACKAGES, _image(model), + "import declarations", false); + // adding patterns to the default DocumentRootNode + for (EObject element : model.getPatterns()) { + createNode(parentNode, element); + } + } + + protected void _createChildren(IOutlineNode parentNode, Pattern model) { + if (model.getBodies().size() == 1) { + _createChildren(parentNode, model.getBodies().get(0)); + } else { + for (PatternBody body : model.getBodies()) { + createNode(parentNode, body); + } + } + } + + protected void _createChildren(IOutlineNode parentNode, EClassifierConstraint constraint) { + // By leaving this method empty, the EClass Constraint will not have any children in the outline view + } + + protected void _createChildren(IOutlineNode parentNode, PathExpressionConstraint constraint) { + PathExpressionHead head = constraint.getHead(); + if (head.getTail() != null) { + createNode(parentNode, head.getTail()); + } + } + + protected void _createChildren(IOutlineNode parentNode, PathExpressionTail tail) { + if (tail.getTail() != null) { + createNode(parentNode, tail.getTail()); + } + } + + protected void _createChildren(IOutlineNode parentNode, PatternCompositionConstraint constraint) { + // By leaving this method empty, the Pattern Composition Constraint will not have any children in the outline + // view + } + + /** + * Simple text styling for {@link Pattern}. + * + * @param pattern + * @return + */ + protected String _text(Pattern pattern) { + StringBuilder result = new StringBuilder(); + result.append(pattern.getName()); + result.append("("); + for (Iterator iter = pattern.getParameters().iterator(); iter.hasNext();) { + result.append(iter.next().getName()); + if (iter.hasNext()) { + result.append(","); + } + } + result.append(")"); + return result.toString(); + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/quickfix/EMFPatternLanguageQuickfixProvider.java b/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/quickfix/EMFPatternLanguageQuickfixProvider.java index ced26dc8..32b8b1c9 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/quickfix/EMFPatternLanguageQuickfixProvider.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/quickfix/EMFPatternLanguageQuickfixProvider.java @@ -31,47 +31,38 @@ public class EMFPatternLanguageQuickfixProvider extends DefaultQuickfixProvider { - @Fix(EMFIssueCodes.IDENTIFIER_AS_KEYWORD) - public void escapeKeywordAsIdentifier(final Issue issue, IssueResolutionAcceptor acceptor) { - acceptor.accept(issue, "Prefix Identifier", "Adds a ^ prefix to the identifier", null, new IModification() { - - @Override - public void apply(IModificationContext context) throws Exception { - IXtextDocument document = context.getXtextDocument(); - document.replace(issue.getOffset(), 0, "^"); - } - }); - } - - @Fix(EMFIssueCodes.IMPORT_DEPENDENCY_MISSING) - public void addDependency(final Issue issue, - IssueResolutionAcceptor acceptor) { - acceptor.accept(issue, "Add dependency", - "Add the required bundle to the manifest.mf file.", null, - new IModification() { + @Fix(EMFIssueCodes.IDENTIFIER_AS_KEYWORD) + public void escapeKeywordAsIdentifier(final Issue issue, IssueResolutionAcceptor acceptor) { + acceptor.accept(issue, "Prefix Identifier", "Adds a ^ prefix to the identifier", null, new IModification() { - @Override - public void apply(IModificationContext context) - throws CoreException, BadLocationException { - URI uriToProblem = issue.getUriToProblem(); - if (uriToProblem.isPlatform()) { - IWorkspaceRoot root = ResourcesPlugin - .getWorkspace().getRoot(); - IFile file = root.getFile(new Path(uriToProblem - .toPlatformString(true))); - if (file.exists() && !file.isReadOnly()) - ProjectGenerationHelper - .ensureBundleDependencies( - file.getProject(), - Arrays.asList(issue.getData())); - // The following change changes the document thus - // triggers its parsing - IXtextDocument document = context - .getXtextDocument(); - document.replace(issue.getOffset(), 1, - document.get(issue.getOffset(), 1)); - } - } - }); - } + @Override + public void apply(IModificationContext context) throws Exception { + IXtextDocument document = context.getXtextDocument(); + document.replace(issue.getOffset(), 0, "^"); + } + }); + } + + @Fix(EMFIssueCodes.IMPORT_DEPENDENCY_MISSING) + public void addDependency(final Issue issue, IssueResolutionAcceptor acceptor) { + acceptor.accept(issue, "Add dependency", "Add the required bundle to the manifest.mf file.", null, + new IModification() { + + @Override + public void apply(IModificationContext context) throws CoreException, BadLocationException { + URI uriToProblem = issue.getUriToProblem(); + if (uriToProblem.isPlatform()) { + IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); + IFile file = root.getFile(new Path(uriToProblem.toPlatformString(true))); + if (file.exists() && !file.isReadOnly()) + ProjectGenerationHelper.ensureBundleDependencies(file.getProject(), + Arrays.asList(issue.getData())); + // The following change changes the document thus + // triggers its parsing + IXtextDocument document = context.getXtextDocument(); + document.replace(issue.getOffset(), 1, document.get(issue.getOffset(), 1)); + } + } + }); + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/refactoring/EMFPatternLanguageRenameStrategy.java b/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/refactoring/EMFPatternLanguageRenameStrategy.java index a931d467..79f0cd4f 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/refactoring/EMFPatternLanguageRenameStrategy.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/refactoring/EMFPatternLanguageRenameStrategy.java @@ -9,23 +9,23 @@ * Zoltan Ujhelyi - initial API and implementation *******************************************************************************/ /* -* generated by Xtext -*/ + * generated by Xtext + */ package org.eclipse.incquery.patternlanguage.emf.ui.refactoring; import org.eclipse.emf.ecore.EObject; import org.eclipse.xtext.xbase.ui.jvmmodel.refactoring.DefaultJvmModelRenameStrategy; /** - * Encapsulates the model changes of a rename refactoring. + * Encapsulates the model changes of a rename refactoring. */ @SuppressWarnings("restriction") public class EMFPatternLanguageRenameStrategy extends DefaultJvmModelRenameStrategy { - @Override - protected void setInferredJvmElementName(String name, EObject renamedSourceElement) { - /* - * TODO: rename inferred elements as you would in IJvmModelInferrer - */ - } + @Override + protected void setInferredJvmElementName(String name, EObject renamedSourceElement) { + /* + * TODO: rename inferred elements as you would in IJvmModelInferrer + */ + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/validation/GenmodelBasedEMFPatternLanguageJavaValidator.java b/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/validation/GenmodelBasedEMFPatternLanguageJavaValidator.java index d6de24cb..b7995e6a 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/validation/GenmodelBasedEMFPatternLanguageJavaValidator.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf.ui/src/org/eclipse/incquery/patternlanguage/emf/ui/validation/GenmodelBasedEMFPatternLanguageJavaValidator.java @@ -28,47 +28,40 @@ import com.google.inject.Inject; -public class GenmodelBasedEMFPatternLanguageJavaValidator extends - EMFPatternLanguageJavaValidator { +public class GenmodelBasedEMFPatternLanguageJavaValidator extends EMFPatternLanguageJavaValidator { - @Inject - private IEiqGenmodelProvider genmodelProvider; - @Inject - private IJavaProjectProvider projectProvider; - @Inject - private Logger logger; - - @Check - public void checkImportDependency(PackageImport importDecl) { - Resource res = importDecl.eResource(); - if (projectProvider == null || res == null) { - return; - } - IProject project = projectProvider.getJavaProject( - res.getResourceSet()).getProject(); - GenPackage genPackage = genmodelProvider.findGenPackage(importDecl, importDecl.getEPackage()); - if (genPackage != null) { - final GenModel genmodel = genPackage.getGenModel(); - if (genmodel != null) { - String modelPluginID = genmodel.getModelPluginID(); - try { - if (modelPluginID != null - && !modelPluginID.isEmpty() - && !ProjectGenerationHelper.checkBundleDependency( - project, modelPluginID)) { - error(String - .format("To refer elements from the Package %s the bundle %s must be added as dependency", - importDecl.getEPackage().getNsURI(), - modelPluginID), - importDecl, - EMFPatternLanguagePackage.Literals.PACKAGE_IMPORT__EPACKAGE, - EMFIssueCodes.IMPORT_DEPENDENCY_MISSING, - modelPluginID); - } - } catch (CoreException e) { - logger.error("Error while checking the dependencies of the import declaration", e); - } - } - } - } + @Inject + private IEiqGenmodelProvider genmodelProvider; + @Inject + private IJavaProjectProvider projectProvider; + @Inject + private Logger logger; + + @Check + public void checkImportDependency(PackageImport importDecl) { + Resource res = importDecl.eResource(); + if (projectProvider == null || res == null) { + return; + } + IProject project = projectProvider.getJavaProject(res.getResourceSet()).getProject(); + GenPackage genPackage = genmodelProvider.findGenPackage(importDecl, importDecl.getEPackage()); + if (genPackage != null) { + final GenModel genmodel = genPackage.getGenModel(); + if (genmodel != null) { + String modelPluginID = genmodel.getModelPluginID(); + try { + if (modelPluginID != null && !modelPluginID.isEmpty() + && !ProjectGenerationHelper.checkBundleDependency(project, modelPluginID)) { + error(String.format( + "To refer elements from the Package %s the bundle %s must be added as dependency", + importDecl.getEPackage().getNsURI(), modelPluginID), importDecl, + EMFPatternLanguagePackage.Literals.PACKAGE_IMPORT__EPACKAGE, + EMFIssueCodes.IMPORT_DEPENDENCY_MISSING, modelPluginID); + } + } catch (CoreException e) { + logger.error("Error while checking the dependencies of the import declaration", e); + } + } + } + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/EMFPatternLanguageQualifiedNameProvider.java b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/EMFPatternLanguageQualifiedNameProvider.java index 6d6ce429..bb20ed66 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/EMFPatternLanguageQualifiedNameProvider.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/EMFPatternLanguageQualifiedNameProvider.java @@ -23,43 +23,40 @@ /** * @author Zoltan Ujhelyi - * + * */ -public class EMFPatternLanguageQualifiedNameProvider extends - XbaseQualifiedNameProvider { +public class EMFPatternLanguageQualifiedNameProvider extends XbaseQualifiedNameProvider { + + @Inject + IQualifiedNameConverter nameConverter; - @Inject - IQualifiedNameConverter nameConverter; - - @Override - public QualifiedName getFullyQualifiedName(EObject obj) { - if (obj instanceof PackageImport) { - PackageImport packageImport = (PackageImport) obj; - String nsURI = (packageImport.getEPackage() != null) ? packageImport - .getEPackage().getNsURI() : ""; - return nameConverter.toQualifiedName("import.nsUri." + nsURI); - } else if (obj instanceof Annotation) { - Annotation annotation = (Annotation) obj; - String name = (annotation != null) ? annotation.getName() - : ""; - return nameConverter.toQualifiedName("annotation." + name); - } else if (obj instanceof AnnotationParameter) { - AnnotationParameter parameter = (AnnotationParameter) obj; - Annotation annotation = (Annotation) parameter.eContainer(); - getFullyQualifiedName(annotation).append(parameter.getName()); - } else if (obj instanceof VariableReference) { - VariableReference variableRef = (VariableReference) obj; - QualifiedName containerName = getFullyQualifiedName(variableRef.eContainer()); + @Override + public QualifiedName getFullyQualifiedName(EObject obj) { + if (obj instanceof PackageImport) { + PackageImport packageImport = (PackageImport) obj; + String nsURI = (packageImport.getEPackage() != null) ? packageImport.getEPackage().getNsURI() : ""; + return nameConverter.toQualifiedName("import.nsUri." + nsURI); + } else if (obj instanceof Annotation) { + Annotation annotation = (Annotation) obj; + String name = (annotation != null) ? annotation.getName() : ""; + return nameConverter.toQualifiedName("annotation." + name); + } else if (obj instanceof AnnotationParameter) { + AnnotationParameter parameter = (AnnotationParameter) obj; + Annotation annotation = (Annotation) parameter.eContainer(); + getFullyQualifiedName(annotation).append(parameter.getName()); + } else if (obj instanceof VariableReference) { + VariableReference variableRef = (VariableReference) obj; + QualifiedName containerName = getFullyQualifiedName(variableRef.eContainer()); String name = variableRef.getVar(); - if (name == null) { - return nameConverter.toQualifiedName(""); - } else if (containerName == null) { - return nameConverter.toQualifiedName(name); - } else { - return containerName.append(name); - } - } - return super.getFullyQualifiedName(obj); - } + if (name == null) { + return nameConverter.toQualifiedName(""); + } else if (containerName == null) { + return nameConverter.toQualifiedName(name); + } else { + return containerName.append(name); + } + } + return super.getFullyQualifiedName(obj); + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/EMFPatternLanguageRuntimeModule.java b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/EMFPatternLanguageRuntimeModule.java index 4e72e8f6..7dc6bc71 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/EMFPatternLanguageRuntimeModule.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/EMFPatternLanguageRuntimeModule.java @@ -42,61 +42,63 @@ */ public class EMFPatternLanguageRuntimeModule extends AbstractEMFPatternLanguageRuntimeModule { - @Provides - Logger provideLoggerImplementation() { - return Logger.getLogger(EMFPatternLanguageRuntimeModule.class); - } - - @Override - public Class bindILinkingService() { - return EMFPatternLanguageLinkingService.class; - } + @Provides + Logger provideLoggerImplementation() { + return Logger.getLogger(EMFPatternLanguageRuntimeModule.class); + } - // contributed by org.eclipse.xtext.generator.xbase.XbaseGeneratorFragment - @Override - public void configureIScopeProviderDelegate(Binder binder) { - binder.bind(IScopeProvider.class).annotatedWith(Names.named(AbstractDeclarativeScopeProvider.NAMED_DELEGATE)).to(EMFPatternLanguageDeclarativeScopeProvider.class); - binder.bind(IScopeProvider.class).annotatedWith(Names.named(MyAbstractDeclarativeScopeProvider.NAMED_DELEGATE)).to(XbaseImportedNamespaceScopeProvider.class); - } - - @Override + @Override + public Class bindILinkingService() { + return EMFPatternLanguageLinkingService.class; + } + + // contributed by org.eclipse.xtext.generator.xbase.XbaseGeneratorFragment + @Override + public void configureIScopeProviderDelegate(Binder binder) { + binder.bind(IScopeProvider.class).annotatedWith(Names.named(AbstractDeclarativeScopeProvider.NAMED_DELEGATE)) + .to(EMFPatternLanguageDeclarativeScopeProvider.class); + binder.bind(IScopeProvider.class).annotatedWith(Names.named(MyAbstractDeclarativeScopeProvider.NAMED_DELEGATE)) + .to(XbaseImportedNamespaceScopeProvider.class); + } + + @Override public Class bindIDefaultResourceDescriptionStrategy() { - return PatternLanguageResourceDescriptionStrategy.class; - } - - @Override - public Class bindIScopeProvider() { - return EMFPatternLanguageScopeProvider.class; - } - - // contributed by org.eclipse.xtext.generator.xbase.XbaseGeneratorFragment - @Override - public Class bindITypeProvider() { - return EMFPatternTypeProvider.class; - } - - public Class bindIEMFTypeProvider() { - return EMFPatternTypeProvider.class; - } - - public Class bindIMetamodelProvider() { - return MetamodelProviderService.class; - } - - public Class bindICrossReferenceSerializer() { - return EMFPatternLanguageCrossRefSerializer.class; - } - - public Class bindISyntaxErrorMessageProvider() { - return EMFPatternLanguageSyntaxErrorMessageProvider.class; - } + return PatternLanguageResourceDescriptionStrategy.class; + } + + @Override + public Class bindIScopeProvider() { + return EMFPatternLanguageScopeProvider.class; + } + + // contributed by org.eclipse.xtext.generator.xbase.XbaseGeneratorFragment + @Override + public Class bindITypeProvider() { + return EMFPatternTypeProvider.class; + } + + public Class bindIEMFTypeProvider() { + return EMFPatternTypeProvider.class; + } + + public Class bindIMetamodelProvider() { + return MetamodelProviderService.class; + } + + public Class bindICrossReferenceSerializer() { + return EMFPatternLanguageCrossRefSerializer.class; + } + + public Class bindISyntaxErrorMessageProvider() { + return EMFPatternLanguageSyntaxErrorMessageProvider.class; + } + + @Override + public Class bindIQualifiedNameProvider() { + return EMFPatternLanguageQualifiedNameProvider.class; + } - @Override - public Class bindIQualifiedNameProvider() { - return EMFPatternLanguageQualifiedNameProvider.class; - } - - public Class bindIGlobalServiceProvider() { - return EMFPatternLanguageServiceProvider.class; - } + public Class bindIGlobalServiceProvider() { + return EMFPatternLanguageServiceProvider.class; + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/EMFPatternLanguageScopeHelper.java b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/EMFPatternLanguageScopeHelper.java index 7b854ea2..9902f658 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/EMFPatternLanguageScopeHelper.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/EMFPatternLanguageScopeHelper.java @@ -19,47 +19,47 @@ public final class EMFPatternLanguageScopeHelper { - public static final String NOT_AN_ENUMERATION_REFERENCE_ERROR = "Not an enumeration reference"; - - private EMFPatternLanguageScopeHelper(){} + public static final String NOT_AN_ENUMERATION_REFERENCE_ERROR = "Not an enumeration reference"; - public static EEnum calculateEnumerationType(PathExpressionHead head) throws ResolutionException{ - if (head.getTail() == null) { - throw new ResolutionException(NOT_AN_ENUMERATION_REFERENCE_ERROR); - } - return calculateEnumerationType(head.getTail()); - } - - public static EEnum calculateEnumerationType(PathExpressionTail tail) throws ResolutionException{ - EClassifier classifier = calculateExpressionType(tail); - if (classifier instanceof EEnum) { - return (EEnum) classifier; - } - throw new ResolutionException(NOT_AN_ENUMERATION_REFERENCE_ERROR); - } - - public static EClassifier calculateExpressionType(PathExpressionHead head) throws ResolutionException{ - if (head.getTail() == null) { - throw new ResolutionException(NOT_AN_ENUMERATION_REFERENCE_ERROR); - } - return calculateExpressionType(head.getTail()); - } + private EMFPatternLanguageScopeHelper() { + } - public static EClassifier calculateExpressionType(PathExpressionTail tail) - throws ResolutionException { - if (tail.getTail() == null) { - Type type = tail.getType(); - return ((ReferenceType)type).getRefname().getEType(); - } else { - return calculateEnumerationType(tail.getTail()); - } - } - - public static PathExpressionHead getExpressionHead(PathExpressionTail tail) { - if (tail.eContainer() instanceof PathExpressionHead) { - return (PathExpressionHead) tail.eContainer(); - } else { - return getExpressionHead((PathExpressionTail) tail.eContainer()); - } - } + public static EEnum calculateEnumerationType(PathExpressionHead head) throws ResolutionException { + if (head.getTail() == null) { + throw new ResolutionException(NOT_AN_ENUMERATION_REFERENCE_ERROR); + } + return calculateEnumerationType(head.getTail()); + } + + public static EEnum calculateEnumerationType(PathExpressionTail tail) throws ResolutionException { + EClassifier classifier = calculateExpressionType(tail); + if (classifier instanceof EEnum) { + return (EEnum) classifier; + } + throw new ResolutionException(NOT_AN_ENUMERATION_REFERENCE_ERROR); + } + + public static EClassifier calculateExpressionType(PathExpressionHead head) throws ResolutionException { + if (head.getTail() == null) { + throw new ResolutionException(NOT_AN_ENUMERATION_REFERENCE_ERROR); + } + return calculateExpressionType(head.getTail()); + } + + public static EClassifier calculateExpressionType(PathExpressionTail tail) throws ResolutionException { + if (tail.getTail() == null) { + Type type = tail.getType(); + return ((ReferenceType) type).getRefname().getEType(); + } else { + return calculateEnumerationType(tail.getTail()); + } + } + + public static PathExpressionHead getExpressionHead(PathExpressionTail tail) { + if (tail.eContainer() instanceof PathExpressionHead) { + return (PathExpressionHead) tail.eContainer(); + } else { + return getExpressionHead((PathExpressionTail) tail.eContainer()); + } + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/EMFPatternLanguageServiceProvider.java b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/EMFPatternLanguageServiceProvider.java index e5f5a2d1..94a6bebd 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/EMFPatternLanguageServiceProvider.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/EMFPatternLanguageServiceProvider.java @@ -22,30 +22,28 @@ /** * @author Zoltan Ujhelyi - * + * */ -public class EMFPatternLanguageServiceProvider extends - ResourceServiceProviderImpl { +public class EMFPatternLanguageServiceProvider extends ResourceServiceProviderImpl { - private final IResourceServiceProvider serviceProvider; + private final IResourceServiceProvider serviceProvider; - @Inject - public EMFPatternLanguageServiceProvider(Registry registry, - IResourceServiceProvider serviceProvider) { - super(registry, serviceProvider); - this.serviceProvider = serviceProvider; - } + @Inject + public EMFPatternLanguageServiceProvider(Registry registry, IResourceServiceProvider serviceProvider) { + super(registry, serviceProvider); + this.serviceProvider = serviceProvider; + } - @Override - public T findService(EObject eObject, Class serviceClazz) { - Resource res = eObject.eResource(); - String nsURI = eObject.eClass().getEPackage().getNsURI(); - if (res == null && (nsURI.equals(PatternLanguagePackage.eNS_URI) || - nsURI.equals(EMFPatternLanguagePackage.eNS_URI))) { - T service = serviceProvider.get(serviceClazz); - return service; - } else { - return super.findService(eObject, serviceClazz); - } - } + @Override + public T findService(EObject eObject, Class serviceClazz) { + Resource res = eObject.eResource(); + String nsURI = eObject.eClass().getEPackage().getNsURI(); + if (res == null + && (nsURI.equals(PatternLanguagePackage.eNS_URI) || nsURI.equals(EMFPatternLanguagePackage.eNS_URI))) { + T service = serviceProvider.get(serviceClazz); + return service; + } else { + return super.findService(eObject, serviceClazz); + } + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/EMFPatternLanguageStandaloneSetup.java b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/EMFPatternLanguageStandaloneSetup.java index c4c404dd..a7900406 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/EMFPatternLanguageStandaloneSetup.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/EMFPatternLanguageStandaloneSetup.java @@ -10,15 +10,12 @@ *******************************************************************************/ package org.eclipse.incquery.patternlanguage.emf; - /** - * Initialization support for running Xtext languages - * without equinox extension registry + * Initialization support for running Xtext languages without equinox extension registry */ -public class EMFPatternLanguageStandaloneSetup extends EMFPatternLanguageStandaloneSetupGenerated{ +public class EMFPatternLanguageStandaloneSetup extends EMFPatternLanguageStandaloneSetupGenerated { - public static void doSetup() { - new EMFPatternLanguageStandaloneSetup().createInjectorAndDoEMFRegistration(); - } + public static void doSetup() { + new EMFPatternLanguageStandaloneSetup().createInjectorAndDoEMFRegistration(); + } } - diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/EcoreGenmodelRegistry.java b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/EcoreGenmodelRegistry.java index beafe156..e231ce3c 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/EcoreGenmodelRegistry.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/EcoreGenmodelRegistry.java @@ -27,76 +27,72 @@ public class EcoreGenmodelRegistry { - private static final String EPACKAGE_EXTENSION_ID = "org.eclipse.emf.ecore.generated_package"; - private static final String GENMODEL_ATTRIBUTE = "genModel"; - private static final String URI_ATTRIBUTE = "uri"; - private Map genmodelUriMap = Maps.newHashMap(); - private Map genpackageMap = Maps.newHashMap(); - private Logger logger; - - public EcoreGenmodelRegistry(Logger logger) { - this.logger = logger; - - if (Platform.getExtensionRegistry() == null) { - return; - } - IConfigurationElement[] packages = Platform.getExtensionRegistry() - .getConfigurationElementsFor(EPACKAGE_EXTENSION_ID); - for (IConfigurationElement packageExtension : packages) { - if (packageExtension.isValid()) { - String genmodelUri = packageExtension - .getAttribute(GENMODEL_ATTRIBUTE); - if (genmodelUri != null && !genmodelUri.isEmpty()) { - String uri = packageExtension.getAttribute(URI_ATTRIBUTE); - if (URI.createURI(genmodelUri).isRelative()) { - genmodelUriMap.put(uri, String.format("platform:/plugin/%s/%s", - packageExtension.getContributor().getName(), - genmodelUri)); - } else { - genmodelUriMap.put(uri, genmodelUri); - } - } - } - } - } + private static final String EPACKAGE_EXTENSION_ID = "org.eclipse.emf.ecore.generated_package"; + private static final String GENMODEL_ATTRIBUTE = "genModel"; + private static final String URI_ATTRIBUTE = "uri"; + private Map genmodelUriMap = Maps.newHashMap(); + private Map genpackageMap = Maps.newHashMap(); + private Logger logger; - public GenPackage findGenPackage(String nsURI, ResourceSet set) { - if (!genpackageMap.containsKey(nsURI)) { - if (!genmodelUriMap.containsKey(nsURI)) { - return null; - } - GenPackage genPackage = loadGenPackage(nsURI, genmodelUriMap.get(nsURI), set); - if (genPackage != null) { - genpackageMap.put(nsURI, genPackage); - } - return genPackage; - } - return genpackageMap.get(nsURI); - } - - private GenPackage loadGenPackage(String nsURI, String genmodelUri, ResourceSet set) { - try { - URI uri = URI.createURI(genmodelUri); - if (uri.isRelative()) { - uri = URI.createPlatformPluginURI(genmodelUri, true); - } - Resource resource = set.getResource(uri, true); - TreeIterator it = resource.getAllContents(); - while (it.hasNext()) { - EObject object = it.next(); - if (object instanceof GenPackage) { - if (((GenPackage) object).getNSURI().equals(nsURI)) { - return (GenPackage) object; - } else if (object instanceof GenModel) { - it.prune(); - } - } - } - } catch (RuntimeException ex) { - logger.error( - "Error while retrieving genmodel of EPackage " + nsURI - + " from location: " + genmodelUri, ex); - } - return null; - } + public EcoreGenmodelRegistry(Logger logger) { + this.logger = logger; + + if (Platform.getExtensionRegistry() == null) { + return; + } + IConfigurationElement[] packages = Platform.getExtensionRegistry().getConfigurationElementsFor( + EPACKAGE_EXTENSION_ID); + for (IConfigurationElement packageExtension : packages) { + if (packageExtension.isValid()) { + String genmodelUri = packageExtension.getAttribute(GENMODEL_ATTRIBUTE); + if (genmodelUri != null && !genmodelUri.isEmpty()) { + String uri = packageExtension.getAttribute(URI_ATTRIBUTE); + if (URI.createURI(genmodelUri).isRelative()) { + genmodelUriMap.put(uri, String.format("platform:/plugin/%s/%s", packageExtension + .getContributor().getName(), genmodelUri)); + } else { + genmodelUriMap.put(uri, genmodelUri); + } + } + } + } + } + + public GenPackage findGenPackage(String nsURI, ResourceSet set) { + if (!genpackageMap.containsKey(nsURI)) { + if (!genmodelUriMap.containsKey(nsURI)) { + return null; + } + GenPackage genPackage = loadGenPackage(nsURI, genmodelUriMap.get(nsURI), set); + if (genPackage != null) { + genpackageMap.put(nsURI, genPackage); + } + return genPackage; + } + return genpackageMap.get(nsURI); + } + + private GenPackage loadGenPackage(String nsURI, String genmodelUri, ResourceSet set) { + try { + URI uri = URI.createURI(genmodelUri); + if (uri.isRelative()) { + uri = URI.createPlatformPluginURI(genmodelUri, true); + } + Resource resource = set.getResource(uri, true); + TreeIterator it = resource.getAllContents(); + while (it.hasNext()) { + EObject object = it.next(); + if (object instanceof GenPackage) { + if (((GenPackage) object).getNSURI().equals(nsURI)) { + return (GenPackage) object; + } else if (object instanceof GenModel) { + it.prune(); + } + } + } + } catch (RuntimeException ex) { + logger.error("Error while retrieving genmodel of EPackage " + nsURI + " from location: " + genmodelUri, ex); + } + return null; + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/IResourceSetPreparer.java b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/IResourceSetPreparer.java index e4615ae6..317ebd43 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/IResourceSetPreparer.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/IResourceSetPreparer.java @@ -13,5 +13,5 @@ import org.eclipse.emf.ecore.resource.ResourceSet; public interface IResourceSetPreparer { - void prepareResourceSet(ResourceSet set); + void prepareResourceSet(ResourceSet set); } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/ResolutionException.java b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/ResolutionException.java index 7e0d125f..4d789da1 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/ResolutionException.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/ResolutionException.java @@ -12,23 +12,22 @@ public class ResolutionException extends Exception { - private static final long serialVersionUID = 5920889201819465489L; + private static final long serialVersionUID = 5920889201819465489L; - public ResolutionException() { - super(); - } + public ResolutionException() { + super(); + } - public ResolutionException(String message, Throwable cause) { - super(message, cause); - } + public ResolutionException(String message, Throwable cause) { + super(message, cause); + } - public ResolutionException(String message) { - super(message); - } + public ResolutionException(String message) { + super(message); + } - public ResolutionException(Throwable cause) { - super(cause); - } + public ResolutionException(Throwable cause) { + super(cause); + } - } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/formatting/EMFPatternLanguageFormatter.java b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/formatting/EMFPatternLanguageFormatter.java index 3ba7de9d..398f558f 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/formatting/EMFPatternLanguageFormatter.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/formatting/EMFPatternLanguageFormatter.java @@ -22,75 +22,75 @@ * Formatting rules for the EMF pattern language. */ public class EMFPatternLanguageFormatter extends AbstractDeclarativeFormatter { - - @Override - protected void configureFormatting(FormattingConfig c) { - EMFPatternLanguageGrammarAccess grammar = (EMFPatternLanguageGrammarAccess) getGrammarAccess(); - - EMFPatternModelElements patternModelAccess = grammar.getEMFPatternModelAccess(); - c.setLinewrap(2).after(patternModelAccess.getPackageNameAssignment_1_1()); - c.setLinewrap(1).after(patternModelAccess.getImportPackagesAssignment_2()); - c.setLinewrap().before(patternModelAccess.getPatternsAssignment_3()); - c.setLinewrap(2).before(patternModelAccess.getPatternsAssignment_3()); - c.setLinewrap(2).between(patternModelAccess.getPatternsAssignment_3(), patternModelAccess.getPatternsAssignment_3()); - - PatternElements patternAccess = grammar.getPatternAccess(); - c.setLinewrap(1).after(patternAccess.getAnnotationsAssignment_0()); - c.setSpace(" ").around(patternAccess.getOrKeyword_9_0()); - - AnnotationElements annotationAccess = grammar.getAnnotationAccess(); - c.setLinewrap().after(annotationAccess.getRule()); - - // Preserve newlines around comments - c.setLinewrap(0, 1, 2).before(grammar.getSL_COMMENTRule()); - c.setLinewrap(0, 1, 2).before(grammar.getML_COMMENTRule()); - c.setLinewrap(0, 1, 1).after(grammar.getML_COMMENTRule()); - - - for (Keyword keyword : grammar.findKeywords("=")) { - c.setSpace(" ").around(keyword); - } - for (Keyword keyword : grammar.findKeywords(".")) { - c.setNoSpace().before(keyword); - c.setNoSpace().after(keyword); - } - for (Keyword keyword : grammar.findKeywords(":")) { - c.setSpace(" ").before(keyword); - c.setSpace(" ").after(keyword); - } - for (Keyword keyword : grammar.findKeywords("::")) { - c.setNoSpace().before(keyword); - c.setNoSpace().after(keyword); - } - for (Keyword keyword : grammar.findKeywords(",")) { - c.setNoSpace().before(keyword); - c.setSpace(" ").after(keyword); - } - for (Keyword keyword : grammar.findKeywords("(")) { - c.setNoSpace().before(keyword); - c.setNoSpace().after(keyword); - } - for (Keyword keyword : grammar.findKeywords(";")) { - c.setNoSpace().before(keyword); - c.setLinewrap(1,1,2).after(keyword); - } - - for (Keyword keyword : grammar.findKeywords(")")) { - c.setNoSpace().before(keyword); - c.setLinewrap(1).after(keyword); - } - for (Keyword keyword : grammar.findKeywords("@")) { - c.setNoSpace().after(keyword); - } - for (Keyword keyword : grammar.findKeywords("{")) { - c.setSpace(" ").before(keyword); - c.setLinewrap(1,1,2).after(keyword); - c.setIndentationIncrement().after(keyword); - } - for (Keyword keyword : grammar.findKeywords("}")) { - c.setLinewrap(2).after(keyword); - c.setIndentationDecrement().before(keyword); - } - } + @Override + protected void configureFormatting(FormattingConfig c) { + EMFPatternLanguageGrammarAccess grammar = (EMFPatternLanguageGrammarAccess) getGrammarAccess(); + + EMFPatternModelElements patternModelAccess = grammar.getEMFPatternModelAccess(); + c.setLinewrap(2).after(patternModelAccess.getPackageNameAssignment_1_1()); + c.setLinewrap(1).after(patternModelAccess.getImportPackagesAssignment_2()); + c.setLinewrap().before(patternModelAccess.getPatternsAssignment_3()); + c.setLinewrap(2).before(patternModelAccess.getPatternsAssignment_3()); + c.setLinewrap(2).between(patternModelAccess.getPatternsAssignment_3(), + patternModelAccess.getPatternsAssignment_3()); + + PatternElements patternAccess = grammar.getPatternAccess(); + c.setLinewrap(1).after(patternAccess.getAnnotationsAssignment_0()); + c.setSpace(" ").around(patternAccess.getOrKeyword_9_0()); + + AnnotationElements annotationAccess = grammar.getAnnotationAccess(); + c.setLinewrap().after(annotationAccess.getRule()); + + // Preserve newlines around comments + c.setLinewrap(0, 1, 2).before(grammar.getSL_COMMENTRule()); + c.setLinewrap(0, 1, 2).before(grammar.getML_COMMENTRule()); + c.setLinewrap(0, 1, 1).after(grammar.getML_COMMENTRule()); + + for (Keyword keyword : grammar.findKeywords("=")) { + c.setSpace(" ").around(keyword); + } + for (Keyword keyword : grammar.findKeywords(".")) { + c.setNoSpace().before(keyword); + c.setNoSpace().after(keyword); + } + for (Keyword keyword : grammar.findKeywords(":")) { + c.setSpace(" ").before(keyword); + c.setSpace(" ").after(keyword); + } + for (Keyword keyword : grammar.findKeywords("::")) { + c.setNoSpace().before(keyword); + c.setNoSpace().after(keyword); + } + for (Keyword keyword : grammar.findKeywords(",")) { + c.setNoSpace().before(keyword); + c.setSpace(" ").after(keyword); + } + for (Keyword keyword : grammar.findKeywords("(")) { + c.setNoSpace().before(keyword); + c.setNoSpace().after(keyword); + } + for (Keyword keyword : grammar.findKeywords(";")) { + c.setNoSpace().before(keyword); + c.setLinewrap(1, 1, 2).after(keyword); + } + + for (Keyword keyword : grammar.findKeywords(")")) { + c.setNoSpace().before(keyword); + c.setLinewrap(1).after(keyword); + } + for (Keyword keyword : grammar.findKeywords("@")) { + c.setNoSpace().after(keyword); + } + + for (Keyword keyword : grammar.findKeywords("{")) { + c.setSpace(" ").before(keyword); + c.setLinewrap(1, 1, 2).after(keyword); + c.setIndentationIncrement().after(keyword); + } + for (Keyword keyword : grammar.findKeywords("}")) { + c.setLinewrap(2).after(keyword); + c.setIndentationDecrement().before(keyword); + } + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/jvmmodel/Empty.java b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/jvmmodel/Empty.java index fa287d7d..d7b7dc8f 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/jvmmodel/Empty.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/jvmmodel/Empty.java @@ -11,10 +11,11 @@ package org.eclipse.incquery.patternlanguage.emf.jvmmodel; /** - * This class is only present to avoid causing an empty jvmmodel package build errors. - * This is a hack to circumvent Xbase code generation fragment. + * This class is only present to avoid causing an empty jvmmodel package build errors. This is a hack to circumvent + * Xbase code generation fragment. + * * @author Zoltan Ujhelyi - * + * */ public class Empty { diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/scoping/EMFPatternLanguageDeclarativeScopeProvider.java b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/scoping/EMFPatternLanguageDeclarativeScopeProvider.java index e514739d..cc4fe193 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/scoping/EMFPatternLanguageDeclarativeScopeProvider.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/scoping/EMFPatternLanguageDeclarativeScopeProvider.java @@ -53,163 +53,165 @@ import com.google.inject.Inject; /** - *

An extended abstract declarative scope provider to facilitate the reusing of abstract - * declarative scope providers together with XBase scope provider.

- *

See http://www.eclipse.org/forums/index.php/mv/msg/219841/699521/#msg_699521 for details.

+ *

+ * An extended abstract declarative scope provider to facilitate the reusing of abstract declarative scope providers + * together with XBase scope provider. + *

+ *

+ * See http://www.eclipse.org/forums/index + * .php/mv/msg/219841/699521/#msg_699521 for details. + *

+ * * @author Zoltan Ujhelyi - * + * */ -public class EMFPatternLanguageDeclarativeScopeProvider extends - PatternLanguageDeclarativeScopeProvider { - @Inject - private IQualifiedNameConverter qualifiedNameConverter; - @Inject - private IMetamodelProvider metamodelProvider; - - /** - * {@inheritDoc} - * Overridden for debugging purposes. - */ - @Override - protected Predicate getPredicate(EObject context, EClass type) { - String methodName = "scope_" + type.getName(); -// System.out.println(methodName + " ctx " + context.eClass().getName()); - return PolymorphicDispatcher.Predicates.forName(methodName, 2); - } - - /** - * {@inheritDoc} - * Overridden for debugging purposes. - */ - @Override - protected Predicate getPredicate(EObject context, EReference reference) { - String methodName = "scope_" + reference.getEContainingClass().getName() + "_" + reference.getName(); -// System.out.println(methodName + " ctx " + context.eClass().getName()); - return PolymorphicDispatcher.Predicates.forName(methodName, 2); - } - - public IScope scope_EPackage(PackageImport ctx, EReference ref) { - return metamodelProvider.getAllMetamodelObjects(ctx); - } - - public IScope scope_EClassifier(PatternBody ctx, EReference ref) { - // This is needed for content assist - in that case the ClassType does not exists - EObject root = getRootContainer(ctx); - if (root instanceof PatternModel){ - return createReferencedPackagesScope((PatternModel) root); - } else { - return IScope.NULLSCOPE; - } - } - - public IScope scope_EClassifier(ClassType ctx, EReference ref) { - EObject root = getRootContainer(ctx); - if (root instanceof PatternModel){ - return createReferencedPackagesScope((PatternModel) root); - } else { - return IScope.NULLSCOPE; - } - } - - public IScope scope_EClassifier(Variable ctx, EReference ref) { - EObject root = getRootContainer(ctx); - if (root instanceof PatternModel){ - return createReferencedPackagesScope((PatternModel) root); - } else { - return IScope.NULLSCOPE; - } - } - - protected IScope createClassifierScope(Iterable classifiers) { - return Scopes.scopeFor(classifiers); - } - - protected IScope createReferencedPackagesScope(PatternModel model) { - final Collection allClassifiers = new ArrayList(); - for(PackageImport decl: model.getImportPackages()) { - if (decl.getEPackage() != null) { - allClassifiers.addAll(decl.getEPackage().getEClassifiers()); - } - } - return createClassifierScope(allClassifiers); - } - - public IScope scope_EStructuralFeature(PathExpressionHead ctx, EReference ref) { - // This is needed for content assist - in that case the ExpressionTail does not exists - return expressionParentScopeProvider.doSwitch(ctx); - } - - public IScope scope_EStructuralFeature(PathExpressionTail ctx, EReference ref) { - return expressionParentScopeProvider.doSwitch(ctx.eContainer()); - } - - public IScope scope_EEnum(EnumValue ctx, EReference ref) { - PatternModel model = (PatternModel) getRootContainer(ctx); - final Collection enums = Lists.newArrayList(); - for (PackageImport decl : model.getImportPackages()) { - if (decl.getEPackage() != null) { - Iterables.addAll(enums, Iterables.filter(decl.getEPackage() - .getEClassifiers(), EEnum.class)); - } - } - return Scopes.scopeFor(enums); - } - - public IScope scope_EEnumLiteral(EnumValue ctx, EReference ref) { - EEnum type; - try { - type = ctx.getEnumeration(); - type = (type != null) ? type : EMFPatternLanguageScopeHelper - .calculateEnumerationType((PathExpressionHead) ctx - .eContainer()); - } catch (ResolutionException e) { - return IScope.NULLSCOPE; - } - return calculateEnumLiteralScope(type); - } - - private IScope calculateEnumLiteralScope(EEnum enumeration) { - EList literals = enumeration.getELiterals(); - return Scopes.scopeFor(literals, new Function() { - @Override +public class EMFPatternLanguageDeclarativeScopeProvider extends PatternLanguageDeclarativeScopeProvider { + @Inject + private IQualifiedNameConverter qualifiedNameConverter; + @Inject + private IMetamodelProvider metamodelProvider; + + /** + * {@inheritDoc} Overridden for debugging purposes. + */ + @Override + protected Predicate getPredicate(EObject context, EClass type) { + String methodName = "scope_" + type.getName(); + // System.out.println(methodName + " ctx " + context.eClass().getName()); + return PolymorphicDispatcher.Predicates.forName(methodName, 2); + } + + /** + * {@inheritDoc} Overridden for debugging purposes. + */ + @Override + protected Predicate getPredicate(EObject context, EReference reference) { + String methodName = "scope_" + reference.getEContainingClass().getName() + "_" + reference.getName(); + // System.out.println(methodName + " ctx " + context.eClass().getName()); + return PolymorphicDispatcher.Predicates.forName(methodName, 2); + } + + public IScope scope_EPackage(PackageImport ctx, EReference ref) { + return metamodelProvider.getAllMetamodelObjects(ctx); + } + + public IScope scope_EClassifier(PatternBody ctx, EReference ref) { + // This is needed for content assist - in that case the ClassType does not exists + EObject root = getRootContainer(ctx); + if (root instanceof PatternModel) { + return createReferencedPackagesScope((PatternModel) root); + } else { + return IScope.NULLSCOPE; + } + } + + public IScope scope_EClassifier(ClassType ctx, EReference ref) { + EObject root = getRootContainer(ctx); + if (root instanceof PatternModel) { + return createReferencedPackagesScope((PatternModel) root); + } else { + return IScope.NULLSCOPE; + } + } + + public IScope scope_EClassifier(Variable ctx, EReference ref) { + EObject root = getRootContainer(ctx); + if (root instanceof PatternModel) { + return createReferencedPackagesScope((PatternModel) root); + } else { + return IScope.NULLSCOPE; + } + } + + protected IScope createClassifierScope(Iterable classifiers) { + return Scopes.scopeFor(classifiers); + } + + protected IScope createReferencedPackagesScope(PatternModel model) { + final Collection allClassifiers = new ArrayList(); + for (PackageImport decl : model.getImportPackages()) { + if (decl.getEPackage() != null) { + allClassifiers.addAll(decl.getEPackage().getEClassifiers()); + } + } + return createClassifierScope(allClassifiers); + } + + public IScope scope_EStructuralFeature(PathExpressionHead ctx, EReference ref) { + // This is needed for content assist - in that case the ExpressionTail does not exists + return expressionParentScopeProvider.doSwitch(ctx); + } + + public IScope scope_EStructuralFeature(PathExpressionTail ctx, EReference ref) { + return expressionParentScopeProvider.doSwitch(ctx.eContainer()); + } + + public IScope scope_EEnum(EnumValue ctx, EReference ref) { + PatternModel model = (PatternModel) getRootContainer(ctx); + final Collection enums = Lists.newArrayList(); + for (PackageImport decl : model.getImportPackages()) { + if (decl.getEPackage() != null) { + Iterables.addAll(enums, Iterables.filter(decl.getEPackage().getEClassifiers(), EEnum.class)); + } + } + return Scopes.scopeFor(enums); + } + + public IScope scope_EEnumLiteral(EnumValue ctx, EReference ref) { + EEnum type; + try { + type = ctx.getEnumeration(); + type = (type != null) ? type : EMFPatternLanguageScopeHelper + .calculateEnumerationType((PathExpressionHead) ctx.eContainer()); + } catch (ResolutionException e) { + return IScope.NULLSCOPE; + } + return calculateEnumLiteralScope(type); + } + + private IScope calculateEnumLiteralScope(EEnum enumeration) { + EList literals = enumeration.getELiterals(); + return Scopes.scopeFor(literals, new Function() { + @Override public QualifiedName apply(EEnumLiteral literal) { - QualifiedName qualifiedName = qualifiedNameConverter.toQualifiedName(literal.getLiteral()); - return qualifiedName; - } - }, IScope.NULLSCOPE); - } - - private final ParentScopeProvider expressionParentScopeProvider = new ParentScopeProvider(); - - static class ParentScopeProvider extends PatternLanguageSwitch { - - @Override - public IScope casePathExpressionHead(PathExpressionHead object) { - return calculateReferences(object.getType()); - } - - @Override - public IScope casePathExpressionTail(PathExpressionTail object) { - return calculateReferences(object.getType()); - } - - private IScope calculateReferences(Type type) { - List targetReferences = Collections.emptyList(); - if (type instanceof ReferenceType) { - EClassifier referredType = ((ReferenceType) type).getRefname().getEType(); - if (referredType instanceof EClass) { - targetReferences = ((EClass) referredType).getEAllStructuralFeatures(); - } - } else if (type instanceof ClassType) { - EClassifier classifier = ((ClassType) type).getClassname(); - if (classifier instanceof EClass) { - targetReferences = (((EClass)classifier).getEAllStructuralFeatures()); - } - } + QualifiedName qualifiedName = qualifiedNameConverter.toQualifiedName(literal.getLiteral()); + return qualifiedName; + } + }, IScope.NULLSCOPE); + } + + private final ParentScopeProvider expressionParentScopeProvider = new ParentScopeProvider(); + + static class ParentScopeProvider extends PatternLanguageSwitch { + + @Override + public IScope casePathExpressionHead(PathExpressionHead object) { + return calculateReferences(object.getType()); + } + + @Override + public IScope casePathExpressionTail(PathExpressionTail object) { + return calculateReferences(object.getType()); + } + + private IScope calculateReferences(Type type) { + List targetReferences = Collections.emptyList(); + if (type instanceof ReferenceType) { + EClassifier referredType = ((ReferenceType) type).getRefname().getEType(); + if (referredType instanceof EClass) { + targetReferences = ((EClass) referredType).getEAllStructuralFeatures(); + } + } else if (type instanceof ClassType) { + EClassifier classifier = ((ClassType) type).getClassname(); + if (classifier instanceof EClass) { + targetReferences = (((EClass) classifier).getEAllStructuralFeatures()); + } + } if (targetReferences.isEmpty()) { return IScope.NULLSCOPE; } - return Scopes.scopeFor(targetReferences); - } - } + return Scopes.scopeFor(targetReferences); + } + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/scoping/EMFPatternLanguageLinkingService.java b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/scoping/EMFPatternLanguageLinkingService.java index 137cc05e..b7f9de64 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/scoping/EMFPatternLanguageLinkingService.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/scoping/EMFPatternLanguageLinkingService.java @@ -34,85 +34,79 @@ import com.google.inject.Inject; public class EMFPatternLanguageLinkingService extends DefaultLinkingService { - private static final Logger LOG = Logger.getLogger(EMFPatternLanguageLinkingService.class); - - @Inject - private IValueConverterService valueConverterService; - @Inject - private IMetamodelProvider metamodelProvider; - - @Override - public List getLinkedObjects(EObject context, EReference ref, INode node) { - if (ref == EMFPatternLanguagePackage.eINSTANCE - .getPackageImport_EPackage() - && context instanceof PackageImport - && node instanceof ILeafNode) { - return getPackage((PackageImport) context, (ILeafNode) node); - } else if (ref == EMFPatternLanguagePackage.eINSTANCE - .getEnumValue_Literal() - && context instanceof EnumValue - && node instanceof ILeafNode) { - return getEnumLiteral((EnumValue)context, node); - } - return super.getLinkedObjects(context, ref, node); - } + private static final Logger LOG = Logger.getLogger(EMFPatternLanguageLinkingService.class); - private List getEnumLiteral(EnumValue value, INode node) { - try { - EEnum type = null; - if (value.getEnumeration() != null) { - type = value.getEnumeration(); - } else if (value.eContainer() instanceof PathExpressionHead) { - type = EMFPatternLanguageScopeHelper - .calculateEnumerationType(getExpressionHead(value - .eContainer())); - } else { - return Collections.emptyList(); - } - String typename = ((ILeafNode)node).getText(); - EEnumLiteral literal = type.getEEnumLiteralByLiteral(typename); - if (literal == null) { - literal = type.getEEnumLiteral(typename); - } - if (literal != null) { - return Collections.singletonList(literal); - } else { - return Collections.emptyList(); - } - } catch (ResolutionException e) { - return Collections.emptyList(); - } - } - - private PathExpressionHead getExpressionHead(EObject obj) { - if (obj instanceof PathExpressionHead) { - return (PathExpressionHead) obj; - } else if (obj.eContainer() != null) { - return getExpressionHead(obj.eContainer()); - } else { - return null; - } - } - - private List getPackage(PackageImport context, ILeafNode text) { - String nsUri = getMetamodelNsURI(text); - if (nsUri == null) { - return Collections.emptyList(); - } - EPackage pack = metamodelProvider.loadEPackage(nsUri, context.eResource().getResourceSet()); - if (pack != null) { - return Collections.singletonList(pack); - } - return Collections.emptyList(); - } + @Inject + private IValueConverterService valueConverterService; + @Inject + private IMetamodelProvider metamodelProvider; - private String getMetamodelNsURI(ILeafNode text) { - try { - return (String) valueConverterService.toValue(text.getText(), getLinkingHelper().getRuleNameFrom(text - .getGrammarElement()), text); - } catch (ValueConverterException e) { - LOG.debug("Exception on leaf '" + text.getText() + "'", e); - return null; - } - } + @Override + public List getLinkedObjects(EObject context, EReference ref, INode node) { + if (ref == EMFPatternLanguagePackage.eINSTANCE.getPackageImport_EPackage() && context instanceof PackageImport + && node instanceof ILeafNode) { + return getPackage((PackageImport) context, (ILeafNode) node); + } else if (ref == EMFPatternLanguagePackage.eINSTANCE.getEnumValue_Literal() && context instanceof EnumValue + && node instanceof ILeafNode) { + return getEnumLiteral((EnumValue) context, node); + } + return super.getLinkedObjects(context, ref, node); + } + + private List getEnumLiteral(EnumValue value, INode node) { + try { + EEnum type = null; + if (value.getEnumeration() != null) { + type = value.getEnumeration(); + } else if (value.eContainer() instanceof PathExpressionHead) { + type = EMFPatternLanguageScopeHelper.calculateEnumerationType(getExpressionHead(value.eContainer())); + } else { + return Collections.emptyList(); + } + String typename = ((ILeafNode) node).getText(); + EEnumLiteral literal = type.getEEnumLiteralByLiteral(typename); + if (literal == null) { + literal = type.getEEnumLiteral(typename); + } + if (literal != null) { + return Collections. singletonList(literal); + } else { + return Collections.emptyList(); + } + } catch (ResolutionException e) { + return Collections.emptyList(); + } + } + + private PathExpressionHead getExpressionHead(EObject obj) { + if (obj instanceof PathExpressionHead) { + return (PathExpressionHead) obj; + } else if (obj.eContainer() != null) { + return getExpressionHead(obj.eContainer()); + } else { + return null; + } + } + + private List getPackage(PackageImport context, ILeafNode text) { + String nsUri = getMetamodelNsURI(text); + if (nsUri == null) { + return Collections.emptyList(); + } + EPackage pack = metamodelProvider.loadEPackage(nsUri, context.eResource().getResourceSet()); + if (pack != null) { + return Collections. singletonList(pack); + } + return Collections.emptyList(); + } + + private String getMetamodelNsURI(ILeafNode text) { + try { + return (String) valueConverterService.toValue(text.getText(), + getLinkingHelper().getRuleNameFrom(text.getGrammarElement()), text); + } catch (ValueConverterException e) { + LOG.debug("Exception on leaf '" + text.getText() + "'", e); + return null; + } + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/scoping/EMFPatternLanguageScopeProvider.java b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/scoping/EMFPatternLanguageScopeProvider.java index 277da609..dcf8f042 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/scoping/EMFPatternLanguageScopeProvider.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/scoping/EMFPatternLanguageScopeProvider.java @@ -15,9 +15,8 @@ /** * This class contains custom scoping description. * - * see : http://www.eclipse.org/Xtext/documentation/latest/xtext.html#scoping - * on how and when to use it - * + * see : http://www.eclipse.org/Xtext/documentation/latest/xtext.html#scoping on how and when to use it + * */ public class EMFPatternLanguageScopeProvider extends PatternLanguageScopeProvider { diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/scoping/IMetamodelProvider.java b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/scoping/IMetamodelProvider.java index c181cc6f..e5549d91 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/scoping/IMetamodelProvider.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/scoping/IMetamodelProvider.java @@ -17,23 +17,22 @@ public interface IMetamodelProvider { - /** - * Returns a set of all available EPackages wrapped into - * {@link IEObjectDescription} for the use of scoping - * - * @return - */ - IScope getAllMetamodelObjects(EObject context); + /** + * Returns a set of all available EPackages wrapped into {@link IEObjectDescription} for the use of scoping + * + * @return + */ + IScope getAllMetamodelObjects(EObject context); - /** - * Loads an EMF package from the nsURI or resource URI of the model, and - * uses the resource set given as the second parameter. - * - * @param uri - * @param resourceSet - * @return the loaded EMF EPackage - */ - EPackage loadEPackage(String uri, ResourceSet resourceSet); + /** + * Loads an EMF package from the nsURI or resource URI of the model, and uses the resource set given as the second + * parameter. + * + * @param uri + * @param resourceSet + * @return the loaded EMF EPackage + */ + EPackage loadEPackage(String uri, ResourceSet resourceSet); - boolean isGeneratedCodeAvailable(EPackage ePackage, ResourceSet set); + boolean isGeneratedCodeAvailable(EPackage ePackage, ResourceSet set); } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/scoping/MetamodelProviderService.java b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/scoping/MetamodelProviderService.java index 65b72efa..53386cad 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/scoping/MetamodelProviderService.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/scoping/MetamodelProviderService.java @@ -37,82 +37,79 @@ public class MetamodelProviderService implements IMetamodelProvider { - @Inject - private Logger logger; - - @Inject - private IQualifiedNameConverter qualifiedNameConverter; - - private EcoreGenmodelRegistry genmodelRegistry; + @Inject + private Logger logger; - protected EcoreGenmodelRegistry getGenmodelRegistry() { - if (genmodelRegistry == null) - genmodelRegistry = new EcoreGenmodelRegistry(logger); - return genmodelRegistry; - } - - @Override - public IScope getAllMetamodelObjects(EObject context) { - final Map metamodelMap = getMetamodelMap(); - Set packageURIs = new HashSet( - metamodelMap.keySet()); - Iterable metamodels = Iterables.transform(packageURIs, - new Function() { - @Override + @Inject + private IQualifiedNameConverter qualifiedNameConverter; + + private EcoreGenmodelRegistry genmodelRegistry; + + protected EcoreGenmodelRegistry getGenmodelRegistry() { + if (genmodelRegistry == null) + genmodelRegistry = new EcoreGenmodelRegistry(logger); + return genmodelRegistry; + } + + @Override + public IScope getAllMetamodelObjects(EObject context) { + final Map metamodelMap = getMetamodelMap(); + Set packageURIs = new HashSet(metamodelMap.keySet()); + Iterable metamodels = Iterables.transform(packageURIs, + new Function() { + @Override public IEObjectDescription apply(String from) { - EPackage ePackage = metamodelMap.get(from); - // InternalEObject proxyPackage = (InternalEObject) - // EcoreFactory.eINSTANCE.createEPackage(); - // proxyPackage.eSetProxyURI(URI.createURI(from)); - QualifiedName qualifiedName = qualifiedNameConverter - .toQualifiedName(from); - // return EObjectDescription.create(qualifiedName, - // proxyPackage, - // Collections.singletonMap("nsURI", "true")); - return EObjectDescription.create(qualifiedName, - ePackage, - Collections.singletonMap("nsURI", "true")); - } - }); - return new SimpleScope(IScope.NULLSCOPE, metamodels); - } + EPackage ePackage = metamodelMap.get(from); + // InternalEObject proxyPackage = (InternalEObject) + // EcoreFactory.eINSTANCE.createEPackage(); + // proxyPackage.eSetProxyURI(URI.createURI(from)); + QualifiedName qualifiedName = qualifiedNameConverter.toQualifiedName(from); + // return EObjectDescription.create(qualifiedName, + // proxyPackage, + // Collections.singletonMap("nsURI", "true")); + return EObjectDescription.create(qualifiedName, ePackage, + Collections.singletonMap("nsURI", "true")); + } + }); + return new SimpleScope(IScope.NULLSCOPE, metamodels); + } + + protected Map getMetamodelMap() { + Map packageMap = Maps.newHashMap(); + Set nsURISet = Sets.newHashSet(EPackage.Registry.INSTANCE.keySet()); + for (String key : nsURISet) { + packageMap.put(key, EPackage.Registry.INSTANCE.getEPackage(key)); + } + return packageMap; - protected Map getMetamodelMap(){ - Map packageMap = Maps.newHashMap(); - Set nsURISet = Sets.newHashSet(EPackage.Registry.INSTANCE.keySet()); - for (String key : nsURISet) { - packageMap.put(key, EPackage.Registry.INSTANCE.getEPackage(key)); - } - return packageMap; + } - } - - @Override - public EPackage loadEPackage(String packageUri, ResourceSet resourceSet) { - if (EPackage.Registry.INSTANCE.containsKey(packageUri)) { - return EPackage.Registry.INSTANCE.getEPackage(packageUri); - } - URI uri = null; - try { - uri = URI.createURI(packageUri); - if (uri.fragment() == null) { - Resource resource = resourceSet.getResource(uri, true); - return (EPackage) resource.getContents().get(0); - } - return (EPackage) resourceSet.getEObject(uri, true); - } catch(RuntimeException ex) { - if (uri != null && uri.isPlatformResource()) { - String platformString = uri.toPlatformString(true); - URI platformPluginURI = URI.createPlatformPluginURI(platformString, true); - return loadEPackage(platformPluginURI.toString(), resourceSet); - } - logger.trace("Cannot load package with URI '" + packageUri + "'", ex); - return null; - } - } + @Override + public EPackage loadEPackage(String packageUri, ResourceSet resourceSet) { + if (EPackage.Registry.INSTANCE.containsKey(packageUri)) { + return EPackage.Registry.INSTANCE.getEPackage(packageUri); + } + URI uri = null; + try { + uri = URI.createURI(packageUri); + if (uri.fragment() == null) { + Resource resource = resourceSet.getResource(uri, true); + return (EPackage) resource.getContents().get(0); + } + return (EPackage) resourceSet.getEObject(uri, true); + } catch (RuntimeException ex) { + if (uri != null && uri.isPlatformResource()) { + String platformString = uri.toPlatformString(true); + URI platformPluginURI = URI.createPlatformPluginURI(platformString, true); + return loadEPackage(platformPluginURI.toString(), resourceSet); + } + logger.trace("Cannot load package with URI '" + packageUri + "'", ex); + return null; + } + } - @Override - public boolean isGeneratedCodeAvailable(EPackage ePackage, ResourceSet set) { - return getGenmodelRegistry().findGenPackage(ePackage.getNsURI(), set) != null; - } + @Override + public boolean isGeneratedCodeAvailable(EPackage ePackage, ResourceSet set) { + return getGenmodelRegistry().findGenPackage(ePackage.getNsURI(), set) != null; + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/serializer/EMFPatternLanguageCrossRefSerializer.java b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/serializer/EMFPatternLanguageCrossRefSerializer.java index 3c0ead81..9f533229 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/serializer/EMFPatternLanguageCrossRefSerializer.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/serializer/EMFPatternLanguageCrossRefSerializer.java @@ -20,16 +20,15 @@ public class EMFPatternLanguageCrossRefSerializer extends CrossReferenceSerializer { - @Override - public String serializeCrossRef(EObject semanticObject, - CrossReference crossref, EObject target, INode node, Acceptor errors) { - if (target instanceof EPackage) { - return String.format("\"%s\"", ((EPackage)target).getNsURI()); - } else if (target instanceof ENamedElement) { - return ((ENamedElement) target).getName(); - } - return super.serializeCrossRef(semanticObject, crossref, target, node, - errors); - } + @Override + public String serializeCrossRef(EObject semanticObject, CrossReference crossref, EObject target, INode node, + Acceptor errors) { + if (target instanceof EPackage) { + return String.format("\"%s\"", ((EPackage) target).getNsURI()); + } else if (target instanceof ENamedElement) { + return ((ENamedElement) target).getName(); + } + return super.serializeCrossRef(semanticObject, crossref, target, node, errors); + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/serializer/EMFPatternLanguageSemanticSequencer.java b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/serializer/EMFPatternLanguageSemanticSequencer.java index 121f4f18..cf1da283 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/serializer/EMFPatternLanguageSemanticSequencer.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/serializer/EMFPatternLanguageSemanticSequencer.java @@ -10,6 +10,5 @@ *******************************************************************************/ package org.eclipse.incquery.patternlanguage.emf.serializer; - public class EMFPatternLanguageSemanticSequencer extends AbstractEMFPatternLanguageSemanticSequencer { } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/serializer/EMFPatternLanguageSyntacticSequencer.java b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/serializer/EMFPatternLanguageSyntacticSequencer.java index 447d579f..da7912c6 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/serializer/EMFPatternLanguageSyntacticSequencer.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/serializer/EMFPatternLanguageSyntacticSequencer.java @@ -10,6 +10,5 @@ *******************************************************************************/ package org.eclipse.incquery.patternlanguage.emf.serializer; - public class EMFPatternLanguageSyntacticSequencer extends AbstractEMFPatternLanguageSyntacticSequencer { } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/types/IEMFTypeProvider.java b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/types/IEMFTypeProvider.java index fd5bc87c..f56d0d69 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/types/IEMFTypeProvider.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/types/IEMFTypeProvider.java @@ -43,6 +43,5 @@ public interface IEMFTypeProvider { */ public Set getPossibleClassifiersForVariableInBody(PatternBody patternBody, Variable variable); - public EClassifier getClassifierForPatternParameterVariable(Variable variable); } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/validation/EMFIssueCodes.java b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/validation/EMFIssueCodes.java index e1c852be..13d18392 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/validation/EMFIssueCodes.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/validation/EMFIssueCodes.java @@ -15,32 +15,42 @@ */ public final class EMFIssueCodes { - protected static final String ISSUE_CODE_PREFIX = "org.eclipse.incquery.patternlanguage.emf.validation.IssueCodes."; - - public static final String DUPLICATE_IMPORT = ISSUE_CODE_PREFIX + "duplicate_import"; - public static final String IMPORT_WITH_GENERATEDCODE = ISSUE_CODE_PREFIX + "missing_imported_code"; - public static final String IMPORT_DEPENDENCY_MISSING = ISSUE_CODE_PREFIX + "missing_import_dependency"; - public static final String INVALID_ENUM_LITERAL = ISSUE_CODE_PREFIX + "invalid_enum"; - - public static final String SYMBOLIC_VARIABLE_NEVER_REFERENCED = ISSUE_CODE_PREFIX + "symbolic_variable_never_referenced"; - public static final String SYMBOLIC_VARIABLE_NO_POSITIVE_REFERENCE = ISSUE_CODE_PREFIX + "symbolic_variable_no_positive_reference"; - public static final String LOCAL_VARIABLE_REFERENCED_ONCE = ISSUE_CODE_PREFIX + "local_variable_referenced_once"; - public static final String LOCAL_VARIABLE_READONLY = ISSUE_CODE_PREFIX + "local_variable_no_quantifying_reference"; - public static final String LOCAL_VARIABLE_QUANTIFIED_REFERENCE = ISSUE_CODE_PREFIX + "local_variable_quantified_reference"; - public static final String LOCAL_VARIABLE_NO_POSITIVE_REFERENCE = ISSUE_CODE_PREFIX + "local_variable_no_positive_reference"; - public static final String ANONYM_VARIABLE_MULTIPLE_REFERENCE = ISSUE_CODE_PREFIX + "anonym_variable_multiple_reference"; - public static final String SINGLEUSE_PARAMETER = ISSUE_CODE_PREFIX + "singleuse_parameter"; - public static final String PARAMETER_TYPE_INVALID = ISSUE_CODE_PREFIX + "parameter_type_invalid"; - public static final String VARIABLE_TYPE_INVALID_ERROR = ISSUE_CODE_PREFIX + "variable_type_invalid_error"; - public static final String VARIABLE_TYPE_INVALID_WARNING = ISSUE_CODE_PREFIX + "variable_type_invalid_warning"; - public static final String VARIABLE_TYPE_MULTIPLE_DECLARATION = ISSUE_CODE_PREFIX + "variable_type_multiple_declaration"; - public static final String LITERAL_OR_COMPUTATION_TYPE_MISMATCH_IN_COMPARE = ISSUE_CODE_PREFIX + "literal_and_computation_type_mismatch_in_compare"; - public static final String LITERAL_OR_COMPUTATION_TYPE_MISMATCH_IN_PATH_EXPRESSION = ISSUE_CODE_PREFIX + "literal_or_computation_type_mismatch_in_path_expression"; - public static final String LITERAL_OR_COMPUTATION_TYPE_MISMATCH_IN_PATTERN_CALL = ISSUE_CODE_PREFIX + "literal_or_computation_type_mismatch_in_pattern_call"; - public static final String CARTESIAN_SOFT_WARNING = ISSUE_CODE_PREFIX + "cartesian_soft_warning"; - public static final String CARTESIAN_STRICT_WARNING = ISSUE_CODE_PREFIX + "cartesian_strict_warning"; - public static final String CHECK_CONSTRAINT_SCALAR_VARIABLE_ERROR = ISSUE_CODE_PREFIX + "check_constraint_scalar_variable_error"; - - public static final String IDENTIFIER_AS_KEYWORD = ISSUE_CODE_PREFIX + "identifier_as_keyword"; + protected static final String ISSUE_CODE_PREFIX = "org.eclipse.incquery.patternlanguage.emf.validation.IssueCodes."; + + public static final String DUPLICATE_IMPORT = ISSUE_CODE_PREFIX + "duplicate_import"; + public static final String IMPORT_WITH_GENERATEDCODE = ISSUE_CODE_PREFIX + "missing_imported_code"; + public static final String IMPORT_DEPENDENCY_MISSING = ISSUE_CODE_PREFIX + "missing_import_dependency"; + public static final String INVALID_ENUM_LITERAL = ISSUE_CODE_PREFIX + "invalid_enum"; + + public static final String SYMBOLIC_VARIABLE_NEVER_REFERENCED = ISSUE_CODE_PREFIX + + "symbolic_variable_never_referenced"; + public static final String SYMBOLIC_VARIABLE_NO_POSITIVE_REFERENCE = ISSUE_CODE_PREFIX + + "symbolic_variable_no_positive_reference"; + public static final String LOCAL_VARIABLE_REFERENCED_ONCE = ISSUE_CODE_PREFIX + "local_variable_referenced_once"; + public static final String LOCAL_VARIABLE_READONLY = ISSUE_CODE_PREFIX + "local_variable_no_quantifying_reference"; + public static final String LOCAL_VARIABLE_QUANTIFIED_REFERENCE = ISSUE_CODE_PREFIX + + "local_variable_quantified_reference"; + public static final String LOCAL_VARIABLE_NO_POSITIVE_REFERENCE = ISSUE_CODE_PREFIX + + "local_variable_no_positive_reference"; + public static final String ANONYM_VARIABLE_MULTIPLE_REFERENCE = ISSUE_CODE_PREFIX + + "anonym_variable_multiple_reference"; + public static final String SINGLEUSE_PARAMETER = ISSUE_CODE_PREFIX + "singleuse_parameter"; + public static final String PARAMETER_TYPE_INVALID = ISSUE_CODE_PREFIX + "parameter_type_invalid"; + public static final String VARIABLE_TYPE_INVALID_ERROR = ISSUE_CODE_PREFIX + "variable_type_invalid_error"; + public static final String VARIABLE_TYPE_INVALID_WARNING = ISSUE_CODE_PREFIX + "variable_type_invalid_warning"; + public static final String VARIABLE_TYPE_MULTIPLE_DECLARATION = ISSUE_CODE_PREFIX + + "variable_type_multiple_declaration"; + public static final String LITERAL_OR_COMPUTATION_TYPE_MISMATCH_IN_COMPARE = ISSUE_CODE_PREFIX + + "literal_and_computation_type_mismatch_in_compare"; + public static final String LITERAL_OR_COMPUTATION_TYPE_MISMATCH_IN_PATH_EXPRESSION = ISSUE_CODE_PREFIX + + "literal_or_computation_type_mismatch_in_path_expression"; + public static final String LITERAL_OR_COMPUTATION_TYPE_MISMATCH_IN_PATTERN_CALL = ISSUE_CODE_PREFIX + + "literal_or_computation_type_mismatch_in_pattern_call"; + public static final String CARTESIAN_SOFT_WARNING = ISSUE_CODE_PREFIX + "cartesian_soft_warning"; + public static final String CARTESIAN_STRICT_WARNING = ISSUE_CODE_PREFIX + "cartesian_strict_warning"; + public static final String CHECK_CONSTRAINT_SCALAR_VARIABLE_ERROR = ISSUE_CODE_PREFIX + + "check_constraint_scalar_variable_error"; + + public static final String IDENTIFIER_AS_KEYWORD = ISSUE_CODE_PREFIX + "identifier_as_keyword"; } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/validation/EMFPatternLanguageSyntaxErrorMessageProvider.java b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/validation/EMFPatternLanguageSyntaxErrorMessageProvider.java index 9fc6efea..519cfe9b 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/validation/EMFPatternLanguageSyntaxErrorMessageProvider.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/validation/EMFPatternLanguageSyntaxErrorMessageProvider.java @@ -17,32 +17,27 @@ import com.google.inject.Inject; -public class EMFPatternLanguageSyntaxErrorMessageProvider extends - SyntaxErrorMessageProvider { +public class EMFPatternLanguageSyntaxErrorMessageProvider extends SyntaxErrorMessageProvider { - @Inject - EMFPatternLanguageGrammarAccess grammar; + @Inject + EMFPatternLanguageGrammarAccess grammar; - @Override - public SyntaxErrorMessage getSyntaxErrorMessage(IParserErrorContext context) { - if (context.getRecognitionException() instanceof MismatchedTokenException) { - MismatchedTokenException exception = (MismatchedTokenException) context - .getRecognitionException(); - if (exception.expecting >= 0 && exception.getUnexpectedType() >= 0) { - String expectingTokenTypeName = context.getTokenNames()[exception.expecting]; - String unexpectedTokenTypeName = context.getTokenNames()[exception - .getUnexpectedType()]; - if ("RULE_ID".equals(expectingTokenTypeName) - && Character - .isJavaIdentifierStart(unexpectedTokenTypeName - .replace("'", "").charAt(0))) { - return new SyntaxErrorMessage( - "Keywords of the query language are to be prefixed with the ^ character when used as an identifier", - EMFIssueCodes.IDENTIFIER_AS_KEYWORD); - } - } - } - return super.getSyntaxErrorMessage(context); - } + @Override + public SyntaxErrorMessage getSyntaxErrorMessage(IParserErrorContext context) { + if (context.getRecognitionException() instanceof MismatchedTokenException) { + MismatchedTokenException exception = (MismatchedTokenException) context.getRecognitionException(); + if (exception.expecting >= 0 && exception.getUnexpectedType() >= 0) { + String expectingTokenTypeName = context.getTokenNames()[exception.expecting]; + String unexpectedTokenTypeName = context.getTokenNames()[exception.getUnexpectedType()]; + if ("RULE_ID".equals(expectingTokenTypeName) + && Character.isJavaIdentifierStart(unexpectedTokenTypeName.replace("'", "").charAt(0))) { + return new SyntaxErrorMessage( + "Keywords of the query language are to be prefixed with the ^ character when used as an identifier", + EMFIssueCodes.IDENTIFIER_AS_KEYWORD); + } + } + } + return super.getSyntaxErrorMessage(context); + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/validation/PatternSetValidationDiagnostics.java b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/validation/PatternSetValidationDiagnostics.java index f1d75567..72f384d3 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/validation/PatternSetValidationDiagnostics.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/validation/PatternSetValidationDiagnostics.java @@ -20,11 +20,11 @@ /** * Stateless validator for a set of patterns. + * * @author Zoltan Ujhelyi - * + * */ -public final class PatternSetValidationDiagnostics implements - IAcceptor { +public final class PatternSetValidationDiagnostics implements IAcceptor { Set foundErrors = Sets.newHashSet(); Set foundWarnings = Sets.newHashSet(); @@ -46,40 +46,40 @@ public void accept(Issue issue) { break; } } - - public PatternValidationStatus getStatus() { - if (!foundErrors.isEmpty()) { - return PatternValidationStatus.ERROR; - } else if (!foundWarnings.isEmpty()) { - return PatternValidationStatus.WARNING; - } else { - return PatternValidationStatus.OK; - } - } - + + public PatternValidationStatus getStatus() { + if (!foundErrors.isEmpty()) { + return PatternValidationStatus.ERROR; + } else if (!foundWarnings.isEmpty()) { + return PatternValidationStatus.WARNING; + } else { + return PatternValidationStatus.OK; + } + } + public Set getAllErrors() { - return Sets.newHashSet(foundErrors); - } + return Sets.newHashSet(foundErrors); + } public Set getAllWarnings() { - return Sets.newHashSet(foundWarnings); - } - - public void logErrors(Logger logger) { + return Sets.newHashSet(foundWarnings); + } + + public void logErrors(Logger logger) { for (Issue diag : foundErrors) { - logger.error(stringRepresentation(diag)); - } - } - - public void logAllMessages(Logger logger) { - logErrors(logger); + logger.error(stringRepresentation(diag)); + } + } + + public void logAllMessages(Logger logger) { + logErrors(logger); for (Issue diag : foundWarnings) { - logger.warn(stringRepresentation(diag)); - } - } - + logger.warn(stringRepresentation(diag)); + } + } + private String stringRepresentation(Issue issue) { return String.format("[%s] %s", issue.getSeverity().toString(), issue.getMessage()); - } + } } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/validation/PatternValidationStatus.java b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/validation/PatternValidationStatus.java index 580d1370..a3681686 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/validation/PatternValidationStatus.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/patternlanguage/emf/validation/PatternValidationStatus.java @@ -12,11 +12,9 @@ /** * @author Zoltan Ujhelyi - * + * */ public enum PatternValidationStatus { - OK, - WARNING, - ERROR + OK, WARNING, ERROR } diff --git a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/runtime/exception/IncQueryException.java b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/runtime/exception/IncQueryException.java index 0fadb766..a1bb10c3 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/runtime/exception/IncQueryException.java +++ b/plugins/org.eclipse.incquery.patternlanguage.emf/src/org/eclipse/incquery/runtime/exception/IncQueryException.java @@ -12,41 +12,40 @@ import org.eclipse.incquery.runtime.rete.construction.RetePatternBuildException; - public class IncQueryException extends Exception { - - private static final long serialVersionUID = -74252748358355750L; - - public static final String PARAM_NOT_SUITABLE_WITH_NO = "The type of the parameters are not suitable for the operation. Parameter number: "; - public static final String CONVERSION_FAILED = "Could not convert the term to the designated type"; - public static final String CONVERT_NULL_PARAMETER = "Could not convert null to the designated type"; - public static final String RELATIONAL_PARAM_UNSUITABLE = "The parameters are not acceptable by the operation"; - public static final String PATTERN_MATCHER_PROBLEM = "The following error occurred during the preparation of an EMF-IncQuery pattern matcher"; - public static final String GETNAME_FAILED = "Could not get 'name' attribute of the result"; - - public static final String INVALID_EMFROOT = "Incremental query engine can only be attached on the contents of an EMF EObject, Resource, or ResourceSet. Received instead: "; - public static final String INVALID_EMFROOT_SHORT = "Invalid EMF model root"; -// public static final String EMF_MODEL_PROCESSING_ERROR = "Error while processing the EMF model"; - - private final String shortMessage; - - public IncQueryException(String s, String shortMessage) { - super(s); - this.shortMessage = shortMessage; - } - public IncQueryException(RetePatternBuildException e) { - super(PATTERN_MATCHER_PROBLEM+": " + e.getMessage(), e); - this.shortMessage = e.getShortMessage(); - } - public IncQueryException(String s, String shortMessage, Exception e) { - super(s+": " + e.getMessage(), e); - this.shortMessage = shortMessage; - } - - - public String getShortMessage() { - return shortMessage; - } - + + private static final long serialVersionUID = -74252748358355750L; + + public static final String PARAM_NOT_SUITABLE_WITH_NO = "The type of the parameters are not suitable for the operation. Parameter number: "; + public static final String CONVERSION_FAILED = "Could not convert the term to the designated type"; + public static final String CONVERT_NULL_PARAMETER = "Could not convert null to the designated type"; + public static final String RELATIONAL_PARAM_UNSUITABLE = "The parameters are not acceptable by the operation"; + public static final String PATTERN_MATCHER_PROBLEM = "The following error occurred during the preparation of an EMF-IncQuery pattern matcher"; + public static final String GETNAME_FAILED = "Could not get 'name' attribute of the result"; + + public static final String INVALID_EMFROOT = "Incremental query engine can only be attached on the contents of an EMF EObject, Resource, or ResourceSet. Received instead: "; + public static final String INVALID_EMFROOT_SHORT = "Invalid EMF model root"; + // public static final String EMF_MODEL_PROCESSING_ERROR = "Error while processing the EMF model"; + + private final String shortMessage; + + public IncQueryException(String s, String shortMessage) { + super(s); + this.shortMessage = shortMessage; + } + + public IncQueryException(RetePatternBuildException e) { + super(PATTERN_MATCHER_PROBLEM + ": " + e.getMessage(), e); + this.shortMessage = e.getShortMessage(); + } + + public IncQueryException(String s, String shortMessage, Exception e) { + super(s + ": " + e.getMessage(), e); + this.shortMessage = shortMessage; + } + + public String getShortMessage() { + return shortMessage; + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage.generator/src/org/eclipse/incquery/patternlanguage/generator/ExtendedPatternLanguageGenerator.java b/plugins/org.eclipse.incquery.patternlanguage.generator/src/org/eclipse/incquery/patternlanguage/generator/ExtendedPatternLanguageGenerator.java index 9425eb01..605839ed 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.generator/src/org/eclipse/incquery/patternlanguage/generator/ExtendedPatternLanguageGenerator.java +++ b/plugins/org.eclipse.incquery.patternlanguage.generator/src/org/eclipse/incquery/patternlanguage/generator/ExtendedPatternLanguageGenerator.java @@ -20,17 +20,17 @@ public class ExtendedPatternLanguageGenerator extends Generator { - public ExtendedPatternLanguageGenerator() { - new XtextStandaloneSetup() { - @Override - public Injector createInjector() { - return Guice.createInjector(new XtextRuntimeModule() { - @Override - public Class bindIXtext2EcorePostProcessor() { - return BasePatternLanguageGeneratorPostProcessor.class; - } - }); - } - }.createInjectorAndDoEMFRegistration(); - } + public ExtendedPatternLanguageGenerator() { + new XtextStandaloneSetup() { + @Override + public Injector createInjector() { + return Guice.createInjector(new XtextRuntimeModule() { + @Override + public Class bindIXtext2EcorePostProcessor() { + return BasePatternLanguageGeneratorPostProcessor.class; + } + }); + } + }.createInjectorAndDoEMFRegistration(); + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage.generator/src/org/eclipse/incquery/patternlanguage/generator/PatternLanguageClassResolver.java b/plugins/org.eclipse.incquery.patternlanguage.generator/src/org/eclipse/incquery/patternlanguage/generator/PatternLanguageClassResolver.java index c3f92ec8..cce111e3 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.generator/src/org/eclipse/incquery/patternlanguage/generator/PatternLanguageClassResolver.java +++ b/plugins/org.eclipse.incquery.patternlanguage.generator/src/org/eclipse/incquery/patternlanguage/generator/PatternLanguageClassResolver.java @@ -15,12 +15,15 @@ public class PatternLanguageClassResolver { - public static EClass getVariableType() { - EPackage corePackage = EPackage.Registry.INSTANCE.getEPackage("http://www.eclipse.org/incquery/patternlanguage/PatternLanguage"); - return (EClass) corePackage.getEClassifier("Variable"); - } - public static EClass getVariableReferenceType() { - EPackage corePackage = EPackage.Registry.INSTANCE.getEPackage("http://www.eclipse.org/incquery/patternlanguage/PatternLanguage"); - return (EClass) corePackage.getEClassifier("VariableReference"); - } + public static EClass getVariableType() { + EPackage corePackage = EPackage.Registry.INSTANCE + .getEPackage("http://www.eclipse.org/incquery/patternlanguage/PatternLanguage"); + return (EClass) corePackage.getEClassifier("Variable"); + } + + public static EClass getVariableReferenceType() { + EPackage corePackage = EPackage.Registry.INSTANCE + .getEPackage("http://www.eclipse.org/incquery/patternlanguage/PatternLanguage"); + return (EClass) corePackage.getEClassifier("VariableReference"); + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage.ui/src/org/eclipse/incquery/patternlanguage/ui/PatternLanguageUiModule.java b/plugins/org.eclipse.incquery.patternlanguage.ui/src/org/eclipse/incquery/patternlanguage/ui/PatternLanguageUiModule.java index c185d9e2..dd728c44 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.ui/src/org/eclipse/incquery/patternlanguage/ui/PatternLanguageUiModule.java +++ b/plugins/org.eclipse.incquery.patternlanguage.ui/src/org/eclipse/incquery/patternlanguage/ui/PatternLanguageUiModule.java @@ -16,7 +16,7 @@ * Use this class to register components to be used within the IDE. */ public class PatternLanguageUiModule extends AbstractPatternLanguageUiModule { - public PatternLanguageUiModule(AbstractUIPlugin plugin) { - super(plugin); - } + public PatternLanguageUiModule(AbstractUIPlugin plugin) { + super(plugin); + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage.ui/src/org/eclipse/incquery/patternlanguage/ui/contentassist/PatternLanguageProposalProvider.java b/plugins/org.eclipse.incquery.patternlanguage.ui/src/org/eclipse/incquery/patternlanguage/ui/contentassist/PatternLanguageProposalProvider.java index b7b1573d..1c71f266 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.ui/src/org/eclipse/incquery/patternlanguage/ui/contentassist/PatternLanguageProposalProvider.java +++ b/plugins/org.eclipse.incquery.patternlanguage.ui/src/org/eclipse/incquery/patternlanguage/ui/contentassist/PatternLanguageProposalProvider.java @@ -33,79 +33,68 @@ */ public class PatternLanguageProposalProvider extends AbstractPatternLanguageProposalProvider { - @Inject - private PatternAnnotationProvider annotationProvider; - @Inject - private IScopeProvider scopeProvider; - @Inject - private ReferenceProposalCreator crossReferenceProposalCreator; - - @Override - public void complete_Annotation(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { - for (String annotationName : annotationProvider.getAllAnnotationNames()) { - String prefixedName = String.format("@%s", annotationName); - String prefix = context.getPrefix(); - ContentAssistContext modifiedContext = context; - INode lastNode = context.getLastCompleteNode(); - if ("".equals(prefix) - && lastNode.getSemanticElement() instanceof Annotation) { - Annotation previousNode = (Annotation) lastNode - .getSemanticElement(); - String annotationPrefix = previousNode.getName(); - if (previousNode.getParameters().isEmpty() - && !annotationProvider.getAllAnnotationNames() - .contains(annotationPrefix)) { - modifiedContext = context - .copy() - .setReplaceRegion( - new Region(lastNode.getOffset(), lastNode - .getLength() + prefix.length())) - .toContext(); - prefixedName = annotationName; - } - } - ICompletionProposal proposal = createCompletionProposal( - prefixedName, prefixedName, null, modifiedContext); - if (proposal instanceof ConfigurableCompletionProposal) { - ((ConfigurableCompletionProposal) proposal) - .setAdditionalProposalInfo(annotationProvider - .getAnnotationObject(annotationName)); - ((ConfigurableCompletionProposal) proposal) - .setHover(getHover()); - } - acceptor.accept(proposal); - } - } + @Inject + private PatternAnnotationProvider annotationProvider; + @Inject + private IScopeProvider scopeProvider; + @Inject + private ReferenceProposalCreator crossReferenceProposalCreator; - @Override - public void complete_AnnotationParameter(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { - if (model instanceof Annotation) { - Annotation annotation = (Annotation) model; - for (String paramName : annotationProvider.getAnnotationParameters(annotation.getName())){ - String outputName = String.format("%s = ", paramName); - ICompletionProposal proposal = createCompletionProposal(outputName, paramName, null, context); - if (proposal instanceof ConfigurableCompletionProposal) { - ((ConfigurableCompletionProposal) proposal) - .setAdditionalProposalInfo(annotationProvider - .getAnnotationParameter( - annotation.getName(), paramName)); - ((ConfigurableCompletionProposal) proposal) - .setHover(getHover()); - } - acceptor.accept(proposal); - } - } - } + @Override + public void complete_Annotation(EObject model, RuleCall ruleCall, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { + for (String annotationName : annotationProvider.getAllAnnotationNames()) { + String prefixedName = String.format("@%s", annotationName); + String prefix = context.getPrefix(); + ContentAssistContext modifiedContext = context; + INode lastNode = context.getLastCompleteNode(); + if ("".equals(prefix) && lastNode.getSemanticElement() instanceof Annotation) { + Annotation previousNode = (Annotation) lastNode.getSemanticElement(); + String annotationPrefix = previousNode.getName(); + if (previousNode.getParameters().isEmpty() + && !annotationProvider.getAllAnnotationNames().contains(annotationPrefix)) { + modifiedContext = context.copy() + .setReplaceRegion(new Region(lastNode.getOffset(), lastNode.getLength() + prefix.length())) + .toContext(); + prefixedName = annotationName; + } + } + ICompletionProposal proposal = createCompletionProposal(prefixedName, prefixedName, null, modifiedContext); + if (proposal instanceof ConfigurableCompletionProposal) { + ((ConfigurableCompletionProposal) proposal).setAdditionalProposalInfo(annotationProvider + .getAnnotationObject(annotationName)); + ((ConfigurableCompletionProposal) proposal).setHover(getHover()); + } + acceptor.accept(proposal); + } + } - @Override - public void complete_VariableReference(EObject model, RuleCall ruleCall, - ContentAssistContext context, ICompletionProposalAcceptor acceptor) { - IScope scope = scopeProvider.getScope(model, PatternLanguagePackage.Literals.VARIABLE_REFERENCE__VARIABLE); - crossReferenceProposalCreator.lookupCrossReference(scope, model, - PatternLanguagePackage.Literals.VARIABLE_REFERENCE__VARIABLE, - acceptor, Predicates. alwaysTrue(), - getProposalFactory(ruleCall.getRule().getName(), context)); - + @Override + public void complete_AnnotationParameter(EObject model, RuleCall ruleCall, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { + if (model instanceof Annotation) { + Annotation annotation = (Annotation) model; + for (String paramName : annotationProvider.getAnnotationParameters(annotation.getName())) { + String outputName = String.format("%s = ", paramName); + ICompletionProposal proposal = createCompletionProposal(outputName, paramName, null, context); + if (proposal instanceof ConfigurableCompletionProposal) { + ((ConfigurableCompletionProposal) proposal).setAdditionalProposalInfo(annotationProvider + .getAnnotationParameter(annotation.getName(), paramName)); + ((ConfigurableCompletionProposal) proposal).setHover(getHover()); + } + acceptor.accept(proposal); + } + } + } - } + @Override + public void complete_VariableReference(EObject model, RuleCall ruleCall, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { + IScope scope = scopeProvider.getScope(model, PatternLanguagePackage.Literals.VARIABLE_REFERENCE__VARIABLE); + crossReferenceProposalCreator.lookupCrossReference(scope, model, + PatternLanguagePackage.Literals.VARIABLE_REFERENCE__VARIABLE, acceptor, + Predicates. alwaysTrue(), + getProposalFactory(ruleCall.getRule().getName(), context)); + + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage.ui/src/org/eclipse/incquery/patternlanguage/ui/labeling/PatternLanguageDescriptionLabelProvider.java b/plugins/org.eclipse.incquery.patternlanguage.ui/src/org/eclipse/incquery/patternlanguage/ui/labeling/PatternLanguageDescriptionLabelProvider.java index ca597ab7..fab76a0e 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.ui/src/org/eclipse/incquery/patternlanguage/ui/labeling/PatternLanguageDescriptionLabelProvider.java +++ b/plugins/org.eclipse.incquery.patternlanguage.ui/src/org/eclipse/incquery/patternlanguage/ui/labeling/PatternLanguageDescriptionLabelProvider.java @@ -19,16 +19,12 @@ */ public class PatternLanguageDescriptionLabelProvider extends DefaultDescriptionLabelProvider { -/* - //Labels and icons can be computed like this: - - String text(IEObjectDescription ele) { - return "my "+ele.getName(); - } - - String image(IEObjectDescription ele) { - return ele.getEClass().getName() + ".gif"; - } -*/ + /* + * //Labels and icons can be computed like this: + * + * String text(IEObjectDescription ele) { return "my "+ele.getName(); } + * + * String image(IEObjectDescription ele) { return ele.getEClass().getName() + ".gif"; } + */ } diff --git a/plugins/org.eclipse.incquery.patternlanguage.ui/src/org/eclipse/incquery/patternlanguage/ui/labeling/PatternLanguageLabelProvider.java b/plugins/org.eclipse.incquery.patternlanguage.ui/src/org/eclipse/incquery/patternlanguage/ui/labeling/PatternLanguageLabelProvider.java index c9348d62..d3f6c0cd 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.ui/src/org/eclipse/incquery/patternlanguage/ui/labeling/PatternLanguageLabelProvider.java +++ b/plugins/org.eclipse.incquery.patternlanguage.ui/src/org/eclipse/incquery/patternlanguage/ui/labeling/PatternLanguageLabelProvider.java @@ -22,20 +22,16 @@ */ public class PatternLanguageLabelProvider extends DefaultEObjectLabelProvider { - @Inject - public PatternLanguageLabelProvider(AdapterFactoryLabelProvider delegate) { - super(delegate); - } - -/* - //Labels and icons can be computed like this: - - String text(MyModel ele) { - return "my "+ele.getName(); - } - - String image(MyModel ele) { - return "MyModel.gif"; + @Inject + public PatternLanguageLabelProvider(AdapterFactoryLabelProvider delegate) { + super(delegate); } -*/ + + /* + * //Labels and icons can be computed like this: + * + * String text(MyModel ele) { return "my "+ele.getName(); } + * + * String image(MyModel ele) { return "MyModel.gif"; } + */ } diff --git a/plugins/org.eclipse.incquery.patternlanguage.ui/src/org/eclipse/incquery/patternlanguage/ui/outline/PatternLanguageOutlineTreeProvider.java b/plugins/org.eclipse.incquery.patternlanguage.ui/src/org/eclipse/incquery/patternlanguage/ui/outline/PatternLanguageOutlineTreeProvider.java index ecd5d6be..2ce23e1c 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.ui/src/org/eclipse/incquery/patternlanguage/ui/outline/PatternLanguageOutlineTreeProvider.java +++ b/plugins/org.eclipse.incquery.patternlanguage.ui/src/org/eclipse/incquery/patternlanguage/ui/outline/PatternLanguageOutlineTreeProvider.java @@ -17,5 +17,5 @@ * */ public class PatternLanguageOutlineTreeProvider extends DefaultOutlineTreeProvider { - + } diff --git a/plugins/org.eclipse.incquery.patternlanguage.ui/src/org/eclipse/incquery/patternlanguage/ui/quickfix/PatternLanguageQuickfixProvider.java b/plugins/org.eclipse.incquery.patternlanguage.ui/src/org/eclipse/incquery/patternlanguage/ui/quickfix/PatternLanguageQuickfixProvider.java index d1c3312e..cf713205 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.ui/src/org/eclipse/incquery/patternlanguage/ui/quickfix/PatternLanguageQuickfixProvider.java +++ b/plugins/org.eclipse.incquery.patternlanguage.ui/src/org/eclipse/incquery/patternlanguage/ui/quickfix/PatternLanguageQuickfixProvider.java @@ -14,15 +14,15 @@ public class PatternLanguageQuickfixProvider extends DefaultQuickfixProvider { -// @Fix(MyJavaValidator.INVALID_NAME) -// public void capitalizeName(final Issue issue, IssueResolutionAcceptor acceptor) { -// acceptor.accept(issue, "Capitalize name", "Capitalize the name.", "upcase.png", new IModification() { -// public void apply(IModificationContext context) throws BadLocationException { -// IXtextDocument xtextDocument = context.getXtextDocument(); -// String firstLetter = xtextDocument.get(issue.getOffset(), 1); -// xtextDocument.replace(issue.getOffset(), 1, firstLetter.toUpperCase()); -// } -// }); -// } + // @Fix(MyJavaValidator.INVALID_NAME) + // public void capitalizeName(final Issue issue, IssueResolutionAcceptor acceptor) { + // acceptor.accept(issue, "Capitalize name", "Capitalize the name.", "upcase.png", new IModification() { + // public void apply(IModificationContext context) throws BadLocationException { + // IXtextDocument xtextDocument = context.getXtextDocument(); + // String firstLetter = xtextDocument.get(issue.getOffset(), 1); + // xtextDocument.replace(issue.getOffset(), 1, firstLetter.toUpperCase()); + // } + // }); + // } } diff --git a/plugins/org.eclipse.incquery.patternlanguage.ui/src/org/eclipse/incquery/patternlanguage/ui/refactoring/PatternLanguageRenameStrategy.java b/plugins/org.eclipse.incquery.patternlanguage.ui/src/org/eclipse/incquery/patternlanguage/ui/refactoring/PatternLanguageRenameStrategy.java index dc8f1f30..9bcc748f 100644 --- a/plugins/org.eclipse.incquery.patternlanguage.ui/src/org/eclipse/incquery/patternlanguage/ui/refactoring/PatternLanguageRenameStrategy.java +++ b/plugins/org.eclipse.incquery.patternlanguage.ui/src/org/eclipse/incquery/patternlanguage/ui/refactoring/PatternLanguageRenameStrategy.java @@ -14,15 +14,15 @@ import org.eclipse.xtext.xbase.ui.jvmmodel.refactoring.DefaultJvmModelRenameStrategy; /** - * Encapsulates the model changes of a rename refactoring. + * Encapsulates the model changes of a rename refactoring. */ @SuppressWarnings("restriction") public class PatternLanguageRenameStrategy extends DefaultJvmModelRenameStrategy { - @Override - protected void setInferredJvmElementName(String name, EObject renamedSourceElement) { - /* - * TODO: rename inferred elements as you would in IJvmModelInferrer - */ - } + @Override + protected void setInferredJvmElementName(String name, EObject renamedSourceElement) { + /* + * TODO: rename inferred elements as you would in IJvmModelInferrer + */ + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/PatternLanguageRuntimeModule.java b/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/PatternLanguageRuntimeModule.java index 57d6f9dc..36059b93 100644 --- a/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/PatternLanguageRuntimeModule.java +++ b/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/PatternLanguageRuntimeModule.java @@ -27,12 +27,12 @@ Logger provideLoggerImplementation() { return Logger.getLogger(PatternLanguageRuntimeModule.class); } - @Override - public Class bindIQualifiedNameProvider() { - return PatternNameProvider.class; - } - - public Class bindPatternAnnotationProvider() { - return PatternAnnotationProvider.class; - } + @Override + public Class bindIQualifiedNameProvider() { + return PatternNameProvider.class; + } + + public Class bindPatternAnnotationProvider() { + return PatternAnnotationProvider.class; + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/PatternLanguageStandaloneSetup.java b/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/PatternLanguageStandaloneSetup.java index 414cb114..f1cdb57c 100644 --- a/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/PatternLanguageStandaloneSetup.java +++ b/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/PatternLanguageStandaloneSetup.java @@ -10,15 +10,12 @@ *******************************************************************************/ package org.eclipse.incquery.patternlanguage; - /** - * Initialization support for running Xtext languages - * without equinox extension registry + * Initialization support for running Xtext languages without equinox extension registry */ -public class PatternLanguageStandaloneSetup extends PatternLanguageStandaloneSetupGenerated{ +public class PatternLanguageStandaloneSetup extends PatternLanguageStandaloneSetupGenerated { - public static void doSetup() { - new PatternLanguageStandaloneSetup().createInjectorAndDoEMFRegistration(); - } + public static void doSetup() { + new PatternLanguageStandaloneSetup().createInjectorAndDoEMFRegistration(); + } } - diff --git a/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/annotations/IPatternAnnotationValidator.java b/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/annotations/IPatternAnnotationValidator.java index 94184508..e07f44f6 100644 --- a/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/annotations/IPatternAnnotationValidator.java +++ b/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/annotations/IPatternAnnotationValidator.java @@ -16,37 +16,39 @@ /** * An interface for validating pattern {@link Annotation} objects. + * * @author Zoltan Ujhelyi - * + * */ public interface IPatternAnnotationValidator { - Iterable getMissingMandatoryAttributes(Annotation annotation); - - /** - * @param annotation - * @return - */ - Iterable getUnknownAttributes(Annotation annotation); - - /** - * Returns whether a parameter of an annotation is mistyped - * @param parameter - * @return the expected class of the parameter variable - */ - Class getExpectedParameterType(AnnotationParameter parameter); - - Iterable getAllAvailableParameterNames(); - - String getAnnotationName(); - - String getDescription(); - - String getDescription(String parameterName); - - boolean isDeprecated(); - - boolean isDeprecated(String parameterName); + Iterable getMissingMandatoryAttributes(Annotation annotation); + + /** + * @param annotation + * @return + */ + Iterable getUnknownAttributes(Annotation annotation); + + /** + * Returns whether a parameter of an annotation is mistyped + * + * @param parameter + * @return the expected class of the parameter variable + */ + Class getExpectedParameterType(AnnotationParameter parameter); + + Iterable getAllAvailableParameterNames(); + + String getAnnotationName(); + + String getDescription(); + + String getDescription(String parameterName); + + boolean isDeprecated(); + + boolean isDeprecated(String parameterName); /** * Provides an additional validator implementation. diff --git a/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/annotations/PatternAnnotationProvider.java b/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/annotations/PatternAnnotationProvider.java index b9c5608b..831ff5c3 100644 --- a/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/annotations/PatternAnnotationProvider.java +++ b/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/annotations/PatternAnnotationProvider.java @@ -42,7 +42,7 @@ public class PatternAnnotationProvider { private Logger log; @Inject private Injector injector; - + private static final class ExtensionConverter implements Function { @Override diff --git a/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/annotations/impl/ExtensionBasedPatternAnnotationParameter.java b/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/annotations/impl/ExtensionBasedPatternAnnotationParameter.java index cd86e290..f0b8b301 100644 --- a/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/annotations/impl/ExtensionBasedPatternAnnotationParameter.java +++ b/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/annotations/impl/ExtensionBasedPatternAnnotationParameter.java @@ -11,46 +11,51 @@ package org.eclipse.incquery.patternlanguage.annotations.impl; public class ExtensionBasedPatternAnnotationParameter { - public static final String STRING = "string"; - public static final String VARIABLEREFERENCE = "variablereference"; - public static final String LIST = "list"; - public static final String BOOLEAN = "boolean"; - public static final String DOUBLE = "double"; - public static final String INT = "int"; - private String name; - private String type; - private boolean multiple; - private boolean mandatory; - private String description; - private boolean deprecated; - - public ExtensionBasedPatternAnnotationParameter(String name, String type, - String description, boolean multiple, boolean mandatory, - boolean deprecated) { - super(); - this.name = name; - this.type = type; - this.description = description; - this.multiple = multiple; - this.mandatory = mandatory; - this.deprecated = deprecated; - } - public String getName() { - return name; - } - public String getType() { - return type; - } - public String getDescription() { - return description; - } - public boolean isMultiple() { - return multiple; - } - public boolean isMandatory() { - return mandatory; - } - public boolean isDeprecated() { - return deprecated; - } + public static final String STRING = "string"; + public static final String VARIABLEREFERENCE = "variablereference"; + public static final String LIST = "list"; + public static final String BOOLEAN = "boolean"; + public static final String DOUBLE = "double"; + public static final String INT = "int"; + private String name; + private String type; + private boolean multiple; + private boolean mandatory; + private String description; + private boolean deprecated; + + public ExtensionBasedPatternAnnotationParameter(String name, String type, String description, boolean multiple, + boolean mandatory, boolean deprecated) { + super(); + this.name = name; + this.type = type; + this.description = description; + this.multiple = multiple; + this.mandatory = mandatory; + this.deprecated = deprecated; + } + + public String getName() { + return name; + } + + public String getType() { + return type; + } + + public String getDescription() { + return description; + } + + public boolean isMultiple() { + return multiple; + } + + public boolean isMandatory() { + return mandatory; + } + + public boolean isDeprecated() { + return deprecated; + } } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/formatting/PatternLanguageFormatter.java b/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/formatting/PatternLanguageFormatter.java index d270635a..01642fec 100644 --- a/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/formatting/PatternLanguageFormatter.java +++ b/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/formatting/PatternLanguageFormatter.java @@ -16,19 +16,18 @@ /** * This class contains custom formatting description. * - * see : http://www.eclipse.org/Xtext/documentation/latest/xtext.html#formatting - * on how and when to use it + * see : http://www.eclipse.org/Xtext/documentation/latest/xtext.html#formatting on how and when to use it * * Also see {@link org.eclipse.xtext.xtext.XtextFormattingTokenSerializer} as an example */ public class PatternLanguageFormatter extends AbstractDeclarativeFormatter { - - @Override - protected void configureFormatting(FormattingConfig c) { -// It's usually a good idea to activate the following three statements. -// They will add and preserve newlines around comments -// c.setLinewrap(0, 1, 2).before(getGrammarAccess().getSL_COMMENTRule()); -// c.setLinewrap(0, 1, 2).before(getGrammarAccess().getML_COMMENTRule()); -// c.setLinewrap(0, 1, 1).after(getGrammarAccess().getML_COMMENTRule()); - } + + @Override + protected void configureFormatting(FormattingConfig c) { + // It's usually a good idea to activate the following three statements. + // They will add and preserve newlines around comments + // c.setLinewrap(0, 1, 2).before(getGrammarAccess().getSL_COMMENTRule()); + // c.setLinewrap(0, 1, 2).before(getGrammarAccess().getML_COMMENTRule()); + // c.setLinewrap(0, 1, 1).after(getGrammarAccess().getML_COMMENTRule()); + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/naming/PatternNameProvider.java b/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/naming/PatternNameProvider.java index a947489d..2239fd67 100644 --- a/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/naming/PatternNameProvider.java +++ b/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/naming/PatternNameProvider.java @@ -24,24 +24,23 @@ public class PatternNameProvider extends XbaseQualifiedNameProvider { - @Inject - private IQualifiedNameConverter nameConverter; - - @Override - public QualifiedName getFullyQualifiedName(EObject obj) { - if (obj instanceof Pattern) { - Pattern pattern = (Pattern) obj; - return nameConverter.toQualifiedName(CorePatternLanguageHelper.getFullyQualifiedName(pattern)); - } else if (obj instanceof PatternBody) { - PatternBody patternBody = (PatternBody) obj; - Pattern pattern = (Pattern) patternBody.eContainer(); - return getFullyQualifiedName(pattern).append( - Integer.toString(pattern.getBodies().indexOf(patternBody))); - } else if(obj instanceof Variable) { - Variable variable = (Variable) obj; - return getFullyQualifiedName(variable.eContainer()).append(variable.getName()); - } - return super.getFullyQualifiedName(obj); - } + @Inject + private IQualifiedNameConverter nameConverter; + + @Override + public QualifiedName getFullyQualifiedName(EObject obj) { + if (obj instanceof Pattern) { + Pattern pattern = (Pattern) obj; + return nameConverter.toQualifiedName(CorePatternLanguageHelper.getFullyQualifiedName(pattern)); + } else if (obj instanceof PatternBody) { + PatternBody patternBody = (PatternBody) obj; + Pattern pattern = (Pattern) patternBody.eContainer(); + return getFullyQualifiedName(pattern).append(Integer.toString(pattern.getBodies().indexOf(patternBody))); + } else if (obj instanceof Variable) { + Variable variable = (Variable) obj; + return getFullyQualifiedName(variable.eContainer()).append(variable.getName()); + } + return super.getFullyQualifiedName(obj); + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/scoping/MyAbstractDeclarativeScopeProvider.java b/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/scoping/MyAbstractDeclarativeScopeProvider.java index 5f8afe5a..e82849f4 100644 --- a/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/scoping/MyAbstractDeclarativeScopeProvider.java +++ b/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/scoping/MyAbstractDeclarativeScopeProvider.java @@ -27,124 +27,122 @@ import com.google.inject.name.Named; /** - *

An extended abstract declarative scope provider to facilitate the reusing of abstract - * declarative scope providers together with XBase scope provider.

- *

See http://www.eclipse.org/forums/index.php/mv/msg/219841/699521/#msg_699521 for details.

+ *

+ * An extended abstract declarative scope provider to facilitate the reusing of abstract declarative scope providers + * together with XBase scope provider. + *

+ *

+ * See http://www.eclipse.org/forums/index + * .php/mv/msg/219841/699521/#msg_699521 for details. + *

+ * * @author Zoltan Ujhelyi - * + * */ public class MyAbstractDeclarativeScopeProvider extends AbstractScopeProvider { - public static final String NAMED_DELEGATE = "org.eclipse.xtext.scoping.impl.MyAbstractDeclarativeScopeProvider.delegate"; - public static final String NAMED_ERROR_HANDLER = "org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider.errorHandler"; - - public final Logger logger = Logger.getLogger(getClass()); - - @Inject - @Named(NAMED_DELEGATE) - private IScopeProvider delegate; - - protected IScope delegateGetScope(EObject context, EReference reference) { - return getDelegate().getScope(context, reference); - } - - public void setDelegate(IScopeProvider delegate) { - this.delegate = delegate; - } - - public IScopeProvider getDelegate() { - return delegate; - } - - @Inject(optional = true) - @Named(NAMED_ERROR_HANDLER) - private PolymorphicDispatcher.ErrorHandler errorHandler = new PolymorphicDispatcher.NullErrorHandler(); - - protected Predicate getPredicate(EObject context, EClass type) { - String methodName = "scope_" + type.getName(); - return PolymorphicDispatcher.Predicates.forName(methodName, 2); - } - - protected Predicate getPredicate(EObject context, - EReference reference) { - String methodName = "scope_" - + reference.getEContainingClass().getName() + "_" - + reference.getName(); - return PolymorphicDispatcher.Predicates.forName(methodName, 2); - } - - public IScope getScope(EObject context, EReference reference) { - IScope scope = polymorphicFindScopeForReferenceName(context, reference); - if (scope == null) { - scope = polymorphicFindScopeForClassName(context, reference); - if (scope == null) { - scope = delegateGetScope(context, reference); - } - } - return scope; - } - - protected IScope polymorphicFindScopeForClassName(EObject context, - EReference reference) { - IScope scope = null; - PolymorphicDispatcher dispatcher = new PolymorphicDispatcher( - Collections.singletonList(this), getPredicate(context, - reference.getEReferenceType()), errorHandler) { - @Override - protected IScope handleNoSuchMethod(Object... params) { - if (PolymorphicDispatcher.NullErrorHandler.class - .equals(errorHandler.getClass())) { - return null; - } - return super.handleNoSuchMethod(params); - } - }; - EObject current = context; - while (scope == null && current != null) { - scope = dispatcher.invoke(current, reference); - current = current.eContainer(); - } - current = context; - while (scope == null && current != null) { - scope = dispatcher.invoke(current, reference.getEReferenceType()); - if (scope != null) { - logger.warn("scope_(EObject,EClass) is deprecated. Use scope_(EObject,EReference) instead."); - } - current = current.eContainer(); - } - return scope; - } - - protected IScope polymorphicFindScopeForReferenceName(EObject context, - EReference reference) { - Predicate predicate = getPredicate(context, reference); - PolymorphicDispatcher dispatcher = new PolymorphicDispatcher( - Collections.singletonList(this), predicate, errorHandler) { - @Override - protected IScope handleNoSuchMethod(Object... params) { - if (PolymorphicDispatcher.NullErrorHandler.class - .equals(errorHandler.getClass())) { - return null; - } - return super.handleNoSuchMethod(params); - } - }; - EObject current = context; - IScope scope = null; - while (scope == null && current != null) { - scope = dispatcher.invoke(current, reference); - current = current.eContainer(); - } - return scope; - } - - public void setErrorHandler( - PolymorphicDispatcher.ErrorHandler errorHandler) { - this.errorHandler = errorHandler; - } - - public PolymorphicDispatcher.ErrorHandler getErrorHandler() { - return errorHandler; - } + public static final String NAMED_DELEGATE = "org.eclipse.xtext.scoping.impl.MyAbstractDeclarativeScopeProvider.delegate"; + public static final String NAMED_ERROR_HANDLER = "org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider.errorHandler"; + + public final Logger logger = Logger.getLogger(getClass()); + + @Inject + @Named(NAMED_DELEGATE) + private IScopeProvider delegate; + + protected IScope delegateGetScope(EObject context, EReference reference) { + return getDelegate().getScope(context, reference); + } + + public void setDelegate(IScopeProvider delegate) { + this.delegate = delegate; + } + + public IScopeProvider getDelegate() { + return delegate; + } + + @Inject(optional = true) + @Named(NAMED_ERROR_HANDLER) + private PolymorphicDispatcher.ErrorHandler errorHandler = new PolymorphicDispatcher.NullErrorHandler(); + + protected Predicate getPredicate(EObject context, EClass type) { + String methodName = "scope_" + type.getName(); + return PolymorphicDispatcher.Predicates.forName(methodName, 2); + } + + protected Predicate getPredicate(EObject context, EReference reference) { + String methodName = "scope_" + reference.getEContainingClass().getName() + "_" + reference.getName(); + return PolymorphicDispatcher.Predicates.forName(methodName, 2); + } + + public IScope getScope(EObject context, EReference reference) { + IScope scope = polymorphicFindScopeForReferenceName(context, reference); + if (scope == null) { + scope = polymorphicFindScopeForClassName(context, reference); + if (scope == null) { + scope = delegateGetScope(context, reference); + } + } + return scope; + } + + protected IScope polymorphicFindScopeForClassName(EObject context, EReference reference) { + IScope scope = null; + PolymorphicDispatcher dispatcher = new PolymorphicDispatcher(Collections.singletonList(this), + getPredicate(context, reference.getEReferenceType()), errorHandler) { + @Override + protected IScope handleNoSuchMethod(Object... params) { + if (PolymorphicDispatcher.NullErrorHandler.class.equals(errorHandler.getClass())) { + return null; + } + return super.handleNoSuchMethod(params); + } + }; + EObject current = context; + while (scope == null && current != null) { + scope = dispatcher.invoke(current, reference); + current = current.eContainer(); + } + current = context; + while (scope == null && current != null) { + scope = dispatcher.invoke(current, reference.getEReferenceType()); + if (scope != null) { + logger.warn("scope_(EObject,EClass) is deprecated. Use scope_(EObject,EReference) instead."); + } + current = current.eContainer(); + } + return scope; + } + + protected IScope polymorphicFindScopeForReferenceName(EObject context, EReference reference) { + Predicate predicate = getPredicate(context, reference); + PolymorphicDispatcher dispatcher = new PolymorphicDispatcher(Collections.singletonList(this), + predicate, errorHandler) { + @Override + protected IScope handleNoSuchMethod(Object... params) { + if (PolymorphicDispatcher.NullErrorHandler.class.equals(errorHandler.getClass())) { + return null; + } + return super.handleNoSuchMethod(params); + } + }; + EObject current = context; + IScope scope = null; + while (scope == null && current != null) { + scope = dispatcher.invoke(current, reference); + current = current.eContainer(); + } + return scope; + } + + public void setErrorHandler(PolymorphicDispatcher.ErrorHandler errorHandler) { + this.errorHandler = errorHandler; + } + + public PolymorphicDispatcher.ErrorHandler getErrorHandler() { + return errorHandler; + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/scoping/PatternLanguageDeclarativeScopeProvider.java b/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/scoping/PatternLanguageDeclarativeScopeProvider.java index 654ba982..c4b0887d 100644 --- a/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/scoping/PatternLanguageDeclarativeScopeProvider.java +++ b/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/scoping/PatternLanguageDeclarativeScopeProvider.java @@ -29,75 +29,71 @@ /** *

- * An extended abstract declarative scope provider to facilitate the reusing of - * abstract declarative scope providers together with XBase scope provider. + * An extended abstract declarative scope provider to facilitate the reusing of abstract declarative scope providers + * together with XBase scope provider. *

*

- * See http://www.eclipse.org/forums/index.php/mv/msg/219841/699521/#msg_699521 - * for details. + * See http://www.eclipse.org/forums/index.php/mv/msg/219841/699521/#msg_699521 for details. *

* * @author Zoltan Ujhelyi * */ -public class PatternLanguageDeclarativeScopeProvider extends - MyAbstractDeclarativeScopeProvider { +public class PatternLanguageDeclarativeScopeProvider extends MyAbstractDeclarativeScopeProvider { private static final class PrivateDescFilter implements Predicate { @Override public boolean apply(IEObjectDescription input) { - // filter not local, private patterns (private patterns in other - // resources) - // this information stored in the userdata of the - // EObjectDescription - // EObjectDescription only created for not local eObjects, so - // check for resource equality is unnecessary. - if ("true".equals(input.getUserData("private"))) { - return false; - } - return true; + // filter not local, private patterns (private patterns in other + // resources) + // this information stored in the userdata of the + // EObjectDescription + // EObjectDescription only created for not local eObjects, so + // check for resource equality is unnecessary. + if ("true".equals(input.getUserData("private"))) { + return false; + } + return true; } } private static final class UndefinedVariable implements Predicate { - @Override + @Override public boolean apply(Variable input) { - return input.getName() != null && !input.getName().isEmpty(); - } - } + return input.getName() != null && !input.getName().isEmpty(); + } + } - private static final class CreateObjectDescFunction implements - Function { + private static final class CreateObjectDescFunction implements Function { @Override public IEObjectDescription apply(Variable from) { - return EObjectDescription.create(from.getName(), from); - } - } + return EObjectDescription.create(from.getName(), from); + } + } - /** - * Custom scoping for patternRef in {@link PatternCall}. Currently returns - * all Pattern that is visible from the current context. - * - * @param ctx - * @param ref - * @return - */ - public IScope scope_PatternCall_patternRef(PatternCall ctx, EReference ref) { - IScope scope = delegateGetScope(ctx, ref); + /** + * Custom scoping for patternRef in {@link PatternCall}. Currently returns all Pattern that is visible from the + * current context. + * + * @param ctx + * @param ref + * @return + */ + public IScope scope_PatternCall_patternRef(PatternCall ctx, EReference ref) { + IScope scope = delegateGetScope(ctx, ref); return new FilteringScope(scope, new PrivateDescFilter()); - } + } - public IScope scope_VariableReference_variable(EObject ctx, EReference ref) { - EObject it = ctx; - PatternBody body = null; - while (it != null && !(it instanceof Pattern)) { - if (it instanceof PatternBody) { - body = (PatternBody) it; - } - it = it.eContainer(); - } + public IScope scope_VariableReference_variable(EObject ctx, EReference ref) { + EObject it = ctx; + PatternBody body = null; + while (it != null && !(it instanceof Pattern)) { + if (it instanceof PatternBody) { + body = (PatternBody) it; + } + it = it.eContainer(); + } CreateObjectDescFunction createObjectDescFunction = new CreateObjectDescFunction(); EList variables; if (body != null) { @@ -107,12 +103,10 @@ public IScope scope_VariableReference_variable(EObject ctx, EReference ref) { variables = pattern.getParameters(); } else { return IScope.NULLSCOPE; - } - UndefinedVariable variableFilter = new UndefinedVariable(); - IScope localScope = new SimpleScope(IScope.NULLSCOPE, - Iterables.transform( - Iterables.filter(variables, variableFilter), - createObjectDescFunction)); - return localScope; - } + } + UndefinedVariable variableFilter = new UndefinedVariable(); + IScope localScope = new SimpleScope(IScope.NULLSCOPE, Iterables.transform( + Iterables.filter(variables, variableFilter), createObjectDescFunction)); + return localScope; + } } diff --git a/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/scoping/PatternLanguageResourceDescriptionStrategy.java b/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/scoping/PatternLanguageResourceDescriptionStrategy.java index f52f46d1..8b3055ca 100644 --- a/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/scoping/PatternLanguageResourceDescriptionStrategy.java +++ b/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/scoping/PatternLanguageResourceDescriptionStrategy.java @@ -26,35 +26,35 @@ import com.google.common.collect.Constraint; /** - * Custom strategy for computing ResourceDescription for eiq resources. - * Adds user data for Pattern EObjectDescription about private modifier. + * Custom strategy for computing ResourceDescription for eiq resources. Adds user data for Pattern EObjectDescription + * about private modifier. + * * @author Mark Czotter - * + * */ public class PatternLanguageResourceDescriptionStrategy extends DefaultResourceDescriptionStrategy { - - @Override - public boolean createEObjectDescriptions(EObject eObject, - IAcceptor acceptor) { - if (eObject instanceof Pattern) { - boolean isPrivate = CorePatternLanguageHelper.isPrivate((Pattern)eObject); - QualifiedName qualifiedName = getQualifiedNameProvider().getFullyQualifiedName(eObject); - if (qualifiedName != null) { - acceptor.accept(EObjectDescription.create(qualifiedName, eObject, Collections.singletonMap("private", String.valueOf(isPrivate)))); - } - return true; - } else if (eObject instanceof Variable - && !(eObject.eContainer() instanceof Pattern)) { - // Internal variable - not usable from outside - return false; - } else if (eObject instanceof Constraint) { - // Constraints are not needed in the index - return false; - } else if (eObject instanceof PatternBody) { - // Pattern bodies are not needed in the index - return false; - } - return super.createEObjectDescriptions(eObject, acceptor); - } + + @Override + public boolean createEObjectDescriptions(EObject eObject, IAcceptor acceptor) { + if (eObject instanceof Pattern) { + boolean isPrivate = CorePatternLanguageHelper.isPrivate((Pattern) eObject); + QualifiedName qualifiedName = getQualifiedNameProvider().getFullyQualifiedName(eObject); + if (qualifiedName != null) { + acceptor.accept(EObjectDescription.create(qualifiedName, eObject, + Collections.singletonMap("private", String.valueOf(isPrivate)))); + } + return true; + } else if (eObject instanceof Variable && !(eObject.eContainer() instanceof Pattern)) { + // Internal variable - not usable from outside + return false; + } else if (eObject instanceof Constraint) { + // Constraints are not needed in the index + return false; + } else if (eObject instanceof PatternBody) { + // Pattern bodies are not needed in the index + return false; + } + return super.createEObjectDescriptions(eObject, acceptor); + } } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/serializer/PatternLanguageSemanticSequencer.java b/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/serializer/PatternLanguageSemanticSequencer.java index 8d2e51f6..cf5357e6 100644 --- a/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/serializer/PatternLanguageSemanticSequencer.java +++ b/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/serializer/PatternLanguageSemanticSequencer.java @@ -10,6 +10,5 @@ *******************************************************************************/ package org.eclipse.incquery.patternlanguage.serializer; - public class PatternLanguageSemanticSequencer extends AbstractPatternLanguageSemanticSequencer { } diff --git a/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/serializer/PatternLanguageSyntacticSequencer.java b/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/serializer/PatternLanguageSyntacticSequencer.java index 1aee9f74..3ae0966d 100644 --- a/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/serializer/PatternLanguageSyntacticSequencer.java +++ b/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/serializer/PatternLanguageSyntacticSequencer.java @@ -10,6 +10,5 @@ *******************************************************************************/ package org.eclipse.incquery.patternlanguage.serializer; - public class PatternLanguageSyntacticSequencer extends AbstractPatternLanguageSyntacticSequencer { } diff --git a/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/validation/IIssueCallback.java b/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/validation/IIssueCallback.java index ca8c89fc..721a3845 100644 --- a/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/validation/IIssueCallback.java +++ b/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/validation/IIssueCallback.java @@ -15,7 +15,7 @@ /** * @author Zoltan Ujhelyi - * + * */ public interface IIssueCallback { diff --git a/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/validation/IssueCodes.java b/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/validation/IssueCodes.java index 9cf0e58a..9dd94413 100644 --- a/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/validation/IssueCodes.java +++ b/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/validation/IssueCodes.java @@ -14,31 +14,36 @@ * @author Mark Czotter */ public final class IssueCodes { - - private IssueCodes() {} - - protected static final String ISSUE_CODE_PREFIX = "org.eclipse.incquery.patternlanguage.validation.IssueCodes."; - - public static final String DUPLICATE_PATTERN_PARAMETER_NAME = ISSUE_CODE_PREFIX + "duplicate_pattern_parameter_name"; - public static final String DUPLICATE_PATTERN_DEFINITION = ISSUE_CODE_PREFIX + "duplicate_pattern_definition"; - public static final String WRONG_NUMBER_PATTERNCALL_PARAMETER = ISSUE_CODE_PREFIX + "wrong_number_pattern_parameter"; - public static final String TRANSITIVE_PATTERNCALL_NOT_APPLICABLE = ISSUE_CODE_PREFIX + "transitive_patterncall_not_applicable"; - public static final String TRANSITIVE_PATTERNCALL_ARITY = ISSUE_CODE_PREFIX + "transitive_patterncall_wrong_arity"; - public static final String PATTERN_BODY_EMPTY = ISSUE_CODE_PREFIX + "patternbody_empty"; - - public static final String UNKNOWN_ANNOTATION = ISSUE_CODE_PREFIX + "unknown_annotation"; - public static final String UNKNOWN_ANNOTATION_PARAMETER = ISSUE_CODE_PREFIX + "unknown_annotation_attribute"; - public static final String MISSING_REQUIRED_ANNOTATION_PARAMETER = ISSUE_CODE_PREFIX + "missing_annotation_parameter"; - public static final String MISTYPED_ANNOTATION_PARAMETER = ISSUE_CODE_PREFIX + "mistyped_annotation_parameter"; - - public static final String CONSTANT_COMPARE_CONSTRAINT = ISSUE_CODE_PREFIX + "constant_compare_constraint"; - public static final String SELF_COMPARE_CONSTRAINT = ISSUE_CODE_PREFIX + "self_compare_constraint"; - - public static final String LOWERCASE_PATTERN_NAME = ISSUE_CODE_PREFIX + "lowercase_pattern_name"; - public static final String UNUSED_PRIVATE_PATTERN = ISSUE_CODE_PREFIX + "unused_private_pattern"; - public static final String MISSING_PATTERN_PARAMETERS = ISSUE_CODE_PREFIX + "missing_pattern_parameters"; - - public static final String CHECK_MUST_BE_BOOLEAN = ISSUE_CODE_PREFIX + "check_boolean"; - public static final String CHECK_WITH_IMPURE_JAVA_CALLS = ISSUE_CODE_PREFIX + "check_with_impure_java_calls"; - + + private IssueCodes() { + } + + protected static final String ISSUE_CODE_PREFIX = "org.eclipse.incquery.patternlanguage.validation.IssueCodes."; + + public static final String DUPLICATE_PATTERN_PARAMETER_NAME = ISSUE_CODE_PREFIX + + "duplicate_pattern_parameter_name"; + public static final String DUPLICATE_PATTERN_DEFINITION = ISSUE_CODE_PREFIX + "duplicate_pattern_definition"; + public static final String WRONG_NUMBER_PATTERNCALL_PARAMETER = ISSUE_CODE_PREFIX + + "wrong_number_pattern_parameter"; + public static final String TRANSITIVE_PATTERNCALL_NOT_APPLICABLE = ISSUE_CODE_PREFIX + + "transitive_patterncall_not_applicable"; + public static final String TRANSITIVE_PATTERNCALL_ARITY = ISSUE_CODE_PREFIX + "transitive_patterncall_wrong_arity"; + public static final String PATTERN_BODY_EMPTY = ISSUE_CODE_PREFIX + "patternbody_empty"; + + public static final String UNKNOWN_ANNOTATION = ISSUE_CODE_PREFIX + "unknown_annotation"; + public static final String UNKNOWN_ANNOTATION_PARAMETER = ISSUE_CODE_PREFIX + "unknown_annotation_attribute"; + public static final String MISSING_REQUIRED_ANNOTATION_PARAMETER = ISSUE_CODE_PREFIX + + "missing_annotation_parameter"; + public static final String MISTYPED_ANNOTATION_PARAMETER = ISSUE_CODE_PREFIX + "mistyped_annotation_parameter"; + + public static final String CONSTANT_COMPARE_CONSTRAINT = ISSUE_CODE_PREFIX + "constant_compare_constraint"; + public static final String SELF_COMPARE_CONSTRAINT = ISSUE_CODE_PREFIX + "self_compare_constraint"; + + public static final String LOWERCASE_PATTERN_NAME = ISSUE_CODE_PREFIX + "lowercase_pattern_name"; + public static final String UNUSED_PRIVATE_PATTERN = ISSUE_CODE_PREFIX + "unused_private_pattern"; + public static final String MISSING_PATTERN_PARAMETERS = ISSUE_CODE_PREFIX + "missing_pattern_parameters"; + + public static final String CHECK_MUST_BE_BOOLEAN = ISSUE_CODE_PREFIX + "check_boolean"; + public static final String CHECK_WITH_IMPURE_JAVA_CALLS = ISSUE_CODE_PREFIX + "check_with_impure_java_calls"; + } diff --git a/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/validation/PatternLanguageJavaValidator.java b/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/validation/PatternLanguageJavaValidator.java index 0b914fa9..4224b5a2 100644 --- a/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/validation/PatternLanguageJavaValidator.java +++ b/plugins/org.eclipse.incquery.patternlanguage/src/org/eclipse/incquery/patternlanguage/validation/PatternLanguageJavaValidator.java @@ -90,8 +90,8 @@ public class PatternLanguageJavaValidator extends AbstractPatternLanguageJavaVal @Check public void checkPatternParameters(Pattern pattern) { if (pattern.getParameters().size() == 0) { - warning("Parameterless patterns can only be used to check for existence of a condition.", PatternLanguagePackage.Literals.PATTERN__NAME, - IssueCodes.MISSING_PATTERN_PARAMETERS); + warning("Parameterless patterns can only be used to check for existence of a condition.", + PatternLanguagePackage.Literals.PATTERN__NAME, IssueCodes.MISSING_PATTERN_PARAMETERS); // As no duplicate parameters are available, returning now return; } @@ -99,9 +99,11 @@ public void checkPatternParameters(Pattern pattern) { String leftParameterName = pattern.getParameters().get(i).getName(); for (int j = i + 1; j < pattern.getParameters().size(); ++j) { if (equal(leftParameterName, pattern.getParameters().get(j).getName())) { - error(DUPLICATE_VARIABLE_MESSAGE + leftParameterName, PatternLanguagePackage.Literals.PATTERN__PARAMETERS, i, + error(DUPLICATE_VARIABLE_MESSAGE + leftParameterName, + PatternLanguagePackage.Literals.PATTERN__PARAMETERS, i, IssueCodes.DUPLICATE_PATTERN_PARAMETER_NAME); - error(DUPLICATE_VARIABLE_MESSAGE + leftParameterName, PatternLanguagePackage.Literals.PATTERN__PARAMETERS, j, + error(DUPLICATE_VARIABLE_MESSAGE + leftParameterName, + PatternLanguagePackage.Literals.PATTERN__PARAMETERS, j, IssueCodes.DUPLICATE_PATTERN_PARAMETER_NAME); } } @@ -168,10 +170,10 @@ public void checkPatterns(PatternModel model) { Pattern rightPattern = model.getPatterns().get(j); String rightPatternName = rightPattern.getName(); if (equal(leftPatternName, rightPatternName)) { - error(DUPLICATE_PATTERN_DEFINITION_MESSAGE + leftPatternName, leftPattern, PatternLanguagePackage.Literals.PATTERN__NAME, - IssueCodes.DUPLICATE_PATTERN_DEFINITION); - error(DUPLICATE_PATTERN_DEFINITION_MESSAGE + rightPatternName, rightPattern, PatternLanguagePackage.Literals.PATTERN__NAME, - IssueCodes.DUPLICATE_PATTERN_DEFINITION); + error(DUPLICATE_PATTERN_DEFINITION_MESSAGE + leftPatternName, leftPattern, + PatternLanguagePackage.Literals.PATTERN__NAME, IssueCodes.DUPLICATE_PATTERN_DEFINITION); + error(DUPLICATE_PATTERN_DEFINITION_MESSAGE + rightPatternName, rightPattern, + PatternLanguagePackage.Literals.PATTERN__NAME, IssueCodes.DUPLICATE_PATTERN_DEFINITION); } } } @@ -421,14 +423,12 @@ private boolean isImpureElement(JvmOperation jvmOperation) { } @Override - public void warning(String message, EObject source, EStructuralFeature feature, String code, - String... issueData) { + public void warning(String message, EObject source, EStructuralFeature feature, String code, String... issueData) { super.warning(message, source, feature, code, issueData); } @Override - public void error(String message, EObject source, EStructuralFeature feature, String code, - String... issueData) { + public void error(String message, EObject source, EStructuralFeature feature, String code, String... issueData) { super.error(message, source, feature, code, issueData); } diff --git a/plugins/org.eclipse.incquery.querybasedfeatures.runtime/src/org/eclipse/incquery/querybasedfeatures/runtime/DerivedFeatureAdapter.java b/plugins/org.eclipse.incquery.querybasedfeatures.runtime/src/org/eclipse/incquery/querybasedfeatures/runtime/DerivedFeatureAdapter.java index b4a7a8ab..76259284 100644 --- a/plugins/org.eclipse.incquery.querybasedfeatures.runtime/src/org/eclipse/incquery/querybasedfeatures/runtime/DerivedFeatureAdapter.java +++ b/plugins/org.eclipse.incquery.querybasedfeatures.runtime/src/org/eclipse/incquery/querybasedfeatures/runtime/DerivedFeatureAdapter.java @@ -34,355 +34,349 @@ /** * @author Abel Hegedus - * - * TODO: move to incquery code - * - * + * + * TODO: move to incquery code + * + * */ public class DerivedFeatureAdapter extends AdapterImpl { - private final InternalEObject source; - private final EStructuralFeature derivedFeature; - private final DerivedFeatureEMFVisitor visitor = new DerivedFeatureEMFVisitor(); - - /** - * Only used for single reference! - */ - private Object currentValue; - private Object oldValue; - private EClassifier type; - - private final List localFeatures = new ArrayList(); - private final List featurePaths = new ArrayList(); - - /* - * Convenience constructor for a local and navigated dependency - */ - public DerivedFeatureAdapter(EObject source, EStructuralFeature derivedFeature, - EStructuralFeature navigationFeature, EStructuralFeature dependantFeature, EStructuralFeature localFeature) { - this(source, derivedFeature); - addNavigatedDependencyInternal(navigationFeature, dependantFeature); - addLocalDependencyInternal(localFeature); - } - - /* - * Convenience constructor for a navigated dependency - */ - public DerivedFeatureAdapter(EObject source, EStructuralFeature derivedFeature, - EStructuralFeature navigationFeature, EStructuralFeature dependantFeature) { - this(source, derivedFeature); - addNavigatedDependencyInternal(navigationFeature, dependantFeature); - } - - /* - * Convenience constructor for a local dependency - */ - public DerivedFeatureAdapter(EObject source, EStructuralFeature derivedFeature, - EStructuralFeature localFeature) { - this(source, derivedFeature); - addLocalDependencyInternal(localFeature); - } - - public DerivedFeatureAdapter(EObject source, EStructuralFeature derivedFeature) { - super(); - this.source = (InternalEObject) source; - this.derivedFeature = derivedFeature; - source.eAdapters().add(this); - } - - public void addNavigatedDependency(EStructuralFeature navigationFeature, - EStructuralFeature dependantFeature) { - if(navigationFeature == null || dependantFeature == null) { - return; - } - if(!source.eClass().getEAllStructuralFeatures().contains(navigationFeature)) { - return; - } - if(!(navigationFeature.getEType() instanceof EClass) || !dependantFeature.getEContainingClass().isSuperTypeOf((EClass) navigationFeature.getEType())) { - return; - } - addNavigatedDependencyInternal(navigationFeature, dependantFeature); - } - - public void addLocalDependency(EStructuralFeature localFeature) { - if(localFeature == null) { - return; - } - if(!source.eClass().getEAllStructuralFeatures().contains(localFeature)) { - return; - } - addLocalDependencyInternal(localFeature); - } - - private void addNavigatedDependencyInternal(EStructuralFeature navigationFeature, - EStructuralFeature dependantFeature) { - featurePaths.add(new DependentFeaturePath(navigationFeature, dependantFeature)); - } - - private void addLocalDependencyInternal(EStructuralFeature localFeature) { - localFeatures.add(localFeature); - } - - @Override - public void notifyChanged(Notification notification) { - //System.err.println("[Source: " + derivedFeature.getName() + "] New notification: " + notification); - for(DependentFeaturePath path : featurePaths) { - if (notification.getFeature().equals(path.getNavigationFeature())) { - //System.err.println("Handling notification."); - switch (notification.getEventType()) { - case Notification.SET: - EObject newValue = (EObject) notification.getNewValue(); - EObject tempOldValue = (EObject) notification.getOldValue(); - if (tempOldValue != null) { - tempOldValue.eAdapters().remove(path.getDependantAdapter()); - } - else { - IncQueryEngine.getDefaultLogger().debug("[DerivedFeatureAdapter] oldValue is not set"); - } - if (newValue != null) { - newValue.eAdapters().add(path.getDependantAdapter()); - } - else { - IncQueryEngine.getDefaultLogger().debug("[DerivedFeatureAdapter] new value is not set"); - } - break; - case Notification.ADD: - EObject added = (EObject) notification.getNewValue(); - added.eAdapters().add(path.getDependantAdapter()); - break; - case Notification.ADD_MANY: - EObject newValueCollection = (EObject) notification.getNewValue(); - for (Object newElement: (Collection)newValueCollection) { - ((Notifier) newElement).eAdapters().add(path.getDependantAdapter()); - } - break; - case Notification.REMOVE: - EObject removed = (EObject) notification.getOldValue(); - removed.eAdapters().remove(path.getDependantAdapter()); - break; - case Notification.REMOVE_MANY: - EObject oldValueCollection = (EObject) notification.getOldValue(); - for (Object oldElement: (Collection)oldValueCollection) { - ((Notifier) oldElement).eAdapters().remove(path.getDependantAdapter()); - } - break; - case Notification.UNSET: - EObject unset = (EObject) notification.getOldValue(); - unset.eAdapters().remove(path.getDependantAdapter()); - break; - case Notification.CREATE: - case Notification.MOVE: // currently no support for ordering - case Notification.RESOLVE: //TODO is it safe to ignore all of them? - case Notification.REMOVING_ADAPTER: - break; - default: - IncQueryEngine.getDefaultLogger().debug("[DerivedFeatureAdapter] Unhandled notification: " + notification.getEventType()); - return; // No notification - } - refreshDerivedFeature(); - } - } - if (localFeatures.contains(notification.getFeature())) { - //System.err.println("Handling notification."); - refreshDerivedFeature(); - } - } - - @SuppressWarnings("unchecked") - private void refreshDerivedFeature() { - //System.err.println("[Notify: " + derivedFeature.getName() + "] Derived refresh."); - try { - if (source.eNotificationRequired()) { - if(type == null) { - type = derivedFeature.getEType(); - } - if (derivedFeature.isMany()) { - if(currentValue != null) { - oldValue = new HashSet((Collection) currentValue); - } else { - oldValue = new HashSet(); - } - //if(currentValue == null) { - currentValue = new HashSet(); - //} else { - // ((Collection) currentValue).clear(); - //} - Collection targets = (Collection) source.eGet(derivedFeature); - for (Object target : targets) { - EMFModelComprehension.traverseFeature(visitor, source, derivedFeature, target); - } - if(currentValue instanceof Collection && oldValue instanceof Collection) { - ((Collection)oldValue).removeAll((Collection) currentValue); - if(((Collection) oldValue).size() > 0) { - sendRemoveManyNotification(source, derivedFeature, oldValue); - } - } - } else { - Object target = source.eGet(derivedFeature); - EMFModelComprehension.traverseFeature(visitor, source, derivedFeature, target); - } - } - } catch (Exception ex) { - IncQueryEngine.getDefaultLogger().error("The derived feature adapter encountered an error in processing the EMF model. " + - "This happened while maintaining the derived feature " + - derivedFeature.getName() + " of object " + source, ex); - } - } - - private class DependentFeaturePath{ - private EStructuralFeature dependantFeature = null; - private EStructuralFeature navigationFeature = null; - - private final AdapterImpl dependantAdapter = new AdapterImpl() { - - @Override - public void notifyChanged(Notification msg) { - //System.err.println("[Dependant: " + derivedFeature.getName() + "] New notification: " + msg); - if (msg.getFeature().equals(dependantFeature) ) { - refreshDerivedFeature(); - } - } - }; - - /** + private final InternalEObject source; + private final EStructuralFeature derivedFeature; + private final DerivedFeatureEMFVisitor visitor = new DerivedFeatureEMFVisitor(); + + /** + * Only used for single reference! + */ + private Object currentValue; + private Object oldValue; + private EClassifier type; + + private final List localFeatures = new ArrayList(); + private final List featurePaths = new ArrayList(); + + /* + * Convenience constructor for a local and navigated dependency + */ + public DerivedFeatureAdapter(EObject source, EStructuralFeature derivedFeature, + EStructuralFeature navigationFeature, EStructuralFeature dependantFeature, EStructuralFeature localFeature) { + this(source, derivedFeature); + addNavigatedDependencyInternal(navigationFeature, dependantFeature); + addLocalDependencyInternal(localFeature); + } + + /* + * Convenience constructor for a navigated dependency + */ + public DerivedFeatureAdapter(EObject source, EStructuralFeature derivedFeature, + EStructuralFeature navigationFeature, EStructuralFeature dependantFeature) { + this(source, derivedFeature); + addNavigatedDependencyInternal(navigationFeature, dependantFeature); + } + + /* + * Convenience constructor for a local dependency + */ + public DerivedFeatureAdapter(EObject source, EStructuralFeature derivedFeature, EStructuralFeature localFeature) { + this(source, derivedFeature); + addLocalDependencyInternal(localFeature); + } + + public DerivedFeatureAdapter(EObject source, EStructuralFeature derivedFeature) { + super(); + this.source = (InternalEObject) source; + this.derivedFeature = derivedFeature; + source.eAdapters().add(this); + } + + public void addNavigatedDependency(EStructuralFeature navigationFeature, EStructuralFeature dependantFeature) { + if (navigationFeature == null || dependantFeature == null) { + return; + } + if (!source.eClass().getEAllStructuralFeatures().contains(navigationFeature)) { + return; + } + if (!(navigationFeature.getEType() instanceof EClass) + || !dependantFeature.getEContainingClass().isSuperTypeOf((EClass) navigationFeature.getEType())) { + return; + } + addNavigatedDependencyInternal(navigationFeature, dependantFeature); + } + + public void addLocalDependency(EStructuralFeature localFeature) { + if (localFeature == null) { + return; + } + if (!source.eClass().getEAllStructuralFeatures().contains(localFeature)) { + return; + } + addLocalDependencyInternal(localFeature); + } + + private void addNavigatedDependencyInternal(EStructuralFeature navigationFeature, + EStructuralFeature dependantFeature) { + featurePaths.add(new DependentFeaturePath(navigationFeature, dependantFeature)); + } + + private void addLocalDependencyInternal(EStructuralFeature localFeature) { + localFeatures.add(localFeature); + } + + @Override + public void notifyChanged(Notification notification) { + // System.err.println("[Source: " + derivedFeature.getName() + "] New notification: " + notification); + for (DependentFeaturePath path : featurePaths) { + if (notification.getFeature().equals(path.getNavigationFeature())) { + // System.err.println("Handling notification."); + switch (notification.getEventType()) { + case Notification.SET: + EObject newValue = (EObject) notification.getNewValue(); + EObject tempOldValue = (EObject) notification.getOldValue(); + if (tempOldValue != null) { + tempOldValue.eAdapters().remove(path.getDependantAdapter()); + } else { + IncQueryEngine.getDefaultLogger().debug("[DerivedFeatureAdapter] oldValue is not set"); + } + if (newValue != null) { + newValue.eAdapters().add(path.getDependantAdapter()); + } else { + IncQueryEngine.getDefaultLogger().debug("[DerivedFeatureAdapter] new value is not set"); + } + break; + case Notification.ADD: + EObject added = (EObject) notification.getNewValue(); + added.eAdapters().add(path.getDependantAdapter()); + break; + case Notification.ADD_MANY: + EObject newValueCollection = (EObject) notification.getNewValue(); + for (Object newElement : (Collection) newValueCollection) { + ((Notifier) newElement).eAdapters().add(path.getDependantAdapter()); + } + break; + case Notification.REMOVE: + EObject removed = (EObject) notification.getOldValue(); + removed.eAdapters().remove(path.getDependantAdapter()); + break; + case Notification.REMOVE_MANY: + EObject oldValueCollection = (EObject) notification.getOldValue(); + for (Object oldElement : (Collection) oldValueCollection) { + ((Notifier) oldElement).eAdapters().remove(path.getDependantAdapter()); + } + break; + case Notification.UNSET: + EObject unset = (EObject) notification.getOldValue(); + unset.eAdapters().remove(path.getDependantAdapter()); + break; + case Notification.CREATE: + case Notification.MOVE: // currently no support for ordering + case Notification.RESOLVE: // TODO is it safe to ignore all of them? + case Notification.REMOVING_ADAPTER: + break; + default: + IncQueryEngine.getDefaultLogger().debug( + "[DerivedFeatureAdapter] Unhandled notification: " + notification.getEventType()); + return; // No notification + } + refreshDerivedFeature(); + } + } + if (localFeatures.contains(notification.getFeature())) { + // System.err.println("Handling notification."); + refreshDerivedFeature(); + } + } + + @SuppressWarnings("unchecked") + private void refreshDerivedFeature() { + // System.err.println("[Notify: " + derivedFeature.getName() + "] Derived refresh."); + try { + if (source.eNotificationRequired()) { + if (type == null) { + type = derivedFeature.getEType(); + } + if (derivedFeature.isMany()) { + if (currentValue != null) { + oldValue = new HashSet((Collection) currentValue); + } else { + oldValue = new HashSet(); + } + // if(currentValue == null) { + currentValue = new HashSet(); + // } else { + // ((Collection) currentValue).clear(); + // } + Collection targets = (Collection) source.eGet(derivedFeature); + for (Object target : targets) { + EMFModelComprehension.traverseFeature(visitor, source, derivedFeature, target); + } + if (currentValue instanceof Collection && oldValue instanceof Collection) { + ((Collection) oldValue).removeAll((Collection) currentValue); + if (((Collection) oldValue).size() > 0) { + sendRemoveManyNotification(source, derivedFeature, oldValue); + } + } + } else { + Object target = source.eGet(derivedFeature); + EMFModelComprehension.traverseFeature(visitor, source, derivedFeature, target); + } + } + } catch (Exception ex) { + IncQueryEngine.getDefaultLogger().error( + "The derived feature adapter encountered an error in processing the EMF model. " + + "This happened while maintaining the derived feature " + derivedFeature.getName() + + " of object " + source, ex); + } + } + + private class DependentFeaturePath { + private EStructuralFeature dependantFeature = null; + private EStructuralFeature navigationFeature = null; + + private final AdapterImpl dependantAdapter = new AdapterImpl() { + + @Override + public void notifyChanged(Notification msg) { + // System.err.println("[Dependant: " + derivedFeature.getName() + "] New notification: " + msg); + if (msg.getFeature().equals(dependantFeature)) { + refreshDerivedFeature(); + } + } + }; + + /** * */ - public DependentFeaturePath(EStructuralFeature navigationFeature, EStructuralFeature dependantFeature) { - this.dependantFeature = dependantFeature; - this.navigationFeature = navigationFeature; - } + public DependentFeaturePath(EStructuralFeature navigationFeature, EStructuralFeature dependantFeature) { + this.dependantFeature = dependantFeature; + this.navigationFeature = navigationFeature; + } - /** - * @return the dependantAdapter - */ - public AdapterImpl getDependantAdapter() { - return dependantAdapter; - } + /** + * @return the dependantAdapter + */ + public AdapterImpl getDependantAdapter() { + return dependantAdapter; + } - /** - * @return the dependantFeature - */ - public EStructuralFeature getDependantFeature() { - return dependantFeature; - } + /** + * @return the dependantFeature + */ + public EStructuralFeature getDependantFeature() { + return dependantFeature; + } - /** - * @return the navigationFeature - */ - public EStructuralFeature getNavigationFeature() { - return navigationFeature; - } - } - - - - /** - * @param direction - * @return - */ - protected class DerivedFeatureEMFVisitor extends EMFVisitor{ - - @Override - public void visitAttribute(EObject source, EAttribute feature, Object target) { - //System.err.println("Attribute refresh."); - // send set notification - sendSetNotification(source, feature, currentValue, target); - storeSingleValue(feature, target); - } - - - @Override - public void visitElement(EObject source) { - return; - } - -// @Override -// public void visitExternalReference(EObject source, EReference feature, EObject target) { -// } - - @Override - public void visitNonContainmentReference(EObject source, EReference feature, EObject target) { - //System.err.println("Non-containment reference refresh."); - sendNotificationForEReference(source, feature, target); - } - - @Override - public void visitInternalContainment(EObject source, EReference feature, EObject target) { - //System.err.println("Containment reference refresh."); - sendNotificationForEReference(source, feature, target); - } - - @Override - public boolean pruneSubtrees(EObject source) { - return true; - } - } - - /** - * @param source - * @param feature - * @param target - */ - private void sendSetNotification(EObject source, EStructuralFeature feature, Object oldTarget, Object target) { - source.eNotify(new ENotificationImpl((InternalEObject) source, Notification.SET, - feature, oldTarget, target)); - } - - /** - * @param source - * @param feature - * @param target - */ - private void sendAddNotification(EObject source, EStructuralFeature feature, Object target) { - source.eNotify(new ENotificationImpl((InternalEObject) source, Notification.ADD, - feature, null, target)); - } - - /** - * @param source - * @param feature - * @param target - */ - private void sendRemoveManyNotification(EObject source, EStructuralFeature feature, Object oldTarget) { - source.eNotify(new ENotificationImpl((InternalEObject) source, Notification.REMOVE_MANY, - feature, oldTarget, null)); - } - - /** - * @param source - * @param feature - * @param target - */ - /*private void sendRemoveNotification(EObject source, EStructuralFeature feature, Object oldTarget) { - source.eNotify(new ENotificationImpl((InternalEObject) source, Notification.REMOVE, - feature, oldTarget, null)); - }*/ - - @SuppressWarnings("unchecked") - private void sendNotificationForEReference(EObject source, EReference feature, EObject target) { - if(feature.isMany() && oldValue instanceof Collection && currentValue instanceof Collection) { - // send ADD notification - if(!((Collection) oldValue).contains(target)) { - sendAddNotification(source, feature, target); - // add to currentValue - } - ((Collection)currentValue).add(target); - } else { - sendSetNotification(source, feature, currentValue, target); - } - } - - /** - * @param feature - * @param target - */ - private void storeSingleValue(EAttribute feature, Object target) { - // store current value - if(feature.isChangeable()) { - if(target instanceof EObject) { - currentValue = EcoreUtil.copy((EObject)target); - } - } else { - currentValue = target; - } - } + /** + * @return the navigationFeature + */ + public EStructuralFeature getNavigationFeature() { + return navigationFeature; + } + } + + /** + * @param direction + * @return + */ + protected class DerivedFeatureEMFVisitor extends EMFVisitor { + + @Override + public void visitAttribute(EObject source, EAttribute feature, Object target) { + // System.err.println("Attribute refresh."); + // send set notification + sendSetNotification(source, feature, currentValue, target); + storeSingleValue(feature, target); + } + + @Override + public void visitElement(EObject source) { + return; + } + + // @Override + // public void visitExternalReference(EObject source, EReference feature, EObject target) { + // } + + @Override + public void visitNonContainmentReference(EObject source, EReference feature, EObject target) { + // System.err.println("Non-containment reference refresh."); + sendNotificationForEReference(source, feature, target); + } + + @Override + public void visitInternalContainment(EObject source, EReference feature, EObject target) { + // System.err.println("Containment reference refresh."); + sendNotificationForEReference(source, feature, target); + } + + @Override + public boolean pruneSubtrees(EObject source) { + return true; + } + } + + /** + * @param source + * @param feature + * @param target + */ + private void sendSetNotification(EObject source, EStructuralFeature feature, Object oldTarget, Object target) { + source.eNotify(new ENotificationImpl((InternalEObject) source, Notification.SET, feature, oldTarget, target)); + } + + /** + * @param source + * @param feature + * @param target + */ + private void sendAddNotification(EObject source, EStructuralFeature feature, Object target) { + source.eNotify(new ENotificationImpl((InternalEObject) source, Notification.ADD, feature, null, target)); + } + + /** + * @param source + * @param feature + * @param target + */ + private void sendRemoveManyNotification(EObject source, EStructuralFeature feature, Object oldTarget) { + source.eNotify(new ENotificationImpl((InternalEObject) source, Notification.REMOVE_MANY, feature, oldTarget, + null)); + } + + /** + * @param source + * @param feature + * @param target + */ + /* + * private void sendRemoveNotification(EObject source, EStructuralFeature feature, Object oldTarget) { + * source.eNotify(new ENotificationImpl((InternalEObject) source, Notification.REMOVE, feature, oldTarget, null)); } + */ + + @SuppressWarnings("unchecked") + private void sendNotificationForEReference(EObject source, EReference feature, EObject target) { + if (feature.isMany() && oldValue instanceof Collection && currentValue instanceof Collection) { + // send ADD notification + if (!((Collection) oldValue).contains(target)) { + sendAddNotification(source, feature, target); + // add to currentValue + } + ((Collection) currentValue).add(target); + } else { + sendSetNotification(source, feature, currentValue, target); + } + } + + /** + * @param feature + * @param target + */ + private void storeSingleValue(EAttribute feature, Object target) { + // store current value + if (feature.isChangeable()) { + if (target instanceof EObject) { + currentValue = EcoreUtil.copy((EObject) target); + } + } else { + currentValue = target; + } + } } diff --git a/plugins/org.eclipse.incquery.querybasedfeatures.runtime/src/org/eclipse/incquery/querybasedfeatures/runtime/IQueryBasedFeatureHandler.java b/plugins/org.eclipse.incquery.querybasedfeatures.runtime/src/org/eclipse/incquery/querybasedfeatures/runtime/IQueryBasedFeatureHandler.java index d66bf0d1..02402f94 100644 --- a/plugins/org.eclipse.incquery.querybasedfeatures.runtime/src/org/eclipse/incquery/querybasedfeatures/runtime/IQueryBasedFeatureHandler.java +++ b/plugins/org.eclipse.incquery.querybasedfeatures.runtime/src/org/eclipse/incquery/querybasedfeatures/runtime/IQueryBasedFeatureHandler.java @@ -16,7 +16,7 @@ /** * @author Abel Hegedus - * + * */ public interface IQueryBasedFeatureHandler { diff --git a/plugins/org.eclipse.incquery.querybasedfeatures.runtime/src/org/eclipse/incquery/querybasedfeatures/runtime/InvertableQueryBasedEList.java b/plugins/org.eclipse.incquery.querybasedfeatures.runtime/src/org/eclipse/incquery/querybasedfeatures/runtime/InvertableQueryBasedEList.java index d7cad915..70adab48 100644 --- a/plugins/org.eclipse.incquery.querybasedfeatures.runtime/src/org/eclipse/incquery/querybasedfeatures/runtime/InvertableQueryBasedEList.java +++ b/plugins/org.eclipse.incquery.querybasedfeatures.runtime/src/org/eclipse/incquery/querybasedfeatures/runtime/InvertableQueryBasedEList.java @@ -19,197 +19,213 @@ /** * @author Abel Hegedus - * + * */ public class InvertableQueryBasedEList extends AbstractEList { - - private EList storageEList; - private EObject sourceObject; - private IQueryBasedFeatureHandler handler; - private QueryBasedFeatureInverter inverter; - - /** - * - */ - public InvertableQueryBasedEList(EObject sourceObject, EList storageEList, - IQueryBasedFeatureHandler handler, QueryBasedFeatureInverter inverter) { - super(); - this.storageEList = storageEList; - this.sourceObject = sourceObject; - this.handler = handler; - this.inverter = inverter; - } - - /* (non-Javadoc) - * @see org.eclipse.emf.common.util.AbstractEList#validate(int, java.lang.Object) - */ - @Override - protected ComputedType validate(int index, ComputedType object) { - ComputedType s = super.validate(index, object); - return inverter.validate(s); - } - - /* (non-Javadoc) - * @see org.eclipse.emf.common.util.AbstractEList#primitiveGet(int) - */ - @SuppressWarnings("unchecked") - @Override - protected ComputedType primitiveGet(int index) { - // TODO efficient reversal of index - StorageType t = storageEList.get(index); - List values = handler.getManyReferenceValue(sourceObject); - for (Object object : values) { - if(inverter.invert((ComputedType) object).equals(t)) { - return (ComputedType) object; - } - } - return null; - // NOTE indexing based on source list - //return (Source) handler.getManyReferenceValue(sourceObject).get(index); - } - - - /* (non-Javadoc) - * @see org.eclipse.emf.common.util.AbstractEList#setUnique(int, java.lang.Object) - */ - @Override - public ComputedType setUnique(int index, ComputedType object) { - ComputedType source = get(index); - StorageType newTarget = inverter.invert(object); - storageEList.set(index, newTarget); - return source; - } + private EList storageEList; + private EObject sourceObject; + private IQueryBasedFeatureHandler handler; + private QueryBasedFeatureInverter inverter; - /* (non-Javadoc) - * @see org.eclipse.emf.common.util.AbstractEList#addUnique(java.lang.Object) - */ - @Override - public void addUnique(ComputedType object) { - StorageType newTarget = inverter.invert(object); - storageEList.add(newTarget); - } - - - /* (non-Javadoc) - * @see org.eclipse.emf.common.util.AbstractEList#addUnique(int, java.lang.Object) - */ - @Override - public void addUnique(int index, ComputedType object) { - StorageType newTarget = inverter.invert(object); - storageEList.add(index, newTarget); - } - - - /* (non-Javadoc) - * @see org.eclipse.emf.common.util.AbstractEList#addAllUnique(java.util.Collection) + /** + * */ - @Override - public boolean addAllUnique(Collection collection) { - boolean hasChanged = false; - for (ComputedType source : collection) { - StorageType newTarget = inverter.invert(source); - hasChanged |= storageEList.add(newTarget); + public InvertableQueryBasedEList(EObject sourceObject, EList storageEList, + IQueryBasedFeatureHandler handler, QueryBasedFeatureInverter inverter) { + super(); + this.storageEList = storageEList; + this.sourceObject = sourceObject; + this.handler = handler; + this.inverter = inverter; } - return hasChanged; - } - - /* (non-Javadoc) - * @see org.eclipse.emf.common.util.AbstractEList#addAllUnique(int, java.util.Collection) - */ - @Override - public boolean addAllUnique(int index, Collection collection) { - int oldSize = storageEList.size(); - for (ComputedType source : collection) { - StorageType newTarget = inverter.invert(source); - storageEList.add(index,newTarget); - index++; + /* + * (non-Javadoc) + * + * @see org.eclipse.emf.common.util.AbstractEList#validate(int, java.lang.Object) + */ + @Override + protected ComputedType validate(int index, ComputedType object) { + ComputedType s = super.validate(index, object); + return inverter.validate(s); } - return oldSize < storageEList.size(); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.emf.common.util.AbstractEList#primitiveGet(int) + */ + @SuppressWarnings("unchecked") + @Override + protected ComputedType primitiveGet(int index) { + // TODO efficient reversal of index + StorageType t = storageEList.get(index); + List values = handler.getManyReferenceValue(sourceObject); + for (Object object : values) { + if (inverter.invert((ComputedType) object).equals(t)) { + return (ComputedType) object; + } + } + return null; + // NOTE indexing based on source list + // return (Source) handler.getManyReferenceValue(sourceObject).get(index); + } - /* (non-Javadoc) - * @see org.eclipse.emf.common.util.AbstractEList#addAllUnique(java.lang.Object[], int, int) - */ - @Override - public boolean addAllUnique(Object[] objects, int start, int end) { - boolean hasChanged = false; - for (int i = start; i <= end; i++) { - @SuppressWarnings("unchecked") - StorageType newTarget = inverter.invert((ComputedType) objects[i]); - hasChanged |= storageEList.add(newTarget); + /* + * (non-Javadoc) + * + * @see org.eclipse.emf.common.util.AbstractEList#setUnique(int, java.lang.Object) + */ + @Override + public ComputedType setUnique(int index, ComputedType object) { + ComputedType source = get(index); + StorageType newTarget = inverter.invert(object); + storageEList.set(index, newTarget); + return source; } - return hasChanged; - } + /* + * (non-Javadoc) + * + * @see org.eclipse.emf.common.util.AbstractEList#addUnique(java.lang.Object) + */ + @Override + public void addUnique(ComputedType object) { + StorageType newTarget = inverter.invert(object); + storageEList.add(newTarget); + } - /* (non-Javadoc) - * @see org.eclipse.emf.common.util.AbstractEList#addAllUnique(int, java.lang.Object[], int, int) - */ - @Override - public boolean addAllUnique(int index, Object[] objects, int start, int end) { - int oldSize = storageEList.size(); - for (int i = start; i <= end; i++) { - @SuppressWarnings("unchecked") - StorageType newTarget = inverter.invert((ComputedType) objects[i]); - storageEList.add(index,newTarget); - index++; + /* + * (non-Javadoc) + * + * @see org.eclipse.emf.common.util.AbstractEList#addUnique(int, java.lang.Object) + */ + @Override + public void addUnique(int index, ComputedType object) { + StorageType newTarget = inverter.invert(object); + storageEList.add(index, newTarget); } - return oldSize < storageEList.size(); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.emf.common.util.AbstractEList#addAllUnique(java.util.Collection) + */ + @Override + public boolean addAllUnique(Collection collection) { + boolean hasChanged = false; + for (ComputedType source : collection) { + StorageType newTarget = inverter.invert(source); + hasChanged |= storageEList.add(newTarget); + } + return hasChanged; + } - /* (non-Javadoc) - * @see org.eclipse.emf.common.util.AbstractEList#remove(int) - */ - @Override - public ComputedType remove(int index) { - ComputedType source = get(index); - StorageType target = inverter.invert(source); - storageEList.remove(target); - return source; - } + /* + * (non-Javadoc) + * + * @see org.eclipse.emf.common.util.AbstractEList#addAllUnique(int, java.util.Collection) + */ + @Override + public boolean addAllUnique(int index, Collection collection) { + int oldSize = storageEList.size(); + for (ComputedType source : collection) { + StorageType newTarget = inverter.invert(source); + storageEList.add(index, newTarget); + index++; + } + return oldSize < storageEList.size(); + } + /* + * (non-Javadoc) + * + * @see org.eclipse.emf.common.util.AbstractEList#addAllUnique(java.lang.Object[], int, int) + */ + @Override + public boolean addAllUnique(Object[] objects, int start, int end) { + boolean hasChanged = false; + for (int i = start; i <= end; i++) { + @SuppressWarnings("unchecked") + StorageType newTarget = inverter.invert((ComputedType) objects[i]); + hasChanged |= storageEList.add(newTarget); + } + return hasChanged; + } - /* (non-Javadoc) - * @see org.eclipse.emf.common.util.AbstractEList#move(int, int) - */ - @Override - public ComputedType move(int targetIndex, int sourceIndex) { - ComputedType t_source = get(sourceIndex); - StorageType t_target = inverter.invert(t_source); - storageEList.move(targetIndex, t_target); - return t_source; - } + /* + * (non-Javadoc) + * + * @see org.eclipse.emf.common.util.AbstractEList#addAllUnique(int, java.lang.Object[], int, int) + */ + @Override + public boolean addAllUnique(int index, Object[] objects, int start, int end) { + int oldSize = storageEList.size(); + for (int i = start; i <= end; i++) { + @SuppressWarnings("unchecked") + StorageType newTarget = inverter.invert((ComputedType) objects[i]); + storageEList.add(index, newTarget); + index++; + } + return oldSize < storageEList.size(); + } + /* + * (non-Javadoc) + * + * @see org.eclipse.emf.common.util.AbstractEList#remove(int) + */ + @Override + public ComputedType remove(int index) { + ComputedType source = get(index); + StorageType target = inverter.invert(source); + storageEList.remove(target); + return source; + } - /* (non-Javadoc) - * @see org.eclipse.emf.common.util.AbstractEList#basicList() - */ - @SuppressWarnings("unchecked") - @Override - protected List basicList() { - return (List) handler.getManyReferenceValue(sourceObject); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.emf.common.util.AbstractEList#move(int, int) + */ + @Override + public ComputedType move(int targetIndex, int sourceIndex) { + ComputedType t_source = get(sourceIndex); + StorageType t_target = inverter.invert(t_source); + storageEList.move(targetIndex, t_target); + return t_source; + } + /* + * (non-Javadoc) + * + * @see org.eclipse.emf.common.util.AbstractEList#basicList() + */ + @SuppressWarnings("unchecked") + @Override + protected List basicList() { + return (List) handler.getManyReferenceValue(sourceObject); + } - /* (non-Javadoc) - * @see java.util.AbstractList#get(int) - */ - @Override - public ComputedType get(int index) { - return basicGet(index); - } + /* + * (non-Javadoc) + * + * @see java.util.AbstractList#get(int) + */ + @Override + public ComputedType get(int index) { + return basicGet(index); + } + /* + * (non-Javadoc) + * + * @see java.util.AbstractCollection#size() + */ + @Override + public int size() { + return handler.getManyReferenceValue(sourceObject).size(); + } - /* (non-Javadoc) - * @see java.util.AbstractCollection#size() - */ - @Override - public int size() { - return handler.getManyReferenceValue(sourceObject).size(); - } - } diff --git a/plugins/org.eclipse.incquery.querybasedfeatures.runtime/src/org/eclipse/incquery/querybasedfeatures/runtime/QueryBasedFeatureHelper.java b/plugins/org.eclipse.incquery.querybasedfeatures.runtime/src/org/eclipse/incquery/querybasedfeatures/runtime/QueryBasedFeatureHelper.java index fecbb4d7..9e8f1cf4 100644 --- a/plugins/org.eclipse.incquery.querybasedfeatures.runtime/src/org/eclipse/incquery/querybasedfeatures/runtime/QueryBasedFeatureHelper.java +++ b/plugins/org.eclipse.incquery.querybasedfeatures.runtime/src/org/eclipse/incquery/querybasedfeatures/runtime/QueryBasedFeatureHelper.java @@ -34,28 +34,34 @@ public final class QueryBasedFeatureHelper { /** - * Weak hash map for keeping the created + * Weak hash map for keeping the created */ private static final Map>> FEATURE_MAP = new WeakHashMap>>(); /** - * Constructor hidden for static utility class - */ + * Constructor hidden for static utility class + */ private QueryBasedFeatureHelper() { } /** - * Decide what {@link Notifier} to use as the scope of the {@link IncQueryMatcher} underlying the created {@link IQueryBasedFeatureHandler}. + * Decide what {@link Notifier} to use as the scope of the {@link IncQueryMatcher} underlying the created + * {@link IQueryBasedFeatureHandler}. * - *

Optimally, the {@link ResourceSet} is reachable and most other matchers will use it as well. + *

+ * Optimally, the {@link ResourceSet} is reachable and most other matchers will use it as well. * - *

Otherwise, the {@link Resource} is used if the model is not inside a resource set. + *

+ * Otherwise, the {@link Resource} is used if the model is not inside a resource set. * - *

If none of the above are reachable, the container hierarchy is traversed for a top element. + *

+ * If none of the above are reachable, the container hierarchy is traversed for a top element. * - *

Finally, the source itself is returned. + *

+ * Finally, the source itself is returned. * - * @param source the source object that initializes the handler + * @param source + * the source object that initializes the handler * @return the topmost reachable Notifier from the source */ private static Notifier prepareNotifierForSource(EObject source) { @@ -70,7 +76,7 @@ private static Notifier prepareNotifierForSource(EObject source) { } } else { EObject top = source; - while(top.eContainer() != null) { + while (top.eContainer() != null) { top = top.eContainer(); } return prepareNotifierForSource(top); @@ -80,18 +86,27 @@ private static Notifier prepareNotifierForSource(EObject source) { } /** - * Returns the {@link IQueryBasedFeatureHandler} for the given {@link EStructuralFeature} in the given {@link Notifier}. - * If the handler does not exist yet, it is also initialized, before being returned. - * - *

The required matcher is initialized using the pattern fully qualified name passed as a parameter. - * - * @param notifier the exact notifier to use for the handler initialization - * @param feature the feature that is managed by the handler - * @param patternFQN the fully qualified name of the pattern used by the handler - * @param sourceParamName the name of the parameter in the pattern that represents the source end of the feature - * @param targetParamName the name of the parameter in the pattern that represents the target end of the feature - * @param kind the {@link QueryBasedFeatureKind} that is used by the handler - * @param keepCache specifies whether the handler uses an internal cache for feature values. Only possible with single and many reference kinds + * Returns the {@link IQueryBasedFeatureHandler} for the given {@link EStructuralFeature} in the given + * {@link Notifier}. If the handler does not exist yet, it is also initialized, before being returned. + * + *

+ * The required matcher is initialized using the pattern fully qualified name passed as a parameter. + * + * @param notifier + * the exact notifier to use for the handler initialization + * @param feature + * the feature that is managed by the handler + * @param patternFQN + * the fully qualified name of the pattern used by the handler + * @param sourceParamName + * the name of the parameter in the pattern that represents the source end of the feature + * @param targetParamName + * the name of the parameter in the pattern that represents the target end of the feature + * @param kind + * the {@link QueryBasedFeatureKind} that is used by the handler + * @param keepCache + * specifies whether the handler uses an internal cache for feature values. Only possible with single and + * many reference kinds * @return the query-based feature handler that manages the feature values */ public static IQueryBasedFeatureHandler getQueryBasedFeatureHandler(Notifier notifier, EStructuralFeature feature, @@ -132,21 +147,30 @@ public static IQueryBasedFeatureHandler getQueryBasedFeatureHandler(Notifier not return newDerivedFeature; } - /** - * Returns the {@link IQueryBasedFeatureHandler} for the given {@link EStructuralFeature} in the given {@link Notifier}. - * If the handler does not exist yet, it is also initialized, before being returned. + * Returns the {@link IQueryBasedFeatureHandler} for the given {@link EStructuralFeature} in the given + * {@link Notifier}. If the handler does not exist yet, it is also initialized, before being returned. * - *

The required matcher is initialized using the pattern fully qualified name passed as a parameter. + *

+ * The required matcher is initialized using the pattern fully qualified name passed as a parameter. * - *

Calls {@link #getQueryBasedFeatureHandler(Notifier, EStructuralFeature, String, String, String, QueryBasedFeatureKind, boolean)} with keepCache = true. + *

+ * Calls + * {@link #getQueryBasedFeatureHandler(Notifier, EStructuralFeature, String, String, String, QueryBasedFeatureKind, boolean)} + * with keepCache = true. * - * @param notifier the exact notifier to use for the handler initialization - * @param feature the feature that is managed by the handler - * @param patternFQN the fully qualified name of the pattern used by the handler - * @param sourceParamName the name of the parameter in the pattern that represents the source end of the feature - * @param targetParamName the name of the parameter in the pattern that represents the target end of the feature - * @param kind the {@link QueryBasedFeatureKind} that is used by the handler + * @param notifier + * the exact notifier to use for the handler initialization + * @param feature + * the feature that is managed by the handler + * @param patternFQN + * the fully qualified name of the pattern used by the handler + * @param sourceParamName + * the name of the parameter in the pattern that represents the source end of the feature + * @param targetParamName + * the name of the parameter in the pattern that represents the target end of the feature + * @param kind + * the {@link QueryBasedFeatureKind} that is used by the handler * @return the query-based feature handler that manages the feature values */ public static IQueryBasedFeatureHandler getQueryBasedFeatureHandlerOnNotifier(Notifier notifier, @@ -156,21 +180,35 @@ public static IQueryBasedFeatureHandler getQueryBasedFeatureHandlerOnNotifier(No } /** - * Returns the {@link IQueryBasedFeatureHandler} for the given {@link EStructuralFeature} on the source or the topmost {@link Notifier} - * reachable from the source. If the handler does not exist yet, it is also initialized, before being returned. + * Returns the {@link IQueryBasedFeatureHandler} for the given {@link EStructuralFeature} on the source or the + * topmost {@link Notifier} reachable from the source. If the handler does not exist yet, it is also initialized, + * before being returned. * - *

The required matcher is initialized using the pattern fully qualified name passed as a parameter. + *

+ * The required matcher is initialized using the pattern fully qualified name passed as a parameter. * - *

Calls {@link #getQueryBasedFeatureHandler(Notifier, EStructuralFeature, String, String, String, QueryBasedFeatureKind, boolean)}. + *

+ * Calls + * {@link #getQueryBasedFeatureHandler(Notifier, EStructuralFeature, String, String, String, QueryBasedFeatureKind, boolean)}. * - * @param source the source object used for the handler initialization (used for determining the notifier for the underlying matcher) - * @param feature the feature that is managed by the handler - * @param patternFQN the fully qualified name of the pattern used by the handler - * @param sourceParamName the name of the parameter in the pattern that represents the source end of the feature - * @param targetParamName the name of the parameter in the pattern that represents the target end of the feature - * @param kind the {@link QueryBasedFeatureKind} that is used by the handler - * @param keepCache specifies whether the handler uses an internal cache for feature values. Only possible with single and many reference kinds - * @param useSourceAsNotifier if true, the source is used as the notifier for the matcher initialization + * @param source + * the source object used for the handler initialization (used for determining the notifier for the + * underlying matcher) + * @param feature + * the feature that is managed by the handler + * @param patternFQN + * the fully qualified name of the pattern used by the handler + * @param sourceParamName + * the name of the parameter in the pattern that represents the source end of the feature + * @param targetParamName + * the name of the parameter in the pattern that represents the target end of the feature + * @param kind + * the {@link QueryBasedFeatureKind} that is used by the handler + * @param keepCache + * specifies whether the handler uses an internal cache for feature values. Only possible with single and + * many reference kinds + * @param useSourceAsNotifier + * if true, the source is used as the notifier for the matcher initialization * @return the query-based feature handler that manages the feature values */ public static IQueryBasedFeatureHandler getQueryBasedFeatureHandler(EObject source, EStructuralFeature feature, @@ -185,19 +223,30 @@ public static IQueryBasedFeatureHandler getQueryBasedFeatureHandler(EObject sour } /** - * Returns the {@link IQueryBasedFeatureHandler} for the given {@link EStructuralFeature} on the topmost {@link Notifier} - * reachable from the source. If the handler does not exist yet, it is also initialized, before being returned. + * Returns the {@link IQueryBasedFeatureHandler} for the given {@link EStructuralFeature} on the topmost + * {@link Notifier} reachable from the source. If the handler does not exist yet, it is also initialized, before + * being returned. * - *

The required matcher is initialized using the pattern fully qualified name passed as a parameter. + *

+ * The required matcher is initialized using the pattern fully qualified name passed as a parameter. * - *

Calls {@link #getQueryBasedFeatureHandler(EObject, EStructuralFeature, String, String, String, QueryBasedFeatureKind, boolean, boolean)}. + *

+ * Calls + * {@link #getQueryBasedFeatureHandler(EObject, EStructuralFeature, String, String, String, QueryBasedFeatureKind, boolean, boolean)}. * - * @param source the source object used for the handler initialization (used for determining the notifier for the underlying matcher) - * @param feature the feature that is managed by the handler - * @param patternFQN the fully qualified name of the pattern used by the handler - * @param sourceParamName the name of the parameter in the pattern that represents the source end of the feature - * @param targetParamName the name of the parameter in the pattern that represents the target end of the feature - * @param kind the {@link QueryBasedFeatureKind} that is used by the handler + * @param source + * the source object used for the handler initialization (used for determining the notifier for the + * underlying matcher) + * @param feature + * the feature that is managed by the handler + * @param patternFQN + * the fully qualified name of the pattern used by the handler + * @param sourceParamName + * the name of the parameter in the pattern that represents the source end of the feature + * @param targetParamName + * the name of the parameter in the pattern that represents the target end of the feature + * @param kind + * the {@link QueryBasedFeatureKind} that is used by the handler * @return the query-based feature handler that manages the feature values */ public static IQueryBasedFeatureHandler getQueryBasedFeatureHandler(EObject source, EStructuralFeature feature, diff --git a/plugins/org.eclipse.incquery.querybasedfeatures.runtime/src/org/eclipse/incquery/querybasedfeatures/runtime/QueryBasedFeatureInverter.java b/plugins/org.eclipse.incquery.querybasedfeatures.runtime/src/org/eclipse/incquery/querybasedfeatures/runtime/QueryBasedFeatureInverter.java index 30f8f8b0..814726eb 100644 --- a/plugins/org.eclipse.incquery.querybasedfeatures.runtime/src/org/eclipse/incquery/querybasedfeatures/runtime/QueryBasedFeatureInverter.java +++ b/plugins/org.eclipse.incquery.querybasedfeatures.runtime/src/org/eclipse/incquery/querybasedfeatures/runtime/QueryBasedFeatureInverter.java @@ -21,6 +21,7 @@ public interface QueryBasedFeatureInverter { /** * Validate the computed value to ensure that inverting is possible + * * @param computedValue * @return */ diff --git a/plugins/org.eclipse.incquery.querybasedfeatures.runtime/src/org/eclipse/incquery/querybasedfeatures/runtime/QueryBasedFeatureKind.java b/plugins/org.eclipse.incquery.querybasedfeatures.runtime/src/org/eclipse/incquery/querybasedfeatures/runtime/QueryBasedFeatureKind.java index 3b4d68ad..813c8390 100644 --- a/plugins/org.eclipse.incquery.querybasedfeatures.runtime/src/org/eclipse/incquery/querybasedfeatures/runtime/QueryBasedFeatureKind.java +++ b/plugins/org.eclipse.incquery.querybasedfeatures.runtime/src/org/eclipse/incquery/querybasedfeatures/runtime/QueryBasedFeatureKind.java @@ -10,6 +10,6 @@ *******************************************************************************/ package org.eclipse.incquery.querybasedfeatures.runtime; -public enum QueryBasedFeatureKind{ - SUM, COUNTER, SINGLE_REFERENCE, MANY_REFERENCE, ITERATION +public enum QueryBasedFeatureKind { + SUM, COUNTER, SINGLE_REFERENCE, MANY_REFERENCE, ITERATION } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.querybasedfeatures.tooling/src/org/eclipse/incquery/querybasedfeatures/tooling/ProjectLocator.java b/plugins/org.eclipse.incquery.querybasedfeatures.tooling/src/org/eclipse/incquery/querybasedfeatures/tooling/ProjectLocator.java index 66b0ed64..c76101d2 100644 --- a/plugins/org.eclipse.incquery.querybasedfeatures.tooling/src/org/eclipse/incquery/querybasedfeatures/tooling/ProjectLocator.java +++ b/plugins/org.eclipse.incquery.querybasedfeatures.tooling/src/org/eclipse/incquery/querybasedfeatures/tooling/ProjectLocator.java @@ -22,28 +22,28 @@ /** * @author Abel Hegedus - * + * */ public final class ProjectLocator { - - public static IJavaProject locateProject(String path, Logger logger) { - IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(path); - if(project.exists()) { - ArrayList dependencies = new ArrayList(); - dependencies.add("org.eclipse.incquery.runtime"); - dependencies.add("org.eclipse.incquery.querybasedfeatures.runtime"); - try { - ProjectGenerationHelper.ensureBundleDependencies(project, dependencies); - } catch (CoreException e) { - logger.error("Could not add required dependencies to model project.", e); - } - return JavaCore.create(project); - } else { - return null; + + public static IJavaProject locateProject(String path, Logger logger) { + IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(path); + if (project.exists()) { + ArrayList dependencies = new ArrayList(); + dependencies.add("org.eclipse.incquery.runtime"); + dependencies.add("org.eclipse.incquery.querybasedfeatures.runtime"); + try { + ProjectGenerationHelper.ensureBundleDependencies(project, dependencies); + } catch (CoreException e) { + logger.error("Could not add required dependencies to model project.", e); + } + return JavaCore.create(project); + } else { + return null; + } } - } - - private ProjectLocator() { - } - + + private ProjectLocator() { + } + } diff --git a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/counting/CountingAlg.java b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/counting/CountingAlg.java index 5238575d..6970f54e 100644 --- a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/counting/CountingAlg.java +++ b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/counting/CountingAlg.java @@ -9,8 +9,8 @@ * Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.itc.alg.counting; - +package org.eclipse.incquery.runtime.base.itc.alg.counting; + import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -23,214 +23,211 @@ import org.eclipse.incquery.runtime.base.itc.igraph.IGraphObserver; import org.eclipse.incquery.runtime.base.itc.igraph.ITcDataSource; import org.eclipse.incquery.runtime.base.itc.igraph.ITcObserver; - -/** - * This class is the optimized implementation of the Counting algorithm. - * - * @author Tamas Szabo - * - * @param - * the type parameter of the nodes in the graph data source - */ -public class CountingAlg implements IGraphObserver, ITcDataSource { - - private static final long serialVersionUID = -2383210800242398869L; - private CountingTcRelation tc = null; - private CountingTcRelation dtc = null; - private IBiDirectionalGraphDataSource gds = null; - private ArrayList> observers; - - /** - * Constructs a new Counting algorithm and initializes the transitive - * closure relation with the given graph data source. Attach itself on the - * graph data source as an observer. - * - * @param gds - * the graph data source instance - */ - public CountingAlg(IGraphDataSource gds) { - - if (gds instanceof IBiDirectionalGraphDataSource) { - this.gds = (IBiDirectionalGraphDataSource) gds; - } else { - this.gds = new IBiDirectionalWrapper(gds); - } - - observers = new ArrayList>(); - tc = new CountingTcRelation(true); - dtc = new CountingTcRelation(false); - - initTc(); - gds.attachObserver(this); - } - - /** - * Initializes the transitive closure relation. - */ - private void initTc() { - this.setTcRelation(CountingTcRelation.createFrom(gds)); - } - - @Override - public void edgeInserted(V source, V target) { - if (!source.equals(target)) { - deriveTc(source, target, 1); - } - } - - @Override - public void edgeDeleted(V source, V target) { - if (!source.equals(target)) { - deriveTc(source, target, -1); - } - } - - @Override - public void nodeInserted(V n) { - - } - - @Override - public void nodeDeleted(V n) { - this.tc.deleteTupleEnd(n); - } - - /** - * Derives the transitive closure relation when an edge is inserted or - * deleted. - * - * @param source - * the source of the edge - * @param target - * the target of the edge - * @param dCount - * the value is -1 if an edge was deleted and +1 if an edge was - * inserted - */ - private void deriveTc(V source, V target, int dCount) { - -// if (dCount == 1 && isReachable(target, source)) { -// System.out.println("The graph contains cycle with (" + source + ","+ target + ") edge!"); -// } - - dtc.clear(); - Set tupEnds = null; - - // 1. d(tc(x,y)) :- d(l(x,y)) - if (tc.addTuple(source, target, dCount)) { - dtc.addTuple(source, target, dCount); - notifyTcObservers(source, target, dCount); - } - - // 2. d(tc(x,y)) :- d(l(x,z)) & tc(z,y) - tupEnds = tc.getTupleEnds(target); - if (tupEnds != null) { - for (V tupEnd : tupEnds) { - if (!tupEnd.equals(source)) { - if (tc.addTuple(source, tupEnd, dCount)) { - dtc.addTuple(source, tupEnd, dCount); - notifyTcObservers(source, tupEnd, dCount); - } - } - } - } - - // 3. d(tc(x,y)) :- lv(x,z) & d(tc(z,y)) - CountingTcRelation newTuples = new CountingTcRelation(false); - CountingTcRelation tmp = null; - List nodes = null; - newTuples.union(dtc); - - while (!newTuples.isEmpty()) { - - tmp = dtc; - dtc = newTuples; - newTuples = tmp; - newTuples.clear(); - - for (V tS : dtc.getTupleStarts()) { - - nodes = gds.getSourceNodes(tS); - if (nodes != null) { - - for (V nS : nodes) { - - tupEnds = dtc.getTupleEnds(tS); - if (tupEnds != null) { - - for (V tT : tupEnds) { - - if (!nS.equals(tT)) { - if (tc.addTuple(nS, tT, dCount)) { - newTuples.addTuple(nS, tT, dCount); - notifyTcObservers(nS, tT, dCount); - } - } - } - } - } - } - } - } - - //System.out.println(tc); - } - - public ITcRelation getTcRelation() { - return this.tc; - } - - public void setTcRelation(CountingTcRelation tc) { - this.tc = tc; - } - - @Override - public boolean isReachable(V source, V target) { - return tc.containsTuple(source, target); - } - - @Override - public void attachObserver(ITcObserver to) { - this.observers.add(to); - - } - - @Override - public void detachObserver(ITcObserver to) { - this.observers.remove(to); - } - - @Override - public Set getAllReachableTargets(V source) { - Set targets = new HashSet(); - if (tc.getTupleEnds(source) != null) { - targets.addAll(tc.getTupleEnds(source)); - } - return targets; - } - - @Override - public Set getAllReachableSources(V target) { - Set sources = new HashSet(); - if (tc.getTupleStarts(target) != null) { - sources.addAll(tc.getTupleStarts(target)); - } - return sources; - } - - private void notifyTcObservers(V source, V target, int dir) { - for (ITcObserver o : observers) { - if (dir == 1) - o.tupleInserted(source, target); - if (dir == -1) - o.tupleDeleted(source, target); - } - } - - @Override - public void dispose() { - tc.clear(); - dtc.clear(); - this.gds.detachObserver(this); - } + +/** + * This class is the optimized implementation of the Counting algorithm. + * + * @author Tamas Szabo + * + * @param + * the type parameter of the nodes in the graph data source + */ +public class CountingAlg implements IGraphObserver, ITcDataSource { + + private static final long serialVersionUID = -2383210800242398869L; + private CountingTcRelation tc = null; + private CountingTcRelation dtc = null; + private IBiDirectionalGraphDataSource gds = null; + private ArrayList> observers; + + /** + * Constructs a new Counting algorithm and initializes the transitive closure relation with the given graph data + * source. Attach itself on the graph data source as an observer. + * + * @param gds + * the graph data source instance + */ + public CountingAlg(IGraphDataSource gds) { + + if (gds instanceof IBiDirectionalGraphDataSource) { + this.gds = (IBiDirectionalGraphDataSource) gds; + } else { + this.gds = new IBiDirectionalWrapper(gds); + } + + observers = new ArrayList>(); + tc = new CountingTcRelation(true); + dtc = new CountingTcRelation(false); + + initTc(); + gds.attachObserver(this); + } + + /** + * Initializes the transitive closure relation. + */ + private void initTc() { + this.setTcRelation(CountingTcRelation.createFrom(gds)); + } + + @Override + public void edgeInserted(V source, V target) { + if (!source.equals(target)) { + deriveTc(source, target, 1); + } + } + + @Override + public void edgeDeleted(V source, V target) { + if (!source.equals(target)) { + deriveTc(source, target, -1); + } + } + + @Override + public void nodeInserted(V n) { + + } + + @Override + public void nodeDeleted(V n) { + this.tc.deleteTupleEnd(n); + } + + /** + * Derives the transitive closure relation when an edge is inserted or deleted. + * + * @param source + * the source of the edge + * @param target + * the target of the edge + * @param dCount + * the value is -1 if an edge was deleted and +1 if an edge was inserted + */ + private void deriveTc(V source, V target, int dCount) { + + // if (dCount == 1 && isReachable(target, source)) { + // System.out.println("The graph contains cycle with (" + source + ","+ target + ") edge!"); + // } + + dtc.clear(); + Set tupEnds = null; + + // 1. d(tc(x,y)) :- d(l(x,y)) + if (tc.addTuple(source, target, dCount)) { + dtc.addTuple(source, target, dCount); + notifyTcObservers(source, target, dCount); + } + + // 2. d(tc(x,y)) :- d(l(x,z)) & tc(z,y) + tupEnds = tc.getTupleEnds(target); + if (tupEnds != null) { + for (V tupEnd : tupEnds) { + if (!tupEnd.equals(source)) { + if (tc.addTuple(source, tupEnd, dCount)) { + dtc.addTuple(source, tupEnd, dCount); + notifyTcObservers(source, tupEnd, dCount); + } + } + } + } + + // 3. d(tc(x,y)) :- lv(x,z) & d(tc(z,y)) + CountingTcRelation newTuples = new CountingTcRelation(false); + CountingTcRelation tmp = null; + List nodes = null; + newTuples.union(dtc); + + while (!newTuples.isEmpty()) { + + tmp = dtc; + dtc = newTuples; + newTuples = tmp; + newTuples.clear(); + + for (V tS : dtc.getTupleStarts()) { + + nodes = gds.getSourceNodes(tS); + if (nodes != null) { + + for (V nS : nodes) { + + tupEnds = dtc.getTupleEnds(tS); + if (tupEnds != null) { + + for (V tT : tupEnds) { + + if (!nS.equals(tT)) { + if (tc.addTuple(nS, tT, dCount)) { + newTuples.addTuple(nS, tT, dCount); + notifyTcObservers(nS, tT, dCount); + } + } + } + } + } + } + } + } + + // System.out.println(tc); + } + + public ITcRelation getTcRelation() { + return this.tc; + } + + public void setTcRelation(CountingTcRelation tc) { + this.tc = tc; + } + + @Override + public boolean isReachable(V source, V target) { + return tc.containsTuple(source, target); + } + + @Override + public void attachObserver(ITcObserver to) { + this.observers.add(to); + + } + + @Override + public void detachObserver(ITcObserver to) { + this.observers.remove(to); + } + + @Override + public Set getAllReachableTargets(V source) { + Set targets = new HashSet(); + if (tc.getTupleEnds(source) != null) { + targets.addAll(tc.getTupleEnds(source)); + } + return targets; + } + + @Override + public Set getAllReachableSources(V target) { + Set sources = new HashSet(); + if (tc.getTupleStarts(target) != null) { + sources.addAll(tc.getTupleStarts(target)); + } + return sources; + } + + private void notifyTcObservers(V source, V target, int dir) { + for (ITcObserver o : observers) { + if (dir == 1) + o.tupleInserted(source, target); + if (dir == -1) + o.tupleDeleted(source, target); + } + } + + @Override + public void dispose() { + tc.clear(); + dtc.clear(); + this.gds.detachObserver(this); + } } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/counting/CountingTcRelation.java b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/counting/CountingTcRelation.java index b0ff21ff..f4afbd0b 100644 --- a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/counting/CountingTcRelation.java +++ b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/counting/CountingTcRelation.java @@ -9,8 +9,8 @@ * Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.itc.alg.counting; - +package org.eclipse.incquery.runtime.base.itc.alg.counting; + import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -22,280 +22,283 @@ import org.eclipse.incquery.runtime.base.itc.alg.misc.ITcRelation; import org.eclipse.incquery.runtime.base.itc.alg.misc.topsort.TopSort; import org.eclipse.incquery.runtime.base.itc.igraph.IBiDirectionalGraphDataSource; - -/** - * Transitive closure relation implementation for the Counting algorithm. - * - * @author Tamas Szabo - * - * @param - */ -public class CountingTcRelation implements ITcRelation { - - private Map> tuplesForward = null; - private Map> tuplesBackward = null; - - protected CountingTcRelation(boolean backwardIndexing) { - tuplesForward = new HashMap>(); - if (backwardIndexing) tuplesBackward = new HashMap>(); - } - - protected boolean isEmpty() { - return this.tuplesForward.isEmpty(); - } - - protected void clear() { - this.tuplesForward.clear(); - - if (tuplesBackward != null) { - this.tuplesBackward.clear(); - } - } - - protected void union(CountingTcRelation rA) { - for (V source : rA.tuplesForward.keySet()) { - for (V target : rA.tuplesForward.get(source).keySet()) { - this.addTuple(source, target, rA.tuplesForward.get(source).get(target)); - } - } - } - - public int getCount(V source, V target) { - if (tuplesForward.containsKey(source) && tuplesForward.get(source).containsKey(target)) { - return tuplesForward.get(source).get(target); - } - else { - return 0; - } - } - - /** - * Returns true if the tc relation did not contain previously such a tuple that is defined by (source,target), - * false otherwise (in this case count is incremented with the given count parameter). - * - * @param source the source of the tuple - * @param target the target of the tuple - * @param count the count of the tuple - * @return true if the relation did not contain previously the tuple - */ - public boolean addTuple(V source, V target, int count) { - - Map sMap = null; - Map tMap = null; - - if (tuplesBackward != null) { - tMap = tuplesBackward.get(target); - - if (tMap == null) { - sMap = new HashMap(); - sMap.put(source, count); - tuplesBackward.put(target, sMap); - } - else { - if (tMap.containsKey(source)) { - tMap.put(source, tMap.get(source)+count); - if (tMap.get(source) == 0) { - tMap.remove(source); - if (tMap.size() == 0) - tuplesBackward.remove(target); - } - } - else { - tMap.put(source, count); - } - } - } - - sMap = tuplesForward.get(source); - - if (sMap == null) { - tMap = new HashMap(); - tMap.put(target, count); - tuplesForward.put(source, tMap); - return true; - } - else { - if (sMap.containsKey(target)) { - sMap.put(target, sMap.get(target)+count); - if (sMap.get(target) == 0) { - sMap.remove(target); - if (sMap.size() == 0) - tuplesForward.remove(source); - - return true; - } - - return false; - } - else { - sMap.put(target, count); - return true; - } - } - } - - public void deleteTupleEnd(V tupleEnd) { - this.tuplesForward.remove(tupleEnd); - - if (tuplesForward.keySet() != null) { - Set tmp = new HashSet(tuplesForward.keySet()); - - for (V key : tmp) { - this.tuplesForward.get(key).remove(tupleEnd); - if (this.tuplesForward.get(key).size() == 0) - this.tuplesForward.remove(key); - } - } - - if (tuplesBackward != null) { - this.tuplesBackward.remove(tupleEnd); - - if (tuplesBackward.keySet() != null) { - Set tmp = new HashSet(tuplesBackward.keySet()); - - for (V key : tmp) { - this.tuplesBackward.get(key).remove(tupleEnd); - if (this.tuplesBackward.get(key).size() == 0) { - this.tuplesBackward.remove(key); - } - } - } - } - } - - /* - * (non-Javadoc) - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - StringBuilder sb = new StringBuilder("TcRelation = "); - - for (V source : this.tuplesForward.keySet()) { - for (V target : this.tuplesForward.get(source).keySet()) { - sb.append("{("+source+","+target+"),"+this.tuplesForward.get(source).get(target)+"} "); - } - } - return sb.toString(); - } - - @Override - public Set getTupleEnds(V source) { - Map tupEnds = tuplesForward.get(source); - if (tupEnds == null) return null; - return new HashSet(tuplesForward.get(source).keySet()); - } - - /** - * Returns the set of nodes from which the target node is reachable. - * - * @param target the target node - * @return the set of source nodes - */ - public Set getTupleStarts(V target) { - if (tuplesBackward != null) { - Map tupStarts = tuplesBackward.get(target); - if (tupStarts == null) return null; - return tuplesBackward.get(target).keySet(); - } - else { - return null; - } - } - - @Override - public Set getTupleStarts() { - Set nodes = new HashSet(); - nodes.addAll(tuplesForward.keySet()); - return nodes; - } - - /** - * Returns true if a (source, target) node is present in the transitive closure relation, false otherwise. - * - * @param source the source node - * @param target the target node - * @return true if tuple is present, false otherwise - */ - public boolean containsTuple(V source, V target) { - if (tuplesForward.containsKey(source)) { - if (tuplesForward.get(source).containsKey(target)) - return true; - } - return false; - } - - /* - * (non-Javadoc) - * @see java.lang.Object#equals(java.lang.Object) - */ - @SuppressWarnings("unchecked") - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - else if (obj == null || this.getClass() != obj.getClass()) { - return false; - } - else { - CountingTcRelation aTR = (CountingTcRelation) obj; - - for (V source : aTR.tuplesForward.keySet()) { - for (V target : aTR.tuplesForward.get(source).keySet()) { - if (!this.containsTuple(source, target)) { - return false; - } - } - } - - for (V source : this.tuplesForward.keySet()) { - for (V target : this.tuplesForward.get(source).keySet()) { - if (!aTR.containsTuple(source, target)) { - return false; - } - } - } - - return true; - } - } - - @Override - public int hashCode() { - int hash = 7; - - for (Entry> entry : this.tuplesForward.entrySet()) { - hash = 31 * hash + entry.hashCode(); - } - - for (Entry> entry : this.tuplesBackward.entrySet()) { - hash = 31 * hash + entry.hashCode(); - } - - return hash; - } - - @SuppressWarnings("unchecked") - public static CountingTcRelation createFrom(IBiDirectionalGraphDataSource gds) { - List topologicalSorting = (List) TopSort.getTopologicalSorting(gds); - CountingTcRelation tc = new CountingTcRelation(true); - Collections.reverse(topologicalSorting); - for (V n : topologicalSorting) { - List sourceNodes = gds.getSourceNodes(n); - if (sourceNodes != null) { - Set tupEnds = tc.getTupleEnds(n); - for (V s : sourceNodes) { - tc.addTuple(s, n, 1); - if (tupEnds != null) { - for (V t : tupEnds) { - tc.addTuple(s, t, 1); - } - } - } - } - } - - return tc; - } -} + +/** + * Transitive closure relation implementation for the Counting algorithm. + * + * @author Tamas Szabo + * + * @param + */ +public class CountingTcRelation implements ITcRelation { + + private Map> tuplesForward = null; + private Map> tuplesBackward = null; + + protected CountingTcRelation(boolean backwardIndexing) { + tuplesForward = new HashMap>(); + if (backwardIndexing) + tuplesBackward = new HashMap>(); + } + + protected boolean isEmpty() { + return this.tuplesForward.isEmpty(); + } + + protected void clear() { + this.tuplesForward.clear(); + + if (tuplesBackward != null) { + this.tuplesBackward.clear(); + } + } + + protected void union(CountingTcRelation rA) { + for (V source : rA.tuplesForward.keySet()) { + for (V target : rA.tuplesForward.get(source).keySet()) { + this.addTuple(source, target, rA.tuplesForward.get(source).get(target)); + } + } + } + + public int getCount(V source, V target) { + if (tuplesForward.containsKey(source) && tuplesForward.get(source).containsKey(target)) { + return tuplesForward.get(source).get(target); + } else { + return 0; + } + } + + /** + * Returns true if the tc relation did not contain previously such a tuple that is defined by (source,target), false + * otherwise (in this case count is incremented with the given count parameter). + * + * @param source + * the source of the tuple + * @param target + * the target of the tuple + * @param count + * the count of the tuple + * @return true if the relation did not contain previously the tuple + */ + public boolean addTuple(V source, V target, int count) { + + Map sMap = null; + Map tMap = null; + + if (tuplesBackward != null) { + tMap = tuplesBackward.get(target); + + if (tMap == null) { + sMap = new HashMap(); + sMap.put(source, count); + tuplesBackward.put(target, sMap); + } else { + if (tMap.containsKey(source)) { + tMap.put(source, tMap.get(source) + count); + if (tMap.get(source) == 0) { + tMap.remove(source); + if (tMap.size() == 0) + tuplesBackward.remove(target); + } + } else { + tMap.put(source, count); + } + } + } + + sMap = tuplesForward.get(source); + + if (sMap == null) { + tMap = new HashMap(); + tMap.put(target, count); + tuplesForward.put(source, tMap); + return true; + } else { + if (sMap.containsKey(target)) { + sMap.put(target, sMap.get(target) + count); + if (sMap.get(target) == 0) { + sMap.remove(target); + if (sMap.size() == 0) + tuplesForward.remove(source); + + return true; + } + + return false; + } else { + sMap.put(target, count); + return true; + } + } + } + + public void deleteTupleEnd(V tupleEnd) { + this.tuplesForward.remove(tupleEnd); + + if (tuplesForward.keySet() != null) { + Set tmp = new HashSet(tuplesForward.keySet()); + + for (V key : tmp) { + this.tuplesForward.get(key).remove(tupleEnd); + if (this.tuplesForward.get(key).size() == 0) + this.tuplesForward.remove(key); + } + } + + if (tuplesBackward != null) { + this.tuplesBackward.remove(tupleEnd); + + if (tuplesBackward.keySet() != null) { + Set tmp = new HashSet(tuplesBackward.keySet()); + + for (V key : tmp) { + this.tuplesBackward.get(key).remove(tupleEnd); + if (this.tuplesBackward.get(key).size() == 0) { + this.tuplesBackward.remove(key); + } + } + } + } + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder("TcRelation = "); + + for (V source : this.tuplesForward.keySet()) { + for (V target : this.tuplesForward.get(source).keySet()) { + sb.append("{(" + source + "," + target + ")," + this.tuplesForward.get(source).get(target) + "} "); + } + } + return sb.toString(); + } + + @Override + public Set getTupleEnds(V source) { + Map tupEnds = tuplesForward.get(source); + if (tupEnds == null) + return null; + return new HashSet(tuplesForward.get(source).keySet()); + } + + /** + * Returns the set of nodes from which the target node is reachable. + * + * @param target + * the target node + * @return the set of source nodes + */ + public Set getTupleStarts(V target) { + if (tuplesBackward != null) { + Map tupStarts = tuplesBackward.get(target); + if (tupStarts == null) + return null; + return tuplesBackward.get(target).keySet(); + } else { + return null; + } + } + + @Override + public Set getTupleStarts() { + Set nodes = new HashSet(); + nodes.addAll(tuplesForward.keySet()); + return nodes; + } + + /** + * Returns true if a (source, target) node is present in the transitive closure relation, false otherwise. + * + * @param source + * the source node + * @param target + * the target node + * @return true if tuple is present, false otherwise + */ + public boolean containsTuple(V source, V target) { + if (tuplesForward.containsKey(source)) { + if (tuplesForward.get(source).containsKey(target)) + return true; + } + return false; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @SuppressWarnings("unchecked") + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } else if (obj == null || this.getClass() != obj.getClass()) { + return false; + } else { + CountingTcRelation aTR = (CountingTcRelation) obj; + + for (V source : aTR.tuplesForward.keySet()) { + for (V target : aTR.tuplesForward.get(source).keySet()) { + if (!this.containsTuple(source, target)) { + return false; + } + } + } + + for (V source : this.tuplesForward.keySet()) { + for (V target : this.tuplesForward.get(source).keySet()) { + if (!aTR.containsTuple(source, target)) { + return false; + } + } + } + + return true; + } + } + + @Override + public int hashCode() { + int hash = 7; + + for (Entry> entry : this.tuplesForward.entrySet()) { + hash = 31 * hash + entry.hashCode(); + } + + for (Entry> entry : this.tuplesBackward.entrySet()) { + hash = 31 * hash + entry.hashCode(); + } + + return hash; + } + + @SuppressWarnings("unchecked") + public static CountingTcRelation createFrom(IBiDirectionalGraphDataSource gds) { + List topologicalSorting = (List) TopSort.getTopologicalSorting(gds); + CountingTcRelation tc = new CountingTcRelation(true); + Collections.reverse(topologicalSorting); + for (V n : topologicalSorting) { + List sourceNodes = gds.getSourceNodes(n); + if (sourceNodes != null) { + Set tupEnds = tc.getTupleEnds(n); + for (V s : sourceNodes) { + tc.addTuple(s, n, 1); + if (tupEnds != null) { + for (V t : tupEnds) { + tc.addTuple(s, t, 1); + } + } + } + } + } + + return tc; + } +} diff --git a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/dred/DRedAlg.java b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/dred/DRedAlg.java index 560814ad..490dee89 100644 --- a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/dred/DRedAlg.java +++ b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/dred/DRedAlg.java @@ -9,9 +9,8 @@ * Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.itc.alg.dred; - - +package org.eclipse.incquery.runtime.base.itc.alg.dred; + import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -25,329 +24,342 @@ import org.eclipse.incquery.runtime.base.itc.igraph.IGraphObserver; import org.eclipse.incquery.runtime.base.itc.igraph.ITcDataSource; import org.eclipse.incquery.runtime.base.itc.igraph.ITcObserver; - -/** - * This class is the optimized implementation of the DRED algorithm. - * - * @author Tamas Szabo - * - * @param the type parameter of the nodes in the graph data source - */ -public class DRedAlg implements IGraphObserver, ITcDataSource { - - private static final long serialVersionUID = 356353826099208151L; - private IGraphDataSource graphDataSource = null; - private DRedTcRelation tc = null; - private DRedTcRelation dtc = null; - private ArrayList> observers; - - /** - * Constructs a new DRED algorithm and initializes the transitive closure relation with the given graph data source. - * Attach itself on the graph data source as an observer. - * - * @param gds the graph data source instance - */ - public DRedAlg(IGraphDataSource gds) { - this.observers = new ArrayList>(); - this.graphDataSource = gds; - this.tc = new DRedTcRelation(); - this.dtc = new DRedTcRelation(); - initTc(); - graphDataSource.attachObserver(this); - } - - /** - * Constructs a new DRED algorithm and initializes the transitive closure relation with the given relation. - * Attach itself on the graph data source as an observer. - * - * @param gds the graph data source instance - * @param tc the transitive closure instance - */ - public DRedAlg(IGraphDataSource gds, DRedTcRelation tc) { - this.graphDataSource = gds; - this.tc = tc; - this.dtc = new DRedTcRelation(); - graphDataSource.attachObserver(this); - } - - /** - * Initializes the transitive closure relation. - */ - private void initTc() { - DFSAlg dfsa = new DFSAlg(this.graphDataSource); - this.setTcRelation(dfsa.getTcRelation()); - this.graphDataSource.detachObserver(dfsa); - } - - /* - * (non-Javadoc) - * @see itc.igraph.IGraphObserver#edgeInserted(java.lang.Object, java.lang.Object) - */ - @Override - public void edgeInserted(V source, V target) { - if (!source.equals(target)) { - Set tupStarts = null; - Set tupEnds = null; - Set> tuples = new HashSet>(); - - //1. d+(tc(x,y)) :- d(l(x,y)) - if (!source.equals(target)) { - if (tc.addTuple(source, target)) { - tuples.add(new Tuple(source, target)); - } - } - - //2. d+(tc(x,y)) :- d+(tc(x,z)) & lv(z,y) Descartes product - tupStarts = tc.getTupleStarts(source); - tupEnds = tc.getTupleEnds(target); - - if (tupStarts != null && tupEnds != null) { - for (V s : tupStarts) { - for (V t : tupEnds) { - if (!s.equals(t)) { - if (tc.addTuple(s, t)) { - tuples.add(new Tuple(s, t)); - } - } - } - } - } - - // (s, source) -> (source, target) - //tupStarts = tc.getTupleStarts(source); - if (tupStarts != null) { - for (V s : tupStarts) { - if (!s.equals(target)) { - if (tc.addTuple(s, target)) { - tuples.add(new Tuple(s, target)); - } - } - } - } - - // (source, target) -> (target, t) - //tupEnds = tc.getTupleEnds(target); - if (tupEnds != null) { - for (V t : tupEnds) { - if (!source.equals(t)) { - if (tc.addTuple(source, t)) { - tuples.add(new Tuple(source, t)); - } - } - } - } - - notifyTcObservers(tuples, 1); - } - } - - /* - * (non-Javadoc) - * @see itc.igraph.IGraphObserver#edgeDeleted(java.lang.Object, java.lang.Object) - */ - @Override - public void edgeDeleted(V source, V target) { - if (!source.equals(target)) { - - //Computing overestimate, Descartes product of A and B sets, where - // A: those nodes from which source is reachable - // B: those nodes which is reachable from target - - Map, Integer> tuples = new HashMap, Integer>(); - Set sources = tc.getTupleStarts(source); - Set targets = tc.getTupleEnds(target); - - tc.removeTuple(source, target); - tuples.put(new Tuple(source,target), -1); - - for (V s : sources) { - for (V t : targets) { - if (!s.equals(t)) { - tc.removeTuple(s, t); - tuples.put(new Tuple(s,t), -1); - } - } - } - - for (V s : sources) { - if (!s.equals(target)) { - tc.removeTuple(s, target); - tuples.put(new Tuple(s,target), -1); - } - } - - for (V t : targets) { - if (!source.equals(t)) { - tc.removeTuple(source, t); - tuples.put(new Tuple(source,t), -1); - } - } - - //System.out.println("overestimate: "+dtc); - - //Modify overestimate with those tuples that have alternative derivations - //1. q+(tc(x,y)) :- lv(x,y) - for (V s : graphDataSource.getAllNodes()) { - List targetNodes = graphDataSource.getTargetNodes(s); - if (targetNodes != null) { - for (V t : targetNodes) { - if (!s.equals(t)) { - tc.addTuple(s, t); - - Tuple tuple = new Tuple(s, t); - - Integer count = tuples.get(tuple); - if (count != null && count == -1) { - tuples.remove(tuple); - } - } - } - } - } - - //2. q+(tc(x,y)) :- tcv(x,z) & lv(z,y) - DRedTcRelation newTups = new DRedTcRelation(); - dtc.clear(); - dtc.union(tc); - - while (!dtc.isEmpty()) { - - newTups.clear(); - newTups.union(dtc); - dtc.clear(); - - for (V s : newTups.getTupleStarts()) { - for (V t : newTups.getTupleEnds(s)) { - List targetNodes = graphDataSource.getTargetNodes(t); - if (targetNodes != null) { - for (V tn : targetNodes) { - if (!s.equals(tn)) { - if (tc.addTuple(s, tn)) { - dtc.addTuple(s, tn); - tuples.remove(new Tuple(s, tn)); - } - } - } - } - } - } - } - - notifyTcObservers(tuples.keySet(), -1); - } - } - - /* - * (non-Javadoc) - * @see itc.igraph.IGraphObserver#nodeInserted(java.lang.Object) - */ - @Override - public void nodeInserted(V n) { - //Node inserted does not result new tc tuple. - } - - /* - * (non-Javadoc) - * @see itc.igraph.IGraphObserver#nodeDeleted(java.lang.Object) - */ - @Override - public void nodeDeleted(V n) { - //FIXME node deletion may involve the deletion of incoming and outgoing edges too - Set set = tc.getTupleEnds(n); - Set modSet = null; - - // n -> target - if (set != null) { - modSet = new HashSet(set); - - for (V tn : modSet) { - this.tc.removeTuple(n, tn); - } - } - - //source -> n - set = tc.getTupleStarts(n); - - if (set != null) { - modSet = new HashSet(set); - - for (V sn : modSet) { - this.tc.removeTuple(sn, n); - } - } - } - - public DRedTcRelation getTcRelation() { - return this.tc; - } - - public void setTcRelation(DRedTcRelation tc) { - this.tc = tc; - } - - /* - * (non-Javadoc) - * @see itc.igraph.ITcDataSource#isReachable(java.lang.Object, java.lang.Object) - */ - @Override - public boolean isReachable(V source, V target) { - return tc.containsTuple(source, target); - } - - /* - * (non-Javadoc) - * @see itc.igraph.ITcDataSource#attachObserver(itc.igraph.ITcObserver) - */ - @Override - public void attachObserver(ITcObserver to) { - this.observers.add(to); - } - - /* - * (non-Javadoc) - * @see itc.igraph.ITcDataSource#detachObserver(itc.igraph.ITcObserver) - */ - @Override - public void detachObserver(ITcObserver to) { - this.observers.remove(to); - } - - /* - * (non-Javadoc) - * @see itc.igraph.ITcDataSource#getTargetNodes(java.lang.Object) - */ - @Override - public Set getAllReachableTargets(V source) { - return tc.getTupleEnds(source); - } - - /* - * (non-Javadoc) - * @see itc.igraph.ITcDataSource#getSourceNodes(java.lang.Object) - */ - @Override - public Set getAllReachableSources(V target) { - return tc.getTupleStarts(target); - } - - protected void notifyTcObservers(Set> tuples, int dir) { - for (ITcObserver o : observers) { - for (Tuple t : tuples) { - if (!t.getSource().equals(t.getTarget())) { - if (dir == 1) { - o.tupleInserted(t.getSource(), t.getTarget()); - } - if (dir == -1) { - o.tupleDeleted(t.getSource(), t.getTarget()); - } - } - } - } - } - - @Override - public void dispose() { - tc = null; - dtc = null; - } -} + +/** + * This class is the optimized implementation of the DRED algorithm. + * + * @author Tamas Szabo + * + * @param + * the type parameter of the nodes in the graph data source + */ +public class DRedAlg implements IGraphObserver, ITcDataSource { + + private static final long serialVersionUID = 356353826099208151L; + private IGraphDataSource graphDataSource = null; + private DRedTcRelation tc = null; + private DRedTcRelation dtc = null; + private ArrayList> observers; + + /** + * Constructs a new DRED algorithm and initializes the transitive closure relation with the given graph data source. + * Attach itself on the graph data source as an observer. + * + * @param gds + * the graph data source instance + */ + public DRedAlg(IGraphDataSource gds) { + this.observers = new ArrayList>(); + this.graphDataSource = gds; + this.tc = new DRedTcRelation(); + this.dtc = new DRedTcRelation(); + initTc(); + graphDataSource.attachObserver(this); + } + + /** + * Constructs a new DRED algorithm and initializes the transitive closure relation with the given relation. Attach + * itself on the graph data source as an observer. + * + * @param gds + * the graph data source instance + * @param tc + * the transitive closure instance + */ + public DRedAlg(IGraphDataSource gds, DRedTcRelation tc) { + this.graphDataSource = gds; + this.tc = tc; + this.dtc = new DRedTcRelation(); + graphDataSource.attachObserver(this); + } + + /** + * Initializes the transitive closure relation. + */ + private void initTc() { + DFSAlg dfsa = new DFSAlg(this.graphDataSource); + this.setTcRelation(dfsa.getTcRelation()); + this.graphDataSource.detachObserver(dfsa); + } + + /* + * (non-Javadoc) + * + * @see itc.igraph.IGraphObserver#edgeInserted(java.lang.Object, java.lang.Object) + */ + @Override + public void edgeInserted(V source, V target) { + if (!source.equals(target)) { + Set tupStarts = null; + Set tupEnds = null; + Set> tuples = new HashSet>(); + + // 1. d+(tc(x,y)) :- d(l(x,y)) + if (!source.equals(target)) { + if (tc.addTuple(source, target)) { + tuples.add(new Tuple(source, target)); + } + } + + // 2. d+(tc(x,y)) :- d+(tc(x,z)) & lv(z,y) Descartes product + tupStarts = tc.getTupleStarts(source); + tupEnds = tc.getTupleEnds(target); + + if (tupStarts != null && tupEnds != null) { + for (V s : tupStarts) { + for (V t : tupEnds) { + if (!s.equals(t)) { + if (tc.addTuple(s, t)) { + tuples.add(new Tuple(s, t)); + } + } + } + } + } + + // (s, source) -> (source, target) + // tupStarts = tc.getTupleStarts(source); + if (tupStarts != null) { + for (V s : tupStarts) { + if (!s.equals(target)) { + if (tc.addTuple(s, target)) { + tuples.add(new Tuple(s, target)); + } + } + } + } + + // (source, target) -> (target, t) + // tupEnds = tc.getTupleEnds(target); + if (tupEnds != null) { + for (V t : tupEnds) { + if (!source.equals(t)) { + if (tc.addTuple(source, t)) { + tuples.add(new Tuple(source, t)); + } + } + } + } + + notifyTcObservers(tuples, 1); + } + } + + /* + * (non-Javadoc) + * + * @see itc.igraph.IGraphObserver#edgeDeleted(java.lang.Object, java.lang.Object) + */ + @Override + public void edgeDeleted(V source, V target) { + if (!source.equals(target)) { + + // Computing overestimate, Descartes product of A and B sets, where + // A: those nodes from which source is reachable + // B: those nodes which is reachable from target + + Map, Integer> tuples = new HashMap, Integer>(); + Set sources = tc.getTupleStarts(source); + Set targets = tc.getTupleEnds(target); + + tc.removeTuple(source, target); + tuples.put(new Tuple(source, target), -1); + + for (V s : sources) { + for (V t : targets) { + if (!s.equals(t)) { + tc.removeTuple(s, t); + tuples.put(new Tuple(s, t), -1); + } + } + } + + for (V s : sources) { + if (!s.equals(target)) { + tc.removeTuple(s, target); + tuples.put(new Tuple(s, target), -1); + } + } + + for (V t : targets) { + if (!source.equals(t)) { + tc.removeTuple(source, t); + tuples.put(new Tuple(source, t), -1); + } + } + + // System.out.println("overestimate: "+dtc); + + // Modify overestimate with those tuples that have alternative derivations + // 1. q+(tc(x,y)) :- lv(x,y) + for (V s : graphDataSource.getAllNodes()) { + List targetNodes = graphDataSource.getTargetNodes(s); + if (targetNodes != null) { + for (V t : targetNodes) { + if (!s.equals(t)) { + tc.addTuple(s, t); + + Tuple tuple = new Tuple(s, t); + + Integer count = tuples.get(tuple); + if (count != null && count == -1) { + tuples.remove(tuple); + } + } + } + } + } + + // 2. q+(tc(x,y)) :- tcv(x,z) & lv(z,y) + DRedTcRelation newTups = new DRedTcRelation(); + dtc.clear(); + dtc.union(tc); + + while (!dtc.isEmpty()) { + + newTups.clear(); + newTups.union(dtc); + dtc.clear(); + + for (V s : newTups.getTupleStarts()) { + for (V t : newTups.getTupleEnds(s)) { + List targetNodes = graphDataSource.getTargetNodes(t); + if (targetNodes != null) { + for (V tn : targetNodes) { + if (!s.equals(tn)) { + if (tc.addTuple(s, tn)) { + dtc.addTuple(s, tn); + tuples.remove(new Tuple(s, tn)); + } + } + } + } + } + } + } + + notifyTcObservers(tuples.keySet(), -1); + } + } + + /* + * (non-Javadoc) + * + * @see itc.igraph.IGraphObserver#nodeInserted(java.lang.Object) + */ + @Override + public void nodeInserted(V n) { + // Node inserted does not result new tc tuple. + } + + /* + * (non-Javadoc) + * + * @see itc.igraph.IGraphObserver#nodeDeleted(java.lang.Object) + */ + @Override + public void nodeDeleted(V n) { + // FIXME node deletion may involve the deletion of incoming and outgoing edges too + Set set = tc.getTupleEnds(n); + Set modSet = null; + + // n -> target + if (set != null) { + modSet = new HashSet(set); + + for (V tn : modSet) { + this.tc.removeTuple(n, tn); + } + } + + // source -> n + set = tc.getTupleStarts(n); + + if (set != null) { + modSet = new HashSet(set); + + for (V sn : modSet) { + this.tc.removeTuple(sn, n); + } + } + } + + public DRedTcRelation getTcRelation() { + return this.tc; + } + + public void setTcRelation(DRedTcRelation tc) { + this.tc = tc; + } + + /* + * (non-Javadoc) + * + * @see itc.igraph.ITcDataSource#isReachable(java.lang.Object, java.lang.Object) + */ + @Override + public boolean isReachable(V source, V target) { + return tc.containsTuple(source, target); + } + + /* + * (non-Javadoc) + * + * @see itc.igraph.ITcDataSource#attachObserver(itc.igraph.ITcObserver) + */ + @Override + public void attachObserver(ITcObserver to) { + this.observers.add(to); + } + + /* + * (non-Javadoc) + * + * @see itc.igraph.ITcDataSource#detachObserver(itc.igraph.ITcObserver) + */ + @Override + public void detachObserver(ITcObserver to) { + this.observers.remove(to); + } + + /* + * (non-Javadoc) + * + * @see itc.igraph.ITcDataSource#getTargetNodes(java.lang.Object) + */ + @Override + public Set getAllReachableTargets(V source) { + return tc.getTupleEnds(source); + } + + /* + * (non-Javadoc) + * + * @see itc.igraph.ITcDataSource#getSourceNodes(java.lang.Object) + */ + @Override + public Set getAllReachableSources(V target) { + return tc.getTupleStarts(target); + } + + protected void notifyTcObservers(Set> tuples, int dir) { + for (ITcObserver o : observers) { + for (Tuple t : tuples) { + if (!t.getSource().equals(t.getTarget())) { + if (dir == 1) { + o.tupleInserted(t.getSource(), t.getTarget()); + } + if (dir == -1) { + o.tupleDeleted(t.getSource(), t.getTarget()); + } + } + } + } + } + + @Override + public void dispose() { + tc = null; + dtc = null; + } +} diff --git a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/dred/DRedTcRelation.java b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/dred/DRedTcRelation.java index 4867d995..e70a081d 100644 --- a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/dred/DRedTcRelation.java +++ b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/dred/DRedTcRelation.java @@ -9,8 +9,8 @@ * Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.itc.alg.dred; - +package org.eclipse.incquery.runtime.base.itc.alg.dred; + import java.io.Serializable; import java.util.HashMap; import java.util.HashSet; @@ -18,204 +18,212 @@ import java.util.Set; import org.eclipse.incquery.runtime.base.itc.alg.misc.ITcRelation; - -public class DRedTcRelation implements Serializable, ITcRelation { - - private static final long serialVersionUID = 1L; - - // tc(a,b) means that b is transitively reachable from a - private Map> tuplesForward; - - // data structure to efficiently get those nodes from which a given node is reachable - // symmetric to tuplesForward - private Map> tuplesBackward; - - public DRedTcRelation() { - this.tuplesForward = new HashMap>(); - this.tuplesBackward = new HashMap>(); - } - - public void clear() { - this.tuplesForward.clear(); - this.tuplesBackward.clear(); - } - - public boolean isEmpty() { - return tuplesForward.isEmpty(); - } - - public void removeTuple(V source, V target) { - - //removing tuple from 'forward' tc relation - Set sSet = tuplesForward.get(source); - if (sSet != null) { - sSet.remove(target); - if (sSet.size() == 0) - tuplesForward.remove(source); - } - - //removing tuple from 'backward' tc relation - Set tSet = tuplesBackward.get(target); - if (tSet != null) { - tSet.remove(source); - if (tSet.size() == 0) - tuplesBackward.remove(target); - } - } - - /** - * Returns true if the tc relation did not contain previously such a tuple that is defined by (source,target), - * false otherwise. - * - * @param source the source of the tuple - * @param target the target of the tuple - * @return true if the relation did not contain previously the tuple - */ - public boolean addTuple(V source, V target) { - - //symmetric modification, it is sufficient to check the return value in one collection - //adding tuple to 'forward' tc relation - Set sSet = tuplesForward.get(source); - if (sSet == null) { - Set newSet = new HashSet(); - newSet.add(target); - tuplesForward.put(source, newSet); - } - else { - sSet.add(target); - } - - //adding tuple to 'backward' tc relation - Set tSet = tuplesBackward.get(target); - if (tSet == null) { - Set newSet = new HashSet(); - newSet.add(source); - tuplesBackward.put(target, newSet); - return true; - } - else { - boolean ret = tSet.add(source); - return ret; - } - - } - - /** - * Union operation of two tc realtions. - * - * @param rA the other tc relation - */ - public void union(DRedTcRelation rA) { - for (V source : rA.tuplesForward.keySet()) { - for (V target : rA.tuplesForward.get(source)) { - this.addTuple(source, target); - } - } - } - - /** - * Computes the difference of this tc relation and the given rA parameter. - * - * @param rA the subtrahend relation - */ - public void difference(DRedTcRelation rA) { - for (V source : rA.tuplesForward.keySet()) { - for (V target : rA.tuplesForward.get(source)) { - this.removeTuple(source, target); - } - } - } - - @Override - public Set getTupleEnds(V source) { - Set t = tuplesForward.get(source); - return (t == null) ? new HashSet() : new HashSet(t); - } - - /** - * Returns the set of nodes from which the target node is reachable. - * - * @param target the target node - * @return the set of source nodes - */ - public Set getTupleStarts(V target) { - Set t = tuplesBackward.get(target); - return (t == null) ? new HashSet() : new HashSet(t); - } - - @Override - public Set getTupleStarts() { - Set t = tuplesForward.keySet(); - return new HashSet(t); - } - - /* - * (non-Javadoc) - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - StringBuilder sb = new StringBuilder("TcRelation = "); - - for (V source : this.tuplesForward.keySet()) { - for (V target : this.tuplesForward.get(source)) { - sb.append("("+source+","+target+") "); - } - } - return sb.toString(); - } - - /** - * Returns true if a (source, target) node is present in the transitive closure relation, false otherwise. - * - * @param source the source node - * @param target the target node - * @return true if tuple is present, false otherwise - */ - public boolean containsTuple(V source, V target) { - if (tuplesForward.containsKey(source)) { - if (tuplesForward.get(source).contains(target)) - return true; - } - return false; - } - - @SuppressWarnings("unchecked") - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if((obj == null) || (obj.getClass() != this.getClass())) { - return false; - } - - DRedTcRelation aTR = (DRedTcRelation) obj; - - for (V source : aTR.tuplesForward.keySet()) { - for (V target : aTR.tuplesForward.get(source)) { - if (!this.containsTuple(source, target)) return false; - } - } - - for (V source : this.tuplesForward.keySet()) { - for (V target : this.tuplesForward.get(source)) { - if (!aTR.containsTuple(source, target)) return false; - } - } - - return true; - } - - @Override - public int hashCode() { - int hash = 7; - hash = 31 * hash + tuplesForward.hashCode(); - hash = 31 * hash + tuplesBackward.hashCode(); - return hash; - } - - public Map> getTuplesForward() { - return tuplesForward; - } -} + +public class DRedTcRelation implements Serializable, ITcRelation { + + private static final long serialVersionUID = 1L; + + // tc(a,b) means that b is transitively reachable from a + private Map> tuplesForward; + + // data structure to efficiently get those nodes from which a given node is reachable + // symmetric to tuplesForward + private Map> tuplesBackward; + + public DRedTcRelation() { + this.tuplesForward = new HashMap>(); + this.tuplesBackward = new HashMap>(); + } + + public void clear() { + this.tuplesForward.clear(); + this.tuplesBackward.clear(); + } + + public boolean isEmpty() { + return tuplesForward.isEmpty(); + } + + public void removeTuple(V source, V target) { + + // removing tuple from 'forward' tc relation + Set sSet = tuplesForward.get(source); + if (sSet != null) { + sSet.remove(target); + if (sSet.size() == 0) + tuplesForward.remove(source); + } + + // removing tuple from 'backward' tc relation + Set tSet = tuplesBackward.get(target); + if (tSet != null) { + tSet.remove(source); + if (tSet.size() == 0) + tuplesBackward.remove(target); + } + } + + /** + * Returns true if the tc relation did not contain previously such a tuple that is defined by (source,target), false + * otherwise. + * + * @param source + * the source of the tuple + * @param target + * the target of the tuple + * @return true if the relation did not contain previously the tuple + */ + public boolean addTuple(V source, V target) { + + // symmetric modification, it is sufficient to check the return value in one collection + // adding tuple to 'forward' tc relation + Set sSet = tuplesForward.get(source); + if (sSet == null) { + Set newSet = new HashSet(); + newSet.add(target); + tuplesForward.put(source, newSet); + } else { + sSet.add(target); + } + + // adding tuple to 'backward' tc relation + Set tSet = tuplesBackward.get(target); + if (tSet == null) { + Set newSet = new HashSet(); + newSet.add(source); + tuplesBackward.put(target, newSet); + return true; + } else { + boolean ret = tSet.add(source); + return ret; + } + + } + + /** + * Union operation of two tc realtions. + * + * @param rA + * the other tc relation + */ + public void union(DRedTcRelation rA) { + for (V source : rA.tuplesForward.keySet()) { + for (V target : rA.tuplesForward.get(source)) { + this.addTuple(source, target); + } + } + } + + /** + * Computes the difference of this tc relation and the given rA parameter. + * + * @param rA + * the subtrahend relation + */ + public void difference(DRedTcRelation rA) { + for (V source : rA.tuplesForward.keySet()) { + for (V target : rA.tuplesForward.get(source)) { + this.removeTuple(source, target); + } + } + } + + @Override + public Set getTupleEnds(V source) { + Set t = tuplesForward.get(source); + return (t == null) ? new HashSet() : new HashSet(t); + } + + /** + * Returns the set of nodes from which the target node is reachable. + * + * @param target + * the target node + * @return the set of source nodes + */ + public Set getTupleStarts(V target) { + Set t = tuplesBackward.get(target); + return (t == null) ? new HashSet() : new HashSet(t); + } + + @Override + public Set getTupleStarts() { + Set t = tuplesForward.keySet(); + return new HashSet(t); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder("TcRelation = "); + + for (V source : this.tuplesForward.keySet()) { + for (V target : this.tuplesForward.get(source)) { + sb.append("(" + source + "," + target + ") "); + } + } + return sb.toString(); + } + + /** + * Returns true if a (source, target) node is present in the transitive closure relation, false otherwise. + * + * @param source + * the source node + * @param target + * the target node + * @return true if tuple is present, false otherwise + */ + public boolean containsTuple(V source, V target) { + if (tuplesForward.containsKey(source)) { + if (tuplesForward.get(source).contains(target)) + return true; + } + return false; + } + + @SuppressWarnings("unchecked") + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if ((obj == null) || (obj.getClass() != this.getClass())) { + return false; + } + + DRedTcRelation aTR = (DRedTcRelation) obj; + + for (V source : aTR.tuplesForward.keySet()) { + for (V target : aTR.tuplesForward.get(source)) { + if (!this.containsTuple(source, target)) + return false; + } + } + + for (V source : this.tuplesForward.keySet()) { + for (V target : this.tuplesForward.get(source)) { + if (!aTR.containsTuple(source, target)) + return false; + } + } + + return true; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + tuplesForward.hashCode(); + hash = 31 * hash + tuplesBackward.hashCode(); + return hash; + } + + public Map> getTuplesForward() { + return tuplesForward; + } +} diff --git a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/fw/FloydWarshallAlg.java b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/fw/FloydWarshallAlg.java index c8dae1ea..d0807a48 100644 --- a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/fw/FloydWarshallAlg.java +++ b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/fw/FloydWarshallAlg.java @@ -9,107 +9,106 @@ * Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.itc.alg.fw; - -import java.util.HashMap; -import java.util.List; - +package org.eclipse.incquery.runtime.base.itc.alg.fw; + +import java.util.HashMap; +import java.util.List; + import org.eclipse.incquery.runtime.base.itc.alg.dred.DRedTcRelation; import org.eclipse.incquery.runtime.base.itc.igraph.IBiDirectionalGraphDataSource; import org.eclipse.incquery.runtime.base.itc.igraph.IBiDirectionalWrapper; import org.eclipse.incquery.runtime.base.itc.igraph.IGraphDataSource; import org.eclipse.incquery.runtime.base.itc.igraph.IGraphObserver; - - -public class FloydWarshallAlg implements IGraphObserver { - - private static final long serialVersionUID = 8551056305625218732L; - private DRedTcRelation tc = null; - private IBiDirectionalGraphDataSource gds = null; - - public FloydWarshallAlg(IGraphDataSource gds) { - if (gds instanceof IBiDirectionalGraphDataSource) { - this.gds = (IBiDirectionalGraphDataSource) gds; - } - else { - this.gds = new IBiDirectionalWrapper(gds); - } - - this.tc = new DRedTcRelation(); - gds.attachObserver(this); - generateTc(); - } - - private void generateTc() { - - tc.clear(); - - int n = gds.getAllNodes().size(); - HashMap mapForw = new HashMap(); - HashMap mapBackw = new HashMap(); - int[][] P = new int[n][n]; - - int i, j, k; - - //initialize adjacent matrix - for (i=0;i targets = gds.getTargetNodes(source); - if (targets != null) { - for (V target : targets) { - P[mapForw.get(source)][mapForw.get(target)] = 1; - } - } - } - - for (k=0;k getTcRelation() { - return this.tc; - } -} + +public class FloydWarshallAlg implements IGraphObserver { + + private static final long serialVersionUID = 8551056305625218732L; + private DRedTcRelation tc = null; + private IBiDirectionalGraphDataSource gds = null; + + public FloydWarshallAlg(IGraphDataSource gds) { + if (gds instanceof IBiDirectionalGraphDataSource) { + this.gds = (IBiDirectionalGraphDataSource) gds; + } else { + this.gds = new IBiDirectionalWrapper(gds); + } + + this.tc = new DRedTcRelation(); + gds.attachObserver(this); + generateTc(); + } + + private void generateTc() { + + tc.clear(); + + int n = gds.getAllNodes().size(); + HashMap mapForw = new HashMap(); + HashMap mapBackw = new HashMap(); + int[][] P = new int[n][n]; + + int i, j, k; + + // initialize adjacent matrix + for (i = 0; i < n; i++) { + for (j = 0; j < n; j++) { + P[i][j] = 0; + } + } + + i = 0; + for (V node : gds.getAllNodes()) { + mapForw.put(node, i); + mapBackw.put(i, node); + i++; + } + + for (V source : gds.getAllNodes()) { + List targets = gds.getTargetNodes(source); + if (targets != null) { + for (V target : targets) { + P[mapForw.get(source)][mapForw.get(target)] = 1; + } + } + } + + for (k = 0; k < n; k++) { + for (i = 0; i < n; i++) { + for (j = 0; j < n; j++) { + P[i][j] = P[i][j] | (P[i][k] & P[k][j]); + } + } + } + + for (i = 0; i < n; i++) { + for (j = 0; j < n; j++) { + if (P[i][j] == 1 && i != j) + tc.addTuple(mapBackw.get(i), mapBackw.get(j)); + } + } + } + + @Override + public void edgeInserted(V source, V target) { + generateTc(); + } + + @Override + public void edgeDeleted(V source, V target) { + generateTc(); + } + + @Override + public void nodeInserted(V n) { + generateTc(); + } + + @Override + public void nodeDeleted(V n) { + generateTc(); + } + + public DRedTcRelation getTcRelation() { + return this.tc; + } +} diff --git a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/CollectionHelper.java b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/CollectionHelper.java index 0f616bb7..63f077d6 100644 --- a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/CollectionHelper.java +++ b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/CollectionHelper.java @@ -15,42 +15,46 @@ /** * @author Tamas Szabo - * + * */ public class CollectionHelper { - /** - * Returns the intersection of two sets. - * - * @param set1 the first set - * @param set2 the second set - * @return the intersection of the sets - */ - public static Set intersection(Set set1, Set set2) { - Set intersection = new HashSet(); - for (V n : set1) { - if (set2.contains(n)) { - intersection.add(n); - } - } - return intersection; - } - - /** - * Returns the difference of two sets (S1\S2). - * - * @param set1 the first set - * @param set2 the second set - * @return the difference of the sets - */ - public static Set difference(Set set1, Set set2) { - Set difference = new HashSet(); - for (V n : set1) { - if (!set2.contains(n)) { - difference.add(n); - } - } - return difference; - } - + /** + * Returns the intersection of two sets. + * + * @param set1 + * the first set + * @param set2 + * the second set + * @return the intersection of the sets + */ + public static Set intersection(Set set1, Set set2) { + Set intersection = new HashSet(); + for (V n : set1) { + if (set2.contains(n)) { + intersection.add(n); + } + } + return intersection; + } + + /** + * Returns the difference of two sets (S1\S2). + * + * @param set1 + * the first set + * @param set2 + * the second set + * @return the difference of the sets + */ + public static Set difference(Set set1, Set set2) { + Set difference = new HashSet(); + for (V n : set1) { + if (!set2.contains(n)) { + difference.add(n); + } + } + return difference; + } + } diff --git a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/CountingListener.java b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/CountingListener.java index 47e6bced..84cd0e3b 100644 --- a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/CountingListener.java +++ b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/CountingListener.java @@ -14,24 +14,24 @@ /** * @author Tamas Szabo - * + * */ public class CountingListener implements ITcObserver { - private IncSCCAlg alg; - - public CountingListener(IncSCCAlg alg) { - this.alg = alg; - } - - @Override - public void tupleInserted(V source, V target) { - alg.notifyTcObservers(alg.sccs.setMap.get(source), alg.sccs.setMap.get(target), Direction.INSERT); - } + private IncSCCAlg alg; + + public CountingListener(IncSCCAlg alg) { + this.alg = alg; + } + + @Override + public void tupleInserted(V source, V target) { + alg.notifyTcObservers(alg.sccs.setMap.get(source), alg.sccs.setMap.get(target), Direction.INSERT); + } - @Override - public void tupleDeleted(V source, V target) { - alg.notifyTcObservers(alg.sccs.setMap.get(source), alg.sccs.setMap.get(target), Direction.DELETE); - } + @Override + public void tupleDeleted(V source, V target) { + alg.notifyTcObservers(alg.sccs.setMap.get(source), alg.sccs.setMap.get(target), Direction.DELETE); + } } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/Direction.java b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/Direction.java index fcaf6eff..13aaab49 100644 --- a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/Direction.java +++ b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/Direction.java @@ -12,9 +12,8 @@ /** * @author Tamas Szabo - * + * */ public enum Direction { - INSERT, - DELETE + INSERT, DELETE } diff --git a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/GraphHelper.java b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/GraphHelper.java index 5020d9f7..bacd7dda 100644 --- a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/GraphHelper.java +++ b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/GraphHelper.java @@ -18,111 +18,112 @@ /** * @author Tamas Szabo - * + * */ public class GraphHelper { - - private IncSCCAlg alg; - - public GraphHelper(IncSCCAlg alg) { - this.alg = alg; - } - - /** - * Return the SCCs from which the SCC represented by the root node is reachable. - * Note that an SCC can be present multiple times in the returned list (multiple edges between the two SCCs). - * - * @param root - * @return the list of reachable target SCCs - */ - public List getSourceSCCsOfSCC(V root) { - List sourceSCCs = new ArrayList(); - - for (V containedNode : alg.sccs.setMap.get(root)) { - List sourceNodes = alg.gds.getSourceNodes(containedNode); - - if (sourceNodes != null) { - for (V source : sourceNodes) { - sourceSCCs.add(alg.sccs.find(source)); - } - } - } - - return sourceSCCs; - } - - /** - * Return the SCCs which are reachable from the SCC represented by the root node. - * Note that an SCC can be present multiple times in the returned list (multiple edges between the two SCCs). - * - * @param root - * @return the list of reachable target SCCs - */ - public List getTargetSCCsOfSCC(V root) { - - List targetSCCs = new ArrayList(); - - for (V containedNode : alg.sccs.setMap.get(root)) { - List targetNodes = alg.gds.getTargetNodes(containedNode); - - if (targetNodes != null) { - for (V target : targetNodes) { - targetSCCs.add(alg.sccs.find(target)); - } - } - } - - return targetSCCs; - } - - public int getEdgeCount(V node) { - return getEdgeCount(node, node); - } - - public int getEdgeCount(V source, V target) { - if (this.alg.gds.getTargetNodes(source) == null) { - return 0; - } - else { - int count = 0; - for (V n : this.alg.gds.getTargetNodes(source)) { - if (n.equals(target)) { - count++; - } - } - return count; - } - } - - /** - * Returns the Graph for the given root node in the union find structure. - * - * @param root the root node - * @return the graph for the subtree - */ - public Graph getGraphOfSCC(V root) { - - Graph g = new Graph(); - Set nodeSet = alg.sccs.setMap.get(root); - - if (nodeSet != null) { - for (V node : nodeSet) { - g.insertNode(node); - } - for (V node : nodeSet) { - - List sources = (alg.gds.getSourceNodes(node) == null) ? null : new ArrayList(alg.gds.getSourceNodes(node)); - - if (sources != null) { - for (V _s : sources) { - if (nodeSet.contains(_s)) { - g.insertEdge(_s, node); - } - } - } - } - } - - return g; - } + + private IncSCCAlg alg; + + public GraphHelper(IncSCCAlg alg) { + this.alg = alg; + } + + /** + * Return the SCCs from which the SCC represented by the root node is reachable. Note that an SCC can be present + * multiple times in the returned list (multiple edges between the two SCCs). + * + * @param root + * @return the list of reachable target SCCs + */ + public List getSourceSCCsOfSCC(V root) { + List sourceSCCs = new ArrayList(); + + for (V containedNode : alg.sccs.setMap.get(root)) { + List sourceNodes = alg.gds.getSourceNodes(containedNode); + + if (sourceNodes != null) { + for (V source : sourceNodes) { + sourceSCCs.add(alg.sccs.find(source)); + } + } + } + + return sourceSCCs; + } + + /** + * Return the SCCs which are reachable from the SCC represented by the root node. Note that an SCC can be present + * multiple times in the returned list (multiple edges between the two SCCs). + * + * @param root + * @return the list of reachable target SCCs + */ + public List getTargetSCCsOfSCC(V root) { + + List targetSCCs = new ArrayList(); + + for (V containedNode : alg.sccs.setMap.get(root)) { + List targetNodes = alg.gds.getTargetNodes(containedNode); + + if (targetNodes != null) { + for (V target : targetNodes) { + targetSCCs.add(alg.sccs.find(target)); + } + } + } + + return targetSCCs; + } + + public int getEdgeCount(V node) { + return getEdgeCount(node, node); + } + + public int getEdgeCount(V source, V target) { + if (this.alg.gds.getTargetNodes(source) == null) { + return 0; + } else { + int count = 0; + for (V n : this.alg.gds.getTargetNodes(source)) { + if (n.equals(target)) { + count++; + } + } + return count; + } + } + + /** + * Returns the Graph for the given root node in the union find structure. + * + * @param root + * the root node + * @return the graph for the subtree + */ + public Graph getGraphOfSCC(V root) { + + Graph g = new Graph(); + Set nodeSet = alg.sccs.setMap.get(root); + + if (nodeSet != null) { + for (V node : nodeSet) { + g.insertNode(node); + } + for (V node : nodeSet) { + + List sources = (alg.gds.getSourceNodes(node) == null) ? null : new ArrayList( + alg.gds.getSourceNodes(node)); + + if (sources != null) { + for (V _s : sources) { + if (nodeSet.contains(_s)) { + g.insertEdge(_s, node); + } + } + } + } + } + + return g; + } } diff --git a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/IncSCCAlg.java b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/IncSCCAlg.java index 8ee31942..5d4232b2 100644 --- a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/IncSCCAlg.java +++ b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/IncSCCAlg.java @@ -9,9 +9,8 @@ * Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.itc.alg.incscc; - - +package org.eclipse.incquery.runtime.base.itc.alg.incscc; + import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; @@ -31,472 +30,480 @@ import org.eclipse.incquery.runtime.base.itc.igraph.IGraphObserver; import org.eclipse.incquery.runtime.base.itc.igraph.ITcDataSource; import org.eclipse.incquery.runtime.base.itc.igraph.ITcObserver; - -/** - * Incremental SCC maintenance + counting algorithm. - * - * @author Tamas Szabo - * - * @param the type parameter of the nodes in the graph data source - */ -public class IncSCCAlg implements IGraphObserver, ITcDataSource { - - private static final long serialVersionUID = 6207002106223444807L; - - public UnionFind sccs; - public IBiDirectionalGraphDataSource gds; - private CountingAlg counting; - private Graph reducedGraph; - private IBiDirectionalGraphDataSource reducedGraphIndexer; - private List> observers; - private GraphHelper graphHelper; - private CountingListener countingListener; - - public IncSCCAlg(IGraphDataSource graphDataSource) { - - if (graphDataSource instanceof IBiDirectionalGraphDataSource) { - gds = (IBiDirectionalGraphDataSource) graphDataSource; - } - else { - gds = new IBiDirectionalWrapper(graphDataSource); - } - observers = new ArrayList>(); - sccs = new UnionFind(); - reducedGraph = new Graph(); - reducedGraphIndexer = new IBiDirectionalWrapper(reducedGraph); - graphHelper = new GraphHelper(this); - countingListener = new CountingListener(this); - init(); - gds.attachObserver(this); - } - - @SuppressWarnings("unchecked") - private void init() { - SCCResult _sccres = SCC.computeSCC(gds); - Set> _sccs = _sccres.getSccs(); - - for (Set _set : _sccs) { - sccs.makeSet((V[]) _set.toArray()); - } - - //init reduced graph - for (V n : sccs.setMap.keySet()) { - reducedGraph.insertNode(n); - } - - for (V source : gds.getAllNodes()) { - final List targetNodes = gds.getTargetNodes(source); - if (targetNodes != null) for (V target : targetNodes) { - V sourceRoot = sccs.find(source); - V targetRoot = sccs.find(target); - - if (!sourceRoot.equals(targetRoot)) { - reducedGraph.insertEdge(sourceRoot, targetRoot); - } - } - } - - counting = new CountingAlg(reducedGraph); - } - - @Override - public void edgeInserted(V source, V target) { - V sourceRoot = sccs.find(source); - V targetRoot = sccs.find(target); - - //Different SCC - if (!sourceRoot.equals(targetRoot)) { - - //source is reachable from target? - if (counting.isReachable(targetRoot, sourceRoot)) { - - Set predecessorRoots = counting.getAllReachableSources(sourceRoot); - Set successorRoots = counting.getAllReachableTargets(targetRoot); - - //1. intersection - Set isectRoots = CollectionHelper.intersection(predecessorRoots, successorRoots); - isectRoots.add(sourceRoot); - isectRoots.add(targetRoot); - - //notifications must be issued before Union-Find modifications - if (observers.size() > 0) { - Set sourceSCCs = new HashSet(); - Set targetSCCs = new HashSet(); - - sourceSCCs.add(sourceRoot); - sourceSCCs.addAll(predecessorRoots); - targetSCCs.add(targetRoot); - targetSCCs.addAll(successorRoots); - - //tracing back to actual nodes - for (V sourceSCC : sourceSCCs) { - for (V targetSCC : CollectionHelper.difference(targetSCCs, counting.getAllReachableTargets(sourceSCC))) { - boolean needsNotification = false; - - if (sourceSCC.equals(targetSCC) && sccs.setMap.get(sourceSCC).size() == 1 && graphHelper.getEdgeCount(sourceSCC) == 0) { - needsNotification = true; - } - else if (!sourceSCC.equals(targetSCC)) { - needsNotification = true; - } - //if self loop is already present omit the notification - if (needsNotification) { - notifyTcObservers(sccs.setMap.get(sourceSCC), sccs.setMap.get(targetSCC), Direction.INSERT); - } - } - } - } - - //2. delete edges, nodes - List sources = new ArrayList(); - List targets = new ArrayList(); - - for (V r : isectRoots) { - List _srcList = graphHelper.getSourceSCCsOfSCC(r); - List _trgList = graphHelper.getTargetSCCsOfSCC(r); - - for (V _source : _srcList) { - if (!_source.equals(r)) { - reducedGraph.deleteEdge(_source, r); - } - } - - for (V _target : _trgList) { - if (!isectRoots.contains(_target) && !r.equals(_target)) { - reducedGraph.deleteEdge(r, _target); - } - } - - sources.addAll(_srcList); - targets.addAll(_trgList); - } - - for (V r : isectRoots) { - reducedGraph.deleteNode(r); - } - - //3. union - Iterator iterator = isectRoots.iterator(); - V newRoot = iterator.next(); - while (iterator.hasNext()) { - newRoot = sccs.union(newRoot, iterator.next()); - } - - //4. add new node - reducedGraph.insertNode(newRoot); - - //5. add edges - Set containedNodes = sccs.setMap.get(newRoot); - - for (V _s : sources) { - if (!containedNodes.contains(_s) && !_s.equals(newRoot)) { - reducedGraph.insertEdge(_s, newRoot); - } - } - for (V _t : targets) { - if (!containedNodes.contains(_t) && !_t.equals(newRoot)) { - reducedGraph.insertEdge(newRoot, _t); - } - } - } - else { - if (observers.size() > 0 && graphHelper.getEdgeCount(source, target) == 1) { - counting.attachObserver(countingListener); - } - reducedGraph.insertEdge(sourceRoot, targetRoot); - counting.detachObserver(countingListener); - } - } - else { - //Notifications about self-loops - if (observers.size() > 0 && sccs.setMap.get(sourceRoot).size() == 1 && graphHelper.getEdgeCount(source, target) == 1) { - notifyTcObservers(source, source, Direction.INSERT); - } - } - } - - @SuppressWarnings("unchecked") - @Override - public void edgeDeleted(V source, V target) { - V sourceRoot = sccs.find(source); - V targetRoot = sccs.find(target); - - if (!sourceRoot.equals(targetRoot)) { - if (observers.size() > 0 && graphHelper.getEdgeCount(source, target) == 0) { - counting.attachObserver(countingListener); - } - reducedGraph.deleteEdge(sourceRoot, targetRoot); - counting.detachObserver(countingListener); - } - else { - //get the graph for the scc whose root is sourceRoot - Graph g = graphHelper.getGraphOfSCC(sourceRoot); - - //if source is not reachable from target anymore - if (!BFS.isReachable(source, target, g)) { - List reachableSources = null; - List reachableTargets = null; - - SCCResult _newSccs = SCC.computeSCC(g); - - //delete scc node (and with its edges too) - reachableSources = reducedGraphIndexer.getSourceNodes(sourceRoot); - reachableTargets = reducedGraphIndexer.getTargetNodes(sourceRoot); - - if (reachableSources != null) { - Set tmp = new HashSet(reachableSources); - for (V s : tmp) { - reducedGraph.deleteEdge(s, sourceRoot); - } - } - if (reachableTargets != null) { - Set tmp = new HashSet(reachableTargets); - for (V t : tmp) { - reducedGraph.deleteEdge(sourceRoot, t); - } - } - sccs.deleteSet(sourceRoot); - reducedGraph.deleteNode(sourceRoot); - - Set> newSccs = _newSccs.getSccs(); - Set roots = new HashSet(); - - //add new nodes and edges to the reduced graph - for (Set _scc : newSccs) { - V newRoot = sccs.makeSet((V[]) _scc.toArray()); - reducedGraph.insertNode(newRoot); - roots.add(newRoot); - } - for (V _root : roots) { - List sourceNodes = graphHelper.getSourceSCCsOfSCC(_root); - List targetNodes = graphHelper.getTargetSCCsOfSCC(_root); - - for (V _s : sourceNodes) { - V _sR = sccs.find(_s); - if (!_sR.equals(_root)) - reducedGraph.insertEdge(sccs.find(_s), _root); - } - for (V _t : targetNodes) { - V _tR = sccs.find(_t); - if (!roots.contains(_t) && !_tR.equals(_root)) - reducedGraph.insertEdge(_root, _tR); - } - } - - //Must be after the union-find modifications - if (observers.size() > 0) { - V newSourceRoot = sccs.find(source); - V newTargetRoot = sccs.find(target); - - Set sourceSCCs = counting.getAllReachableSources(newSourceRoot); - sourceSCCs.add(newSourceRoot); - - Set targetSCCs = counting.getAllReachableTargets(newTargetRoot); - targetSCCs.add(newTargetRoot); - - for (V sourceSCC : sourceSCCs) { - for (V targetSCC : CollectionHelper.difference(targetSCCs, counting.getAllReachableTargets(sourceSCC))) { - boolean needsNotification = false; - - if (sourceSCC.equals(targetSCC) && sccs.setMap.get(sourceSCC).size() == 1 && graphHelper.getEdgeCount(sourceSCC) == 0) { - needsNotification = true; - } - else if (!sourceSCC.equals(targetSCC)) { - needsNotification = true; - } - //if self loop is already present omit the notification - if (needsNotification) { - notifyTcObservers(sccs.setMap.get(sourceSCC), sccs.setMap.get(targetSCC), Direction.DELETE); - } - } - } - } - } - else { - //only handle self-loop notifications - sourceRoot equals to targetRoot - if (observers.size() > 0 && sccs.setMap.get(sourceRoot).size() == 1 && graphHelper.getEdgeCount(source, target) == 0) { - notifyTcObservers(source, source, Direction.DELETE); - } - } - } - } - - @Override - public void nodeInserted(V n) { - sccs.makeSet(n); - reducedGraph.insertNode(n); - } - - @Override - public void nodeDeleted(V n) { - List sources = gds.getSourceNodes(n); - List targets = gds.getTargetNodes(n); - - if (sources != null) { - for (V source : sources) { - edgeDeleted(source, n); - } - } - - if (targets != null) { - for (V target : gds.getTargetNodes(n)) { - edgeDeleted(n, target); - } - } - - sccs.deleteSet(n); - } - - @Override - public void attachObserver(ITcObserver to) { - observers.add(to); - } - - @Override - public void detachObserver(ITcObserver to) { - observers.remove(to); - } - - @Override - public Set getAllReachableTargets(V source) { - V sourceRoot = sccs.find(source); - Set containedNodes = sccs.setMap.get(sourceRoot); - Set targets = new HashSet(); - - if (containedNodes.size() > 1 || graphHelper.getEdgeCount(source) == 1) { - targets.addAll(containedNodes); - } - - Set rootSet = counting.getAllReachableTargets(sourceRoot); - if (rootSet != null) { - for (V _root : rootSet) { - targets.addAll(sccs.setMap.get(_root)); - } - } - - return targets; - } - - @Override - public Set getAllReachableSources(V target) { - V targetRoot = sccs.find(target); - Set containedNodes = sccs.setMap.get(targetRoot); - Set sources = new HashSet(); - - if (containedNodes.size() > 1 || graphHelper.getEdgeCount(target) == 1) { - sources.addAll(containedNodes); - } - - Set rootSet = counting.getAllReachableSources(targetRoot); - if (rootSet != null) { - for (V _root : rootSet) { - sources.addAll(sccs.setMap.get(_root)); - } - } - return sources; - } - - @Override - public boolean isReachable(V source, V target) { - V sourceRoot = sccs.find(source); - V targetRoot = sccs.find(target); - - if (sourceRoot.equals(targetRoot)) return true; - else return counting.isReachable(sourceRoot, targetRoot); - } - - // for JUnit - public boolean checkTcRelation(DRedTcRelation tc) { - - for (V s : tc.getTupleStarts()) { - for (V t : tc.getTupleEnds(s)) { - if (!isReachable(s, t)) return false; - } - } - - for (V root : counting.getTcRelation().getTupleStarts()) { - for (V end : counting.getTcRelation().getTupleEnds(root)) { - for (V s : sccs.setMap.get(root)) { - for (V t : sccs.setMap.get(end)) { - if (!tc.containsTuple(s, t)) return false; - } - } - } - } - - return true; - } - - @Override - public void dispose() { - gds.detachObserver(this); - counting.dispose(); - } - - /** - * Call this method to notify the observers of the transitive closure relation. - * The tuples used in the notification will be the Descartes product of the two sets given. - * - * @param sources the source nodes - * @param targets the target nodes - * @param direction - */ - protected void notifyTcObservers(Set sources, Set targets, Direction direction) { - for (V s : sources) { - for (V t : targets) { - notifyTcObservers(s, t, direction); - } - } - } - - private void notifyTcObservers(V source, V target, Direction direction) { - for (ITcObserver observer : observers) { - if (direction == Direction.INSERT) { - observer.tupleInserted(source, target); - } - if (direction == Direction.DELETE) { - observer.tupleDeleted(source, target); - } - } - } - - public Set> getTcRelation() { - Set> resultSet = new HashSet>(); - - for (V sourceRoot : sccs.setMap.keySet()) { - Set sccMembers = sccs.setMap.get(sourceRoot); - if (sccMembers.size() > 1 || graphHelper.getEdgeCount(sccMembers.iterator().next()) == 1) { - for (V nS : sccs.setMap.get(sourceRoot)) { - for (V nT : sccs.setMap.get(sourceRoot)) { - resultSet.add(new Tuple(nS, nT)); - } - } - } - - Set reachableTargets = counting.getAllReachableTargets(sourceRoot); - if (reachableTargets != null) { - for (V targetRoot : reachableTargets) { - for (V sN : sccs.setMap.get(sourceRoot)) { - for (V tN : sccs.setMap.get(targetRoot)) { - resultSet.add(new Tuple(sN, tN)); - } - } - } - } - } - - return resultSet; - } - - public boolean isIsolated(V node) { - List targets = gds.getTargetNodes(node); - List sources = gds.getSourceNodes(node); - - if (((targets == null) || (targets.isEmpty())) && ((sources == null) || (sources.isEmpty()))) { - return true; - } - else { - return false; - } - } -} + +/** + * Incremental SCC maintenance + counting algorithm. + * + * @author Tamas Szabo + * + * @param + * the type parameter of the nodes in the graph data source + */ +public class IncSCCAlg implements IGraphObserver, ITcDataSource { + + private static final long serialVersionUID = 6207002106223444807L; + + public UnionFind sccs; + public IBiDirectionalGraphDataSource gds; + private CountingAlg counting; + private Graph reducedGraph; + private IBiDirectionalGraphDataSource reducedGraphIndexer; + private List> observers; + private GraphHelper graphHelper; + private CountingListener countingListener; + + public IncSCCAlg(IGraphDataSource graphDataSource) { + + if (graphDataSource instanceof IBiDirectionalGraphDataSource) { + gds = (IBiDirectionalGraphDataSource) graphDataSource; + } else { + gds = new IBiDirectionalWrapper(graphDataSource); + } + observers = new ArrayList>(); + sccs = new UnionFind(); + reducedGraph = new Graph(); + reducedGraphIndexer = new IBiDirectionalWrapper(reducedGraph); + graphHelper = new GraphHelper(this); + countingListener = new CountingListener(this); + init(); + gds.attachObserver(this); + } + + @SuppressWarnings("unchecked") + private void init() { + SCCResult _sccres = SCC.computeSCC(gds); + Set> _sccs = _sccres.getSccs(); + + for (Set _set : _sccs) { + sccs.makeSet((V[]) _set.toArray()); + } + + // init reduced graph + for (V n : sccs.setMap.keySet()) { + reducedGraph.insertNode(n); + } + + for (V source : gds.getAllNodes()) { + final List targetNodes = gds.getTargetNodes(source); + if (targetNodes != null) + for (V target : targetNodes) { + V sourceRoot = sccs.find(source); + V targetRoot = sccs.find(target); + + if (!sourceRoot.equals(targetRoot)) { + reducedGraph.insertEdge(sourceRoot, targetRoot); + } + } + } + + counting = new CountingAlg(reducedGraph); + } + + @Override + public void edgeInserted(V source, V target) { + V sourceRoot = sccs.find(source); + V targetRoot = sccs.find(target); + + // Different SCC + if (!sourceRoot.equals(targetRoot)) { + + // source is reachable from target? + if (counting.isReachable(targetRoot, sourceRoot)) { + + Set predecessorRoots = counting.getAllReachableSources(sourceRoot); + Set successorRoots = counting.getAllReachableTargets(targetRoot); + + // 1. intersection + Set isectRoots = CollectionHelper.intersection(predecessorRoots, successorRoots); + isectRoots.add(sourceRoot); + isectRoots.add(targetRoot); + + // notifications must be issued before Union-Find modifications + if (observers.size() > 0) { + Set sourceSCCs = new HashSet(); + Set targetSCCs = new HashSet(); + + sourceSCCs.add(sourceRoot); + sourceSCCs.addAll(predecessorRoots); + targetSCCs.add(targetRoot); + targetSCCs.addAll(successorRoots); + + // tracing back to actual nodes + for (V sourceSCC : sourceSCCs) { + for (V targetSCC : CollectionHelper.difference(targetSCCs, + counting.getAllReachableTargets(sourceSCC))) { + boolean needsNotification = false; + + if (sourceSCC.equals(targetSCC) && sccs.setMap.get(sourceSCC).size() == 1 + && graphHelper.getEdgeCount(sourceSCC) == 0) { + needsNotification = true; + } else if (!sourceSCC.equals(targetSCC)) { + needsNotification = true; + } + // if self loop is already present omit the notification + if (needsNotification) { + notifyTcObservers(sccs.setMap.get(sourceSCC), sccs.setMap.get(targetSCC), + Direction.INSERT); + } + } + } + } + + // 2. delete edges, nodes + List sources = new ArrayList(); + List targets = new ArrayList(); + + for (V r : isectRoots) { + List _srcList = graphHelper.getSourceSCCsOfSCC(r); + List _trgList = graphHelper.getTargetSCCsOfSCC(r); + + for (V _source : _srcList) { + if (!_source.equals(r)) { + reducedGraph.deleteEdge(_source, r); + } + } + + for (V _target : _trgList) { + if (!isectRoots.contains(_target) && !r.equals(_target)) { + reducedGraph.deleteEdge(r, _target); + } + } + + sources.addAll(_srcList); + targets.addAll(_trgList); + } + + for (V r : isectRoots) { + reducedGraph.deleteNode(r); + } + + // 3. union + Iterator iterator = isectRoots.iterator(); + V newRoot = iterator.next(); + while (iterator.hasNext()) { + newRoot = sccs.union(newRoot, iterator.next()); + } + + // 4. add new node + reducedGraph.insertNode(newRoot); + + // 5. add edges + Set containedNodes = sccs.setMap.get(newRoot); + + for (V _s : sources) { + if (!containedNodes.contains(_s) && !_s.equals(newRoot)) { + reducedGraph.insertEdge(_s, newRoot); + } + } + for (V _t : targets) { + if (!containedNodes.contains(_t) && !_t.equals(newRoot)) { + reducedGraph.insertEdge(newRoot, _t); + } + } + } else { + if (observers.size() > 0 && graphHelper.getEdgeCount(source, target) == 1) { + counting.attachObserver(countingListener); + } + reducedGraph.insertEdge(sourceRoot, targetRoot); + counting.detachObserver(countingListener); + } + } else { + // Notifications about self-loops + if (observers.size() > 0 && sccs.setMap.get(sourceRoot).size() == 1 + && graphHelper.getEdgeCount(source, target) == 1) { + notifyTcObservers(source, source, Direction.INSERT); + } + } + } + + @SuppressWarnings("unchecked") + @Override + public void edgeDeleted(V source, V target) { + V sourceRoot = sccs.find(source); + V targetRoot = sccs.find(target); + + if (!sourceRoot.equals(targetRoot)) { + if (observers.size() > 0 && graphHelper.getEdgeCount(source, target) == 0) { + counting.attachObserver(countingListener); + } + reducedGraph.deleteEdge(sourceRoot, targetRoot); + counting.detachObserver(countingListener); + } else { + // get the graph for the scc whose root is sourceRoot + Graph g = graphHelper.getGraphOfSCC(sourceRoot); + + // if source is not reachable from target anymore + if (!BFS.isReachable(source, target, g)) { + List reachableSources = null; + List reachableTargets = null; + + SCCResult _newSccs = SCC.computeSCC(g); + + // delete scc node (and with its edges too) + reachableSources = reducedGraphIndexer.getSourceNodes(sourceRoot); + reachableTargets = reducedGraphIndexer.getTargetNodes(sourceRoot); + + if (reachableSources != null) { + Set tmp = new HashSet(reachableSources); + for (V s : tmp) { + reducedGraph.deleteEdge(s, sourceRoot); + } + } + if (reachableTargets != null) { + Set tmp = new HashSet(reachableTargets); + for (V t : tmp) { + reducedGraph.deleteEdge(sourceRoot, t); + } + } + sccs.deleteSet(sourceRoot); + reducedGraph.deleteNode(sourceRoot); + + Set> newSccs = _newSccs.getSccs(); + Set roots = new HashSet(); + + // add new nodes and edges to the reduced graph + for (Set _scc : newSccs) { + V newRoot = sccs.makeSet((V[]) _scc.toArray()); + reducedGraph.insertNode(newRoot); + roots.add(newRoot); + } + for (V _root : roots) { + List sourceNodes = graphHelper.getSourceSCCsOfSCC(_root); + List targetNodes = graphHelper.getTargetSCCsOfSCC(_root); + + for (V _s : sourceNodes) { + V _sR = sccs.find(_s); + if (!_sR.equals(_root)) + reducedGraph.insertEdge(sccs.find(_s), _root); + } + for (V _t : targetNodes) { + V _tR = sccs.find(_t); + if (!roots.contains(_t) && !_tR.equals(_root)) + reducedGraph.insertEdge(_root, _tR); + } + } + + // Must be after the union-find modifications + if (observers.size() > 0) { + V newSourceRoot = sccs.find(source); + V newTargetRoot = sccs.find(target); + + Set sourceSCCs = counting.getAllReachableSources(newSourceRoot); + sourceSCCs.add(newSourceRoot); + + Set targetSCCs = counting.getAllReachableTargets(newTargetRoot); + targetSCCs.add(newTargetRoot); + + for (V sourceSCC : sourceSCCs) { + for (V targetSCC : CollectionHelper.difference(targetSCCs, + counting.getAllReachableTargets(sourceSCC))) { + boolean needsNotification = false; + + if (sourceSCC.equals(targetSCC) && sccs.setMap.get(sourceSCC).size() == 1 + && graphHelper.getEdgeCount(sourceSCC) == 0) { + needsNotification = true; + } else if (!sourceSCC.equals(targetSCC)) { + needsNotification = true; + } + // if self loop is already present omit the notification + if (needsNotification) { + notifyTcObservers(sccs.setMap.get(sourceSCC), sccs.setMap.get(targetSCC), + Direction.DELETE); + } + } + } + } + } else { + // only handle self-loop notifications - sourceRoot equals to targetRoot + if (observers.size() > 0 && sccs.setMap.get(sourceRoot).size() == 1 + && graphHelper.getEdgeCount(source, target) == 0) { + notifyTcObservers(source, source, Direction.DELETE); + } + } + } + } + + @Override + public void nodeInserted(V n) { + sccs.makeSet(n); + reducedGraph.insertNode(n); + } + + @Override + public void nodeDeleted(V n) { + List sources = gds.getSourceNodes(n); + List targets = gds.getTargetNodes(n); + + if (sources != null) { + for (V source : sources) { + edgeDeleted(source, n); + } + } + + if (targets != null) { + for (V target : gds.getTargetNodes(n)) { + edgeDeleted(n, target); + } + } + + sccs.deleteSet(n); + } + + @Override + public void attachObserver(ITcObserver to) { + observers.add(to); + } + + @Override + public void detachObserver(ITcObserver to) { + observers.remove(to); + } + + @Override + public Set getAllReachableTargets(V source) { + V sourceRoot = sccs.find(source); + Set containedNodes = sccs.setMap.get(sourceRoot); + Set targets = new HashSet(); + + if (containedNodes.size() > 1 || graphHelper.getEdgeCount(source) == 1) { + targets.addAll(containedNodes); + } + + Set rootSet = counting.getAllReachableTargets(sourceRoot); + if (rootSet != null) { + for (V _root : rootSet) { + targets.addAll(sccs.setMap.get(_root)); + } + } + + return targets; + } + + @Override + public Set getAllReachableSources(V target) { + V targetRoot = sccs.find(target); + Set containedNodes = sccs.setMap.get(targetRoot); + Set sources = new HashSet(); + + if (containedNodes.size() > 1 || graphHelper.getEdgeCount(target) == 1) { + sources.addAll(containedNodes); + } + + Set rootSet = counting.getAllReachableSources(targetRoot); + if (rootSet != null) { + for (V _root : rootSet) { + sources.addAll(sccs.setMap.get(_root)); + } + } + return sources; + } + + @Override + public boolean isReachable(V source, V target) { + V sourceRoot = sccs.find(source); + V targetRoot = sccs.find(target); + + if (sourceRoot.equals(targetRoot)) + return true; + else + return counting.isReachable(sourceRoot, targetRoot); + } + + // for JUnit + public boolean checkTcRelation(DRedTcRelation tc) { + + for (V s : tc.getTupleStarts()) { + for (V t : tc.getTupleEnds(s)) { + if (!isReachable(s, t)) + return false; + } + } + + for (V root : counting.getTcRelation().getTupleStarts()) { + for (V end : counting.getTcRelation().getTupleEnds(root)) { + for (V s : sccs.setMap.get(root)) { + for (V t : sccs.setMap.get(end)) { + if (!tc.containsTuple(s, t)) + return false; + } + } + } + } + + return true; + } + + @Override + public void dispose() { + gds.detachObserver(this); + counting.dispose(); + } + + /** + * Call this method to notify the observers of the transitive closure relation. The tuples used in the notification + * will be the Descartes product of the two sets given. + * + * @param sources + * the source nodes + * @param targets + * the target nodes + * @param direction + */ + protected void notifyTcObservers(Set sources, Set targets, Direction direction) { + for (V s : sources) { + for (V t : targets) { + notifyTcObservers(s, t, direction); + } + } + } + + private void notifyTcObservers(V source, V target, Direction direction) { + for (ITcObserver observer : observers) { + if (direction == Direction.INSERT) { + observer.tupleInserted(source, target); + } + if (direction == Direction.DELETE) { + observer.tupleDeleted(source, target); + } + } + } + + public Set> getTcRelation() { + Set> resultSet = new HashSet>(); + + for (V sourceRoot : sccs.setMap.keySet()) { + Set sccMembers = sccs.setMap.get(sourceRoot); + if (sccMembers.size() > 1 || graphHelper.getEdgeCount(sccMembers.iterator().next()) == 1) { + for (V nS : sccs.setMap.get(sourceRoot)) { + for (V nT : sccs.setMap.get(sourceRoot)) { + resultSet.add(new Tuple(nS, nT)); + } + } + } + + Set reachableTargets = counting.getAllReachableTargets(sourceRoot); + if (reachableTargets != null) { + for (V targetRoot : reachableTargets) { + for (V sN : sccs.setMap.get(sourceRoot)) { + for (V tN : sccs.setMap.get(targetRoot)) { + resultSet.add(new Tuple(sN, tN)); + } + } + } + } + } + + return resultSet; + } + + public boolean isIsolated(V node) { + List targets = gds.getTargetNodes(node); + List sources = gds.getSourceNodes(node); + + if (((targets == null) || (targets.isEmpty())) && ((sources == null) || (sources.isEmpty()))) { + return true; + } else { + return false; + } + } +} diff --git a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/NotifierThread.java b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/NotifierThread.java index 8bb37496..3351cc20 100644 --- a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/NotifierThread.java +++ b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/NotifierThread.java @@ -9,40 +9,39 @@ * Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.itc.alg.incscc; - -import java.util.Set; - +package org.eclipse.incquery.runtime.base.itc.alg.incscc; + +import java.util.Set; + import org.eclipse.incquery.runtime.base.itc.igraph.ITcObserver; - -public class NotifierThread extends Thread { - - private Set sources; - private Set targets; - private ITcObserver observer; - private int dir; - - public NotifierThread(Set sources, Set targets, ITcObserver observer, int dir) { - this.sources = sources; - this.targets = targets; - this.observer = observer; - this.dir = dir; - } - - @Override - public void run() { - for (V s : sources) { - for (V t : targets) { - if (dir == 1) { - observer.tupleInserted(s, t); - } - if (dir == -1) { - observer.tupleDeleted(s, t); - } - - } - } - } - - -} + +public class NotifierThread extends Thread { + + private Set sources; + private Set targets; + private ITcObserver observer; + private int dir; + + public NotifierThread(Set sources, Set targets, ITcObserver observer, int dir) { + this.sources = sources; + this.targets = targets; + this.observer = observer; + this.dir = dir; + } + + @Override + public void run() { + for (V s : sources) { + for (V t : targets) { + if (dir == 1) { + observer.tupleInserted(s, t); + } + if (dir == -1) { + observer.tupleDeleted(s, t); + } + + } + } + } + +} diff --git a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/UnionFind.java b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/UnionFind.java index 8cd9f611..2e300e20 100644 --- a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/UnionFind.java +++ b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/UnionFind.java @@ -9,159 +9,161 @@ * Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.itc.alg.incscc; - +package org.eclipse.incquery.runtime.base.itc.alg.incscc; + import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; - -/** - * Union-find data structure implementation. - * Note that the implementation relies on the correct implementation of the equals method of the type parameter's class. - * - * @author Tamas Szabo - * - * @param the type parameter of the element's stored in the union-find data structure - */ -public class UnionFind { - - public Map> nodeMap; - public Map> setMap; - - /** - * Instantiate a new union-find data structure. - */ - public UnionFind() { - nodeMap = new HashMap>(); - setMap = new HashMap>(); - } - - /** - * Creates a new set from the array of elements. - * - * @param nodes the array of elements - * @return the root element - */ - public V makeSet(V[] nodes) { - if (nodes.length > 1) { - V root = makeSet(nodes[0]); - for (int i = 1;i prop = new UnionFindNodeProperty(0, node); - nodeMap.put(node, prop); - Set set = new HashSet(); - set.add(node); - setMap.put(node, set); - } - return node; - } - - /** - * Find method with path compression. - * - * @param node the node to find - * @return the root node of the set in which the given node can be found - */ - public V find(V node) { - UnionFindNodeProperty prop = nodeMap.get(node); - - if (prop != null) { - if (prop.parent.equals(node)) { - return node; - } - else { - prop.parent = find(prop.parent); - return prop.parent; - } - } - return null; - } - - /** - * Union by rank implementation of the two sets which contain x and y; - * x and/or y can be a single element from the universe. - * - * @param x set or single element of the universe - * @param y set or single element of the universe - * @return the new root of the two sets - */ - public V union(V x, V y) { - - V xRoot = find(x); - V yRoot = find(y); - - if ((xRoot == null) && (yRoot == null)) { - makeSet(x); - makeSet(y); - return union(x, y); - } - - else if ((xRoot != null) && (yRoot == null)) { - makeSet(y); - return union(x, y); - } - - else if ((xRoot == null) && (yRoot != null)) { - makeSet(x); - return union(x, y); - } - - else if ((xRoot != null) && (yRoot != null) && !xRoot.equals(yRoot)) { - UnionFindNodeProperty xRootProp = nodeMap.get(xRoot); - UnionFindNodeProperty yRootProp = nodeMap.get(yRoot); - - if (xRootProp.rank < yRootProp.rank) { - xRootProp.parent = yRoot; - setMap.get(yRoot).addAll(setMap.get(xRoot)); - setMap.remove(xRoot); - return yRoot; - } - else if (xRootProp.rank > yRootProp.rank) { - yRootProp.parent = xRoot; - setMap.get(xRoot).addAll(setMap.get(yRoot)); - setMap.remove(yRoot); - return xRoot; - } - else { - yRootProp.parent = xRoot; - xRootProp.rank += 1; - setMap.get(xRoot).addAll(setMap.get(yRoot)); - setMap.remove(yRoot); - return xRoot; - } - } - else return xRoot; - } - - /** - * Delete the set whose root is the given node. - * - * @param root the root node - */ - public void deleteSet(V root) { - //if (setMap.containsKey(root)) - for (V n : setMap.get(root)) { - nodeMap.remove(n); - } - setMap.remove(root); - } -} + +/** + * Union-find data structure implementation. Note that the implementation relies on the correct implementation of the + * equals method of the type parameter's class. + * + * @author Tamas Szabo + * + * @param + * the type parameter of the element's stored in the union-find data structure + */ +public class UnionFind { + + public Map> nodeMap; + public Map> setMap; + + /** + * Instantiate a new union-find data structure. + */ + public UnionFind() { + nodeMap = new HashMap>(); + setMap = new HashMap>(); + } + + /** + * Creates a new set from the array of elements. + * + * @param nodes + * the array of elements + * @return the root element + */ + public V makeSet(V[] nodes) { + if (nodes.length > 1) { + V root = makeSet(nodes[0]); + for (int i = 1; i < nodes.length; i++) + root = union(nodes[i], root); + return root; + } else if (nodes.length == 1) { + return makeSet(nodes[0]); + } else { + return null; + } + } + + /** + * This method creates a single set containing the given node. + * + * @param node + * the root node of the set + * @return the root element + */ + public V makeSet(V node) { + if (!nodeMap.containsKey(node)) { + UnionFindNodeProperty prop = new UnionFindNodeProperty(0, node); + nodeMap.put(node, prop); + Set set = new HashSet(); + set.add(node); + setMap.put(node, set); + } + return node; + } + + /** + * Find method with path compression. + * + * @param node + * the node to find + * @return the root node of the set in which the given node can be found + */ + public V find(V node) { + UnionFindNodeProperty prop = nodeMap.get(node); + + if (prop != null) { + if (prop.parent.equals(node)) { + return node; + } else { + prop.parent = find(prop.parent); + return prop.parent; + } + } + return null; + } + + /** + * Union by rank implementation of the two sets which contain x and y; x and/or y can be a single element from the + * universe. + * + * @param x + * set or single element of the universe + * @param y + * set or single element of the universe + * @return the new root of the two sets + */ + public V union(V x, V y) { + + V xRoot = find(x); + V yRoot = find(y); + + if ((xRoot == null) && (yRoot == null)) { + makeSet(x); + makeSet(y); + return union(x, y); + } + + else if ((xRoot != null) && (yRoot == null)) { + makeSet(y); + return union(x, y); + } + + else if ((xRoot == null) && (yRoot != null)) { + makeSet(x); + return union(x, y); + } + + else if ((xRoot != null) && (yRoot != null) && !xRoot.equals(yRoot)) { + UnionFindNodeProperty xRootProp = nodeMap.get(xRoot); + UnionFindNodeProperty yRootProp = nodeMap.get(yRoot); + + if (xRootProp.rank < yRootProp.rank) { + xRootProp.parent = yRoot; + setMap.get(yRoot).addAll(setMap.get(xRoot)); + setMap.remove(xRoot); + return yRoot; + } else if (xRootProp.rank > yRootProp.rank) { + yRootProp.parent = xRoot; + setMap.get(xRoot).addAll(setMap.get(yRoot)); + setMap.remove(yRoot); + return xRoot; + } else { + yRootProp.parent = xRoot; + xRootProp.rank += 1; + setMap.get(xRoot).addAll(setMap.get(yRoot)); + setMap.remove(yRoot); + return xRoot; + } + } else + return xRoot; + } + + /** + * Delete the set whose root is the given node. + * + * @param root + * the root node + */ + public void deleteSet(V root) { + // if (setMap.containsKey(root)) + for (V n : setMap.get(root)) { + nodeMap.remove(n); + } + setMap.remove(root); + } +} diff --git a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/UnionFindNodeProperty.java b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/UnionFindNodeProperty.java index 21236234..95d65994 100644 --- a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/UnionFindNodeProperty.java +++ b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/incscc/UnionFindNodeProperty.java @@ -9,26 +9,26 @@ * Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.itc.alg.incscc; - -public class UnionFindNodeProperty { - - public int rank; - public V parent; - - public UnionFindNodeProperty() { - this.rank = 0; - this.parent = null; - } - - public UnionFindNodeProperty(int rank, V parent) { - super(); - this.rank = rank; - this.parent = parent; - } - - @Override - public String toString() { - return "[rank:"+rank+", parent:"+parent.toString()+"]"; - } -} +package org.eclipse.incquery.runtime.base.itc.alg.incscc; + +public class UnionFindNodeProperty { + + public int rank; + public V parent; + + public UnionFindNodeProperty() { + this.rank = 0; + this.parent = null; + } + + public UnionFindNodeProperty(int rank, V parent) { + super(); + this.rank = rank; + this.parent = parent; + } + + @Override + public String toString() { + return "[rank:" + rank + ", parent:" + parent.toString() + "]"; + } +} diff --git a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/Edge.java b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/Edge.java index 65625e14..516d1a92 100644 --- a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/Edge.java +++ b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/Edge.java @@ -9,32 +9,32 @@ * Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.itc.alg.misc; - -public class Edge { - private V source; - private V target; - - public Edge(V source, V target) { - super(); - this.source = source; - this.target = target; - } - - public V getSource() { - return source; - } - - public void setSource(V source) { - this.source = source; - } - - public V getTarget() { - return target; - } - - public void setTarget(V target) { - this.target = target; - } - -} +package org.eclipse.incquery.runtime.base.itc.alg.misc; + +public class Edge { + private V source; + private V target; + + public Edge(V source, V target) { + super(); + this.source = source; + this.target = target; + } + + public V getSource() { + return source; + } + + public void setSource(V source) { + this.source = source; + } + + public V getTarget() { + return target; + } + + public void setTarget(V target) { + this.target = target; + } + +} diff --git a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/ITcRelation.java b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/ITcRelation.java index 63809aac..f8931723 100644 --- a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/ITcRelation.java +++ b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/ITcRelation.java @@ -9,24 +9,25 @@ * Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.itc.alg.misc; - -import java.util.Set; - -public interface ITcRelation { - - /** - * Returns the starting nodes from a transitive closure relation. - * - * @return the set of starting nodes - */ - public Set getTupleStarts(); - - /** - * Returns the set of nodes that are reachable from the given node. - * - * @param start the starting node - * @return the set of reachable nodes - */ - public Set getTupleEnds(V start); -} +package org.eclipse.incquery.runtime.base.itc.alg.misc; + +import java.util.Set; + +public interface ITcRelation { + + /** + * Returns the starting nodes from a transitive closure relation. + * + * @return the set of starting nodes + */ + public Set getTupleStarts(); + + /** + * Returns the set of nodes that are reachable from the given node. + * + * @param start + * the starting node + * @return the set of reachable nodes + */ + public Set getTupleEnds(V start); +} diff --git a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/Tuple.java b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/Tuple.java index f7376278..89fae012 100644 --- a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/Tuple.java +++ b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/Tuple.java @@ -9,54 +9,54 @@ * Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.itc.alg.misc; - -public class Tuple { - - private V source; - private V target; - - public Tuple(V source, V target) { - super(); - this.source = source; - this.target = target; - } - - public V getSource() { - return source; - } - - public void setSource(V source) { - this.source = source; - } - - public V getTarget() { - return target; - } - - public void setTarget(V target) { - this.target = target; - } - - @Override - public String toString() { - return "("+source.toString()+","+target.toString()+")"; - } - - @Override - public boolean equals(Object o) { - if (o instanceof Tuple) { - Tuple t = (Tuple) o; - - if (t.getSource().equals(this.source) && t.getTarget().equals(this.target)) { - return true; - } - } - return false; - } - - @Override - public int hashCode() { - return source.hashCode() + target.hashCode(); - } -} +package org.eclipse.incquery.runtime.base.itc.alg.misc; + +public class Tuple { + + private V source; + private V target; + + public Tuple(V source, V target) { + super(); + this.source = source; + this.target = target; + } + + public V getSource() { + return source; + } + + public void setSource(V source) { + this.source = source; + } + + public V getTarget() { + return target; + } + + public void setTarget(V target) { + this.target = target; + } + + @Override + public String toString() { + return "(" + source.toString() + "," + target.toString() + ")"; + } + + @Override + public boolean equals(Object o) { + if (o instanceof Tuple) { + Tuple t = (Tuple) o; + + if (t.getSource().equals(this.source) && t.getTarget().equals(this.target)) { + return true; + } + } + return false; + } + + @Override + public int hashCode() { + return source.hashCode() + target.hashCode(); + } +} diff --git a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/bfs/BFS.java b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/bfs/BFS.java index ff9f6dd0..835e273a 100644 --- a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/bfs/BFS.java +++ b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/bfs/BFS.java @@ -9,9 +9,8 @@ * Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.itc.alg.misc.bfs; - - +package org.eclipse.incquery.runtime.base.itc.alg.misc.bfs; + import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -21,133 +20,144 @@ import org.eclipse.incquery.runtime.base.itc.igraph.IBiDirectionalGraphDataSource; import org.eclipse.incquery.runtime.base.itc.igraph.IGraphDataSource; - -public class BFS { - - /** - * Performs a breadth first search on the given graph to determine whether source is reachable from target. - * - * @param the type parameter of the nodes in the graph - * @param source the source node - * @param target the target node - * @param graph the graph data source - * @return true if source is reachable from target, false otherwise - */ - public static boolean isReachable(V source, V target, IGraphDataSource graph) { - List nodeQueue = new ArrayList(); - Map visited = new HashMap(); - - nodeQueue.add(source); - visited.put(source, true); - - boolean ret = _isReachable(target, graph, nodeQueue, visited); - return ret; - } - - private static boolean _isReachable(V target, IGraphDataSource graph, List nodeQueue, Map visited) { - - while (!nodeQueue.isEmpty()) { - V node = nodeQueue.remove(0); - List targets = graph.getTargetNodes(node); - if (targets != null) { - for (V _node : targets) { - - if (_node.equals(target)) return true; - - if (visited.get(_node) == null) { - visited.put(_node, true); - nodeQueue.add(_node); - } - } - } - } - - return false; - } - - public static Set reachableSources(IBiDirectionalGraphDataSource graph, V target) { - Set retSet = new HashSet(); - retSet.add(target); - List nodeQueue = new ArrayList(); - nodeQueue.add(target); - - _reachableSources(graph, nodeQueue, retSet); - - return retSet; - } - - private static void _reachableSources(IBiDirectionalGraphDataSource graph, List nodeQueue, Set retSet) { - while (!nodeQueue.isEmpty()) { - V node = nodeQueue.remove(0); - List sourceNodes = graph.getSourceNodes(node); - - if (sourceNodes != null) { - for (V _node : graph.getSourceNodes(node)) { - - if (!retSet.contains(_node)) { - retSet.add(_node); - nodeQueue.add(_node); - } - } - } - } - } - - public static Set reachableTargets(IGraphDataSource graph, V source) { - Set retSet = new HashSet(); - retSet.add(source); - List nodeQueue = new ArrayList(); - nodeQueue.add(source); - - _reachableTargets(graph, nodeQueue, retSet); - - return retSet; - } - - private static void _reachableTargets(IGraphDataSource graph, List nodeQueue, Set retSet) { - while (!nodeQueue.isEmpty()) { - V node = nodeQueue.remove(0); - - for (V _node : graph.getTargetNodes(node)) { - - if (!retSet.contains(_node)) { - retSet.add(_node); - nodeQueue.add(_node); - } - } - } - } - - /** - * Performs a breadth first search on the given graph and collects all the nodes along the path from source to target if such path exists. - * - * @param the type parameter of the nodes in the graph - * @param source the source node - * @param target the target node - * @param graph the graph data source - * @return the set of nodes along the path - */ - public static Set collectNodesAlongPath(V source, V target, IGraphDataSource graph) { - Set path = new HashSet(); - _collectNodesAlongPath(source, target, graph, path); - return path; - } - - private static boolean _collectNodesAlongPath(V node, V target, IGraphDataSource graph, Set path) { - - boolean res = false; - - //end recursion - if (node.equals(target)) { - path.add(node); - return true; - } - else { - for (V _nodeT : graph.getTargetNodes(node)) { - res = (_collectNodesAlongPath(_nodeT, target, graph, path)) || res; - } - if (res) path.add(node); - return res; - } - } -} + +public class BFS { + + /** + * Performs a breadth first search on the given graph to determine whether source is reachable from target. + * + * @param + * the type parameter of the nodes in the graph + * @param source + * the source node + * @param target + * the target node + * @param graph + * the graph data source + * @return true if source is reachable from target, false otherwise + */ + public static boolean isReachable(V source, V target, IGraphDataSource graph) { + List nodeQueue = new ArrayList(); + Map visited = new HashMap(); + + nodeQueue.add(source); + visited.put(source, true); + + boolean ret = _isReachable(target, graph, nodeQueue, visited); + return ret; + } + + private static boolean _isReachable(V target, IGraphDataSource graph, List nodeQueue, + Map visited) { + + while (!nodeQueue.isEmpty()) { + V node = nodeQueue.remove(0); + List targets = graph.getTargetNodes(node); + if (targets != null) { + for (V _node : targets) { + + if (_node.equals(target)) + return true; + + if (visited.get(_node) == null) { + visited.put(_node, true); + nodeQueue.add(_node); + } + } + } + } + + return false; + } + + public static Set reachableSources(IBiDirectionalGraphDataSource graph, V target) { + Set retSet = new HashSet(); + retSet.add(target); + List nodeQueue = new ArrayList(); + nodeQueue.add(target); + + _reachableSources(graph, nodeQueue, retSet); + + return retSet; + } + + private static void _reachableSources(IBiDirectionalGraphDataSource graph, List nodeQueue, Set retSet) { + while (!nodeQueue.isEmpty()) { + V node = nodeQueue.remove(0); + List sourceNodes = graph.getSourceNodes(node); + + if (sourceNodes != null) { + for (V _node : graph.getSourceNodes(node)) { + + if (!retSet.contains(_node)) { + retSet.add(_node); + nodeQueue.add(_node); + } + } + } + } + } + + public static Set reachableTargets(IGraphDataSource graph, V source) { + Set retSet = new HashSet(); + retSet.add(source); + List nodeQueue = new ArrayList(); + nodeQueue.add(source); + + _reachableTargets(graph, nodeQueue, retSet); + + return retSet; + } + + private static void _reachableTargets(IGraphDataSource graph, List nodeQueue, Set retSet) { + while (!nodeQueue.isEmpty()) { + V node = nodeQueue.remove(0); + + for (V _node : graph.getTargetNodes(node)) { + + if (!retSet.contains(_node)) { + retSet.add(_node); + nodeQueue.add(_node); + } + } + } + } + + /** + * Performs a breadth first search on the given graph and collects all the nodes along the path from source to + * target if such path exists. + * + * @param + * the type parameter of the nodes in the graph + * @param source + * the source node + * @param target + * the target node + * @param graph + * the graph data source + * @return the set of nodes along the path + */ + public static Set collectNodesAlongPath(V source, V target, IGraphDataSource graph) { + Set path = new HashSet(); + _collectNodesAlongPath(source, target, graph, path); + return path; + } + + private static boolean _collectNodesAlongPath(V node, V target, IGraphDataSource graph, Set path) { + + boolean res = false; + + // end recursion + if (node.equals(target)) { + path.add(node); + return true; + } else { + for (V _nodeT : graph.getTargetNodes(node)) { + res = (_collectNodesAlongPath(_nodeT, target, graph, path)) || res; + } + if (res) + path.add(node); + return res; + } + } +} diff --git a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/dfs/DFSAlg.java b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/dfs/DFSAlg.java index 4c84bfa4..16e722f6 100644 --- a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/dfs/DFSAlg.java +++ b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/dfs/DFSAlg.java @@ -9,93 +9,92 @@ * Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.itc.alg.misc.dfs; - -import java.util.HashMap; -import java.util.List; - +package org.eclipse.incquery.runtime.base.itc.alg.misc.dfs; + +import java.util.HashMap; +import java.util.List; + import org.eclipse.incquery.runtime.base.itc.alg.dred.DRedTcRelation; import org.eclipse.incquery.runtime.base.itc.igraph.IGraphDataSource; import org.eclipse.incquery.runtime.base.itc.igraph.IGraphObserver; - - -public class DFSAlg implements IGraphObserver { - - private static final long serialVersionUID = 7397186805581323071L; - private IGraphDataSource gds; - private DRedTcRelation tc; - private int[] visited; - private HashMap nodeMap; - - public DFSAlg(IGraphDataSource gds) { - this.gds = gds; - this.tc = new DRedTcRelation(); - gds.attachObserver(this); - deriveTc(); - } - - private void deriveTc() { - tc.clear(); - - this.visited = new int[gds.getAllNodes().size()]; - nodeMap = new HashMap(); - - int j = 0; - for (V n : gds.getAllNodes()) { - nodeMap.put(n, j); - j++; - } - - for (V n : gds.getAllNodes()) { - oneDFS(n, n); - initVisitedArray(); - } - } - - private void initVisitedArray() { - for (int i=0;i targets = gds.getTargetNodes(act); - if (targets != null) { - for (V t : targets) { - if (visited[nodeMap.get(t)] == 0) { - oneDFS(t, source); - } - } - } - } - - public DRedTcRelation getTcRelation() { - return this.tc; - } - - @Override - public void edgeInserted(V source, V target) { - deriveTc(); - } - - @Override - public void edgeDeleted(V source, V target) { - deriveTc(); - } - - @Override - public void nodeInserted(V n) { - deriveTc(); - } - - @Override - public void nodeDeleted(V n) { - deriveTc(); - } -} + +public class DFSAlg implements IGraphObserver { + + private static final long serialVersionUID = 7397186805581323071L; + private IGraphDataSource gds; + private DRedTcRelation tc; + private int[] visited; + private HashMap nodeMap; + + public DFSAlg(IGraphDataSource gds) { + this.gds = gds; + this.tc = new DRedTcRelation(); + gds.attachObserver(this); + deriveTc(); + } + + private void deriveTc() { + tc.clear(); + + this.visited = new int[gds.getAllNodes().size()]; + nodeMap = new HashMap(); + + int j = 0; + for (V n : gds.getAllNodes()) { + nodeMap.put(n, j); + j++; + } + + for (V n : gds.getAllNodes()) { + oneDFS(n, n); + initVisitedArray(); + } + } + + private void initVisitedArray() { + for (int i = 0; i < visited.length; i++) + visited[i] = 0; + } + + private void oneDFS(V act, V source) { + + if (!act.equals(source)) { + tc.addTuple(source, act); + } + + visited[nodeMap.get(act)] = 1; + + List targets = gds.getTargetNodes(act); + if (targets != null) { + for (V t : targets) { + if (visited[nodeMap.get(t)] == 0) { + oneDFS(t, source); + } + } + } + } + + public DRedTcRelation getTcRelation() { + return this.tc; + } + + @Override + public void edgeInserted(V source, V target) { + deriveTc(); + } + + @Override + public void edgeDeleted(V source, V target) { + deriveTc(); + } + + @Override + public void nodeInserted(V n) { + deriveTc(); + } + + @Override + public void nodeDeleted(V n) { + deriveTc(); + } +} diff --git a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/scc/PKAlg.java b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/scc/PKAlg.java index babcec7d..50817d0d 100644 --- a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/scc/PKAlg.java +++ b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/scc/PKAlg.java @@ -9,184 +9,180 @@ * Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.itc.alg.misc.scc; - - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; - +package org.eclipse.incquery.runtime.base.itc.alg.misc.scc; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; + import org.eclipse.incquery.runtime.base.itc.igraph.IBiDirectionalGraphDataSource; import org.eclipse.incquery.runtime.base.itc.igraph.IBiDirectionalWrapper; import org.eclipse.incquery.runtime.base.itc.igraph.IGraphDataSource; import org.eclipse.incquery.runtime.base.itc.igraph.IGraphObserver; - -public class PKAlg implements IGraphObserver { - - private static final long serialVersionUID = -4382533946686076317L; - - /** - * Maps the nodes to their indicies. - */ - private HashMap node2index; - private HashMap index2node; - private HashMap node2mark; - - /** - * Maps the index of a node to the index in the topsort. - */ - private HashMap index2topsort; - private HashMap topsort2index; - - /** - * Index associated to the inserted nodes (incrementing with every insertion). - */ - private int index; - - /** - * Index within the topsort for the target node when edge insertion occurs. - */ - private int lower_bound; - - /** - * Index within the topsort for the source node when edge insertion occurs. - */ - private int upper_bound; - - private ArrayList RF; - private ArrayList RB; - private IBiDirectionalGraphDataSource gds; - - public PKAlg(IGraphDataSource gds) { - if (gds instanceof IBiDirectionalGraphDataSource) { - this.gds = (IBiDirectionalGraphDataSource) gds; - } - else { - this.gds = new IBiDirectionalWrapper(gds); - } - - node2mark = new HashMap(); - node2index = new HashMap(); - index2node = new HashMap(); - index2topsort = new HashMap(); - topsort2index = new HashMap(); - index = 0; - - gds.attachObserver(this); - } - - - @Override - public void edgeInserted(V source, V target) { - - RF = new ArrayList(); - RB = new ArrayList(); - - lower_bound = index2topsort.get(node2index.get(target)); - upper_bound = index2topsort.get(node2index.get(source)); - - if (lower_bound < upper_bound) { - dfsForward(target); - dfsBackward(source); - reorder(); - } - } - - private ArrayList getIndicies(ArrayList list) { - ArrayList indicies = new ArrayList(); - - for (V n : list) - indicies.add(index2topsort.get(node2index.get(n))); - - return indicies; - } - - private void reorder() { - - Collections.reverse(RB); - - //azon csomopontok indexei amelyek sorrendje nem jo - ArrayList L = getIndicies(RF); - L.addAll(getIndicies(RB)); - Collections.sort(L); - - for (int i = 0;i getTopSort() { - List topsort = new ArrayList(); - - for (int i : topsort2index.values()) { - topsort.add(index2node.get(i)); - } - - return topsort; - } - - private void dfsBackward(V node) { - node2mark.put(node, true); - RB.add(node); - - List sources = gds.getSourceNodes(node); - - if (sources != null) - for (V sn : sources) { - int top_id = index2topsort.get(node2index.get(sn)); - - if (!node2mark.get(sn) && lower_bound < top_id) - dfsBackward(sn); - } - } - - - private void dfsForward(V node) { - node2mark.put(node, true); - RF.add(node); - - List targets = gds.getTargetNodes(node); - - if (targets != null) - for (V tn : targets) { - int top_id = index2topsort.get(node2index.get(tn)); - - if (top_id == upper_bound) - System.out.println("!!!Cycle detected!!!"); - else if (!node2mark.get(tn) && top_id < upper_bound) - dfsForward(tn); - } - } - - @Override - public void edgeDeleted(V source, V target) { - //Edge deletion does not affect topsort - } - - @Override - public void nodeInserted(V n) { - node2mark.put(n, false); - node2index.put(n, index); - index2node.put(index, n); - index2topsort.put(index, index); - topsort2index.put(index, index); - index++; - } - - @Override - public void nodeDeleted(V n) { - node2mark.remove(n); - int node_id = node2index.remove(n); - index2node.remove(node_id); - int top_id = index2topsort.remove(node_id); - topsort2index.remove(top_id); - } -} + +public class PKAlg implements IGraphObserver { + + private static final long serialVersionUID = -4382533946686076317L; + + /** + * Maps the nodes to their indicies. + */ + private HashMap node2index; + private HashMap index2node; + private HashMap node2mark; + + /** + * Maps the index of a node to the index in the topsort. + */ + private HashMap index2topsort; + private HashMap topsort2index; + + /** + * Index associated to the inserted nodes (incrementing with every insertion). + */ + private int index; + + /** + * Index within the topsort for the target node when edge insertion occurs. + */ + private int lower_bound; + + /** + * Index within the topsort for the source node when edge insertion occurs. + */ + private int upper_bound; + + private ArrayList RF; + private ArrayList RB; + private IBiDirectionalGraphDataSource gds; + + public PKAlg(IGraphDataSource gds) { + if (gds instanceof IBiDirectionalGraphDataSource) { + this.gds = (IBiDirectionalGraphDataSource) gds; + } else { + this.gds = new IBiDirectionalWrapper(gds); + } + + node2mark = new HashMap(); + node2index = new HashMap(); + index2node = new HashMap(); + index2topsort = new HashMap(); + topsort2index = new HashMap(); + index = 0; + + gds.attachObserver(this); + } + + @Override + public void edgeInserted(V source, V target) { + + RF = new ArrayList(); + RB = new ArrayList(); + + lower_bound = index2topsort.get(node2index.get(target)); + upper_bound = index2topsort.get(node2index.get(source)); + + if (lower_bound < upper_bound) { + dfsForward(target); + dfsBackward(source); + reorder(); + } + } + + private ArrayList getIndicies(ArrayList list) { + ArrayList indicies = new ArrayList(); + + for (V n : list) + indicies.add(index2topsort.get(node2index.get(n))); + + return indicies; + } + + private void reorder() { + + Collections.reverse(RB); + + // azon csomopontok indexei amelyek sorrendje nem jo + ArrayList L = getIndicies(RF); + L.addAll(getIndicies(RB)); + Collections.sort(L); + + for (int i = 0; i < RB.size(); i++) { + index2topsort.put(node2index.get(RB.get(i)), L.get(i)); + topsort2index.put(L.get(i), node2index.get(RB.get(i))); + } + + for (int i = 0; i < RF.size(); i++) { + index2topsort.put(node2index.get(RF.get(i)), L.get(i + RB.size())); + topsort2index.put(L.get(i + RB.size()), node2index.get(RF.get(i))); + } + } + + @SuppressWarnings("unused") + private List getTopSort() { + List topsort = new ArrayList(); + + for (int i : topsort2index.values()) { + topsort.add(index2node.get(i)); + } + + return topsort; + } + + private void dfsBackward(V node) { + node2mark.put(node, true); + RB.add(node); + + List sources = gds.getSourceNodes(node); + + if (sources != null) + for (V sn : sources) { + int top_id = index2topsort.get(node2index.get(sn)); + + if (!node2mark.get(sn) && lower_bound < top_id) + dfsBackward(sn); + } + } + + private void dfsForward(V node) { + node2mark.put(node, true); + RF.add(node); + + List targets = gds.getTargetNodes(node); + + if (targets != null) + for (V tn : targets) { + int top_id = index2topsort.get(node2index.get(tn)); + + if (top_id == upper_bound) + System.out.println("!!!Cycle detected!!!"); + else if (!node2mark.get(tn) && top_id < upper_bound) + dfsForward(tn); + } + } + + @Override + public void edgeDeleted(V source, V target) { + // Edge deletion does not affect topsort + } + + @Override + public void nodeInserted(V n) { + node2mark.put(n, false); + node2index.put(n, index); + index2node.put(index, n); + index2topsort.put(index, index); + topsort2index.put(index, index); + index++; + } + + @Override + public void nodeDeleted(V n) { + node2mark.remove(n); + int node_id = node2index.remove(n); + index2node.remove(node_id); + int top_id = index2topsort.remove(node_id); + topsort2index.remove(top_id); + } +} diff --git a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/scc/SCC.java b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/scc/SCC.java index 509ee425..e8251b8b 100644 --- a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/scc/SCC.java +++ b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/scc/SCC.java @@ -9,8 +9,8 @@ * Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.itc.alg.misc.scc; - +package org.eclipse.incquery.runtime.base.itc.alg.misc.scc; + import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -20,275 +20,278 @@ import java.util.Stack; import org.eclipse.incquery.runtime.base.itc.igraph.IGraphDataSource; - -/** - * Efficient algorithms to compute the Strongly Connected Components in a directed graph. - * - * @author Tamas Szabo - * - * @param the type parameter of the nodes in the graph - */ -public class SCC { - - public static long sccId = 0; - - /** - * Computes the SCCs for the given graph and returns them as a multiset. - * (Iterative version of Tarjan's algorithm) - * - * @param g the directed graph data source - * @return the set of SCCs - */ - public static SCCResult computeSCC(IGraphDataSource g) { - int index = 0; - Set> ret = new HashSet>(); - Map nodeMap = new HashMap(); - Map> targetNodeMap = new HashMap>(); - Map> notVisitedMap = new HashMap>(); - - //stores the nodes during the traversal - Stack nodeStack = new Stack(); - //stores the nodes that are in the same strongly connected component - Stack sccStack = new Stack(); - boolean sink = false, finishedTraversal = true; - - //initialize all nodes with 0 index and 0 lowlink - Set allNodes = g.getAllNodes(); - for (V n : allNodes) { - nodeMap.put(n, new SCCProperty(0, 0)); - } - - for (V n : allNodes) { - if (nodeMap.get(n).getIndex() == 0) { - - index++; - sccStack.push(n); - nodeMap.get(n).setIndex(index); - nodeMap.get(n).setLowlink(index); - - notVisitedMap.put(n, new HashSet()); - - List targetNodes = g.getTargetNodes(n); - - if (targetNodes != null) { - targetNodeMap.put(n, new ArrayList(targetNodes)); - } - - nodeStack.push(n); - - while(!nodeStack.isEmpty()) { - - V currentNode = nodeStack.peek(); - sink = false; finishedTraversal = false; - SCCProperty prop = nodeMap.get(currentNode); - - //if node is not visited yet - if (nodeMap.get(currentNode).getIndex() == 0) { - index++; - sccStack.push(currentNode); - prop.setIndex(index); - prop.setLowlink(index); - - notVisitedMap.put(currentNode, new HashSet()); - - //storing the target nodes of the actual node - if (g.getTargetNodes(currentNode) != null) { - targetNodeMap.put(currentNode, new ArrayList(g.getTargetNodes(currentNode))); - } - } - - if (targetNodeMap.get(currentNode) != null) { - - if (targetNodeMap.get(currentNode).size() == 0) { - targetNodeMap.remove(currentNode); - - //remove node from stack, the exploration of its children has finished - nodeStack.pop(); - - List targets = g.getTargetNodes(currentNode); - if (targets != null) { - for (V targetNode : g.getTargetNodes(currentNode)) { - if (notVisitedMap.get(currentNode).contains(targetNode)) { - prop.setLowlink(Math.min(prop.getLowlink(), nodeMap.get(targetNode).getLowlink())); - } else if (sccStack.contains(targetNode)) { - prop.setLowlink(Math.min(prop.getLowlink(), nodeMap.get(targetNode).getIndex())); - } - } - } - - finishedTraversal = true; - } - else { - //push next node to stack - V targetNode = targetNodeMap.get(currentNode).remove(0); - //if _t has not yet been visited - if (nodeMap.get(targetNode).getIndex() == 0) { - notVisitedMap.get(currentNode).add(targetNode); - nodeStack.add(targetNode); - } - } - } - //if _node has no target nodes - else { - nodeStack.pop(); - sink = true; - } - - //create scc if node is a sink or an scc has been found - if ((sink || finishedTraversal) && (prop.getLowlink() == prop.getIndex())) { - Set sc = new HashSet(); - V targetNode = null; - - do { - targetNode = sccStack.pop(); - sc.add(targetNode); - } while (!targetNode.equals(currentNode)); - - ret.add(sc); - } - } - } - } - - return new SCCResult(ret, g); - } - -// static class SCCComputationTask extends RecursiveTask>> { -// -// private static final long serialVersionUID = -7247372604863927633L; -// private IBiDirectionalGraphDataSource graph; -// -// public SCCComputationTask(IBiDirectionalGraphDataSource graph) { -// this.graph = graph; -// } -// -// @Override -// protected Set> compute() { -// Set> multiSet = null; -// //System.out.println(Thread.currentThread().getName()+" nodes: "+graph.getAllNodes()); -// V node = graph.getAllNodes().iterator().next(); -// -// Set allNodes = new HashSet(); -// allNodes.addAll(graph.getAllNodes()); -// Set sourceNodes = BFS.reachableSources(graph, node); -// Set targetNodes = BFS.reachableTargets(graph, node); -// -// Set intersection = setIntersection(sourceNodes, targetNodes); -// //System.out.println(Thread.currentThread().getName()+" isect "+intersection); -// if (intersection.size() == graph.getAllNodes().size()) { -// //Recursion ends -// multiSet = new HashSet>(); -// multiSet.add(intersection); -// } -// else { -// allNodes.removeAll(sourceNodes); -// allNodes.removeAll(targetNodes); -// sourceNodes.removeAll(intersection); -// targetNodes.removeAll(intersection); -// -// SCCComputationTask task1 = null; -// Set> task1Result = null; -// -// SCCComputationTask task2 = null; -// Set> task2Result = null; -// -// SCCComputationTask task3 = null; -// Set> task3Result = null; -// -// //DCSC(Pred(G, v) \ SCC) -// if (!sourceNodes.isEmpty()) { -// task1 = new SCCComputationTask(getGraphOfSCC(graph, sourceNodes)); -// task1.fork(); -// } -// //DCSC(Desc(G, v) \ SCC) -// if (!targetNodes.isEmpty()) { -// task2 = new SCCComputationTask(getGraphOfSCC(graph, targetNodes)); -// task2.fork(); -// } -// //DCSC(Rem(G, v)) -// if (!allNodes.isEmpty()) { -// task3 = new SCCComputationTask(getGraphOfSCC(graph, allNodes)); -// task3.fork(); -// } -// -// if (task1 != null) task1Result = task1.join(); -// if (task2 != null) task2Result = task2.join(); -// if (task3 != null) task3Result = task3.join(); -// -// multiSet = multisetUnion(task1Result, multisetUnion(task2Result, task3Result)); -// multiSet.add(intersection); -// } -// -// return multiSet; -// } -// -// } -// -// private static Set setIntersection(Set sourceNodes, Set targetNodes) { -// HashSet retSet = new HashSet(); -// -// for (V e : sourceNodes) { -// if (targetNodes.contains(e)) { -// retSet.add(e); -// } -// } -// -// return retSet; -// } -// -// private static Set> multisetUnion(Set> m1, Set> m2) { -// Set> multiSet = new HashSet>(); -// -// if (m1 != null) { -// for (Set s : m1) { -// multiSet.add(s); -// } -// } -// if (m2 != null) { -// for (Set s : m2) { -// multiSet.add(s); -// } -// } -// -// return multiSet; -// } -// -// private static IBiDirectionalGraphDataSource getGraphOfSCC(IBiDirectionalGraphDataSource graph, Set scc) { -// Graph g = new Graph(); -// -// for (V node : scc) { -// g.insertNode(node); -// } -// -// for (V src : graph.getAllNodes()) { -// for (V trg : graph.getTargetNodes(src)) { -// if (scc.contains(src) && scc.contains(trg)) { -// g.insertEdge(src, trg); -// } -// } -// } -// -// IBiDirectionalGraphDataSource bG = new IBiDirectionalWrapper(g); -// return bG; -// } -// -// /** -// * Parallel algorithm to compute the Strongly Connected Components in a directed graph. -// * The implementation is based on the Fork Join Framework. -// * -// * Note that the implementation relies on the correct implementation of the equals method of the type paramter's class. -// * -// * @param g the directed graph datasource -// * @return the set of SCCs -// */ -// public static SCCResult parallelSCCComputation(IBiDirectionalGraphDataSource graph) { -// ForkJoinPool pool = new ForkJoinPool(); -// SCCComputationTask task = new SCCComputationTask(graph); -// pool.invoke(task); -// -// return new SCCResult(task.join(), graph); -// } - - -} +/** + * Efficient algorithms to compute the Strongly Connected Components in a directed graph. + * + * @author Tamas Szabo + * + * @param + * the type parameter of the nodes in the graph + */ +public class SCC { + + public static long sccId = 0; + + /** + * Computes the SCCs for the given graph and returns them as a multiset. (Iterative version of Tarjan's algorithm) + * + * @param g + * the directed graph data source + * @return the set of SCCs + */ + public static SCCResult computeSCC(IGraphDataSource g) { + int index = 0; + Set> ret = new HashSet>(); + Map nodeMap = new HashMap(); + Map> targetNodeMap = new HashMap>(); + Map> notVisitedMap = new HashMap>(); + + // stores the nodes during the traversal + Stack nodeStack = new Stack(); + // stores the nodes that are in the same strongly connected component + Stack sccStack = new Stack(); + + boolean sink = false, finishedTraversal = true; + + // initialize all nodes with 0 index and 0 lowlink + Set allNodes = g.getAllNodes(); + for (V n : allNodes) { + nodeMap.put(n, new SCCProperty(0, 0)); + } + + for (V n : allNodes) { + if (nodeMap.get(n).getIndex() == 0) { + + index++; + sccStack.push(n); + nodeMap.get(n).setIndex(index); + nodeMap.get(n).setLowlink(index); + + notVisitedMap.put(n, new HashSet()); + + List targetNodes = g.getTargetNodes(n); + + if (targetNodes != null) { + targetNodeMap.put(n, new ArrayList(targetNodes)); + } + + nodeStack.push(n); + + while (!nodeStack.isEmpty()) { + + V currentNode = nodeStack.peek(); + sink = false; + finishedTraversal = false; + SCCProperty prop = nodeMap.get(currentNode); + + // if node is not visited yet + if (nodeMap.get(currentNode).getIndex() == 0) { + index++; + sccStack.push(currentNode); + prop.setIndex(index); + prop.setLowlink(index); + + notVisitedMap.put(currentNode, new HashSet()); + + // storing the target nodes of the actual node + if (g.getTargetNodes(currentNode) != null) { + targetNodeMap.put(currentNode, new ArrayList(g.getTargetNodes(currentNode))); + } + } + + if (targetNodeMap.get(currentNode) != null) { + + if (targetNodeMap.get(currentNode).size() == 0) { + targetNodeMap.remove(currentNode); + + // remove node from stack, the exploration of its children has finished + nodeStack.pop(); + + List targets = g.getTargetNodes(currentNode); + if (targets != null) { + for (V targetNode : g.getTargetNodes(currentNode)) { + if (notVisitedMap.get(currentNode).contains(targetNode)) { + prop.setLowlink(Math.min(prop.getLowlink(), nodeMap.get(targetNode) + .getLowlink())); + } else if (sccStack.contains(targetNode)) { + prop.setLowlink(Math.min(prop.getLowlink(), nodeMap.get(targetNode).getIndex())); + } + } + } + + finishedTraversal = true; + } else { + // push next node to stack + V targetNode = targetNodeMap.get(currentNode).remove(0); + // if _t has not yet been visited + if (nodeMap.get(targetNode).getIndex() == 0) { + notVisitedMap.get(currentNode).add(targetNode); + nodeStack.add(targetNode); + } + } + } + // if _node has no target nodes + else { + nodeStack.pop(); + sink = true; + } + + // create scc if node is a sink or an scc has been found + if ((sink || finishedTraversal) && (prop.getLowlink() == prop.getIndex())) { + Set sc = new HashSet(); + V targetNode = null; + + do { + targetNode = sccStack.pop(); + sc.add(targetNode); + } while (!targetNode.equals(currentNode)); + + ret.add(sc); + } + } + } + } + + return new SCCResult(ret, g); + } + + // static class SCCComputationTask extends RecursiveTask>> { + // + // private static final long serialVersionUID = -7247372604863927633L; + // private IBiDirectionalGraphDataSource graph; + // + // public SCCComputationTask(IBiDirectionalGraphDataSource graph) { + // this.graph = graph; + // } + // + // @Override + // protected Set> compute() { + // Set> multiSet = null; + // //System.out.println(Thread.currentThread().getName()+" nodes: "+graph.getAllNodes()); + // V node = graph.getAllNodes().iterator().next(); + // + // Set allNodes = new HashSet(); + // allNodes.addAll(graph.getAllNodes()); + // Set sourceNodes = BFS.reachableSources(graph, node); + // Set targetNodes = BFS.reachableTargets(graph, node); + // + // Set intersection = setIntersection(sourceNodes, targetNodes); + // //System.out.println(Thread.currentThread().getName()+" isect "+intersection); + // if (intersection.size() == graph.getAllNodes().size()) { + // //Recursion ends + // multiSet = new HashSet>(); + // multiSet.add(intersection); + // } + // else { + // allNodes.removeAll(sourceNodes); + // allNodes.removeAll(targetNodes); + // sourceNodes.removeAll(intersection); + // targetNodes.removeAll(intersection); + // + // SCCComputationTask task1 = null; + // Set> task1Result = null; + // + // SCCComputationTask task2 = null; + // Set> task2Result = null; + // + // SCCComputationTask task3 = null; + // Set> task3Result = null; + // + // //DCSC(Pred(G, v) \ SCC) + // if (!sourceNodes.isEmpty()) { + // task1 = new SCCComputationTask(getGraphOfSCC(graph, sourceNodes)); + // task1.fork(); + // } + // //DCSC(Desc(G, v) \ SCC) + // if (!targetNodes.isEmpty()) { + // task2 = new SCCComputationTask(getGraphOfSCC(graph, targetNodes)); + // task2.fork(); + // } + // //DCSC(Rem(G, v)) + // if (!allNodes.isEmpty()) { + // task3 = new SCCComputationTask(getGraphOfSCC(graph, allNodes)); + // task3.fork(); + // } + // + // if (task1 != null) task1Result = task1.join(); + // if (task2 != null) task2Result = task2.join(); + // if (task3 != null) task3Result = task3.join(); + // + // multiSet = multisetUnion(task1Result, multisetUnion(task2Result, task3Result)); + // multiSet.add(intersection); + // } + // + // return multiSet; + // } + // + // } + // + // private static Set setIntersection(Set sourceNodes, Set targetNodes) { + // HashSet retSet = new HashSet(); + // + // for (V e : sourceNodes) { + // if (targetNodes.contains(e)) { + // retSet.add(e); + // } + // } + // + // return retSet; + // } + // + // private static Set> multisetUnion(Set> m1, Set> m2) { + // Set> multiSet = new HashSet>(); + // + // if (m1 != null) { + // for (Set s : m1) { + // multiSet.add(s); + // } + // } + // if (m2 != null) { + // for (Set s : m2) { + // multiSet.add(s); + // } + // } + // + // return multiSet; + // } + // + // private static IBiDirectionalGraphDataSource getGraphOfSCC(IBiDirectionalGraphDataSource graph, Set + // scc) { + // Graph g = new Graph(); + // + // for (V node : scc) { + // g.insertNode(node); + // } + // + // for (V src : graph.getAllNodes()) { + // for (V trg : graph.getTargetNodes(src)) { + // if (scc.contains(src) && scc.contains(trg)) { + // g.insertEdge(src, trg); + // } + // } + // } + // + // IBiDirectionalGraphDataSource bG = new IBiDirectionalWrapper(g); + // return bG; + // } + // + // /** + // * Parallel algorithm to compute the Strongly Connected Components in a directed graph. + // * The implementation is based on the Fork Join Framework. + // * + // * Note that the implementation relies on the correct implementation of the equals method of the type paramter's + // class. + // * + // * @param g the directed graph datasource + // * @return the set of SCCs + // */ + // public static SCCResult parallelSCCComputation(IBiDirectionalGraphDataSource graph) { + // ForkJoinPool pool = new ForkJoinPool(); + // SCCComputationTask task = new SCCComputationTask(graph); + // pool.invoke(task); + // + // return new SCCResult(task.join(), graph); + // } + +} diff --git a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/scc/SCCProperty.java b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/scc/SCCProperty.java index 25ac70b4..fed0efb9 100644 --- a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/scc/SCCProperty.java +++ b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/scc/SCCProperty.java @@ -9,31 +9,31 @@ * Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.itc.alg.misc.scc; - -public class SCCProperty { - private int index; - private int lowlink; - - public SCCProperty(int index, int lowlink) { - super(); - this.index = index; - this.lowlink = lowlink; - } - - public int getIndex() { - return index; - } - - public void setIndex(int index) { - this.index = index; - } - - public int getLowlink() { - return lowlink; - } - - public void setLowlink(int lowlink) { - this.lowlink = lowlink; - } -} +package org.eclipse.incquery.runtime.base.itc.alg.misc.scc; + +public class SCCProperty { + private int index; + private int lowlink; + + public SCCProperty(int index, int lowlink) { + super(); + this.index = index; + this.lowlink = lowlink; + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } + + public int getLowlink() { + return lowlink; + } + + public void setLowlink(int lowlink) { + this.lowlink = lowlink; + } +} diff --git a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/scc/SCCResult.java b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/scc/SCCResult.java index 68c70968..be192dfd 100644 --- a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/scc/SCCResult.java +++ b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/scc/SCCResult.java @@ -9,74 +9,73 @@ * Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.itc.alg.misc.scc; - - -import java.util.Set; - +package org.eclipse.incquery.runtime.base.itc.alg.misc.scc; + +import java.util.Set; + import org.eclipse.incquery.runtime.base.itc.igraph.IGraphDataSource; - -public class SCCResult { - - private Set> sccs; - private IGraphDataSource gds; - - public SCCResult(Set> sccs, IGraphDataSource gds) { - this.sccs = sccs; - this.gds = gds; - } - - public Set> getSccs() { - return sccs; - } - - public int getSCCCount() { - return sccs.size(); - } - - public double getAverageNodeCount() { - double a = 0; - - for (Set s : sccs) { - a += s.size(); - } - - return a / sccs.size(); - } - - public double getAverageEdgeCount() { - long edgeSum = 0; - - for (Set scc : sccs) { - for (V source : scc) { - for (V target : gds.getTargetNodes(source)) { - if (scc.contains(target)) - edgeSum++; - } - } - } - - return (double) edgeSum / (double) sccs.size(); - } - - public int getBiggestSCCSize() { - int max = 0; - - for (Set scc : sccs) { - if (scc.size() > max) - max = scc.size(); - } - - return max; - } - - public long getSumOfSquares() { - long sum = 0; - - for (Set scc : sccs) { - sum += scc.size() * scc.size(); - } - - return sum; - } -} + +public class SCCResult { + + private Set> sccs; + private IGraphDataSource gds; + + public SCCResult(Set> sccs, IGraphDataSource gds) { + this.sccs = sccs; + this.gds = gds; + } + + public Set> getSccs() { + return sccs; + } + + public int getSCCCount() { + return sccs.size(); + } + + public double getAverageNodeCount() { + double a = 0; + + for (Set s : sccs) { + a += s.size(); + } + + return a / sccs.size(); + } + + public double getAverageEdgeCount() { + long edgeSum = 0; + + for (Set scc : sccs) { + for (V source : scc) { + for (V target : gds.getTargetNodes(source)) { + if (scc.contains(target)) + edgeSum++; + } + } + } + + return (double) edgeSum / (double) sccs.size(); + } + + public int getBiggestSCCSize() { + int max = 0; + + for (Set scc : sccs) { + if (scc.size() > max) + max = scc.size(); + } + + return max; + } + + public long getSumOfSquares() { + long sum = 0; + + for (Set scc : sccs) { + sum += scc.size() * scc.size(); + } + + return sum; + } +} diff --git a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/topsort/TopSort.java b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/topsort/TopSort.java index e465e568..606bb036 100644 --- a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/topsort/TopSort.java +++ b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/alg/misc/topsort/TopSort.java @@ -9,91 +9,91 @@ * Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.itc.alg.misc.topsort; - - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; - +package org.eclipse.incquery.runtime.base.itc.alg.misc.topsort; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; + import org.eclipse.incquery.runtime.base.itc.igraph.IGraphDataSource; - -public class TopSort { - - private IGraphDataSource gds; - private HashMap forwardNodeMap; - private HashMap backwardNodeMap; - private int nodeCount; - - private int[] visited; - private int[] finishNumber; - private int[] depthNumber; - private int[] sourceNumber; - - private int depthCount = 0; - private int finishCount = 0; - - private List topologicalSorting = null; - - public TopSort(IGraphDataSource g) { - this.gds = g; - nodeCount = gds.getAllNodes().size(); - - this.topologicalSorting = new ArrayList(); - - visited = new int[nodeCount]; - finishNumber = new int[nodeCount]; - depthNumber = new int[nodeCount]; - sourceNumber = new int[nodeCount]; - - forwardNodeMap = new HashMap(); - backwardNodeMap = new HashMap(); - - int j = 0; - for (V n : gds.getAllNodes()) { - forwardNodeMap.put(j, n); - backwardNodeMap.put(n, j); - j++; - } - - for (int i=0;i targets = gds.getTargetNodes(forwardNodeMap.get(v)); - if (targets != null) { - for (V t : targets) { - - int u = backwardNodeMap.get(t); - sourceNumber[u] = v; - if (visited[u] == 0) oneDFS(u); - } - } - finishNumber[v] = ++finishCount; - topologicalSorting.add(forwardNodeMap.get(v)); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - public static List getTopologicalSorting(IGraphDataSource g) { - TopSort da = new TopSort(g); - da.doDFS(); - return da.topologicalSorting; - } -} - + +public class TopSort { + + private IGraphDataSource gds; + private HashMap forwardNodeMap; + private HashMap backwardNodeMap; + private int nodeCount; + + private int[] visited; + private int[] finishNumber; + private int[] depthNumber; + private int[] sourceNumber; + + private int depthCount = 0; + private int finishCount = 0; + + private List topologicalSorting = null; + + public TopSort(IGraphDataSource g) { + this.gds = g; + nodeCount = gds.getAllNodes().size(); + + this.topologicalSorting = new ArrayList(); + + visited = new int[nodeCount]; + finishNumber = new int[nodeCount]; + depthNumber = new int[nodeCount]; + sourceNumber = new int[nodeCount]; + + forwardNodeMap = new HashMap(); + backwardNodeMap = new HashMap(); + + int j = 0; + for (V n : gds.getAllNodes()) { + forwardNodeMap.put(j, n); + backwardNodeMap.put(n, j); + j++; + } + + for (int i = 0; i < nodeCount; i++) { + visited[i] = 0; + finishNumber[i] = -1; + depthNumber[i] = -1; + sourceNumber[i] = -1; + } + } + + public void doDFS() { + for (int i = 0; i < nodeCount; i++) { + if (visited[i] == 0) + oneDFS(i); + } + + Collections.reverse(topologicalSorting); + } + + private void oneDFS(int v) { + visited[v] = 1; + depthNumber[v] = ++depthCount; + List targets = gds.getTargetNodes(forwardNodeMap.get(v)); + if (targets != null) { + for (V t : targets) { + + int u = backwardNodeMap.get(t); + sourceNumber[u] = v; + if (visited[u] == 0) + oneDFS(u); + } + } + finishNumber[v] = ++finishCount; + topologicalSorting.add(forwardNodeMap.get(v)); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public static List getTopologicalSorting(IGraphDataSource g) { + TopSort da = new TopSort(g); + da.doDFS(); + return da.topologicalSorting; + } +} diff --git a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/graphimpl/Graph.java b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/graphimpl/Graph.java index a576cd4a..4c3a96cf 100644 --- a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/graphimpl/Graph.java +++ b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/graphimpl/Graph.java @@ -9,8 +9,8 @@ * Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.itc.graphimpl; - +package org.eclipse.incquery.runtime.base.itc.graphimpl; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -20,160 +20,158 @@ import org.eclipse.incquery.runtime.base.itc.igraph.IBiDirectionalGraphDataSource; import org.eclipse.incquery.runtime.base.itc.igraph.IGraphDataSource; import org.eclipse.incquery.runtime.base.itc.igraph.IGraphObserver; - -public class Graph implements IGraphDataSource, IBiDirectionalGraphDataSource { - - private static final long serialVersionUID = 1L; - private Map> edgeList; - private Map> edgeListReversed; - private ArrayList> observers; - - public Graph() { - this.edgeList = new HashMap>(); - this.edgeListReversed = new HashMap>(); - this.observers = new ArrayList>(); - } - - public void insertEdge(V source, V target) { - //insert nodes if necessary -// if (!edgeList.containsKey(source)) { -// this.insertNode(source); -// } -// if (!edgeList.containsKey(target)) { -// this.insertNode(target); -// } - - List outgoingEdges = edgeList.get(source); - if (outgoingEdges == null) { - outgoingEdges = new ArrayList(); - outgoingEdges.add(target); - edgeList.put(source, outgoingEdges); - } - else { - outgoingEdges.add(target); - } - - List incomingEdges = edgeListReversed.get(target); - if (incomingEdges == null) { - incomingEdges = new ArrayList(); - incomingEdges.add(source); - edgeListReversed.put(target, incomingEdges); - } - else { - incomingEdges.add(source); - } - - for (IGraphObserver go : this.observers) { - go.edgeInserted(source, target); - } - } - - public void deleteEdge(V source, V target) { - - boolean containedEdge = false; - List incomingEdges = edgeListReversed.get(target); - if (incomingEdges != null) { - containedEdge = incomingEdges.remove(source); - } - - List outgoingEdges = edgeList.get(source); - if (outgoingEdges != null) { - outgoingEdges.remove(target); - } - - if (containedEdge) { - for (IGraphObserver go : this.observers) { - go.edgeDeleted(source, target); - } - } - } - - public void insertNode(V node) { - if (!edgeList.containsKey(node)) { - this.edgeList.put(node, null); - } - if (!edgeListReversed.containsKey(node)) { - this.edgeListReversed.put(node, null); - } - - for (IGraphObserver go : this.observers) { - go.nodeInserted(node); - } - } - - public void deleteNode(V node) { - boolean containedNode = edgeList.containsKey(node); - List incomingEdges = edgeListReversed.get(node); - List outgoingEdges = edgeList.get(node); - - if (incomingEdges != null) { - List tmp = new ArrayList(incomingEdges); - - for (V s : tmp) { - this.deleteEdge(s, node); - } - } - if (outgoingEdges != null) { - List tmp = new ArrayList(outgoingEdges); - - for (V t : tmp) { - this.deleteEdge(node, t); - } - } - - if (containedNode) { - for (IGraphObserver go : this.observers) { - go.nodeDeleted(node); - } - } - } - - public void attachObserver(IGraphObserver go) { - this.observers.add(go); - } - - public void detachObserver(IGraphObserver go) { - this.observers.remove(go); - } - - @Override - public Set getAllNodes() { - return this.edgeList.keySet(); - } - - @Override - public List getTargetNodes(V source) { - return this.edgeList.get(source); - } - - @Override - public List getSourceNodes(V target) { - return this.edgeListReversed.get(target); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("nodes = "); - for (V n : this.edgeList.keySet()) { - sb.append(n.toString()+" "); - } - sb.append(" edges = "); - for (V source : this.edgeList.keySet()) { - if (edgeList.get(source) != null) { - for (V target : this.edgeList.get(source)) { - sb.append("("+source+","+target+") "); - } - } - } - return sb.toString(); - } - - public Integer[] deleteRandomEdge() { - return null; - } - - public Integer[] insertRandomEdge() { - return null; - } -} + +public class Graph implements IGraphDataSource, IBiDirectionalGraphDataSource { + + private static final long serialVersionUID = 1L; + private Map> edgeList; + private Map> edgeListReversed; + private ArrayList> observers; + + public Graph() { + this.edgeList = new HashMap>(); + this.edgeListReversed = new HashMap>(); + this.observers = new ArrayList>(); + } + + public void insertEdge(V source, V target) { + // insert nodes if necessary + // if (!edgeList.containsKey(source)) { + // this.insertNode(source); + // } + // if (!edgeList.containsKey(target)) { + // this.insertNode(target); + // } + + List outgoingEdges = edgeList.get(source); + if (outgoingEdges == null) { + outgoingEdges = new ArrayList(); + outgoingEdges.add(target); + edgeList.put(source, outgoingEdges); + } else { + outgoingEdges.add(target); + } + + List incomingEdges = edgeListReversed.get(target); + if (incomingEdges == null) { + incomingEdges = new ArrayList(); + incomingEdges.add(source); + edgeListReversed.put(target, incomingEdges); + } else { + incomingEdges.add(source); + } + + for (IGraphObserver go : this.observers) { + go.edgeInserted(source, target); + } + } + + public void deleteEdge(V source, V target) { + + boolean containedEdge = false; + List incomingEdges = edgeListReversed.get(target); + if (incomingEdges != null) { + containedEdge = incomingEdges.remove(source); + } + + List outgoingEdges = edgeList.get(source); + if (outgoingEdges != null) { + outgoingEdges.remove(target); + } + + if (containedEdge) { + for (IGraphObserver go : this.observers) { + go.edgeDeleted(source, target); + } + } + } + + public void insertNode(V node) { + if (!edgeList.containsKey(node)) { + this.edgeList.put(node, null); + } + if (!edgeListReversed.containsKey(node)) { + this.edgeListReversed.put(node, null); + } + + for (IGraphObserver go : this.observers) { + go.nodeInserted(node); + } + } + + public void deleteNode(V node) { + boolean containedNode = edgeList.containsKey(node); + List incomingEdges = edgeListReversed.get(node); + List outgoingEdges = edgeList.get(node); + + if (incomingEdges != null) { + List tmp = new ArrayList(incomingEdges); + + for (V s : tmp) { + this.deleteEdge(s, node); + } + } + if (outgoingEdges != null) { + List tmp = new ArrayList(outgoingEdges); + + for (V t : tmp) { + this.deleteEdge(node, t); + } + } + + if (containedNode) { + for (IGraphObserver go : this.observers) { + go.nodeDeleted(node); + } + } + } + + public void attachObserver(IGraphObserver go) { + this.observers.add(go); + } + + public void detachObserver(IGraphObserver go) { + this.observers.remove(go); + } + + @Override + public Set getAllNodes() { + return this.edgeList.keySet(); + } + + @Override + public List getTargetNodes(V source) { + return this.edgeList.get(source); + } + + @Override + public List getSourceNodes(V target) { + return this.edgeListReversed.get(target); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("nodes = "); + for (V n : this.edgeList.keySet()) { + sb.append(n.toString() + " "); + } + sb.append(" edges = "); + for (V source : this.edgeList.keySet()) { + if (edgeList.get(source) != null) { + for (V target : this.edgeList.get(source)) { + sb.append("(" + source + "," + target + ") "); + } + } + } + return sb.toString(); + } + + public Integer[] deleteRandomEdge() { + return null; + } + + public Integer[] insertRandomEdge() { + return null; + } +} diff --git a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/igraph/IBiDirectionalGraphDataSource.java b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/igraph/IBiDirectionalGraphDataSource.java index 9959bea2..97e9957d 100644 --- a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/igraph/IBiDirectionalGraphDataSource.java +++ b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/igraph/IBiDirectionalGraphDataSource.java @@ -9,27 +9,29 @@ * Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.itc.igraph; - -import java.util.List; - -/** - * This interface extends the functionality of IGraphDataSource with an extra method. - * One can query the source nodes of those edges which have a given target node. - * - * @author Tamas Szabo - * - * @param the type of the nodes in the graph - */ -public interface IBiDirectionalGraphDataSource extends IGraphDataSource{ - - /** - * Returns the source nodes of those edges that end with target. - * The nodes are returned as a {@link List} as multiple edges can be present between two arbitrary nodes. - * If no such node can be found than the method should return null. - * - * @param target the target node - * @return the list of source nodes or null if no sources can be found - */ - public List getSourceNodes(V target); -} +package org.eclipse.incquery.runtime.base.itc.igraph; + +import java.util.List; + +/** + * This interface extends the functionality of IGraphDataSource with an extra method. One can query the source nodes of + * those edges which have a given target node. + * + * @author Tamas Szabo + * + * @param + * the type of the nodes in the graph + */ +public interface IBiDirectionalGraphDataSource extends IGraphDataSource { + + /** + * Returns the source nodes of those edges that end with target. The nodes are returned as a {@link List} as + * multiple edges can be present between two arbitrary nodes. If no such node can be found than the method should + * return null. + * + * @param target + * the target node + * @return the list of source nodes or null if no sources can be found + */ + public List getSourceNodes(V target); +} diff --git a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/igraph/IBiDirectionalWrapper.java b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/igraph/IBiDirectionalWrapper.java index 5ba3a565..83946c26 100644 --- a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/igraph/IBiDirectionalWrapper.java +++ b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/igraph/IBiDirectionalWrapper.java @@ -9,99 +9,98 @@ * Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.itc.igraph; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Set; - -public class IBiDirectionalWrapper implements - IBiDirectionalGraphDataSource, IGraphObserver { - - private static final long serialVersionUID = -5771114630390029106L; - private IGraphDataSource gds; - private HashMap> backwardEdges; - - public IBiDirectionalWrapper(IGraphDataSource gds) { - this.gds = gds; - - this.backwardEdges = new HashMap>(); - - if (gds.getAllNodes() != null) { - for (V s : gds.getAllNodes()) { - for (V t : gds.getTargetNodes(s)) { - edgeInserted(s, t); - } - } - } - - gds.attachObserver(this); - } - - @Override - public void attachObserver(IGraphObserver go) { - gds.attachObserver(go); - } - - @Override - public void detachObserver(IGraphObserver go) { - gds.detachObserver(go); - } - - @Override - public Set getAllNodes() { - return gds.getAllNodes(); - } - - @Override - public List getTargetNodes(V source) { - return gds.getTargetNodes(source); - } - - @Override - public ArrayList getSourceNodes(V target) { - return backwardEdges.get(target); - } - - @Override - public void edgeInserted(V source, V target) { - - if (backwardEdges.get(target) == null) { - ArrayList tSet = new ArrayList(); - tSet.add(source); - backwardEdges.put(target, tSet); - } else { - backwardEdges.get(target).add(source); - } - - } - - @Override - public void edgeDeleted(V source, V target) { - - if (backwardEdges.containsKey(target)) { - backwardEdges.get(target).remove(source); - if (backwardEdges.get(target).size() == 0) - backwardEdges.remove(target); - } - } - - @Override - public void nodeInserted(V n) { - - } - - @Override - public void nodeDeleted(V n) { - for (V key : backwardEdges.keySet()) { - while (backwardEdges.get(key).contains(n)) - backwardEdges.get(key).remove(n); - } - } - - @Override - public String toString() { - return gds.toString(); - } -} +package org.eclipse.incquery.runtime.base.itc.igraph; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Set; + +public class IBiDirectionalWrapper implements IBiDirectionalGraphDataSource, IGraphObserver { + + private static final long serialVersionUID = -5771114630390029106L; + private IGraphDataSource gds; + private HashMap> backwardEdges; + + public IBiDirectionalWrapper(IGraphDataSource gds) { + this.gds = gds; + + this.backwardEdges = new HashMap>(); + + if (gds.getAllNodes() != null) { + for (V s : gds.getAllNodes()) { + for (V t : gds.getTargetNodes(s)) { + edgeInserted(s, t); + } + } + } + + gds.attachObserver(this); + } + + @Override + public void attachObserver(IGraphObserver go) { + gds.attachObserver(go); + } + + @Override + public void detachObserver(IGraphObserver go) { + gds.detachObserver(go); + } + + @Override + public Set getAllNodes() { + return gds.getAllNodes(); + } + + @Override + public List getTargetNodes(V source) { + return gds.getTargetNodes(source); + } + + @Override + public ArrayList getSourceNodes(V target) { + return backwardEdges.get(target); + } + + @Override + public void edgeInserted(V source, V target) { + + if (backwardEdges.get(target) == null) { + ArrayList tSet = new ArrayList(); + tSet.add(source); + backwardEdges.put(target, tSet); + } else { + backwardEdges.get(target).add(source); + } + + } + + @Override + public void edgeDeleted(V source, V target) { + + if (backwardEdges.containsKey(target)) { + backwardEdges.get(target).remove(source); + if (backwardEdges.get(target).size() == 0) + backwardEdges.remove(target); + } + } + + @Override + public void nodeInserted(V n) { + + } + + @Override + public void nodeDeleted(V n) { + for (V key : backwardEdges.keySet()) { + while (backwardEdges.get(key).contains(n)) + backwardEdges.get(key).remove(n); + } + } + + @Override + public String toString() { + return gds.toString(); + } +} diff --git a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/igraph/IGraphDataSource.java b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/igraph/IGraphDataSource.java index a6924191..ce1a9025 100644 --- a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/igraph/IGraphDataSource.java +++ b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/igraph/IGraphDataSource.java @@ -9,51 +9,55 @@ * Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.itc.igraph; - -import java.io.Serializable; -import java.util.List; -import java.util.Set; - -/** - * This interface is used to provide information about the graph to the observers. - * - * @author Tamas Szabo - * - * @param the type of the nodes in the graph - */ -public interface IGraphDataSource extends Serializable { - - /** - * Attach a new graph observer. - * - * Note that the order of attaching the observers may be important (some observers will be notified earlier than others). - * - * @param go the graph observer - */ - public void attachObserver(IGraphObserver go); - - /** - * Detach an existing observer. - * - * @param go the graph observer - */ - public void detachObserver(IGraphObserver go); - - /** - * Get all nodes of the graph. - * - * @return the set of all nodes - */ - public Set getAllNodes(); - - /** - * Get those nodes that are the target of an edge starting with source. - * The list is necessary because there can be more edges between two nodes. - * If no such edge can be found than the method returns null. - * - * @param source the source node - * @return the list of target nodes or null if no targets can be found - */ - public List getTargetNodes(V source); -} +package org.eclipse.incquery.runtime.base.itc.igraph; + +import java.io.Serializable; +import java.util.List; +import java.util.Set; + +/** + * This interface is used to provide information about the graph to the observers. + * + * @author Tamas Szabo + * + * @param + * the type of the nodes in the graph + */ +public interface IGraphDataSource extends Serializable { + + /** + * Attach a new graph observer. + * + * Note that the order of attaching the observers may be important (some observers will be notified earlier than + * others). + * + * @param go + * the graph observer + */ + public void attachObserver(IGraphObserver go); + + /** + * Detach an existing observer. + * + * @param go + * the graph observer + */ + public void detachObserver(IGraphObserver go); + + /** + * Get all nodes of the graph. + * + * @return the set of all nodes + */ + public Set getAllNodes(); + + /** + * Get those nodes that are the target of an edge starting with source. The list is necessary because there can be + * more edges between two nodes. If no such edge can be found than the method returns null. + * + * @param source + * the source node + * @return the list of target nodes or null if no targets can be found + */ + public List getTargetNodes(V source); +} diff --git a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/igraph/IGraphObserver.java b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/igraph/IGraphObserver.java index 5a44bc40..ddbb1468 100644 --- a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/igraph/IGraphObserver.java +++ b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/igraph/IGraphObserver.java @@ -9,45 +9,51 @@ * Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.itc.igraph; - -import java.io.Serializable; - -/** - * Interface GraphObserver is used to observ the changes in a graph; edge and node insertion/deleteion. - * - * @author Tamas Szabo - * - */ -public interface IGraphObserver extends Serializable { - - /** - * Used to notify when an edge is inserted into the graph. - * - * @param source the source of the edge - * @param target the target of the edge - */ - public void edgeInserted(V source, V target); - - /** - * Used to notify when an edge is deleted from the graph. - * - * @param source the source of the edge - * @param target the target of the edge - */ - public void edgeDeleted(V source, V target); - - /** - * Used to notify when a node is inserted into the graph. - * - * @param n the node - */ - public void nodeInserted(V n); - - /** - * Used to notify when a node is deleted from the graph. - * - * @param n the node - */ - public void nodeDeleted(V n); -} +package org.eclipse.incquery.runtime.base.itc.igraph; + +import java.io.Serializable; + +/** + * Interface GraphObserver is used to observ the changes in a graph; edge and node insertion/deleteion. + * + * @author Tamas Szabo + * + */ +public interface IGraphObserver extends Serializable { + + /** + * Used to notify when an edge is inserted into the graph. + * + * @param source + * the source of the edge + * @param target + * the target of the edge + */ + public void edgeInserted(V source, V target); + + /** + * Used to notify when an edge is deleted from the graph. + * + * @param source + * the source of the edge + * @param target + * the target of the edge + */ + public void edgeDeleted(V source, V target); + + /** + * Used to notify when a node is inserted into the graph. + * + * @param n + * the node + */ + public void nodeInserted(V n); + + /** + * Used to notify when a node is deleted from the graph. + * + * @param n + * the node + */ + public void nodeDeleted(V n); +} diff --git a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/igraph/ITcDataSource.java b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/igraph/ITcDataSource.java index ffd8b2ca..a2fe33a5 100644 --- a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/igraph/ITcDataSource.java +++ b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/igraph/ITcDataSource.java @@ -9,60 +9,67 @@ * Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.itc.igraph; - -import java.util.Set; - -/** - * Defines those methods that are necessary to observ a tc relation provider. - * - * @author Tamás Szabó - * - * @param the type parameter of the node - */ -public interface ITcDataSource { - - /** - * Attach a tc relation observer. - * - * @param to the observer object - */ - public void attachObserver(ITcObserver to); - - /** - * Detach a tc relation observer. - * - * @param to the observer object - */ - public void detachObserver(ITcObserver to); - - /** - * Returns all nodes which are reachable from the source node. - * - * @param source the source node - * @return the set of target nodes - */ - public Set getAllReachableTargets(V source); - - /** - * Returns all nodes from which the target node is reachable. - * - * @param target the target node - * @return the set of source nodes - */ - public Set getAllReachableSources(V target); - - /** - * Returns true if the target node is reachable from the source node. - * - * @param source the source node - * @param target the target node - * @return true if target is reachable from source, false otherwise - */ - public boolean isReachable(V source, V target); - - /** - * Call this method to properly dispose the data strucutres of a transitive closure algorithm. - */ - public void dispose(); -} +package org.eclipse.incquery.runtime.base.itc.igraph; + +import java.util.Set; + +/** + * Defines those methods that are necessary to observ a tc relation provider. + * + * @author Tamás Szabó + * + * @param + * the type parameter of the node + */ +public interface ITcDataSource { + + /** + * Attach a tc relation observer. + * + * @param to + * the observer object + */ + public void attachObserver(ITcObserver to); + + /** + * Detach a tc relation observer. + * + * @param to + * the observer object + */ + public void detachObserver(ITcObserver to); + + /** + * Returns all nodes which are reachable from the source node. + * + * @param source + * the source node + * @return the set of target nodes + */ + public Set getAllReachableTargets(V source); + + /** + * Returns all nodes from which the target node is reachable. + * + * @param target + * the target node + * @return the set of source nodes + */ + public Set getAllReachableSources(V target); + + /** + * Returns true if the target node is reachable from the source node. + * + * @param source + * the source node + * @param target + * the target node + * @return true if target is reachable from source, false otherwise + */ + public boolean isReachable(V source, V target); + + /** + * Call this method to properly dispose the data strucutres of a transitive closure algorithm. + */ + public void dispose(); +} diff --git a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/igraph/ITcObserver.java b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/igraph/ITcObserver.java index 6e9a9ef9..8325b8a8 100644 --- a/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/igraph/ITcObserver.java +++ b/plugins/org.eclipse.incquery.runtime.base.itc/src/org/eclipse/incquery/runtime/base/itc/igraph/ITcObserver.java @@ -9,29 +9,33 @@ * Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.itc.igraph; - -/** - * Interface ITcObserver is used to observ the changes in a transitive closure relation; tuple insertion/deleteion. - * - * @author Szabó Tamás - * - */ -public interface ITcObserver { - - /** - * Used to notify when a tuple is inserted into the transitive closure relation. - * - * @param source the source of the tuple - * @param target the target of the tuple - */ - public void tupleInserted(V source, V target); - - /** - * Used to notify when a tuple is deleted from the transitive closure relation. - * - * @param source the source of the tuple - * @param target the target of the tuple - */ - public void tupleDeleted(V source, V target); -} +package org.eclipse.incquery.runtime.base.itc.igraph; + +/** + * Interface ITcObserver is used to observ the changes in a transitive closure relation; tuple insertion/deleteion. + * + * @author Szabó Tamás + * + */ +public interface ITcObserver { + + /** + * Used to notify when a tuple is inserted into the transitive closure relation. + * + * @param source + * the source of the tuple + * @param target + * the target of the tuple + */ + public void tupleInserted(V source, V target); + + /** + * Used to notify when a tuple is deleted from the transitive closure relation. + * + * @param source + * the source of the tuple + * @param target + * the target of the tuple + */ + public void tupleDeleted(V source, V target); +} diff --git a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/IncQueryBasePlugin.java b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/IncQueryBasePlugin.java index dea61e4c..40452886 100644 --- a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/IncQueryBasePlugin.java +++ b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/IncQueryBasePlugin.java @@ -17,40 +17,42 @@ public class IncQueryBasePlugin extends Plugin { - // The shared instance - private static IncQueryBasePlugin plugin; - - public static final String PLUGIN_ID="org.eclipse.incquery.runtime.base"; - public static final String WELLBEHAVING_DERIVED_FEATURE_EXTENSION_POINT_ID = "org.eclipse.incquery.runtime.base.wellbehaving.derived.features"; - - /* - * (non-Javadoc) - * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext) - */ - @Override - public void start(BundleContext context) throws Exception { - super.start(context); - plugin = this; - WellbehavingDerivedFeatureRegistry.initRegistry(); - } - - /* - * (non-Javadoc) - * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) - */ - @Override - public void stop(BundleContext context) throws Exception { - plugin = null; - super.stop(context); - } - - /** - * Returns the shared instance - * - * @return the shared instance - */ - public static IncQueryBasePlugin getDefault() { - return plugin; - } + // The shared instance + private static IncQueryBasePlugin plugin; + + public static final String PLUGIN_ID = "org.eclipse.incquery.runtime.base"; + public static final String WELLBEHAVING_DERIVED_FEATURE_EXTENSION_POINT_ID = "org.eclipse.incquery.runtime.base.wellbehaving.derived.features"; + + /* + * (non-Javadoc) + * + * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext) + */ + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + WellbehavingDerivedFeatureRegistry.initRegistry(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) + */ + @Override + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static IncQueryBasePlugin getDefault() { + return plugin; + } } diff --git a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/DataTypeListener.java b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/DataTypeListener.java index 49322c22..7e00e86f 100644 --- a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/DataTypeListener.java +++ b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/DataTypeListener.java @@ -16,23 +16,27 @@ * Interface for observing insertion and deletion of instances of data types. * * @author Tamas Szabo - * + * */ public interface DataTypeListener { - /** - * Called when the given instance of the given type is inserted. - * - * @param type the {@link EDataType} instance - * @param instance the instance of the data type - */ - public void dataTypeInstanceInserted(EDataType type, Object instance); - - /** - * Called when the given instance of the given type is deleted. - * - * @param type the {@link EDataType} instance - * @param instance the instance of the data type - */ - public void dataTypeInstanceDeleted(EDataType type, Object instance); + /** + * Called when the given instance of the given type is inserted. + * + * @param type + * the {@link EDataType} instance + * @param instance + * the instance of the data type + */ + public void dataTypeInstanceInserted(EDataType type, Object instance); + + /** + * Called when the given instance of the given type is deleted. + * + * @param type + * the {@link EDataType} instance + * @param instance + * the instance of the data type + */ + public void dataTypeInstanceDeleted(EDataType type, Object instance); } diff --git a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/FeatureListener.java b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/FeatureListener.java index 4eb56ba4..25074756 100644 --- a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/FeatureListener.java +++ b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/FeatureListener.java @@ -16,29 +16,35 @@ import org.eclipse.emf.ecore.EStructuralFeature; /** - * Interface for observing insertion and deletion of structural feature values ("settings"). - * (Works both for single-valued and many-valued features.) + * Interface for observing insertion and deletion of structural feature values ("settings"). (Works both for + * single-valued and many-valued features.) * * @author Tamas Szabo - * + * */ public interface FeatureListener { - /** - * Called when the given value is inserted into the given feature of the given host EObject. - * - * @param host the host (holder) of the feature - * @param feature the {@link EAttribute} or {@link EReference} instance - * @param value the target of the feature - */ - public void featureInserted(EObject host, EStructuralFeature feature, Object value); + /** + * Called when the given value is inserted into the given feature of the given host EObject. + * + * @param host + * the host (holder) of the feature + * @param feature + * the {@link EAttribute} or {@link EReference} instance + * @param value + * the target of the feature + */ + public void featureInserted(EObject host, EStructuralFeature feature, Object value); - /** - * Called when the given value is removed from the given feature of the given host EObject. - * - * @param host the host (holder) of the feature - * @param feature the {@link EAttribute} or {@link EReference} instance - * @param value the target of the feature - */ - public void featureDeleted(EObject host, EStructuralFeature feature, Object value); + /** + * Called when the given value is removed from the given feature of the given host EObject. + * + * @param host + * the host (holder) of the feature + * @param feature + * the {@link EAttribute} or {@link EReference} instance + * @param value + * the target of the feature + */ + public void featureDeleted(EObject host, EStructuralFeature feature, Object value); } diff --git a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/IQueryResultSetter.java b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/IQueryResultSetter.java index 0f994b8a..88f46549 100644 --- a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/IQueryResultSetter.java +++ b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/IQueryResultSetter.java @@ -13,44 +13,52 @@ /** * Setter interface for query result multimaps that allow modifications of the model through the multimap. * - *

The model modifications should ensure that the multimap changes exactly as required - * (i.e. a put results in only one new key-value pair and remove results in only one removed pair). - * - *

The input parameters of both put and remove can be validated by implementing the {@link #validate(Object, Object)} method. + *

+ * The model modifications should ensure that the multimap changes exactly as required (i.e. a put results in only one + * new key-value pair and remove results in only one removed pair). + * + *

+ * The input parameters of both put and remove can be validated by implementing the {@link #validate(Object, Object)} + * method. * * @author Abel Hegedus - * + * * @param * @param */ -public interface IQueryResultSetter{ +public interface IQueryResultSetter { /** - * Modify the underlying model of the query in order to have the given key-value pair - * as a new result of the query. - * - * @param key the key for which a new value is added to the query results - * @param value the new value that should be added to the query results for the given key + * Modify the underlying model of the query in order to have the given key-value pair as a new result of the query. + * + * @param key + * the key for which a new value is added to the query results + * @param value + * the new value that should be added to the query results for the given key * @return true, if the query result changed */ boolean put(KeyType key, ValueType value); - + /** - * Modify the underlying model of the query in order to remove the given key-value pair - * from the results of the query. - * - * @param key the key for which the value is removed from the query results - * @param value the value that should be removed from the query results for the given key + * Modify the underlying model of the query in order to remove the given key-value pair from the results of the + * query. + * + * @param key + * the key for which the value is removed from the query results + * @param value + * the value that should be removed from the query results for the given key * @return true, if the query result changed */ boolean remove(KeyType key, ValueType value); - + /** - * Validates a given key-value pair for the query result. The validation has to ensure that - * (1) if the pair does not exist in the result, it can be added safely - * (2) if the pair already exists in the result, it can be removed safely - * - * @param key the key of the pair that is validated - * @param value the value of the pair that is validated + * Validates a given key-value pair for the query result. The validation has to ensure that (1) if the pair does not + * exist in the result, it can be added safely (2) if the pair already exists in the result, it can be removed + * safely + * + * @param key + * the key of the pair that is validated + * @param value + * the value of the pair that is validated * @return true, if the pair does not exists but can be added or the pair exists and can be removed */ boolean validate(KeyType key, ValueType value); diff --git a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/IQueryResultUpdateListener.java b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/IQueryResultUpdateListener.java index 6888e974..10c3d21a 100644 --- a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/IQueryResultUpdateListener.java +++ b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/IQueryResultUpdateListener.java @@ -12,30 +12,36 @@ /** * Listener interface for receiving notification from {@link QueryResultMultimap} - * + * * @author Abel Hegedus - * + * * @param * @param */ -public interface IQueryResultUpdateListener{ +public interface IQueryResultUpdateListener { /** * This method is called by the query result multimap when a new key-value pair is put into the multimap * - *

Only invoked if the contents of the multimap changed! + *

+ * Only invoked if the contents of the multimap changed! * - * @param key the key of the newly inserted pair - * @param value the value of the newly inserted pair + * @param key + * the key of the newly inserted pair + * @param value + * the value of the newly inserted pair */ void notifyPut(KeyType key, ValueType value); - + /** * This method is called by the query result multimap when key-value pair is removed from the multimap * - *

Only invoked if the contents of the multimap changed! + *

+ * Only invoked if the contents of the multimap changed! * - * @param key the key of the removed pair - * @param value the value of the removed pair + * @param key + * the key of the removed pair + * @param value + * the value of the removed pair */ void notifyRemove(KeyType key, ValueType value); } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/IncQueryBaseFactory.java b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/IncQueryBaseFactory.java index dc137d0c..a870f1be 100644 --- a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/IncQueryBaseFactory.java +++ b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/IncQueryBaseFactory.java @@ -9,11 +9,8 @@ * Tamas Szabo, Gabor Bergmann - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.api; - - - - +package org.eclipse.incquery.runtime.base.api; + import java.util.Set; import org.apache.log4j.Logger; @@ -22,66 +19,78 @@ import org.eclipse.incquery.runtime.base.core.NavigationHelperImpl; import org.eclipse.incquery.runtime.base.core.TransitiveClosureHelperImpl; import org.eclipse.incquery.runtime.base.exception.IncQueryBaseException; - -/** - * Factory class for the utils in the library: - * - NavigationHelper (automatic and manual) - * - TransitiveClosureUtil - * - * @author Tamas Szabo - * - */ -public class IncQueryBaseFactory { - - private static IncQueryBaseFactory instance; - - /** - * Get the singleton instance of IncQueryBaseFactory. - * - * @return the singleton instance - */ - public synchronized static IncQueryBaseFactory getInstance() { - if (instance == null) { - instance = new IncQueryBaseFactory(); - } - - return instance; - } - - protected IncQueryBaseFactory() { - super(); - } - - /** - * The method creates a {@link NavigationHelper} index for the given EMF model root.

- * A NavigationHelper in wildcard mode will process and index all EStructuralFeatures, EClasses and EDatatypes. - * If wildcard mode is off, the client will have to manually register the interesting aspects of the model. - * @see NavigationHelper - * - * @param emfRoot the root of the EMF tree to be indexed. Recommended: Resource or ResourceSet. Can be null - you can add a root later using {@link NavigationHelper#addRoot(Notifier)} - * @param wildcardMode true if all aspects of the EMF model should be indexed automatically, false if manual registration of interesting aspects is desirable - * @param logger the log output where errors will be logged if encountered during the operation of the NavigationHelper; if null, the default logger for {@link NavigationHelper} is used. - * @return the NavigationHelper instance - * @throws IncQueryBaseException - */ - public NavigationHelper createNavigationHelper(Notifier emfRoot, boolean wildcardMode, Logger logger) throws IncQueryBaseException { - if (logger == null) logger = Logger.getLogger(NavigationHelper.class); - return new NavigationHelperImpl(emfRoot, wildcardMode, logger); - } - - - /** - * The method creates a TransitiveClosureHelper instance for the given EMF model root. - * - *

One must specify the set of EReferences that will be considered as edged. The set can contain multiple elements; this way one can query forward and backward reachability information along heterogenous paths. - * - * @param emfRoot the root of the EMF tree to be processed. Recommended: Resource or ResourceSet. - * @param referencesToObserve the set of references to observe - * @return the TransitiveClosureHelper instance - * @throws IncQueryBaseException - */ - public TransitiveClosureHelper createTransitiveClosureHelper(Notifier emfRoot, Set referencesToObserve) throws IncQueryBaseException { - return new TransitiveClosureHelperImpl(emfRoot, referencesToObserve); - } - -} + +/** + * Factory class for the utils in the library: - NavigationHelper (automatic and manual) - TransitiveClosureUtil + * + * @author Tamas Szabo + * + */ +public class IncQueryBaseFactory { + + private static IncQueryBaseFactory instance; + + /** + * Get the singleton instance of IncQueryBaseFactory. + * + * @return the singleton instance + */ + public synchronized static IncQueryBaseFactory getInstance() { + if (instance == null) { + instance = new IncQueryBaseFactory(); + } + + return instance; + } + + protected IncQueryBaseFactory() { + super(); + } + + /** + * The method creates a {@link NavigationHelper} index for the given EMF model root. + *

+ * A NavigationHelper in wildcard mode will process and index all EStructuralFeatures, EClasses and EDatatypes. If + * wildcard mode is off, the client will have to manually register the interesting aspects of the model. + * + * @see NavigationHelper + * + * @param emfRoot + * the root of the EMF tree to be indexed. Recommended: Resource or ResourceSet. Can be null - you can + * add a root later using {@link NavigationHelper#addRoot(Notifier)} + * @param wildcardMode + * true if all aspects of the EMF model should be indexed automatically, false if manual registration of + * interesting aspects is desirable + * @param logger + * the log output where errors will be logged if encountered during the operation of the + * NavigationHelper; if null, the default logger for {@link NavigationHelper} is used. + * @return the NavigationHelper instance + * @throws IncQueryBaseException + */ + public NavigationHelper createNavigationHelper(Notifier emfRoot, boolean wildcardMode, Logger logger) + throws IncQueryBaseException { + if (logger == null) + logger = Logger.getLogger(NavigationHelper.class); + return new NavigationHelperImpl(emfRoot, wildcardMode, logger); + } + + /** + * The method creates a TransitiveClosureHelper instance for the given EMF model root. + * + *

+ * One must specify the set of EReferences that will be considered as edged. The set can contain multiple elements; + * this way one can query forward and backward reachability information along heterogenous paths. + * + * @param emfRoot + * the root of the EMF tree to be processed. Recommended: Resource or ResourceSet. + * @param referencesToObserve + * the set of references to observe + * @return the TransitiveClosureHelper instance + * @throws IncQueryBaseException + */ + public TransitiveClosureHelper createTransitiveClosureHelper(Notifier emfRoot, Set referencesToObserve) + throws IncQueryBaseException { + return new TransitiveClosureHelperImpl(emfRoot, referencesToObserve); + } + +} diff --git a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/InstanceListener.java b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/InstanceListener.java index b64bcc2e..282fe836 100644 --- a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/InstanceListener.java +++ b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/InstanceListener.java @@ -14,27 +14,30 @@ import org.eclipse.emf.ecore.EObject; /** - * Interface for observing insertion / deletion of EClass instances. - * Note that: EClass may be omitted + * Interface for observing insertion / deletion of EClass instances. Note that: EClass may be omitted * * @author Tamas Szabo - * + * */ public interface InstanceListener { - /** - * Called when the given instance appeared under the given Notifier instance. - * - * @param clazz the EClass of the instance - * @param instance the EObject instance - */ - public void instanceInserted(EClass clazz, EObject instance); + /** + * Called when the given instance appeared under the given Notifier instance. + * + * @param clazz + * the EClass of the instance + * @param instance + * the EObject instance + */ + public void instanceInserted(EClass clazz, EObject instance); - /** - * Called when the given instance disappeared under the given Notifier instance. - * - * @param clazz the EClass of the instance - * @param instance the EObject instance - */ - public void instanceDeleted(EClass clazz, EObject instance); + /** + * Called when the given instance disappeared under the given Notifier instance. + * + * @param clazz + * the EClass of the instance + * @param instance + * the EObject instance + */ + public void instanceDeleted(EClass clazz, EObject instance); } diff --git a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/NavigationHelper.java b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/NavigationHelper.java index 86df37d7..58ceaf99 100644 --- a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/NavigationHelper.java +++ b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/NavigationHelper.java @@ -29,337 +29,398 @@ /** * - * Using an index of the EMF model, this interface exposes useful query functionalities, such as:

    + * Using an index of the EMF model, this interface exposes useful query functionalities, such as: + *
      *
    • - * Inverse navigation along arbitrary {@link EReference} instances (heterogenous paths too) + * Inverse navigation along arbitrary {@link EReference} instances (heterogenous paths too) *
    • - * Finding model elements by attribute value (i.e. inverse navigation along {@link EAttribute}) + * Finding model elements by attribute value (i.e. inverse navigation along {@link EAttribute}) *
    • - * Getting all the (direct) instances of a given {@link EClass} + * Getting all the (direct) instances of a given {@link EClass} *
    • * Querying instances of given data types *
    * *

    - * These indices will be built on an EMF model rooted at an {@link EObject}, {@link Resource} or {@link ResourceSet}. - * The indices will be maintained incrementally on changes to the model; - * these changes can also be observed by registering listeners. - *

    + * These indices will be built on an EMF model rooted at an {@link EObject}, {@link Resource} or {@link ResourceSet}. + * The indices will be maintained incrementally on changes to the model; these changes can also be + * observed by registering listeners. + *

    * *

    - * One of the options is to build indices in wildcard mode, meaning that all EClasses, EDataTypes, EReferences and EAttributes are indexed. This is convenient, but comes at a high memory cost. - * To save memory, one can disable wildcard mode and manually register those EClasses, EDataTypes, EReferences and EAttributes that should be indexed. - *

    + * One of the options is to build indices in wildcard mode, meaning that all EClasses, EDataTypes, EReferences + * and EAttributes are indexed. This is convenient, but comes at a high memory cost. To save memory, one can disable + * wildcard mode and manually register those EClasses, EDataTypes, EReferences and EAttributes that should be + * indexed. + *

    * *

    - * Note that none of the defined methods return null upon empty result sets. - * All query methods return either a copy of the result sets (where {@link Setting} is instantiated) or an unmodifiable collection of the result view. + * Note that none of the defined methods return null upon empty result sets. All query methods return either a copy of + * the result sets (where {@link Setting} is instantiated) or an unmodifiable collection of the result view. * *

    * Instantiate using {@link IncQueryBaseFactory} * * @author Tamas Szabo - * + * */ public interface NavigationHelper { - - /** - * Indicates whether indexing is performed in wildcard mode, where every aspect of the EMF model is automatically indexed. - * - * @return true if everything is indexed, false if manual registration of interesting EClassifiers and EStructuralFeatures is required. - */ - public boolean isInWildcardMode(); -// /** // COMING SOON -// * Sets the wildcard mode. -// *

    If turned on from off, all registrations are erased and the model is re-parsed in a single pass. -// * Turning off from on is not supported yet. -// */ -// public void setInWildcardMode(boolean newWildcardMode); - - /** - * Find all {@link EAttribute} and their owners for a given value of the attribute. - * The method will return these information as a collection of {@link EStructuralFeature.Setting}. - * - *

    Precondition: Will only find those EAttributes that have - * already been registered using {@link #registerEStructuralFeatures(Set)}, - * unless running in wildcard mode (see {@link #isInWildcardMode()}). - * - * @param value the value of the attribute - * @return the collection of settings - */ - public Collection findByAttributeValue(Object value); - - /** - * Find all the EAttributes and their owners for a given value of the attribute. - * The method will return these information as a collection of {@link EStructuralFeature.Setting}. - * Note that a setting will be present in the returned collection only if - * its attribute instance can be found in the given collection of attributes. - * - *

    Precondition: Will only find those EAttributes that have - * already been registered using {@link #registerEStructuralFeatures(Set)}, - * unless running in wildcard mode (see {@link #isInWildcardMode()}). - * - * @param value the value of the attribute - * @param attributes the collection of attributes - * @return the collection of settings - */ - public Collection findByAttributeValue(Object value, Collection attributes); - - /** - * Find all {@link EObject}s that have an attribute {@link EAttribute} and its value equals to the given value. - * - *

    Precondition: Results will be returned only if either (a) the EAttribute - * has already been registered using {@link #registerEStructuralFeatures(Set)}, - * or (b) running in wildcard mode (see {@link #isInWildcardMode()}). - * - * @param value the value of the attribute - * @param attribute the EAttribute instance - * @return the collection of {@link EObject} instances - */ - public Collection findByAttributeValue(Object value, EAttribute attribute); - - /** - * Returns the collection of data type instances for the given {@link EDataType}. - * - *

    Precondition: Results will be returned only if either (a) the EDataType - * has already been registered using {@link #registerEDataTypes(Set)}, - * or (b) running in wildcard mode (see {@link #isInWildcardMode()}). - * - * @param type the data type - * @return the collection of data type instances - */ - public Collection getDataTypeInstances(EDataType type); - -// /** -// * Find all the EAttributes and their owners which have a value of a class that equals to the given one. -// * The method will return these information as a collection of {@link EStructuralFeature.Setting}. -// * -// * @param clazz the class of the value -// * @return the collection of settings -// */ -// public Collection findAllAttributeValuesByType(Class clazz); - - /** - * Find all the {@link EObject} instances that have an {@link EReference} instance with the given target. - * The method will return these information as a collection of {@link EStructuralFeature.Setting}. - * - *

    Precondition: Results will be returned only for those references that - * have already been registered using {@link #registerEStructuralFeatures(Set)}, - * or all references if running in wildcard mode (see {@link #isInWildcardMode()}). - * - * @param target the endpoint of a reference - * @return the collection of settings - */ - public Collection getInverseReferences(EObject target); - - /** - * Find all the {@link EObject} instances that have an EReference instance with the given target. - * The method will return these information as a collection of {@link EStructuralFeature.Setting}. - * Note that a setting will be present in the returned collection only if - * its reference instance can be found in the given collection of references. - * - *

    Precondition: Will only find those EReferences that have - * already been registered using {@link #registerEStructuralFeatures(Set)}, - * unless running in wildcard mode (see {@link #isInWildcardMode()}). - * - * @param target - * @param references - * @return - */ - public Collection getInverseReferences(EObject target, Collection references); - - /** - * Find all {@link EObject}s that have a reference EReference instance with the given target. - * - *

    Precondition: Results will be returned only if either (a) the reference - * has already been registered using {@link #registerEStructuralFeatures(Set)}, - * or (b) running in wildcard mode (see {@link #isInWildcardMode()}). - * - * @param target the endpoint of a reference - * @param reference the EReference instance - * @return the collection of {@link EObject} instances - */ - public Collection getInverseReferences(EObject target, EReference reference); - - /** - * Get the direct {@link EObject} instances of the given EClass instance. - * - *

    Precondition: Results will be returned only if either (a) the EClass - * (or any superclass) has already been registered using {@link #registerEClasses(Set)}, - * or (b) running in wildcard mode (see {@link #isInWildcardMode()}). - * - * @param clazz the EClass instance - * @return the collection of {@link EObject} instances - */ - public Collection getDirectInstances(EClass clazz); - - /** - * Get the exact and descendant {@link EObject} instances of the given EClass. - * - *

    Precondition: Results will be returned only if either (a) the EClass - * (or any superclass) has already been registered using {@link #registerEClasses(Set)}, - * or (b) running in wildcard mode (see {@link #isInWildcardMode()}). - * - * @param clazz the EClass - * @return the collection of {@link EObject} instances - */ - public Collection getAllInstances(EClass clazz); - - /** - * Returns the collection of {@link EObject} instances which have a feature with the given value. - * - *

    Precondition: Results will be returned only if either (a) the feature - * has already been registered using {@link #registerEStructuralFeatures(Set)}, - * or (b) running in wildcard mode (see {@link #isInWildcardMode()}). - * - * @param value the value of the feature - * @param feature the feature instance - * @return the collection of {@link EObject} instances - */ - public Collection findByFeatureValue(Object value, EStructuralFeature feature); - - /** - * Returns the holder(s) of the given feature. - * - *

    Precondition: Results will be returned only if either (a) the feature - * has already been registered using {@link #registerEStructuralFeatures(Set)}, - * or (b) running in wildcard mode (see {@link #isInWildcardMode()}). - * - * @param feature the feature instance - * @return the collection of {@link EObject} instances - */ - public Collection getHoldersOfFeature(EStructuralFeature feature); - - /** - * Call this method to dispose the NavigationHelper instance. - * The NavigationHelper instance will unregister itself from the list of EContentAdapters of the given Notifier instance. - */ - public void dispose(); - - /** - * Registers an instance listener for the navigation helper. - * The listener will be notified about only the instances of the given classes. - * - * @param classes the collection of classes associated to the listener - * @param listener the listener instance - */ - public void registerInstanceListener(Collection classes, InstanceListener listener); - - /** - * Unregisters an instance listener for the given classes. - * - * @param classes the collection of classes - * @param listener the listener instance - */ - public void unregisterInstanceListener(Collection classes, InstanceListener listener); - - /** - * Registers a data type listener for the navigation helper. - * The listener will be notified about only the data type instances of the given types. - * - * @param types the collection of types associated to the listener - * @param listener the data type instance - */ - public void registerDataTypeListener(Collection types, DataTypeListener listener); - - /** - * Unregisters a data type listener for the given types. - * - * @param types the collection of data types - * @param listener the listener instance - */ - public void unregisterDataTypeListener(Collection types, DataTypeListener listener); - - /** - * Registers a feature listener for the navigation helper. - * The listener will be notified about only the settings associated to the given features. - * - * @param features the collection of features associated to the listener - * @param listener the listener instance - */ - public void registerFeatureListener(Collection features, FeatureListener listener); - - /** - * Unregisters a feature listener for the given features. - * - * @param listener the listener instance - * @param features the collection of features - */ - public void unregisterFeatureListener(Collection features, FeatureListener listener); - - /** - * Manually turns on indexing for the given features (indexing of other features are unaffected). - * Note that registering new features will result in iterating through the whole attached model. - * - *

    Not usable in wildcard mode
    - * @param features the set of features to observe - */ - public void registerEStructuralFeatures(Set features); - - /** - * Manually turns off indexing for the given features (indexing of other features are unaffected). - * Note that if the unregistered features are re-registered later, the whole attached model needs to be visited again. - * - * @param features the set of features that will be ignored - */ - public void unregisterEStructuralFeatures(Set features); - - /** - * Manually turns on indexing for the given classes (indexing of other classes are unaffected). - * Instances of subclasses will also be indexed. - * Note that registering new classes will result in iterating through the whole attached model. - * - *
    Not usable in wildcard mode
    - * @param classes the set of classes to observe - */ - public void registerEClasses(Set classes); - - /** - * Manually turns off indexing for the given classes (indexing of other classes are unaffected). - * Note that if the unregistered classes are re-registered later, the whole attached model needs to be visited again. - * - * @param classes the set of classes that will be ignored - */ - public void unregisterEClasses(Set classes); - - /** - * Manually turns on indexing for the given data types (indexing of other features are unaffected). - * Note that registering new data types will result in iterating through the whole attached model. - * - *
    Not usable in wildcard mode
    - * @param dataTypes the set of data types to observe - */ - public void registerEDataTypes(Set dataTypes); - - /** - * Manually turns off indexing for the given data types (indexing of other data types are unaffected). - * Note that if the unregistered data types are re-registered later, the whole attached model needs to be visited again. - * - * @param dataTypes the set of data types that will be ignored - */ - public void unregisterEDataTypes(Set dataTypes); - - /** - * The given callback will be executed, and all model traversals and index registrations will be delayed until the execution is done. - * If there are any outstanding feature or class registrations, a single coalesced model traversal will initialize the caches and deliver the notifications. - * - * @param runnable - */ - public V coalesceTraversals(Callable callable) throws InvocationTargetException; - - - /** - * A set of coarse-grained callbacks that will be invoked after the NavigationHelper index is changed. - * Can be used e.g. to check delta monitors. Not intended for general use. - * - */ - public Set getAfterUpdateCallbacks(); - - /** - * Adds an additional EMF model root. - * @param emfRoot - */ - public void addRoot(Notifier emfRoot) throws IncQueryBaseException; - + + /** + * Indicates whether indexing is performed in wildcard mode, where every aspect of the EMF model is + * automatically indexed. + * + * @return true if everything is indexed, false if manual registration of interesting EClassifiers and + * EStructuralFeatures is required. + */ + public boolean isInWildcardMode(); + + // /** // COMING SOON + // * Sets the wildcard mode. + // *

    If turned on from off, all registrations are erased and the model is re-parsed in a single pass. + // * Turning off from on is not supported yet. + // */ + // public void setInWildcardMode(boolean newWildcardMode); + + /** + * Find all {@link EAttribute} and their owners for a given value of the attribute. The method will + * return these information as a collection of {@link EStructuralFeature.Setting}. + * + *

    + * Precondition: Will only find those EAttributes that have already been registered using + * {@link #registerEStructuralFeatures(Set)}, unless running in wildcard mode (see + * {@link #isInWildcardMode()}). + * + * @param value + * the value of the attribute + * @return the collection of settings + */ + public Collection findByAttributeValue(Object value); + + /** + * Find all the EAttributes and their owners for a given value of the attribute. The method will return + * these information as a collection of {@link EStructuralFeature.Setting}. Note that a setting will be present in + * the returned collection only if its attribute instance can be found in the given collection of + * attributes. + * + *

    + * Precondition: Will only find those EAttributes that have already been registered using + * {@link #registerEStructuralFeatures(Set)}, unless running in wildcard mode (see + * {@link #isInWildcardMode()}). + * + * @param value + * the value of the attribute + * @param attributes + * the collection of attributes + * @return the collection of settings + */ + public Collection findByAttributeValue(Object value, Collection attributes); + + /** + * Find all {@link EObject}s that have an attribute {@link EAttribute} and its value equals to the + * given value. + * + *

    + * Precondition: Results will be returned only if either (a) the EAttribute has already been + * registered using {@link #registerEStructuralFeatures(Set)}, or (b) running in wildcard mode (see + * {@link #isInWildcardMode()}). + * + * @param value + * the value of the attribute + * @param attribute + * the EAttribute instance + * @return the collection of {@link EObject} instances + */ + public Collection findByAttributeValue(Object value, EAttribute attribute); + + /** + * Returns the collection of data type instances for the given {@link EDataType}. + * + *

    + * Precondition: Results will be returned only if either (a) the EDataType has already been + * registered using {@link #registerEDataTypes(Set)}, or (b) running in wildcard mode (see + * {@link #isInWildcardMode()}). + * + * @param type + * the data type + * @return the collection of data type instances + */ + public Collection getDataTypeInstances(EDataType type); + + // /** + // * Find all the EAttributes and their owners which have a value of a class that equals to the given one. + // * The method will return these information as a collection of {@link EStructuralFeature.Setting}. + // * + // * @param clazz the class of the value + // * @return the collection of settings + // */ + // public Collection findAllAttributeValuesByType(Class clazz); + + /** + * Find all the {@link EObject} instances that have an {@link EReference} instance with the given + * target. The method will return these information as a collection of + * {@link EStructuralFeature.Setting}. + * + *

    + * Precondition: Results will be returned only for those references that have already been + * registered using {@link #registerEStructuralFeatures(Set)}, or all references if running in + * wildcard mode (see {@link #isInWildcardMode()}). + * + * @param target + * the endpoint of a reference + * @return the collection of settings + */ + public Collection getInverseReferences(EObject target); + + /** + * Find all the {@link EObject} instances that have an EReference instance with the given target. The + * method will return these information as a collection of {@link EStructuralFeature.Setting}. Note that a setting + * will be present in the returned collection only if its reference instance can be found in the given collection of + * references. + * + *

    + * Precondition: Will only find those EReferences that have already been registered using + * {@link #registerEStructuralFeatures(Set)}, unless running in wildcard mode (see + * {@link #isInWildcardMode()}). + * + * @param target + * @param references + * @return + */ + public Collection getInverseReferences(EObject target, Collection references); + + /** + * Find all {@link EObject}s that have a reference EReference instance with the given + * target. + * + *

    + * Precondition: Results will be returned only if either (a) the reference has already been + * registered using {@link #registerEStructuralFeatures(Set)}, or (b) running in wildcard mode (see + * {@link #isInWildcardMode()}). + * + * @param target + * the endpoint of a reference + * @param reference + * the EReference instance + * @return the collection of {@link EObject} instances + */ + public Collection getInverseReferences(EObject target, EReference reference); + + /** + * Get the direct {@link EObject} instances of the given EClass instance. + * + *

    + * Precondition: Results will be returned only if either (a) the EClass (or any superclass) has + * already been registered using {@link #registerEClasses(Set)}, or (b) running in wildcard mode (see + * {@link #isInWildcardMode()}). + * + * @param clazz + * the EClass instance + * @return the collection of {@link EObject} instances + */ + public Collection getDirectInstances(EClass clazz); + + /** + * Get the exact and descendant {@link EObject} instances of the given EClass. + * + *

    + * Precondition: Results will be returned only if either (a) the EClass (or any superclass) has + * already been registered using {@link #registerEClasses(Set)}, or (b) running in wildcard mode (see + * {@link #isInWildcardMode()}). + * + * @param clazz + * the EClass + * @return the collection of {@link EObject} instances + */ + public Collection getAllInstances(EClass clazz); + + /** + * Returns the collection of {@link EObject} instances which have a feature with the given value. + * + *

    + * Precondition: Results will be returned only if either (a) the feature has already been + * registered using {@link #registerEStructuralFeatures(Set)}, or (b) running in wildcard mode (see + * {@link #isInWildcardMode()}). + * + * @param value + * the value of the feature + * @param feature + * the feature instance + * @return the collection of {@link EObject} instances + */ + public Collection findByFeatureValue(Object value, EStructuralFeature feature); + + /** + * Returns the holder(s) of the given feature. + * + *

    + * Precondition: Results will be returned only if either (a) the feature has already been + * registered using {@link #registerEStructuralFeatures(Set)}, or (b) running in wildcard mode (see + * {@link #isInWildcardMode()}). + * + * @param feature + * the feature instance + * @return the collection of {@link EObject} instances + */ + public Collection getHoldersOfFeature(EStructuralFeature feature); + + /** + * Call this method to dispose the NavigationHelper instance. The NavigationHelper instance will unregister itself + * from the list of EContentAdapters of the given Notifier instance. + */ + public void dispose(); + + /** + * Registers an instance listener for the navigation helper. The listener will be notified about only the instances + * of the given classes. + * + * @param classes + * the collection of classes associated to the listener + * @param listener + * the listener instance + */ + public void registerInstanceListener(Collection classes, InstanceListener listener); + + /** + * Unregisters an instance listener for the given classes. + * + * @param classes + * the collection of classes + * @param listener + * the listener instance + */ + public void unregisterInstanceListener(Collection classes, InstanceListener listener); + + /** + * Registers a data type listener for the navigation helper. The listener will be notified about only the data type + * instances of the given types. + * + * @param types + * the collection of types associated to the listener + * @param listener + * the data type instance + */ + public void registerDataTypeListener(Collection types, DataTypeListener listener); + + /** + * Unregisters a data type listener for the given types. + * + * @param types + * the collection of data types + * @param listener + * the listener instance + */ + public void unregisterDataTypeListener(Collection types, DataTypeListener listener); + + /** + * Registers a feature listener for the navigation helper. The listener will be notified about only the settings + * associated to the given features. + * + * @param features + * the collection of features associated to the listener + * @param listener + * the listener instance + */ + public void registerFeatureListener(Collection features, FeatureListener listener); + + /** + * Unregisters a feature listener for the given features. + * + * @param listener + * the listener instance + * @param features + * the collection of features + */ + public void unregisterFeatureListener(Collection features, FeatureListener listener); + + /** + * Manually turns on indexing for the given features (indexing of other features are unaffected). Note that + * registering new features will result in iterating through the whole attached model. + * + *

    +     * Not usable in wildcard mode
    +     * 
    + * + * @param features + * the set of features to observe + */ + public void registerEStructuralFeatures(Set features); + + /** + * Manually turns off indexing for the given features (indexing of other features are unaffected). Note that if the + * unregistered features are re-registered later, the whole attached model needs to be visited again. + * + * @param features + * the set of features that will be ignored + */ + public void unregisterEStructuralFeatures(Set features); + + /** + * Manually turns on indexing for the given classes (indexing of other classes are unaffected). Instances of + * subclasses will also be indexed. Note that registering new classes will result in iterating through the whole + * attached model. + * + *
    +     * Not usable in wildcard mode
    +     * 
    + * + * @param classes + * the set of classes to observe + */ + public void registerEClasses(Set classes); + + /** + * Manually turns off indexing for the given classes (indexing of other classes are unaffected). Note that if the + * unregistered classes are re-registered later, the whole attached model needs to be visited again. + * + * @param classes + * the set of classes that will be ignored + */ + public void unregisterEClasses(Set classes); + + /** + * Manually turns on indexing for the given data types (indexing of other features are unaffected). Note that + * registering new data types will result in iterating through the whole attached model. + * + *
    +     * Not usable in wildcard mode
    +     * 
    + * + * @param dataTypes + * the set of data types to observe + */ + public void registerEDataTypes(Set dataTypes); + + /** + * Manually turns off indexing for the given data types (indexing of other data types are unaffected). Note that if + * the unregistered data types are re-registered later, the whole attached model needs to be visited again. + * + * @param dataTypes + * the set of data types that will be ignored + */ + public void unregisterEDataTypes(Set dataTypes); + + /** + * The given callback will be executed, and all model traversals and index registrations will be delayed until the + * execution is done. If there are any outstanding feature or class registrations, a single coalesced model + * traversal will initialize the caches and deliver the notifications. + * + * @param runnable + */ + public V coalesceTraversals(Callable callable) throws InvocationTargetException; + + /** + * A set of coarse-grained callbacks that will be invoked after the NavigationHelper index is changed. Can be used + * e.g. to check delta monitors. Not intended for general use. + * + */ + public Set getAfterUpdateCallbacks(); + + /** + * Adds an additional EMF model root. + * + * @param emfRoot + */ + public void addRoot(Notifier emfRoot) throws IncQueryBaseException; } diff --git a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/QueryResultMultimap.java b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/QueryResultMultimap.java index 6ba1b95e..3ba7465c 100644 --- a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/QueryResultMultimap.java +++ b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/QueryResultMultimap.java @@ -28,18 +28,22 @@ import com.google.common.collect.Multisets; /** - * Implementation of {@link Multimap} interface to represent query results. A query result multimap takes - * a model query, with a specified key (input/source) parameter and a value (output/target) parameter. - * - *

    Apart from the standard multimap behavior, it is possible to register listeners that are notified when the - * contents of the multimap change. - * - *

    Subclasses of the query result multimap can attach to any query evaluation engine and shoug + * Implementation of {@link Multimap} interface to represent query results. A query result multimap takes a model query, + * with a specified key (input/source) parameter and a value (output/target) parameter. + * + *

    + * Apart from the standard multimap behavior, it is possible to register listeners that are notified when the contents + * of the multimap change. + * + *

    + * Subclasses of the query result multimap can attach to any query evaluation engine and shoug * * @author Abel Hegedus - * - * @param the type of the keys stored in the multimap - * @param the type of the values stored in the multimap + * + * @param + * the type of the keys stored in the multimap + * @param + * the type of the values stored in the multimap */ public abstract class QueryResultMultimap implements Multimap { @@ -48,8 +52,7 @@ public abstract class QueryResultMultimap implements Multima */ private static final String NOT_ALLOW_MODIFICATIONS = "Query result multimap does not allow modifications"; /** - * This multimap contains the current key-values. - * Implementing classes should not modify it directly + * This multimap contains the current key-values. Implementing classes should not modify it directly */ private Multimap cache; /** @@ -65,50 +68,60 @@ public abstract class QueryResultMultimap implements Multima * The setter registered for changing the contents of the multimap */ private IQueryResultSetter setter; - + /** * Constructor only visible to subclasses. * - * @param logger a logger that can be used for error reporting + * @param logger + * a logger that can be used for error reporting */ - protected QueryResultMultimap(Logger logger){ + protected QueryResultMultimap(Logger logger) { cache = HashMultimap.create(); this.logger = logger; } - + /** - * Registers a listener for this query result multimap that is invoked every time - * when a key-value pair is inserted or removed from the multimap. - * - *

    The listener can be unregistered via {@link #removeCallbackOnQueryResultUpdate(IQueryResultUpdateListener)}. + * Registers a listener for this query result multimap that is invoked every time when a key-value pair is inserted + * or removed from the multimap. * - * @param listener the listener that will be notified of each key-value pair that is inserted or removed, starting from now. - * @param fireNow if true, notifyPut will be immediately invoked on all current key-values as a one-time effect. + *

    + * The listener can be unregistered via {@link #removeCallbackOnQueryResultUpdate(IQueryResultUpdateListener)}. + * + * @param listener + * the listener that will be notified of each key-value pair that is inserted or removed, starting from + * now. + * @param fireNow + * if true, notifyPut will be immediately invoked on all current key-values as a one-time effect. */ public void addCallbackOnQueryResultUpdate(IQueryResultUpdateListener listener, boolean fireNow) { - if(listeners == null) { - listeners = new HashSet>(); + if (listeners == null) { + listeners = new HashSet>(); } listeners.add(listener); } - + /** - * Unregisters a callback registered by {@link #addCallbackOnQueryResultUpdate(IQueryResultUpdateListener, boolean)}. + * Unregisters a callback registered by {@link #addCallbackOnQueryResultUpdate(IQueryResultUpdateListener, boolean)} + * . * - * @param listener the listener that will no longer be notified. + * @param listener + * the listener that will no longer be notified. */ public void removeCallbackOnQueryResultUpdate(IQueryResultUpdateListener listener) { - if(listeners != null) { + if (listeners != null) { listeners.remove(listener); } } - + /** * This method notifies the listeners that the query result multimap has changed. * - * @param direction the type of the change (insert or delete) - * @param key the key of the pair that changed - * @param value the value of the pair that changed + * @param direction + * the type of the change (insert or delete) + * @param key + * the key of the pair that changed + * @param value + * the value of the pair that changed */ private void notifyListeners(Direction direction, KeyType key, ValueType value) { for (IQueryResultUpdateListener listener : listeners) { @@ -129,68 +142,77 @@ private void notifyListeners(Direction direction, KeyType key, ValueType value) } } } - - + /** - * Implementations of QueryResultMultimap can put a new key-value pair into the multimap with this method. - * If the insertion of the key-value pair results in a change, the listeners are notified. + * Implementations of QueryResultMultimap can put a new key-value pair into the multimap with this method. If the + * insertion of the key-value pair results in a change, the listeners are notified. + * + *

    + * No validation or null-checking is performed during the method! * - *

    No validation or null-checking is performed during the method! - * - * @param key the key which identifies the collection where the new value is put - * @param value the value that is put into the collection of the key + * @param key + * the key which identifies the collection where the new value is put + * @param value + * the value that is put into the collection of the key * @return true, if the insertion resulted in a change (the key-value pair was not yet in the multimap) */ protected boolean internalPut(KeyType key, ValueType value) { boolean putResult = cache.put(key, value); - if(putResult) { + if (putResult) { notifyListeners(Direction.INSERT, key, value); } return putResult; } - + /** - * Implementations of QueryResultMultimap can remove a key-value pair from the multimap with this method. - * If the removal of the key-value pair results in a change, the listeners are notified. + * Implementations of QueryResultMultimap can remove a key-value pair from the multimap with this method. If the + * removal of the key-value pair results in a change, the listeners are notified. * - *

    No validation or null-checking is performed during the method! + *

    + * No validation or null-checking is performed during the method! * - * @param key the key which identifies the collection where the value is removed from - * @param value the value that is removed from the collection of the key + * @param key + * the key which identifies the collection where the value is removed from + * @param value + * the value that is removed from the collection of the key * @return true, if the removal resulted in a change (the key-value pair was in the multimap) */ protected boolean internalRemove(KeyType key, ValueType value) { boolean removeResult = cache.remove(key, value); - if(removeResult) { + if (removeResult) { notifyListeners(Direction.DELETE, key, value); } return removeResult; } - + /** - * @param setter the setter to set + * @param setter + * the setter to set */ public void setQueryResultSetter(IQueryResultSetter setter) { this.setter = setter; } - + /** * @return the cache */ protected Multimap getCache() { return cache; } - + /** - * @param cache the cache to set + * @param cache + * the cache to set */ protected void setCache(Multimap cache) { this.cache = cache; } - - // ======================= implemented Multimap methods ====================== - - /* (non-Javadoc) + + // ======================= implemented Multimap methods ====================== + + /* + * (non-Javadoc) + * * @see com.google.common.collect.Multimap#size() */ @Override @@ -198,7 +220,9 @@ public int size() { return cache.size(); } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see com.google.common.collect.Multimap#isEmpty() */ @Override @@ -206,7 +230,9 @@ public boolean isEmpty() { return cache.isEmpty(); } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see com.google.common.collect.Multimap#containsKey(java.lang.Object) */ @Override @@ -214,7 +240,9 @@ public boolean containsKey(Object key) { return cache.containsKey(key); } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see com.google.common.collect.Multimap#containsValue(java.lang.Object) */ @Override @@ -222,7 +250,9 @@ public boolean containsValue(Object value) { return cache.containsValue(value); } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see com.google.common.collect.Multimap#containsEntry(java.lang.Object, java.lang.Object) */ @Override @@ -230,66 +260,72 @@ public boolean containsEntry(Object key, Object value) { return cache.containsEntry(key, value); } - /** + /** * {@inheritDoc} - * - *

    The returned collection is immutable. - * + * + *

    + * The returned collection is immutable. + * */ @Override public Collection get(KeyType key) { return Collections.unmodifiableCollection(cache.get(key)); } - /** + /** * {@inheritDoc} - * - *

    The returned set is immutable. - * + * + *

    + * The returned set is immutable. + * */ @Override public Set keySet() { return Collections.unmodifiableSet(cache.keySet()); } - /** + /** * {@inheritDoc} - * - *

    The returned multiset is immutable. - * + * + *

    + * The returned multiset is immutable. + * */ @Override public Multiset keys() { - return Multisets.unmodifiableMultiset(cache.keys()); //cache.keys(); + return Multisets.unmodifiableMultiset(cache.keys()); // cache.keys(); } - /** + /** * {@inheritDoc} - * - *

    The returned collection is immutable. - * + * + *

    + * The returned collection is immutable. + * */ @Override public Collection values() { return Collections.unmodifiableCollection(cache.values()); } - /** + /** * {@inheritDoc} - * - *

    The returned collection is immutable. - * + * + *

    + * The returned collection is immutable. + * */ @Override public Collection> entries() { return Collections.unmodifiableCollection(cache.entries()); } - /** + /** * {@inheritDoc} - * - *

    The returned map is immutable. - * + * + *

    + * The returned map is immutable. + * */ @Override public Map> asMap() { @@ -299,11 +335,12 @@ public Map> asMap() { /** * {@inheritDoc} * - *

    Throws {@link UnsupportedOperationException} if there is no {@link IQueryResultSetter} + *

    + * Throws {@link UnsupportedOperationException} if there is no {@link IQueryResultSetter} */ @Override public boolean put(KeyType key, ValueType value) { - if(setter == null) { + if (setter == null) { throw new UnsupportedOperationException(NOT_ALLOW_MODIFICATIONS); } return modifyThroughQueryResultSetter(key, value, Direction.INSERT); @@ -312,20 +349,25 @@ public boolean put(KeyType key, ValueType value) { /** * This method is used for calling the query result setter to put or remove a value by modifying the model. * - *

    The given key-value pair is first validated (see {@link IQueryResultSetter#validate(Object, Object)}, - * then the put or remove method is called (see {@link IQueryResultSetter#put(Object, Object)} and - * {@link IQueryResultSetter#remove(Object, Object)}). If the setter reported that the model has been changed, - * the change is checked. - * - *

    If the model modification did not change the result set in the desired way, a warning is logged. - * - *

    If the setter throws any {@link Throwable}, it is either rethrown in case of {@link Error} and logged - * otherwise. - * - * - * @param key the key of the pair to be inserted or removed - * @param value the value of the pair to be inserted or removed - * @param direction specifies whether a put or a remove is performed + *

    + * The given key-value pair is first validated (see {@link IQueryResultSetter#validate(Object, Object)}, then the + * put or remove method is called (see {@link IQueryResultSetter#put(Object, Object)} and + * {@link IQueryResultSetter#remove(Object, Object)}). If the setter reported that the model has been changed, the + * change is checked. + * + *

    + * If the model modification did not change the result set in the desired way, a warning is logged. + * + *

    + * If the setter throws any {@link Throwable}, it is either rethrown in case of {@link Error} and logged otherwise. + * + * + * @param key + * the key of the pair to be inserted or removed + * @param value + * the value of the pair to be inserted or removed + * @param direction + * specifies whether a put or a remove is performed * @return true, if the multimap changed according to the direction */ private boolean modifyThroughQueryResultSetter(KeyType key, ValueType value, Direction direction) { @@ -344,7 +386,9 @@ private boolean modifyThroughQueryResultSetter(KeyType key, ValueType value, Dir } else { logger.warn(String .format("The query result multimap %s of key %s and value %s resulted in %s. (Developer note: %s called from QueryResultMultimap)", - direction == Direction.INSERT ? "insertion" : "removal", key, value, Math.abs(cache.size() - size) > 1 ? "more than one changed result" : "no changed results", setter)); + direction == Direction.INSERT ? "insertion" : "removal", key, value, + Math.abs(cache.size() - size) > 1 ? "more than one changed result" + : "no changed results", setter)); } } } catch (Error e) { // NOPMD @@ -361,19 +405,24 @@ private boolean modifyThroughQueryResultSetter(KeyType key, ValueType value, Dir } /** - * Checks whether the model modification performed by the {@link IQueryResultSetter} resulted - * in the insertion or removal of exactly the required key-value pair. + * Checks whether the model modification performed by the {@link IQueryResultSetter} resulted in the insertion or + * removal of exactly the required key-value pair. * - * @param key the key for the pair that was inserted or removed - * @param value the value for the pair that was inserted or removed - * @param direction the direction of the change - * @param size the size of the cache before the change + * @param key + * the key for the pair that was inserted or removed + * @param value + * the value for the pair that was inserted or removed + * @param direction + * the direction of the change + * @param size + * the size of the cache before the change * @return true, if the changes made by the query result setter were correct */ private boolean checkModificationThroughQueryResultSetter(KeyType key, ValueType value, Direction direction, final int expectedChange, final int size) { - if ((direction == Direction.INSERT) == cache.containsEntry(key, value) && (cache.size() - expectedChange) == size) { - return true; + if ((direction == Direction.INSERT) == cache.containsEntry(key, value) + && (cache.size() - expectedChange) == size) { + return true; } return false; } @@ -381,17 +430,18 @@ private boolean checkModificationThroughQueryResultSetter(KeyType key, ValueType /** * {@inheritDoc} * - *

    Throws {@link UnsupportedOperationException} if there is no {@link IQueryResultSetter} + *

    + * Throws {@link UnsupportedOperationException} if there is no {@link IQueryResultSetter} */ @SuppressWarnings("unchecked") @Override public boolean remove(Object key, Object value) { - if(setter == null) { + if (setter == null) { throw new UnsupportedOperationException(NOT_ALLOW_MODIFICATIONS); } // if it contains the entry, the types MUST be correct - if(cache.containsEntry(key, value)) { - return modifyThroughQueryResultSetter((KeyType)key, (ValueType)value, Direction.DELETE); + if (cache.containsEntry(key, value)) { + return modifyThroughQueryResultSetter((KeyType) key, (ValueType) value, Direction.DELETE); } return false; } @@ -399,11 +449,12 @@ public boolean remove(Object key, Object value) { /** * {@inheritDoc} * - *

    Throws {@link UnsupportedOperationException} if there is no {@link IQueryResultSetter} + *

    + * Throws {@link UnsupportedOperationException} if there is no {@link IQueryResultSetter} */ @Override public boolean putAll(KeyType key, Iterable values) { - if(setter == null) { + if (setter == null) { throw new UnsupportedOperationException(NOT_ALLOW_MODIFICATIONS); } boolean changed = false; @@ -416,11 +467,12 @@ public boolean putAll(KeyType key, Iterable values) { /** * {@inheritDoc} * - *

    Throws {@link UnsupportedOperationException} if there is no {@link IQueryResultSetter} + *

    + * Throws {@link UnsupportedOperationException} if there is no {@link IQueryResultSetter} */ @Override public boolean putAll(Multimap multimap) { - if(setter == null) { + if (setter == null) { throw new UnsupportedOperationException(NOT_ALLOW_MODIFICATIONS); } boolean changed = false; @@ -433,23 +485,25 @@ public boolean putAll(Multimap multimap) /** * {@inheritDoc} * - *

    Throws {@link UnsupportedOperationException} if there is no {@link IQueryResultSetter} - * - *

    The returned collection is immutable. + *

    + * Throws {@link UnsupportedOperationException} if there is no {@link IQueryResultSetter} + * + *

    + * The returned collection is immutable. */ @Override public Collection replaceValues(KeyType key, Iterable values) { - if(setter == null) { + if (setter == null) { throw new UnsupportedOperationException(NOT_ALLOW_MODIFICATIONS); } Collection oldValues = removeAll(key); Iterator iterator = values.iterator(); int inserted = cache.get(key).size(); - while(iterator.hasNext()) { + while (iterator.hasNext()) { modifyThroughQueryResultSetter(key, iterator.next(), Direction.INSERT); inserted--; } - if(inserted != 0) { + if (inserted != 0) { logger.warn(String .format("The query result multimap replaceValues on key %s did not insert all values. (Developer note: %s called from QueryResultMultimap)", key, setter)); @@ -460,23 +514,25 @@ public Collection replaceValues(KeyType key, IterableThrows {@link UnsupportedOperationException} if there is no {@link IQueryResultSetter} - * - *

    The returned collection is immutable. + *

    + * Throws {@link UnsupportedOperationException} if there is no {@link IQueryResultSetter} + * + *

    + * The returned collection is immutable. */ @SuppressWarnings("unchecked") @Override public Collection removeAll(Object key) { - if(setter == null) { + if (setter == null) { throw new UnsupportedOperationException(NOT_ALLOW_MODIFICATIONS); } // if it contains the key, the type MUST be correct - if(cache.containsKey(key)) { - Collection collection = cache.get((KeyType)key); + if (cache.containsKey(key)) { + Collection collection = cache.get((KeyType) key); Collection output = ImmutableSet.copyOf(collection); - + for (ValueType valueType : output) { - modifyThroughQueryResultSetter((KeyType)key, valueType, Direction.DELETE); + modifyThroughQueryResultSetter((KeyType) key, valueType, Direction.DELETE); } if (cache.containsKey(key)) { Collection newValues = cache.get((KeyType) key); @@ -492,30 +548,31 @@ public Collection removeAll(Object key) { /** * {@inheritDoc} * - *

    Throws {@link UnsupportedOperationException} if there is no {@link IQueryResultSetter} + *

    + * Throws {@link UnsupportedOperationException} if there is no {@link IQueryResultSetter} */ @Override public void clear() { - if(setter == null) { + if (setter == null) { throw new UnsupportedOperationException(NOT_ALLOW_MODIFICATIONS); } Iterator> iterator = cache.entries().iterator(); - while(iterator.hasNext()) { + while (iterator.hasNext()) { Entry entry = iterator.next(); modifyThroughQueryResultSetter(entry.getKey(), entry.getValue(), Direction.DELETE); } if (cache.size() != 0) { StringBuilder sb = new StringBuilder(); for (Entry entry : cache.entries()) { - if(sb.length() > 0) { + if (sb.length() > 0) { sb.append(", "); } sb.append(entry.toString()); } logger.warn(String .format("The query result multimap is not empty after clear, remaining entries: %s. (Developer note: %s called from QueryResultMultimap)", - sb.toString(),setter)); + sb.toString(), setter)); } } - + } diff --git a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/TransitiveClosureHelper.java b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/TransitiveClosureHelper.java index b4bb5f3c..10772411 100644 --- a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/TransitiveClosureHelper.java +++ b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/TransitiveClosureHelper.java @@ -9,20 +9,20 @@ * Tamas Szabo, Gabor Bergmann - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.api; - +package org.eclipse.incquery.runtime.base.api; + import org.eclipse.emf.ecore.EObject; import org.eclipse.incquery.runtime.base.itc.igraph.ITcDataSource; - -/** - * The class can be used to compute the transitive closure of a given emf model, - * where the nodes will be the objects in the model and the edges will be represented by the references between them. - * One must provide the set of references that the helper should treat as edges when creating an instance with the factory: - * only the notifications about these references will be handled. - * - * @author Tamas Szabo - * - */ -public interface TransitiveClosureHelper extends ITcDataSource { - -} + +/** + * The class can be used to compute the transitive closure of a given emf model, where the nodes will be the objects in + * the model and the edges will be represented by the references between them. One must provide the set of references + * that the helper should treat as edges when creating an instance with the factory: only the notifications about these + * references will be handled. + * + * @author Tamas Szabo + * + */ +public interface TransitiveClosureHelper extends ITcDataSource { + +} diff --git a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/comprehension/EMFModelComprehension.java b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/comprehension/EMFModelComprehension.java index 5284970f..e687f221 100644 --- a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/comprehension/EMFModelComprehension.java +++ b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/comprehension/EMFModelComprehension.java @@ -32,203 +32,204 @@ /** * @author Bergmann Gábor * - * Does not directly visit derived links, unless marked as a WellBehavingFeature. - * Derived edges are automatically interpreted correctly in these cases: - * - EFeatureMaps - * - eOpposites of containments - * - * + * Does not directly visit derived links, unless marked as a WellBehavingFeature. Derived edges are + * automatically interpreted correctly in these cases: - EFeatureMaps - eOpposites of containments + * + * */ public class EMFModelComprehension { - /** - * Should not traverse this feature directly. - * It is still possible that it can be represented in IQBase if {@link #representable(EStructuralFeature)} is true. - */ - public static boolean untraversableDirectly(EStructuralFeature feature) { - boolean suspect = feature.isDerived() || feature.isVolatile(); - if(suspect) { - // override support here - // (e.g. if manual notifications available, or no changes expected afterwards) - suspect = !WellbehavingDerivedFeatureRegistry.isWellbehavingFeature(feature); - // TODO verbose flag somewhere to ease debugging (for such warnings) - // TODO add warning about not visited subtree (containment, FeatureMap and annotation didn't define otherwise) - } - return suspect; - } - - /** - * This feature can be represented in IQBase. - */ - public static boolean representable(EStructuralFeature feature) { - if (!untraversableDirectly(feature)) return true; - - if (feature instanceof EReference) { - final EReference reference = (EReference) feature; - if (reference.isContainer() && representable(reference.getEOpposite())) return true; - } - - boolean isMixed = "mixed".equals(EcoreUtil.getAnnotation(feature.getEContainingClass(), ExtendedMetaData.ANNOTATION_URI, "kind")); - if (isMixed) return true; // TODO maybe check the "name"=":mixed" or ":group" feature for representability? - - final String groupAnnotation = EcoreUtil.getAnnotation(feature, ExtendedMetaData.ANNOTATION_URI, "group"); - if (groupAnnotation != null && groupAnnotation.length()>1 && '#' == groupAnnotation.charAt(0)) { - final String groupFeatureName = groupAnnotation.substring(1); - final EStructuralFeature groupFeature = feature.getEContainingClass().getEStructuralFeature(groupFeatureName); - return representable(groupFeature); - } - - return false; - } - - public static void traverseModel(EMFVisitor visitor, Notifier source) { - if (source == null) return; - if (source instanceof EObject) { - traverseObject(visitor, (EObject) source); - } - else if (source instanceof Resource) { - traverseResource(visitor, (Resource) source); - } - else if (source instanceof ResourceSet) { - traverseResourceSet(visitor, (ResourceSet) source); - } - } - - public static void traverseResourceSet(EMFVisitor visitor, ResourceSet source) { - if (source == null) return; - final List resources = new ArrayList(source.getResources()); - for (Resource resource : resources) { - traverseResource(visitor, resource); - } - } - - public static void traverseResource(EMFVisitor visitor, Resource source) { - if (source == null) return; - if(visitor.pruneSubtrees(source)) - return; - final EList contents = source.getContents(); - for (EObject eObject : contents) { - traverseObject(visitor, eObject); - } - } - - - public static void traverseObject(EMFVisitor visitor, EObject source) { - if (source == null) return; - if(source.eIsProxy()) { - if (visitor.forceProxyResolution()) - source = EcoreUtil.resolve(source, source); - if (source.eIsProxy()) { - visitor.visitUnresolvableProxyObject(source); - return; - } - } - - visitor.visitElement(source); - for (EStructuralFeature feature: source.eClass().getEAllStructuralFeatures()) { - if (untraversableDirectly(feature)) continue; - final boolean visitorPrunes = visitor.pruneFeature(feature); - if (visitorPrunes && !unprunableFeature(visitor, source, feature)) continue; - - if (feature.isMany()) { - Collection targets = (Collection) source.eGet(feature); - for (Object target : targets) { - traverseFeatureInternal(visitor, source, feature, target, visitorPrunes); - } - } else { - Object target = source.eGet(feature); - if (target != null) traverseFeatureInternal(visitor, source, feature, target, visitorPrunes); - } - } - } - - private static boolean unprunableFeature(EMFVisitor visitor, EObject source, EStructuralFeature feature) { - return - ( - feature instanceof EAttribute && - EcorePackage.eINSTANCE.getEFeatureMapEntry().equals( - ((EAttribute)feature).getEAttributeType() - ) - ) || ( - feature instanceof EReference && - ((EReference)feature).isContainment() && - (!visitor.pruneSubtrees(source) || ((EReference)feature).getEOpposite() != null) - ); - } - - - - public static void traverseFeature( - EMFVisitor visitor, EObject source, EStructuralFeature feature, Object target) - { - if (target == null) return; - if (untraversableDirectly(feature)) return; - traverseFeatureInternalSimple(visitor, source, feature, target); - } - - - private static void traverseFeatureInternalSimple(EMFVisitor visitor, - EObject source, EStructuralFeature feature, Object target) - { - final boolean visitorPrunes = visitor.pruneFeature(feature); - if (visitorPrunes && !unprunableFeature(visitor, source, feature)) return; - - traverseFeatureInternal(visitor, source, feature, target, visitorPrunes); - } - - /** - * @pre target != null - */ - private static void traverseFeatureInternal( - EMFVisitor visitor, EObject source, EStructuralFeature feature, Object target, boolean visitorPrunes) - { - if (feature instanceof EAttribute) { - if (!visitorPrunes) visitor.visitAttribute(source, (EAttribute)feature, target); - if (target instanceof FeatureMap.Entry) { // emulated derived edge based on FeatureMap - Entry entry = (FeatureMap.Entry) target; - final EStructuralFeature emulated = entry.getEStructuralFeature(); - final Object emulatedTarget = entry.getValue(); - - emulateUntraversableFeature(visitor, source, emulated, emulatedTarget); - } - } else if (feature instanceof EReference) { - EReference reference = (EReference)feature; - EObject targetObject = (EObject)target; - if(targetObject.eIsProxy()) { - if (visitor.forceProxyResolution()) - targetObject = EcoreUtil.resolve(targetObject,source); - if (targetObject.eIsProxy()) { - visitor.visitUnresolvableProxyFeature(source, reference, targetObject); - return; - } - } - if (reference.isContainment()) { - if (!visitorPrunes) visitor.visitInternalContainment(source, reference, targetObject); - if (!visitor.pruneSubtrees(source)) traverseObject(visitor, targetObject); - - final EReference opposite = reference.getEOpposite(); - if (opposite != null) { // emulated derived edge based on container opposite - emulateUntraversableFeature(visitor, targetObject, opposite, source); - } - } else { -// if (containedElements.contains(target)) - if (!visitorPrunes) visitor.visitNonContainmentReference(source, reference, targetObject); - } -// else -// visitor.visitExternalReference(source, reference, targetObject); - } - - } - - /** - * Emulates a derived edge, if it is not visited otherwise - * @pre target != null - */ - private static void emulateUntraversableFeature(EMFVisitor visitor, - EObject source, final EStructuralFeature emulated, final Object target) - { - if (untraversableDirectly(emulated)) - traverseFeatureInternalSimple(visitor, source, emulated, target); - } + /** + * Should not traverse this feature directly. It is still possible that it can be represented in IQBase if + * {@link #representable(EStructuralFeature)} is true. + */ + public static boolean untraversableDirectly(EStructuralFeature feature) { + boolean suspect = feature.isDerived() || feature.isVolatile(); + if (suspect) { + // override support here + // (e.g. if manual notifications available, or no changes expected afterwards) + suspect = !WellbehavingDerivedFeatureRegistry.isWellbehavingFeature(feature); + // TODO verbose flag somewhere to ease debugging (for such warnings) + // TODO add warning about not visited subtree (containment, FeatureMap and annotation didn't define + // otherwise) + } + return suspect; + } + + /** + * This feature can be represented in IQBase. + */ + public static boolean representable(EStructuralFeature feature) { + if (!untraversableDirectly(feature)) + return true; + + if (feature instanceof EReference) { + final EReference reference = (EReference) feature; + if (reference.isContainer() && representable(reference.getEOpposite())) + return true; + } + + boolean isMixed = "mixed".equals(EcoreUtil.getAnnotation(feature.getEContainingClass(), + ExtendedMetaData.ANNOTATION_URI, "kind")); + if (isMixed) + return true; // TODO maybe check the "name"=":mixed" or ":group" feature for representability? + + final String groupAnnotation = EcoreUtil.getAnnotation(feature, ExtendedMetaData.ANNOTATION_URI, "group"); + if (groupAnnotation != null && groupAnnotation.length() > 1 && '#' == groupAnnotation.charAt(0)) { + final String groupFeatureName = groupAnnotation.substring(1); + final EStructuralFeature groupFeature = feature.getEContainingClass().getEStructuralFeature( + groupFeatureName); + return representable(groupFeature); + } + + return false; + } + + public static void traverseModel(EMFVisitor visitor, Notifier source) { + if (source == null) + return; + if (source instanceof EObject) { + traverseObject(visitor, (EObject) source); + } else if (source instanceof Resource) { + traverseResource(visitor, (Resource) source); + } else if (source instanceof ResourceSet) { + traverseResourceSet(visitor, (ResourceSet) source); + } + } + + public static void traverseResourceSet(EMFVisitor visitor, ResourceSet source) { + if (source == null) + return; + final List resources = new ArrayList(source.getResources()); + for (Resource resource : resources) { + traverseResource(visitor, resource); + } + } + + public static void traverseResource(EMFVisitor visitor, Resource source) { + if (source == null) + return; + if (visitor.pruneSubtrees(source)) + return; + final EList contents = source.getContents(); + for (EObject eObject : contents) { + traverseObject(visitor, eObject); + } + } + + public static void traverseObject(EMFVisitor visitor, EObject source) { + if (source == null) + return; + if (source.eIsProxy()) { + if (visitor.forceProxyResolution()) + source = EcoreUtil.resolve(source, source); + if (source.eIsProxy()) { + visitor.visitUnresolvableProxyObject(source); + return; + } + } + + visitor.visitElement(source); + for (EStructuralFeature feature : source.eClass().getEAllStructuralFeatures()) { + if (untraversableDirectly(feature)) + continue; + final boolean visitorPrunes = visitor.pruneFeature(feature); + if (visitorPrunes && !unprunableFeature(visitor, source, feature)) + continue; + + if (feature.isMany()) { + Collection targets = (Collection) source.eGet(feature); + for (Object target : targets) { + traverseFeatureInternal(visitor, source, feature, target, visitorPrunes); + } + } else { + Object target = source.eGet(feature); + if (target != null) + traverseFeatureInternal(visitor, source, feature, target, visitorPrunes); + } + } + } + + private static boolean unprunableFeature(EMFVisitor visitor, EObject source, EStructuralFeature feature) { + return (feature instanceof EAttribute && EcorePackage.eINSTANCE.getEFeatureMapEntry().equals( + ((EAttribute) feature).getEAttributeType())) + || (feature instanceof EReference && ((EReference) feature).isContainment() && (!visitor + .pruneSubtrees(source) || ((EReference) feature).getEOpposite() != null)); + } + + public static void traverseFeature(EMFVisitor visitor, EObject source, EStructuralFeature feature, Object target) { + if (target == null) + return; + if (untraversableDirectly(feature)) + return; + traverseFeatureInternalSimple(visitor, source, feature, target); + } + + private static void traverseFeatureInternalSimple(EMFVisitor visitor, EObject source, EStructuralFeature feature, + Object target) { + final boolean visitorPrunes = visitor.pruneFeature(feature); + if (visitorPrunes && !unprunableFeature(visitor, source, feature)) + return; + + traverseFeatureInternal(visitor, source, feature, target, visitorPrunes); + } + + /** + * @pre target != null + */ + private static void traverseFeatureInternal(EMFVisitor visitor, EObject source, EStructuralFeature feature, + Object target, boolean visitorPrunes) { + if (feature instanceof EAttribute) { + if (!visitorPrunes) + visitor.visitAttribute(source, (EAttribute) feature, target); + if (target instanceof FeatureMap.Entry) { // emulated derived edge based on FeatureMap + Entry entry = (FeatureMap.Entry) target; + final EStructuralFeature emulated = entry.getEStructuralFeature(); + final Object emulatedTarget = entry.getValue(); + + emulateUntraversableFeature(visitor, source, emulated, emulatedTarget); + } + } else if (feature instanceof EReference) { + EReference reference = (EReference) feature; + EObject targetObject = (EObject) target; + if (targetObject.eIsProxy()) { + if (visitor.forceProxyResolution()) + targetObject = EcoreUtil.resolve(targetObject, source); + if (targetObject.eIsProxy()) { + visitor.visitUnresolvableProxyFeature(source, reference, targetObject); + return; + } + } + if (reference.isContainment()) { + if (!visitorPrunes) + visitor.visitInternalContainment(source, reference, targetObject); + if (!visitor.pruneSubtrees(source)) + traverseObject(visitor, targetObject); + + final EReference opposite = reference.getEOpposite(); + if (opposite != null) { // emulated derived edge based on container opposite + emulateUntraversableFeature(visitor, targetObject, opposite, source); + } + } else { + // if (containedElements.contains(target)) + if (!visitorPrunes) + visitor.visitNonContainmentReference(source, reference, targetObject); + } + // else + // visitor.visitExternalReference(source, reference, targetObject); + } + + } + + /** + * Emulates a derived edge, if it is not visited otherwise + * + * @pre target != null + */ + private static void emulateUntraversableFeature(EMFVisitor visitor, EObject source, + final EStructuralFeature emulated, final Object target) { + if (untraversableDirectly(emulated)) + traverseFeatureInternalSimple(visitor, source, emulated, target); + } } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/comprehension/EMFVisitor.java b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/comprehension/EMFVisitor.java index 8f056e57..4d494ae6 100644 --- a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/comprehension/EMFVisitor.java +++ b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/comprehension/EMFVisitor.java @@ -19,79 +19,97 @@ /** * Use EMFModelComprehension to visit an EMF model. + * * @author Bergmann Gábor - * + * */ -// FIXME: +// FIXME: // - handle boundary of active emfRoot subtree // - more efficient traversal public class EMFVisitor { - /** - * @param resource - * @param element - */ - public void visitTopElementInResource(Resource resource, EObject element) {} - - /** - * @param resource - */ - public void visitResource(Resource resource) {} - - /** - * @param source - */ - public void visitElement(EObject source) {} - -// /** -// * @param source -// * @param feature -// * @param target -// */ -// public void visitExternalReference(EObject source, EReference feature, EObject target) {} - - /** - * @param source - * @param feature - * @param target - */ - public void visitNonContainmentReference(EObject source, EReference feature, EObject target) {} - - /** - * @param source - * @param feature - * @param target - */ - public void visitInternalContainment(EObject source, EReference feature, EObject target) {} - - /** - * @param current - * @param feature - * @param value - */ - public void visitAttribute(EObject source, EAttribute feature, Object target) {} - - /** - * Returns true if the given feature should not be traversed (interesting esp. if multi-valued) - */ - public boolean pruneFeature(EStructuralFeature feature) { return false;} - - /** - * Returns true if the contents of an object should be pruned (and not explored by the visitor) - */ - public boolean pruneSubtrees(EObject source) { return false;} - - /** - * Returns true if the contents of a resource should be pruned (and not explored by the visitor) - */ - public boolean pruneSubtrees(Resource source) { return false;} - - public void visitUnresolvableProxyObject(EObject source) {} - public void visitUnresolvableProxyFeature(EObject source, EReference feature, EObject target) {} - - /** - * @return - */ - public boolean forceProxyResolution() {return true;} + /** + * @param resource + * @param element + */ + public void visitTopElementInResource(Resource resource, EObject element) { + } + + /** + * @param resource + */ + public void visitResource(Resource resource) { + } + + /** + * @param source + */ + public void visitElement(EObject source) { + } + + // /** + // * @param source + // * @param feature + // * @param target + // */ + // public void visitExternalReference(EObject source, EReference feature, EObject target) {} + + /** + * @param source + * @param feature + * @param target + */ + public void visitNonContainmentReference(EObject source, EReference feature, EObject target) { + } + + /** + * @param source + * @param feature + * @param target + */ + public void visitInternalContainment(EObject source, EReference feature, EObject target) { + } + + /** + * @param current + * @param feature + * @param value + */ + public void visitAttribute(EObject source, EAttribute feature, Object target) { + } + + /** + * Returns true if the given feature should not be traversed (interesting esp. if multi-valued) + */ + public boolean pruneFeature(EStructuralFeature feature) { + return false; + } + + /** + * Returns true if the contents of an object should be pruned (and not explored by the visitor) + */ + public boolean pruneSubtrees(EObject source) { + return false; + } + + /** + * Returns true if the contents of a resource should be pruned (and not explored by the visitor) + */ + public boolean pruneSubtrees(Resource source) { + return false; + } + + public void visitUnresolvableProxyObject(EObject source) { + } + + public void visitUnresolvableProxyFeature(EObject source, EReference feature, EObject target) { + } + + /** + * @return + */ + public boolean forceProxyResolution() { + return true; + } } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/comprehension/WellbehavingDerivedFeatureRegistry.java b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/comprehension/WellbehavingDerivedFeatureRegistry.java index f84db749..1c886521 100644 --- a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/comprehension/WellbehavingDerivedFeatureRegistry.java +++ b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/comprehension/WellbehavingDerivedFeatureRegistry.java @@ -30,122 +30,125 @@ * */ public class WellbehavingDerivedFeatureRegistry { - private static Collection contributedWellbehavingDerivedFeatures = new ArrayList();; - private static Collection contributedWellbehavingDerivedClasses = new ArrayList();; - private static Collection contributedWellbehavingDerivedPackages = new ArrayList();; + private static Collection contributedWellbehavingDerivedFeatures = new ArrayList();; + private static Collection contributedWellbehavingDerivedClasses = new ArrayList();; + private static Collection contributedWellbehavingDerivedPackages = new ArrayList();; - /** + /** * */ - private WellbehavingDerivedFeatureRegistry() { } - /** - * Called by IncQueryBasePlugin. - */ - public static void initRegistry() { - getContributedWellbehavingDerivedFeatures().clear(); - getContributedWellbehavingDerivedClasses().clear(); - getContributedWellbehavingDerivedPackages().clear(); - - IExtensionRegistry reg = Platform.getExtensionRegistry(); - IExtensionPoint poi; - - poi = reg.getExtensionPoint(IncQueryBasePlugin.WELLBEHAVING_DERIVED_FEATURE_EXTENSION_POINT_ID); - if (poi != null) { - IExtension[] exts = poi.getExtensions(); - - for (IExtension ext : exts) { - - IConfigurationElement[] els = ext.getConfigurationElements(); - for (IConfigurationElement el : els) { - if (el.getName().equals("wellbehaving-derived-feature")) { - processWellbehavingExtension(el); - } else { - throw new UnsupportedOperationException("Unknown configuration element " + el.getName() - + " in plugin.xml of " + el.getDeclaringExtension().getUniqueIdentifier()); - } - } - } - } - } - /** - * @param el - */ - private static void processWellbehavingExtension(IConfigurationElement el) { - try { - String packageUri = el.getAttribute("package-nsUri"); - String classifierName = el.getAttribute("classifier-name"); - String featureName = el.getAttribute("feature-name"); - if (packageUri != null) { - EPackage pckg = EPackage.Registry.INSTANCE.getEPackage(packageUri); - if (pckg != null) { - if (classifierName != null) { - EClassifier clsr = pckg.getEClassifier(classifierName); - if (clsr instanceof EClass) { - if (featureName != null) { - EClass cls = (EClass) clsr; - EStructuralFeature feature = cls.getEStructuralFeature(featureName); - if (feature != null) { - contributedWellbehavingDerivedFeatures.add(feature); - } - } else { - contributedWellbehavingDerivedClasses.add((EClass) clsr); - } - } - } else { - contributedWellbehavingDerivedPackages.add(pckg); - } - } - } - } catch (Exception e) { - final Logger logger = Logger.getLogger(WellbehavingDerivedFeatureRegistry.class); - logger.error("Well-behaving feature registration failed", e); - } - } - - /** - * @param feature - */ - public static void registerWellbehavingDerivedFeature(EStructuralFeature feature) { - contributedWellbehavingDerivedFeatures.add(feature); - } + private WellbehavingDerivedFeatureRegistry() { + } - /** - * @param feature - */ - public static void registerWellbehavingDerivedClass(EClass cls) { - contributedWellbehavingDerivedClasses.add(cls); - } + /** + * Called by IncQueryBasePlugin. + */ + public static void initRegistry() { + getContributedWellbehavingDerivedFeatures().clear(); + getContributedWellbehavingDerivedClasses().clear(); + getContributedWellbehavingDerivedPackages().clear(); - /** - * @param feature - */ - public static void registerWellbehavingDerivedPackage(EPackage pkg) { - contributedWellbehavingDerivedPackages.add(pkg); - } + IExtensionRegistry reg = Platform.getExtensionRegistry(); + IExtensionPoint poi; - /** - * @return the contributedWellbehavingDerivedFeatures - */ - public static Collection getContributedWellbehavingDerivedFeatures() { - return contributedWellbehavingDerivedFeatures; - } - - public static Collection getContributedWellbehavingDerivedClasses() { - return contributedWellbehavingDerivedClasses; - } - - public static Collection getContributedWellbehavingDerivedPackages() { - return contributedWellbehavingDerivedPackages; - } - - public static boolean isWellbehavingFeature(EStructuralFeature feature) { - if (contributedWellbehavingDerivedFeatures.contains(feature)) { - return true; - } else if (contributedWellbehavingDerivedClasses.contains(feature.getEContainingClass())) { - return true; - } else if (contributedWellbehavingDerivedPackages.contains(feature.getEContainingClass().getEPackage())) { - return true; - } - return false; - } + poi = reg.getExtensionPoint(IncQueryBasePlugin.WELLBEHAVING_DERIVED_FEATURE_EXTENSION_POINT_ID); + if (poi != null) { + IExtension[] exts = poi.getExtensions(); + + for (IExtension ext : exts) { + + IConfigurationElement[] els = ext.getConfigurationElements(); + for (IConfigurationElement el : els) { + if (el.getName().equals("wellbehaving-derived-feature")) { + processWellbehavingExtension(el); + } else { + throw new UnsupportedOperationException("Unknown configuration element " + el.getName() + + " in plugin.xml of " + el.getDeclaringExtension().getUniqueIdentifier()); + } + } + } + } + } + + /** + * @param el + */ + private static void processWellbehavingExtension(IConfigurationElement el) { + try { + String packageUri = el.getAttribute("package-nsUri"); + String classifierName = el.getAttribute("classifier-name"); + String featureName = el.getAttribute("feature-name"); + if (packageUri != null) { + EPackage pckg = EPackage.Registry.INSTANCE.getEPackage(packageUri); + if (pckg != null) { + if (classifierName != null) { + EClassifier clsr = pckg.getEClassifier(classifierName); + if (clsr instanceof EClass) { + if (featureName != null) { + EClass cls = (EClass) clsr; + EStructuralFeature feature = cls.getEStructuralFeature(featureName); + if (feature != null) { + contributedWellbehavingDerivedFeatures.add(feature); + } + } else { + contributedWellbehavingDerivedClasses.add((EClass) clsr); + } + } + } else { + contributedWellbehavingDerivedPackages.add(pckg); + } + } + } + } catch (Exception e) { + final Logger logger = Logger.getLogger(WellbehavingDerivedFeatureRegistry.class); + logger.error("Well-behaving feature registration failed", e); + } + } + + /** + * @param feature + */ + public static void registerWellbehavingDerivedFeature(EStructuralFeature feature) { + contributedWellbehavingDerivedFeatures.add(feature); + } + + /** + * @param feature + */ + public static void registerWellbehavingDerivedClass(EClass cls) { + contributedWellbehavingDerivedClasses.add(cls); + } + + /** + * @param feature + */ + public static void registerWellbehavingDerivedPackage(EPackage pkg) { + contributedWellbehavingDerivedPackages.add(pkg); + } + + /** + * @return the contributedWellbehavingDerivedFeatures + */ + public static Collection getContributedWellbehavingDerivedFeatures() { + return contributedWellbehavingDerivedFeatures; + } + + public static Collection getContributedWellbehavingDerivedClasses() { + return contributedWellbehavingDerivedClasses; + } + + public static Collection getContributedWellbehavingDerivedPackages() { + return contributedWellbehavingDerivedPackages; + } + + public static boolean isWellbehavingFeature(EStructuralFeature feature) { + if (contributedWellbehavingDerivedFeatures.contains(feature)) { + return true; + } else if (contributedWellbehavingDerivedClasses.contains(feature.getEContainingClass())) { + return true; + } else if (contributedWellbehavingDerivedPackages.contains(feature.getEContainingClass().getEPackage())) { + return true; + } + return false; + } } diff --git a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/EMFDataSource.java b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/EMFDataSource.java index e5ef6e0c..ccf0d518 100644 --- a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/EMFDataSource.java +++ b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/EMFDataSource.java @@ -9,9 +9,8 @@ * Tamas Szabo, Gabor Bergmann - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.core; - - +package org.eclipse.incquery.runtime.base.core; + import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; @@ -27,150 +26,148 @@ import org.eclipse.emf.ecore.util.EObjectEList; import org.eclipse.incquery.runtime.base.itc.igraph.IGraphDataSource; import org.eclipse.incquery.runtime.base.itc.igraph.IGraphObserver; - -public abstract class EMFDataSource implements IGraphDataSource { - - - private static abstract class ForNotifier extends EMFDataSource { - - private static final long serialVersionUID = -1156614160439765303L; - protected Notifier root; - - public ForNotifier(Notifier root, Set _refToObserv) { - this.root = root; - refToObserv = _refToObserv; - } - - } - - public static class ForEObject extends ForNotifier { - - private static final long serialVersionUID = 5213298003205081695L; - - public ForEObject(EObject root, Set _refToObserv) { - super(root, _refToObserv); - } - - @Override - public Set getAllNodes() { - EObject rootObj = (EObject) root; - HashSet set = new HashSet(); - set.add(rootObj); - TreeIterator iterator = rootObj.eAllContents(); - - while (iterator.hasNext()) { - set.add(iterator.next()); - } - - return set; - } - } - - public static class ForResource extends ForNotifier { - - private static final long serialVersionUID = 7372972311144593543L; - - public ForResource(Resource root, Set _refToObserv) { - super(root, _refToObserv); - } - - @Override - public Set getAllNodes() { - Resource rootResource = (Resource) root; - HashSet set = new HashSet(); - TreeIterator iterator = rootResource.getAllContents(); - while (iterator.hasNext()) { - set.add(iterator.next()); - } - return set; - } - } - - public static class ForResourceSet extends ForNotifier { - - private static final long serialVersionUID = 4619478637173366088L; - - public ForResourceSet(ResourceSet root, Set _refToObserv) { - super(root, _refToObserv); - } - - @Override - public Set getAllNodes() { - ResourceSet rootResourceSet = (ResourceSet) root; - HashSet set = new HashSet(); - - for (Resource res : rootResourceSet.getResources()) { - TreeIterator iterator = res.getAllContents(); - while (iterator.hasNext()) { - set.add(iterator.next()); - } - } - - return set; - } - } - - private static void collectContents(Object obj, List contents) { - if (obj instanceof EObjectEList) { - @SuppressWarnings("unchecked") - EObjectEList list = (EObjectEList) obj; - Iterator it = list.iterator(); - - while (it.hasNext()) { - contents.add(it.next()); - } - } - else if (obj instanceof EObject) { - contents.add((EObject) obj); - } - } - - ArrayList> observers = new ArrayList>();; - Set refToObserv; - - @Override - public void attachObserver(IGraphObserver go) { - observers.add(go); - } - - @Override - public void detachObserver(IGraphObserver go) { - observers.remove(go); - } - - public void notifyEdgeInserted(EObject source, EObject target) { - for (IGraphObserver o : observers) { - o.edgeInserted(source, target); - } - } - - public void notifyEdgeDeleted(EObject source, EObject target) { - for (IGraphObserver o : observers) { - o.edgeDeleted(source, target); - } - } - - public void notifyNodeInserted(EObject node) { - for (IGraphObserver o : observers) { - o.nodeInserted(node); - } - } - - public void notifyNodeDeleted(EObject node) { - for (IGraphObserver o : observers) { - o.nodeDeleted(node); - } - } - - @Override - public ArrayList getTargetNodes(EObject source) { - ArrayList targetNodes = new ArrayList(); - - for (EReference ref : source.eClass().getEAllReferences()) { - if (refToObserv.contains(ref)) { - collectContents(source.eGet(ref), targetNodes); - } - } - return targetNodes; - } -} + +public abstract class EMFDataSource implements IGraphDataSource { + + private static abstract class ForNotifier extends EMFDataSource { + + private static final long serialVersionUID = -1156614160439765303L; + protected Notifier root; + + public ForNotifier(Notifier root, Set _refToObserv) { + this.root = root; + refToObserv = _refToObserv; + } + + } + + public static class ForEObject extends ForNotifier { + + private static final long serialVersionUID = 5213298003205081695L; + + public ForEObject(EObject root, Set _refToObserv) { + super(root, _refToObserv); + } + + @Override + public Set getAllNodes() { + EObject rootObj = (EObject) root; + HashSet set = new HashSet(); + set.add(rootObj); + TreeIterator iterator = rootObj.eAllContents(); + + while (iterator.hasNext()) { + set.add(iterator.next()); + } + + return set; + } + } + + public static class ForResource extends ForNotifier { + + private static final long serialVersionUID = 7372972311144593543L; + + public ForResource(Resource root, Set _refToObserv) { + super(root, _refToObserv); + } + + @Override + public Set getAllNodes() { + Resource rootResource = (Resource) root; + HashSet set = new HashSet(); + TreeIterator iterator = rootResource.getAllContents(); + while (iterator.hasNext()) { + set.add(iterator.next()); + } + return set; + } + } + + public static class ForResourceSet extends ForNotifier { + + private static final long serialVersionUID = 4619478637173366088L; + + public ForResourceSet(ResourceSet root, Set _refToObserv) { + super(root, _refToObserv); + } + + @Override + public Set getAllNodes() { + ResourceSet rootResourceSet = (ResourceSet) root; + HashSet set = new HashSet(); + + for (Resource res : rootResourceSet.getResources()) { + TreeIterator iterator = res.getAllContents(); + while (iterator.hasNext()) { + set.add(iterator.next()); + } + } + + return set; + } + } + + private static void collectContents(Object obj, List contents) { + if (obj instanceof EObjectEList) { + @SuppressWarnings("unchecked") + EObjectEList list = (EObjectEList) obj; + Iterator it = list.iterator(); + + while (it.hasNext()) { + contents.add(it.next()); + } + } else if (obj instanceof EObject) { + contents.add((EObject) obj); + } + } + + ArrayList> observers = new ArrayList>();; + Set refToObserv; + + @Override + public void attachObserver(IGraphObserver go) { + observers.add(go); + } + + @Override + public void detachObserver(IGraphObserver go) { + observers.remove(go); + } + + public void notifyEdgeInserted(EObject source, EObject target) { + for (IGraphObserver o : observers) { + o.edgeInserted(source, target); + } + } + + public void notifyEdgeDeleted(EObject source, EObject target) { + for (IGraphObserver o : observers) { + o.edgeDeleted(source, target); + } + } + + public void notifyNodeInserted(EObject node) { + for (IGraphObserver o : observers) { + o.nodeInserted(node); + } + } + + public void notifyNodeDeleted(EObject node) { + for (IGraphObserver o : observers) { + o.nodeDeleted(node); + } + } + + @Override + public ArrayList getTargetNodes(EObject source) { + ArrayList targetNodes = new ArrayList(); + + for (EReference ref : source.eClass().getEAllReferences()) { + if (refToObserv.contains(ref)) { + collectContents(source.eGet(ref), targetNodes); + } + } + return targetNodes; + } +} diff --git a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/NavigationHelperContentAdapter.java b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/NavigationHelperContentAdapter.java index cc3e017f..fb0162b4 100644 --- a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/NavigationHelperContentAdapter.java +++ b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/NavigationHelperContentAdapter.java @@ -9,8 +9,8 @@ * Tamas Szabo, Gabor Bergmann - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.core; - +package org.eclipse.incquery.runtime.base.core; + import java.lang.reflect.InvocationTargetException; import java.util.Collection; import java.util.Collections; @@ -46,665 +46,649 @@ import com.google.common.collect.ListMultimap; import com.google.common.collect.Multiset; import com.google.common.collect.Table; - -public class NavigationHelperContentAdapter extends EContentAdapter { - - public static final EClass eObjectClass = EcorePackage.eINSTANCE - .getEObject(); - - // value -> feature (attr or ref) -> holder(s) - protected Map>> featureMap; - - // feature -> holder(s) - protected Map> reversedFeatureMap; - - // eclass -> instance(s) - protected Map> instanceMap; - - // edatatype -> multiset of value(s) - protected Map> dataTypeMap; - - // source -> feature -> proxy target -> delayed visitors - protected Table> unresolvableProxyFeaturesMap; - - // proxy source -> delayed visitors - protected ListMultimap unresolvableProxyObjectsMap; - - - // static for all eClasses whose instances were encountered at least once - private static Set knownClasses = new HashSet(); - // static for eclass -> all subtypes in knownClasses - protected static Map> subTypeMap = new HashMap>(); - - - private NavigationHelperImpl navigationHelper; - - // since last run of after-update callbacks - boolean isDirty = false; - - public NavigationHelperContentAdapter(NavigationHelperImpl navigationHelper) { - this.navigationHelper = navigationHelper; - this.featureMap = new HashMap>>(); - this.instanceMap = new HashMap>(); - this.dataTypeMap = new HashMap>(); - this.unresolvableProxyFeaturesMap = HashBasedTable.create(); - this.unresolvableProxyObjectsMap = ArrayListMultimap.create(); - } - - public Map> getReversedFeatureMap() { - if (reversedFeatureMap == null) { - reversedFeatureMap = new HashMap>(); - initReversedFeatureMap(); - } - return reversedFeatureMap; - } - - @Override - public void notifyChanged(Notification notification) { - try { - //baseHandleNotification(notification); - super.notifyChanged(notification); - - Object oFeature = notification.getFeature(); - final Object oNotifier = notification.getNotifier(); - if (oNotifier instanceof EObject - && oFeature instanceof EStructuralFeature) { - final EObject notifier = (EObject) oNotifier; - final EStructuralFeature feature = (EStructuralFeature) oFeature; - final Object oldValue = notification.getOldValue(); - final Object newValue = notification.getNewValue(); - final int eventType = notification.getEventType(); - switch (eventType) { - case Notification.ADD: - featureUpdate(true, notifier, feature, newValue); - break; - case Notification.ADD_MANY: - for (Object newElement : (Collection) newValue) - featureUpdate(true, notifier, feature, newElement); - break; - case Notification.CREATE: - break; - case Notification.MOVE: - break; // currently no support for ordering - case Notification.REMOVE: - featureUpdate(false, notifier, feature, oldValue); - break; - case Notification.REMOVE_MANY: - for (Object oldElement : (Collection) oldValue) - featureUpdate(false, notifier, feature, oldElement); - break; - case Notification.REMOVING_ADAPTER: break; - case Notification.RESOLVE: - featureResolve(notifier, feature, oldValue, newValue); - break; - case Notification.UNSET: - case Notification.SET: - featureUpdate(false, notifier, feature, oldValue); - featureUpdate(true, notifier, feature, newValue); - break; - } - } - // if (feature instanceof EReference) { - // handleReferenceChange(notification, (EReferenceImpl) feature); - // } - // if (feature instanceof EAttribute) { - // handleAttributeChange(notification, (EAttribute) feature); - // } - } catch (Exception ex) { - processingError(ex, "handle the following update notification: " + notification); - } - - if (isDirty) { - isDirty = false; - navigationHelper.runAfterUpdateCallbacks(); - } - - } - - - private void featureResolve(EObject source, EStructuralFeature feature, Object oldValue, Object newValue) { - EReference reference = (EReference) feature; - EObject proxy = (EObject) oldValue; - EObject resolved = (EObject) newValue; - - final List objectVisitors = popVisitorsSuspendedOnObject(proxy); - for (EMFVisitor visitor : objectVisitors) { - EMFModelComprehension.traverseObject(visitor, resolved); - } - - final List featureVisitors = popVisitorsSuspendedOnFeature(source, reference, proxy); - for (EMFVisitor visitor : featureVisitors) { - EMFModelComprehension.traverseFeature(visitor, source, reference, resolved); - } - } - - private void featureUpdate(boolean isInsertion, EObject notifier, - EStructuralFeature feature, Object value) { - EMFModelComprehension.traverseFeature(visitor(isInsertion), notifier, - feature, value); - } - - @Override - protected void addAdapter(final Notifier notifier) { - try { - this.navigationHelper.coalesceTraversals(new Callable() { - @Override - public Void call() throws Exception { - if (notifier instanceof EObject) { - EMFModelComprehension.traverseObject(visitor(true), - (EObject) notifier); - } - NavigationHelperContentAdapter.super.addAdapter(notifier); - return null; + +public class NavigationHelperContentAdapter extends EContentAdapter { + + public static final EClass eObjectClass = EcorePackage.eINSTANCE.getEObject(); + + // value -> feature (attr or ref) -> holder(s) + protected Map>> featureMap; + + // feature -> holder(s) + protected Map> reversedFeatureMap; + + // eclass -> instance(s) + protected Map> instanceMap; + + // edatatype -> multiset of value(s) + protected Map> dataTypeMap; + + // source -> feature -> proxy target -> delayed visitors + protected Table> unresolvableProxyFeaturesMap; + + // proxy source -> delayed visitors + protected ListMultimap unresolvableProxyObjectsMap; + + // static for all eClasses whose instances were encountered at least once + private static Set knownClasses = new HashSet(); + // static for eclass -> all subtypes in knownClasses + protected static Map> subTypeMap = new HashMap>(); + + private NavigationHelperImpl navigationHelper; + + // since last run of after-update callbacks + boolean isDirty = false; + + public NavigationHelperContentAdapter(NavigationHelperImpl navigationHelper) { + this.navigationHelper = navigationHelper; + this.featureMap = new HashMap>>(); + this.instanceMap = new HashMap>(); + this.dataTypeMap = new HashMap>(); + this.unresolvableProxyFeaturesMap = HashBasedTable.create(); + this.unresolvableProxyObjectsMap = ArrayListMultimap.create(); + } + + public Map> getReversedFeatureMap() { + if (reversedFeatureMap == null) { + reversedFeatureMap = new HashMap>(); + initReversedFeatureMap(); + } + return reversedFeatureMap; + } + + @Override + public void notifyChanged(Notification notification) { + try { + // baseHandleNotification(notification); + super.notifyChanged(notification); + + Object oFeature = notification.getFeature(); + final Object oNotifier = notification.getNotifier(); + if (oNotifier instanceof EObject && oFeature instanceof EStructuralFeature) { + final EObject notifier = (EObject) oNotifier; + final EStructuralFeature feature = (EStructuralFeature) oFeature; + final Object oldValue = notification.getOldValue(); + final Object newValue = notification.getNewValue(); + final int eventType = notification.getEventType(); + switch (eventType) { + case Notification.ADD: + featureUpdate(true, notifier, feature, newValue); + break; + case Notification.ADD_MANY: + for (Object newElement : (Collection) newValue) + featureUpdate(true, notifier, feature, newElement); + break; + case Notification.CREATE: + break; + case Notification.MOVE: + break; // currently no support for ordering + case Notification.REMOVE: + featureUpdate(false, notifier, feature, oldValue); + break; + case Notification.REMOVE_MANY: + for (Object oldElement : (Collection) oldValue) + featureUpdate(false, notifier, feature, oldElement); + break; + case Notification.REMOVING_ADAPTER: + break; + case Notification.RESOLVE: + featureResolve(notifier, feature, oldValue, newValue); + break; + case Notification.UNSET: + case Notification.SET: + featureUpdate(false, notifier, feature, oldValue); + featureUpdate(true, notifier, feature, newValue); + break; + } + } + // if (feature instanceof EReference) { + // handleReferenceChange(notification, (EReferenceImpl) feature); + // } + // if (feature instanceof EAttribute) { + // handleAttributeChange(notification, (EAttribute) feature); + // } + } catch (Exception ex) { + processingError(ex, "handle the following update notification: " + notification); + } + + if (isDirty) { + isDirty = false; + navigationHelper.runAfterUpdateCallbacks(); + } + + } + + private void featureResolve(EObject source, EStructuralFeature feature, Object oldValue, Object newValue) { + EReference reference = (EReference) feature; + EObject proxy = (EObject) oldValue; + EObject resolved = (EObject) newValue; + + final List objectVisitors = popVisitorsSuspendedOnObject(proxy); + for (EMFVisitor visitor : objectVisitors) { + EMFModelComprehension.traverseObject(visitor, resolved); + } + + final List featureVisitors = popVisitorsSuspendedOnFeature(source, reference, proxy); + for (EMFVisitor visitor : featureVisitors) { + EMFModelComprehension.traverseFeature(visitor, source, reference, resolved); + } + } + + private void featureUpdate(boolean isInsertion, EObject notifier, EStructuralFeature feature, Object value) { + EMFModelComprehension.traverseFeature(visitor(isInsertion), notifier, feature, value); + } + + @Override + protected void addAdapter(final Notifier notifier) { + try { + this.navigationHelper.coalesceTraversals(new Callable() { + @Override + public Void call() throws Exception { + if (notifier instanceof EObject) { + EMFModelComprehension.traverseObject(visitor(true), (EObject) notifier); + } + NavigationHelperContentAdapter.super.addAdapter(notifier); + return null; + } + }); + } catch (InvocationTargetException ex) { + processingError(ex.getCause(), "add the object: " + notifier); + } catch (Exception ex) { + processingError(ex, "add the object: " + notifier); + } + } + + @Override + protected void removeAdapter(final Notifier notifier) { + try { + this.navigationHelper.coalesceTraversals(new Callable() { + @Override + public Void call() throws Exception { + if (notifier instanceof EObject) { + EMFModelComprehension.traverseObject(visitor(false), (EObject) notifier); + } + NavigationHelperContentAdapter.super.removeAdapter(notifier); + return null; + } + }); + } catch (InvocationTargetException ex) { + processingError(ex.getCause(), "remove the object: " + notifier); + } catch (Exception ex) { + processingError(ex, "remove the object: " + notifier); + } + } + + private void processingError(Throwable ex, String task) { + navigationHelper.getLogger().fatal( + "EMF-IncQuery encountered an error in processing the EMF model. " + "This happened while trying to " + + task, ex); + // throw new + // IncQueryRuntimeException(IncQueryRuntimeException.EMF_MODEL_PROCESSING_ERROR, + // ex); + } + + protected EMFVisitor visitor(final boolean isInsertion) { + return new NavigationHelperVisitor.ChangeVisitor(navigationHelper, isInsertion); + } + + // @SuppressWarnings("unchecked") + // public void handleReferenceChange(Notification notification, EReference + // ref) { + // EObject notifier = (EObject) notification.getNotifier(); + // + // if (notification.getEventType() == Notification.REMOVE_MANY) { + // for (EObject oldValue: (Collection) + // notification.getOldValue()) { + // handleReferenceRemove(ref, oldValue, null, notifier); + // } + // } + // else if (notification.getEventType() == Notification.ADD_MANY) { + // for (EObject newValue: (Collection) + // notification.getNewValue()) { + // handleReferenceAdd(ref, newValue, notifier); + // } + // } + // else if (notification.getEventType() == Notification.ADD) { + // handleReferenceAdd(ref, (EObject) notification.getNewValue(), notifier); + // } + // else if (notification.getEventType() == Notification.REMOVE) { + // handleReferenceRemove(ref, (EObject) notification.getOldValue(), + // (EObject) notification.getNewValue(), notifier); + // } + // if (notification.getEventType() == Notification.SET || + // notification.getEventType() == Notification.UNSET) { + // EObject oldValue = (EObject) notification.getOldValue(); + // EObject newValue = (EObject) notification.getNewValue(); + // + // if (oldValue != null) { + // removeFeatureTuple(ref, oldValue, notifier); + // removeInstanceTuple(oldValue.eClass(), oldValue); + // + // if (ref.isContainment()) + // navigationHelper.getVisitor().visitObjectForEAttribute(oldValue, + // navigationHelper.getObservedFeatures(), + // navigationHelper.getObservedDataTypes(), false); + // } + // if (newValue != null) { + // handleReferenceAdd(ref, newValue, notifier); + // } + // } + // } + // + // public void handleReferenceAdd(EReference ref, EObject newValue, EObject + // notifier) { + // insertFeatureTuple(ref, newValue, notifier); + // insertInstanceTuple(newValue.eClass(), newValue); + // if (ref.isContainment()) { + // navigationHelper.getVisitor().visitObjectForEAttribute(newValue, + // navigationHelper.getObservedFeatures(), + // navigationHelper.getObservedDataTypes(), true); + // } + // } + // + // public void handleReferenceRemove(EReference ref, EObject oldValue, + // EObject newValue, EObject notifier) { + // removeFeatureTuple(ref, oldValue, notifier); + // removeInstanceTuple(oldValue.eClass(), oldValue); + // + // if (ref.isContainment()) { + // navigationHelper.getVisitor().visitObjectForEAttribute(oldValue, + // navigationHelper.getObservedFeatures(), + // navigationHelper.getObservedDataTypes(), false); + // } + // + // if (newValue != null) { + // handleReferenceAdd(ref, newValue, notifier); + // } + // } + // + // public void handleAttributeChange(Notification notification, EAttribute + // attribute) { + // Object oldValue = notification.getOldValue(); + // Object newValue = notification.getNewValue(); + // EObject notifier = (EObject) notification.getNotifier(); + // final EDataType eAttributeType = attribute.getEAttributeType(); + // + // if (notification.getEventType() == Notification.SET || + // notification.getEventType() == Notification.UNSET) { + // if (oldValue != null) { + // removeFeatureTuple(attribute, oldValue, notifier); + // dataTypeInstanceUpdate(eAttributeType, oldValue, false); + // } + // if (newValue != null) { + // insertFeatureTuple(attribute, newValue, notifier); + // dataTypeInstanceUpdate(eAttributeType, newValue, true); + // } + // } + // } + + private void addToFeatureMap(EStructuralFeature feature, Object value, EObject holder) { + Map> mapVal = featureMap.get(value); + Set setVal = null; + + if (mapVal == null) { + mapVal = new HashMap>(); + } + if ((setVal = mapVal.get(feature)) == null) { + setVal = new HashSet(); + } + setVal.add(holder); + mapVal.put(feature, setVal); + featureMap.put(value, mapVal); + } + + private void addToReversedFeatureMap(EStructuralFeature feature, EObject holder) { + Multiset setVal = reversedFeatureMap.get(feature); + + if (setVal == null) { + setVal = HashMultiset.create(); + } + setVal.add(holder); + reversedFeatureMap.put(feature, setVal); + } + + private void removeFromReversedFeatureMap(EStructuralFeature feature, EObject holder) { + if (reversedFeatureMap.containsKey(feature)) { + reversedFeatureMap.get(feature).remove(holder); + + if (reversedFeatureMap.get(feature).size() == 0) { + reversedFeatureMap.remove(feature); + } + } + } + + private void removeFromFeatureMap(EStructuralFeature feature, Object value, EObject holder) { + if (featureMap.containsKey(value) && featureMap.get(value).containsKey(feature)) { + featureMap.get(value).get(feature).remove(holder); + + if (featureMap.get(value).get(feature).size() == 0) { + featureMap.get(value).remove(feature); + } + + if (featureMap.get(value).size() == 0) { + featureMap.remove(value); + } + } + } + + private void addToDataTypeMap(EDataType type, Object value) { + Map valMap = dataTypeMap.get(type); + if (valMap == null) { + valMap = new HashMap(); + dataTypeMap.put(type, valMap); } - }); - } catch (InvocationTargetException ex) { - processingError(ex.getCause(), "add the object: " + notifier); - } catch (Exception ex) { - processingError(ex, "add the object: " + notifier); - } - } - - @Override - protected void removeAdapter(final Notifier notifier) { - try { - this.navigationHelper.coalesceTraversals(new Callable() { - @Override - public Void call() throws Exception { - if (notifier instanceof EObject) { - EMFModelComprehension.traverseObject(visitor(false), - (EObject) notifier); - } - NavigationHelperContentAdapter.super.removeAdapter(notifier); - return null; + if (valMap.get(value) == null) { + valMap.put(value, Integer.valueOf(1)); + } else { + Integer count = valMap.get(value); + valMap.put(value, ++count); } - }); - } catch (InvocationTargetException ex) { - processingError(ex.getCause(), "remove the object: " + notifier); - } catch (Exception ex) { - processingError(ex, "remove the object: " + notifier); - } - } - - private void processingError(Throwable ex, String task) { - navigationHelper.getLogger().fatal( - "EMF-IncQuery encountered an error in processing the EMF model. " - + "This happened while trying to " + task, ex); - // throw new - // IncQueryRuntimeException(IncQueryRuntimeException.EMF_MODEL_PROCESSING_ERROR, - // ex); - } - - protected EMFVisitor visitor(final boolean isInsertion) { - return new NavigationHelperVisitor.ChangeVisitor(navigationHelper, - isInsertion); - } - - // @SuppressWarnings("unchecked") - // public void handleReferenceChange(Notification notification, EReference - // ref) { - // EObject notifier = (EObject) notification.getNotifier(); - // - // if (notification.getEventType() == Notification.REMOVE_MANY) { - // for (EObject oldValue: (Collection) - // notification.getOldValue()) { - // handleReferenceRemove(ref, oldValue, null, notifier); - // } - // } - // else if (notification.getEventType() == Notification.ADD_MANY) { - // for (EObject newValue: (Collection) - // notification.getNewValue()) { - // handleReferenceAdd(ref, newValue, notifier); - // } - // } - // else if (notification.getEventType() == Notification.ADD) { - // handleReferenceAdd(ref, (EObject) notification.getNewValue(), notifier); - // } - // else if (notification.getEventType() == Notification.REMOVE) { - // handleReferenceRemove(ref, (EObject) notification.getOldValue(), - // (EObject) notification.getNewValue(), notifier); - // } - // if (notification.getEventType() == Notification.SET || - // notification.getEventType() == Notification.UNSET) { - // EObject oldValue = (EObject) notification.getOldValue(); - // EObject newValue = (EObject) notification.getNewValue(); - // - // if (oldValue != null) { - // removeFeatureTuple(ref, oldValue, notifier); - // removeInstanceTuple(oldValue.eClass(), oldValue); - // - // if (ref.isContainment()) - // navigationHelper.getVisitor().visitObjectForEAttribute(oldValue, - // navigationHelper.getObservedFeatures(), - // navigationHelper.getObservedDataTypes(), false); - // } - // if (newValue != null) { - // handleReferenceAdd(ref, newValue, notifier); - // } - // } - // } - // - // public void handleReferenceAdd(EReference ref, EObject newValue, EObject - // notifier) { - // insertFeatureTuple(ref, newValue, notifier); - // insertInstanceTuple(newValue.eClass(), newValue); - // if (ref.isContainment()) { - // navigationHelper.getVisitor().visitObjectForEAttribute(newValue, - // navigationHelper.getObservedFeatures(), - // navigationHelper.getObservedDataTypes(), true); - // } - // } - // - // public void handleReferenceRemove(EReference ref, EObject oldValue, - // EObject newValue, EObject notifier) { - // removeFeatureTuple(ref, oldValue, notifier); - // removeInstanceTuple(oldValue.eClass(), oldValue); - // - // if (ref.isContainment()) { - // navigationHelper.getVisitor().visitObjectForEAttribute(oldValue, - // navigationHelper.getObservedFeatures(), - // navigationHelper.getObservedDataTypes(), false); - // } - // - // if (newValue != null) { - // handleReferenceAdd(ref, newValue, notifier); - // } - // } - // - // public void handleAttributeChange(Notification notification, EAttribute - // attribute) { - // Object oldValue = notification.getOldValue(); - // Object newValue = notification.getNewValue(); - // EObject notifier = (EObject) notification.getNotifier(); - // final EDataType eAttributeType = attribute.getEAttributeType(); - // - // if (notification.getEventType() == Notification.SET || - // notification.getEventType() == Notification.UNSET) { - // if (oldValue != null) { - // removeFeatureTuple(attribute, oldValue, notifier); - // dataTypeInstanceUpdate(eAttributeType, oldValue, false); - // } - // if (newValue != null) { - // insertFeatureTuple(attribute, newValue, notifier); - // dataTypeInstanceUpdate(eAttributeType, newValue, true); - // } - // } - // } - - private void addToFeatureMap(EStructuralFeature feature, Object value, - EObject holder) { - Map> mapVal = featureMap.get(value); - Set setVal = null; - - if (mapVal == null) { - mapVal = new HashMap>(); - } - if ((setVal = mapVal.get(feature)) == null) { - setVal = new HashSet(); - } - setVal.add(holder); - mapVal.put(feature, setVal); - featureMap.put(value, mapVal); - } - - private void addToReversedFeatureMap(EStructuralFeature feature, - EObject holder) { - Multiset setVal = reversedFeatureMap.get(feature); - - if (setVal == null) { - setVal = HashMultiset.create(); - } - setVal.add(holder); - reversedFeatureMap.put(feature, setVal); - } - - private void removeFromReversedFeatureMap(EStructuralFeature feature, - EObject holder) { - if (reversedFeatureMap.containsKey(feature)) { - reversedFeatureMap.get(feature).remove(holder); - - if (reversedFeatureMap.get(feature).size() == 0) { - reversedFeatureMap.remove(feature); - } - } - } - - private void removeFromFeatureMap(EStructuralFeature feature, Object value, - EObject holder) { - if (featureMap.containsKey(value) - && featureMap.get(value).containsKey(feature)) { - featureMap.get(value).get(feature).remove(holder); - - if (featureMap.get(value).get(feature).size() == 0) { - featureMap.get(value).remove(feature); - } - - if (featureMap.get(value).size() == 0) { - featureMap.remove(value); - } - } - } - - private void addToDataTypeMap(EDataType type, Object value) { - Map valMap = dataTypeMap.get(type); - if (valMap == null) { - valMap = new HashMap(); - dataTypeMap.put(type, valMap); - } - if (valMap.get(value) == null) { - valMap.put(value, Integer.valueOf(1)); - } else { - Integer count = valMap.get(value); - valMap.put(value, ++count); - } - } - - private void removeFromDataTypeMmap(EDataType type, Object value) { - Map valMap = dataTypeMap.get(type); - if (valMap != null) { - if (valMap.get(value) != null) { - Integer count = valMap.get(value); - if (--count == 0) { - valMap.remove(value); - } else { - valMap.put(value, count); - } - } - if (valMap.size() == 0) { - dataTypeMap.remove(type); - } - } - } - - public void insertFeatureTuple(EStructuralFeature feature, Object value, - EObject holder) { - // if ((navigationHelper.getType() == NavigationHelperType.ALL) || - // navigationHelper.getObservedFeatures().contains(feature)) { - addToFeatureMap(feature, value, holder); - - if (reversedFeatureMap != null) { - addToReversedFeatureMap(feature, holder); - } - - isDirty = true; - notifyFeatureListeners(holder, feature, value, true); - // } - } - - public void removeFeatureTuple(EStructuralFeature feature, Object value, - EObject holder) { - // if ((navigationHelper.getType() == NavigationHelperType.ALL) || - // navigationHelper.getObservedFeatures().contains(feature)) { - removeFromFeatureMap(feature, value, holder); - - if (reversedFeatureMap != null) { - removeFromReversedFeatureMap(feature, holder); - } - - isDirty = true; - notifyFeatureListeners(holder, feature, value, false); - // } - } - - public void dataTypeInstanceUpdate(EDataType type, Object value, - boolean isInsertion) { - // if ((navigationHelper.getType() == NavigationHelperType.ALL) || - // navigationHelper.getObservedDataTypes().contains(type)) { - if (isInsertion) { - addToDataTypeMap(type, value); - } else { - removeFromDataTypeMmap(type, value); - } - isDirty = true; - notifyDataTypeListeners(type, value, isInsertion); - // } - } - - public void insertInstanceTuple(EClass key, EObject value) { - // if (navigationHelper.isObserved(key)) { - if (instanceMap.containsKey(key)) { - instanceMap.get(key).add(value); - } else { - HashSet set = new HashSet(); - set.add(value); - instanceMap.put(key, set); - } - - isDirty = true; - notifyInstanceListeners(key, value, true); - // } - } - - void removeInstanceTuple(EClass key, EObject value) { - // if (navigationHelper.isObserved(key)) { - if (instanceMap.containsKey(key)) { - instanceMap.get(key).remove(value); - if (instanceMap.get(key).size() == 0) { - instanceMap.remove(key); - } - } - - isDirty = true; - notifyInstanceListeners(key, value, false); - // } - } - - /** - * Returns true if sup is a supertype of sub. - * - * @param sub - * subtype - * @param sup - * supertype - * @return - */ - private boolean isSubTypeOf(EClass sub, EClass sup) { - Set set = subTypeMap.get(sup); - if (set != null) { - return set.contains(sub); - } else { - return false; - } - } - - /** - * put subtype information into cache - */ - protected void maintainTypeHierarchy(EClass clazz) { - if (!knownClasses.contains(clazz)) { - knownClasses.add(clazz); - - for (EClass superType : clazz.getEAllSuperTypes()) { - maintainTypeHierarhyInternal(clazz, superType); - } - maintainTypeHierarhyInternal(clazz, eObjectClass); - } - } - - private void maintainTypeHierarhyInternal(EClass clazz, EClass superType) { - if (navigationHelper.directlyObservedClasses.contains(superType)) { - navigationHelper.getAllObservedClasses().add(clazz); - } - - Set set = subTypeMap.get(superType); - if (set == null) { - set = new HashSet(); - subTypeMap.put(superType, set); - } - set.add(clazz); - } - - private void notifyDataTypeListeners(EDataType type, Object value, - boolean isInsertion) { - for (Entry> entry : navigationHelper - .getDataTypeListeners().entrySet()) { - if (entry.getValue().contains(type)) { - if (isInsertion) { - entry.getKey().dataTypeInstanceInserted(type, value); - } else { - entry.getKey().dataTypeInstanceDeleted(type, value); - } - } - } - } - - private void notifyFeatureListeners(EObject host, - EStructuralFeature feature, Object value, boolean isInsertion) { - for (Entry> entry : navigationHelper - .getFeatureListeners().entrySet()) { - if (entry.getValue().contains(feature)) { - if (isInsertion) { - entry.getKey().featureInserted(host, feature, value); - } else { - entry.getKey().featureDeleted(host, feature, value); - } - } - } - } - - private void notifyInstanceListeners(EClass clazz, EObject instance, - boolean isInsertion) { - for (Entry> entry : navigationHelper - .getInstanceListeners().entrySet()) { - for (EClass sup : entry.getValue()) { - if (isSubTypeOf(clazz, sup) || clazz.equals(sup)) { - if (isInsertion) { - entry.getKey().instanceInserted(sup, instance); - } else { - entry.getKey().instanceDeleted(sup, instance); - } - } - } - } - } - - private void initReversedFeatureMap() { - for (Entry>> valueToFeatureHolderMap : featureMap.entrySet()) { - for (Entry> featureToHolders : valueToFeatureHolderMap.getValue().entrySet()) { - final EStructuralFeature feature = featureToHolders.getKey(); - for (EObject holder : featureToHolders.getValue()) { - addToReversedFeatureMap(feature, holder); - } - } - } - } - - // WORKAROUND for EContentAdapter bug - // where proxy resolution during containment traversal would add a new - // Resource to the ResourceSet (and thus the adapter) - // that will be set as target twice: - // - once when resolved (which happens while iterating through the - // resources), - // - and once when said iteration of resources reaches the end of the - // resource list in the ResourceSet - // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=385039 - - @Override - protected void setTarget(ResourceSet target) { - basicSetTarget(target); - List resources = target.getResources(); - for (int i = 0; i < resources.size(); ++i) - { - Notifier notifier = resources.get(i); - if (!notifier.eAdapters().contains(this)) - { - addAdapter(notifier); - } - } - } - -// private void baseHandleNotification(Notification notification) { -// if (notification.getNotifier() instanceof ResourceSet -// && notification.getEventType() == Notification.ADD_MANY -// && notification.getFeatureID(ResourceSet.class) == ResourceSet.RESOURCE_SET__RESOURCES) -// { -// @SuppressWarnings("unchecked") -// Collection newValues = (Collection)notification.getNewValue(); -// for (Notifier notifier : newValues) { -// if (!notifier.eAdapters().contains(this)) { -// addAdapter(notifier); -// } -// } -// } else super.notifyChanged(notification); -// } - - // WORKAROUND (TMP) for eContents vs. derived features bug - @Override - protected void setTarget(EObject target) { - basicSetTarget(target); - spreadToChildren(target, true); - } - /* (non-Javadoc) - * @see org.eclipse.emf.ecore.util.EContentAdapter#unsetTarget(org.eclipse.emf.ecore.EObject) - */ - @Override - protected void unsetTarget(EObject target) { - basicUnsetTarget(target); - spreadToChildren(target, false); - } - /** - * @param target - */ - protected void spreadToChildren(EObject target, boolean add) { - final EList features = - target.eClass().getEAllReferences(); - for (EReference feature : features) { - if (!feature.isContainment()) continue; - if (!EMFModelComprehension.representable(feature)) continue; - if (feature.isMany()) { - Collection values = (Collection) target.eGet(feature); - for (Object value : values) { - final Notifier notifier = (Notifier)value; - if (add) - addAdapter(notifier); - else - removeAdapter(notifier); - } - } else { - Object value = target.eGet(feature); - if (value != null) { - final Notifier notifier = (Notifier)value; - if (add) - addAdapter(notifier); - else - removeAdapter(notifier); - } - } - } - } - - - public void suspendVisitorOnUnresolvableFeature(EMFVisitor visitor, EObject source, EReference reference, EObject target, boolean isInsertion) { - ListMultimap targetToVisitor = unresolvableProxyFeaturesMap.get(source, reference); - if (targetToVisitor == null) { - targetToVisitor = ArrayListMultimap.create(); - unresolvableProxyFeaturesMap.put(source, reference, targetToVisitor); - } - if (isInsertion) - targetToVisitor.put(target, visitor); - else - targetToVisitor.remove(target, visitor); - if (targetToVisitor.isEmpty()) - unresolvableProxyFeaturesMap.remove(source, reference); - } - - public void suspendVisitorOnUnresolvableObject(EMFVisitor visitor, EObject source, boolean isInsertion) { - if (isInsertion) - unresolvableProxyObjectsMap.put(source, visitor); - else - unresolvableProxyObjectsMap.remove(source, visitor); - } - - List popVisitorsSuspendedOnFeature(EObject source, EReference reference, EObject target) { - ListMultimap targetToVisitor = unresolvableProxyFeaturesMap.get(source, reference); - if (targetToVisitor == null) return Collections.emptyList(); - final List result = targetToVisitor.removeAll(target); - if (targetToVisitor.isEmpty()) unresolvableProxyFeaturesMap.remove(source, reference); - return result; - } - List popVisitorsSuspendedOnObject(EObject source) { - return unresolvableProxyObjectsMap.removeAll(source); - } - - -} + } + + private void removeFromDataTypeMmap(EDataType type, Object value) { + Map valMap = dataTypeMap.get(type); + if (valMap != null) { + if (valMap.get(value) != null) { + Integer count = valMap.get(value); + if (--count == 0) { + valMap.remove(value); + } else { + valMap.put(value, count); + } + } + if (valMap.size() == 0) { + dataTypeMap.remove(type); + } + } + } + + public void insertFeatureTuple(EStructuralFeature feature, Object value, EObject holder) { + // if ((navigationHelper.getType() == NavigationHelperType.ALL) || + // navigationHelper.getObservedFeatures().contains(feature)) { + addToFeatureMap(feature, value, holder); + + if (reversedFeatureMap != null) { + addToReversedFeatureMap(feature, holder); + } + + isDirty = true; + notifyFeatureListeners(holder, feature, value, true); + // } + } + + public void removeFeatureTuple(EStructuralFeature feature, Object value, EObject holder) { + // if ((navigationHelper.getType() == NavigationHelperType.ALL) || + // navigationHelper.getObservedFeatures().contains(feature)) { + removeFromFeatureMap(feature, value, holder); + + if (reversedFeatureMap != null) { + removeFromReversedFeatureMap(feature, holder); + } + + isDirty = true; + notifyFeatureListeners(holder, feature, value, false); + // } + } + + public void dataTypeInstanceUpdate(EDataType type, Object value, boolean isInsertion) { + // if ((navigationHelper.getType() == NavigationHelperType.ALL) || + // navigationHelper.getObservedDataTypes().contains(type)) { + if (isInsertion) { + addToDataTypeMap(type, value); + } else { + removeFromDataTypeMmap(type, value); + } + isDirty = true; + notifyDataTypeListeners(type, value, isInsertion); + // } + } + + public void insertInstanceTuple(EClass key, EObject value) { + // if (navigationHelper.isObserved(key)) { + if (instanceMap.containsKey(key)) { + instanceMap.get(key).add(value); + } else { + HashSet set = new HashSet(); + set.add(value); + instanceMap.put(key, set); + } + + isDirty = true; + notifyInstanceListeners(key, value, true); + // } + } + + void removeInstanceTuple(EClass key, EObject value) { + // if (navigationHelper.isObserved(key)) { + if (instanceMap.containsKey(key)) { + instanceMap.get(key).remove(value); + if (instanceMap.get(key).size() == 0) { + instanceMap.remove(key); + } + } + + isDirty = true; + notifyInstanceListeners(key, value, false); + // } + } + + /** + * Returns true if sup is a supertype of sub. + * + * @param sub + * subtype + * @param sup + * supertype + * @return + */ + private boolean isSubTypeOf(EClass sub, EClass sup) { + Set set = subTypeMap.get(sup); + if (set != null) { + return set.contains(sub); + } else { + return false; + } + } + + /** + * put subtype information into cache + */ + protected void maintainTypeHierarchy(EClass clazz) { + if (!knownClasses.contains(clazz)) { + knownClasses.add(clazz); + + for (EClass superType : clazz.getEAllSuperTypes()) { + maintainTypeHierarhyInternal(clazz, superType); + } + maintainTypeHierarhyInternal(clazz, eObjectClass); + } + } + + private void maintainTypeHierarhyInternal(EClass clazz, EClass superType) { + if (navigationHelper.directlyObservedClasses.contains(superType)) { + navigationHelper.getAllObservedClasses().add(clazz); + } + + Set set = subTypeMap.get(superType); + if (set == null) { + set = new HashSet(); + subTypeMap.put(superType, set); + } + set.add(clazz); + } + + private void notifyDataTypeListeners(EDataType type, Object value, boolean isInsertion) { + for (Entry> entry : navigationHelper.getDataTypeListeners().entrySet()) { + if (entry.getValue().contains(type)) { + if (isInsertion) { + entry.getKey().dataTypeInstanceInserted(type, value); + } else { + entry.getKey().dataTypeInstanceDeleted(type, value); + } + } + } + } + + private void notifyFeatureListeners(EObject host, EStructuralFeature feature, Object value, boolean isInsertion) { + for (Entry> entry : navigationHelper.getFeatureListeners() + .entrySet()) { + if (entry.getValue().contains(feature)) { + if (isInsertion) { + entry.getKey().featureInserted(host, feature, value); + } else { + entry.getKey().featureDeleted(host, feature, value); + } + } + } + } + + private void notifyInstanceListeners(EClass clazz, EObject instance, boolean isInsertion) { + for (Entry> entry : navigationHelper.getInstanceListeners().entrySet()) { + for (EClass sup : entry.getValue()) { + if (isSubTypeOf(clazz, sup) || clazz.equals(sup)) { + if (isInsertion) { + entry.getKey().instanceInserted(sup, instance); + } else { + entry.getKey().instanceDeleted(sup, instance); + } + } + } + } + } + + private void initReversedFeatureMap() { + for (Entry>> valueToFeatureHolderMap : featureMap.entrySet()) { + for (Entry> featureToHolders : valueToFeatureHolderMap.getValue() + .entrySet()) { + final EStructuralFeature feature = featureToHolders.getKey(); + for (EObject holder : featureToHolders.getValue()) { + addToReversedFeatureMap(feature, holder); + } + } + } + } + + // WORKAROUND for EContentAdapter bug + // where proxy resolution during containment traversal would add a new + // Resource to the ResourceSet (and thus the adapter) + // that will be set as target twice: + // - once when resolved (which happens while iterating through the + // resources), + // - and once when said iteration of resources reaches the end of the + // resource list in the ResourceSet + // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=385039 + + @Override + protected void setTarget(ResourceSet target) { + basicSetTarget(target); + List resources = target.getResources(); + for (int i = 0; i < resources.size(); ++i) { + Notifier notifier = resources.get(i); + if (!notifier.eAdapters().contains(this)) { + addAdapter(notifier); + } + } + } + + // private void baseHandleNotification(Notification notification) { + // if (notification.getNotifier() instanceof ResourceSet + // && notification.getEventType() == Notification.ADD_MANY + // && notification.getFeatureID(ResourceSet.class) == ResourceSet.RESOURCE_SET__RESOURCES) + // { + // @SuppressWarnings("unchecked") + // Collection newValues = (Collection)notification.getNewValue(); + // for (Notifier notifier : newValues) { + // if (!notifier.eAdapters().contains(this)) { + // addAdapter(notifier); + // } + // } + // } else super.notifyChanged(notification); + // } + + // WORKAROUND (TMP) for eContents vs. derived features bug + @Override + protected void setTarget(EObject target) { + basicSetTarget(target); + spreadToChildren(target, true); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.emf.ecore.util.EContentAdapter#unsetTarget(org.eclipse.emf.ecore.EObject) + */ + @Override + protected void unsetTarget(EObject target) { + basicUnsetTarget(target); + spreadToChildren(target, false); + } + + /** + * @param target + */ + protected void spreadToChildren(EObject target, boolean add) { + final EList features = target.eClass().getEAllReferences(); + for (EReference feature : features) { + if (!feature.isContainment()) + continue; + if (!EMFModelComprehension.representable(feature)) + continue; + if (feature.isMany()) { + Collection values = (Collection) target.eGet(feature); + for (Object value : values) { + final Notifier notifier = (Notifier) value; + if (add) + addAdapter(notifier); + else + removeAdapter(notifier); + } + } else { + Object value = target.eGet(feature); + if (value != null) { + final Notifier notifier = (Notifier) value; + if (add) + addAdapter(notifier); + else + removeAdapter(notifier); + } + } + } + } + + public void suspendVisitorOnUnresolvableFeature(EMFVisitor visitor, EObject source, EReference reference, + EObject target, boolean isInsertion) { + ListMultimap targetToVisitor = unresolvableProxyFeaturesMap.get(source, reference); + if (targetToVisitor == null) { + targetToVisitor = ArrayListMultimap.create(); + unresolvableProxyFeaturesMap.put(source, reference, targetToVisitor); + } + if (isInsertion) + targetToVisitor.put(target, visitor); + else + targetToVisitor.remove(target, visitor); + if (targetToVisitor.isEmpty()) + unresolvableProxyFeaturesMap.remove(source, reference); + } + + public void suspendVisitorOnUnresolvableObject(EMFVisitor visitor, EObject source, boolean isInsertion) { + if (isInsertion) + unresolvableProxyObjectsMap.put(source, visitor); + else + unresolvableProxyObjectsMap.remove(source, visitor); + } + + List popVisitorsSuspendedOnFeature(EObject source, EReference reference, EObject target) { + ListMultimap targetToVisitor = unresolvableProxyFeaturesMap.get(source, reference); + if (targetToVisitor == null) + return Collections.emptyList(); + final List result = targetToVisitor.removeAll(target); + if (targetToVisitor.isEmpty()) + unresolvableProxyFeaturesMap.remove(source, reference); + return result; + } + + List popVisitorsSuspendedOnObject(EObject source) { + return unresolvableProxyObjectsMap.removeAll(source); + } + +} diff --git a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/NavigationHelperImpl.java b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/NavigationHelperImpl.java index 132ddcf7..cf9de75c 100644 --- a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/NavigationHelperImpl.java +++ b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/NavigationHelperImpl.java @@ -9,8 +9,8 @@ * Tamas Szabo, Gabor Bergmann - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.core; - +package org.eclipse.incquery.runtime.base.core; + import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collection; @@ -40,400 +40,403 @@ import org.eclipse.incquery.runtime.base.api.NavigationHelper; import org.eclipse.incquery.runtime.base.comprehension.EMFModelComprehension; import org.eclipse.incquery.runtime.base.exception.IncQueryBaseException; - -public class NavigationHelperImpl implements NavigationHelper { - - protected boolean inWildcardMode; - protected HashSet directlyObservedClasses; - protected HashSet allObservedClasses = null; // including subclasses - protected HashSet observedDataTypes; - protected HashSet observedFeatures; - - protected Notifier notifier; - protected Set modelRoots; - private boolean expansionAllowed; -// protected NavigationHelperVisitor visitor; - protected NavigationHelperContentAdapter contentAdapter; - - private final Logger logger; - - /** - * These global listeners will be called after updates. - */ - protected Set afterUpdateCallbacks; - - private final Map> instanceListeners; - private final Map> featureListeners; - private final Map> dataTypeListeners; - - /** - * Feature registration and model traversal is delayed while true - */ - protected boolean delayTraversals = false; - /** - * Classes to be registered once the coalescing period is over - */ - protected Set delayedClasses; - /** - * EStructuralFeatures to be registered once the coalescing period is over - */ - protected Set delayedFeatures; - /** - * EDataTypes to be registered once the coalescing period is over - */ - protected Set delayedDataTypes; - - private Set noClass() { return Collections.emptySet(); }; - private Set noDataType() { return Collections.emptySet(); }; - private Set noFeature() { return Collections.emptySet(); }; - - - Set setMinus(Set a, Set b) { - Set result = new HashSet(a); - result.removeAll(b); - return result; - } - - Set resolveAll(Set a) { - Set result = new HashSet(a); - for (T t : a) { - if (t.eIsProxy()) - result.add((T) EcoreUtil.resolve(t, (ResourceSet)null)); - else - result.add(t); - } - return result; - } - - @Override - public boolean isInWildcardMode() { - return inWildcardMode; - } -// @Override -// public void setInWildcardMode(boolean newWildcardMode) { -// if (inWildcardMode && !newWildcardMode) -// throw new UnsupportedOperationException(); -// if (!inWildcardMode && newWildcardMode) { -// this.inWildcardMode = true; -// -// this.allObservedClasses = null; -// this.directlyObservedClasses = null; -// this.observedDataTypes = null; -// this.observedFeatures = null; -// -// this.contentAdapter. // TODO lot of work because need to send proper notifications -// } -// -// } - - - public NavigationHelperImpl(Notifier emfRoot, boolean wildcardMode, Logger logger) throws IncQueryBaseException { - this.logger = logger; - assert(logger!=null); - - - this.instanceListeners = new HashMap>(); - this.featureListeners = new HashMap>(); - this.dataTypeListeners = new HashMap>(); - this.directlyObservedClasses = new HashSet(); - this.observedFeatures = new HashSet(); - this.observedDataTypes = new HashSet(); - this.contentAdapter = new NavigationHelperContentAdapter(this); -// this.visitor = new NavigationHelperVisitor(this); - this.afterUpdateCallbacks = new HashSet(); - - this.notifier = emfRoot; - this.modelRoots = new HashSet(); - this.expansionAllowed = false; - this.inWildcardMode = wildcardMode; - -// if (this.navigationHelperType == NavigationHelperType.ALL) { -// visitor.visitModel(notifier, observedFeatures, observedClasses, observedDataTypes); -// } - if (emfRoot != null) addRootInternal(emfRoot); - } - - - - public NavigationHelperContentAdapter getContentAdapter() { - return contentAdapter; - } - - public HashSet getObservedFeatures() { - return observedFeatures; - } - -// public NavigationHelperVisitor getVisitor() { -// return visitor; -// } - - @Override - public void dispose() { - for (Notifier root : modelRoots) { - contentAdapter.removeAdapter(root); - } - } - - @Override - public Collection getDataTypeInstances(EDataType type) { - Map valMap = contentAdapter.dataTypeMap.get(type); - if (valMap != null) { - return Collections.unmodifiableSet(valMap.keySet()); - } - else { - return Collections.emptySet(); - } - } - - @Override - public Collection findByAttributeValue(Object value) { - Set retSet = new HashSet(); - Map> valMap = contentAdapter.featureMap.get(value); - - if (valMap != null) { - for (Entry> entry : valMap.entrySet()) { - for (EObject holder : entry.getValue()) { - retSet.add(new NavigationHelperSetting(entry.getKey(), holder, value)); - } - } - } - - return retSet; - } - - @Override - public Collection findByAttributeValue(Object value, Collection attributes) { - Set retSet = new HashSet(); - Map> valMap = contentAdapter.featureMap.get(value); - - if (valMap != null) { - for (EAttribute attr : attributes) { - if (valMap.get(attr) != null) { - for (EObject holder : valMap.get(attr)) { - retSet.add(new NavigationHelperSetting(attr, holder, value)); - } - } - } - } - - return retSet; - } - - @Override - public Collection findByAttributeValue(Object value, EAttribute attribute) { - Map> valMap = contentAdapter.featureMap.get(value); - if (valMap == null || valMap.get(attribute) == null) { - return Collections.emptySet(); - } - else { - return Collections.unmodifiableSet(valMap.get(attribute)); - } - } - -// @Override -// public Collection findAllAttributeValuesByType(Class clazz) { -// Set retSet = new HashSet(); -// -// for (Object value : contentAdapter.featureMap.keySet()) { -// if (value.getClass().equals(clazz)) { -// for (EStructuralFeature attr : contentAdapter.featureMap.get(value).keySet()) { -// for (EObject holder : contentAdapter.featureMap.get(value).get(attr)) { -// retSet.add(new NavigationHelperSetting(attr, holder, value)); -// } -// } -// } -// } -// -// return retSet; -// } - - @Override - public Collection getInverseReferences(EObject target) { - Set retSet = new HashSet(); - Map> valMap = contentAdapter.featureMap.get(target); - - if (valMap != null) { - for (Entry> entry : valMap.entrySet()) { - for (EObject source : entry.getValue()) { - retSet.add(new NavigationHelperSetting(entry.getKey(), target, source)); - } - } - } - - return retSet; - } - - @Override - public Collection getInverseReferences(EObject target, Collection references) { - Set retSet = new HashSet(); - Map> valMap = contentAdapter.featureMap.get(target); - - if (valMap != null) { - for (EReference ref : references) { - if (valMap.get(ref) != null) { - for (EObject source : valMap.get(ref)) { - retSet.add(new NavigationHelperSetting(ref, target, source)); - } - } - } - } - - return retSet; - } - - @Override - public Collection getInverseReferences(EObject target, EReference reference) { - Map> valMap = contentAdapter.featureMap.get(target); - if (valMap == null || valMap.get(reference) == null) { - return Collections.emptySet(); - } - else { - return Collections.unmodifiableSet(valMap.get(reference)); - } - } - - @Override - public Collection getDirectInstances(EClass type) { - Set valSet = contentAdapter.instanceMap.get(type); - if (valSet == null) { - return Collections.emptySet(); - } - else { - return Collections.unmodifiableSet(valSet); - } - } - - @Override - public Collection getAllInstances(EClass type) { - Set retSet = new HashSet(); - - Set valSet = contentAdapter.subTypeMap.get(type); - if (valSet != null) { - for (EClass c : valSet) { - final Set instances = contentAdapter.instanceMap.get(c); - if (instances != null) retSet.addAll(instances); - } - } - final Set instances = contentAdapter.instanceMap.get(type); - if (instances != null) retSet.addAll(instances); - - return retSet; - } - - @Override - public Collection findByFeatureValue(Object value, EStructuralFeature feature) { - Set retSet = new HashSet(); - Map> valMap = contentAdapter.featureMap.get(value); - if (valMap != null && valMap.get(feature) != null) { - retSet.addAll(valMap.get(feature)); - } - return retSet; - } - - @Override - public Collection getHoldersOfFeature(EStructuralFeature feature) { - if (contentAdapter.getReversedFeatureMap().get(feature) == null) { - return Collections.emptySet(); - } - else { - return Collections.unmodifiableSet(contentAdapter.getReversedFeatureMap().get(feature).elementSet()); - } - } - - @Override - public void registerInstanceListener(Collection classes, InstanceListener listener) { - Collection registered = this.instanceListeners.get(listener); - if (registered == null) { - registered = new HashSet(); - this.instanceListeners.put(listener, registered); - } - registered.addAll(classes); - } - - @Override - public void unregisterInstanceListener(Collection classes, InstanceListener listener) { - Collection restriction = this.instanceListeners.get(listener); - if (restriction != null) { - restriction.removeAll(classes); - if (restriction.size() == 0) { - this.instanceListeners.remove(listener); - } - } - } - - @Override - public void registerFeatureListener(Collection features, FeatureListener listener) { - Collection registered = this.featureListeners.get(listener); - if (registered == null) { - registered = new HashSet(); - this.featureListeners.put(listener, registered); - } - registered.addAll(features); - } - - @Override - public void unregisterFeatureListener(Collection features, FeatureListener listener) { - Collection restriction = this.featureListeners.get(listener); - if (restriction != null) { - restriction.removeAll(features); - if (restriction.size() == 0) { - this.featureListeners.remove(listener); - } - } - } - - @Override - public void registerDataTypeListener(Collection types, DataTypeListener listener) { - Collection registered = this.dataTypeListeners.get(listener); - if (registered == null) { - registered = new HashSet(); - this.dataTypeListeners.put(listener, registered); - } - registered.addAll(types); - } - - @Override - public void unregisterDataTypeListener(Collection types, DataTypeListener listener) { - Collection restriction = this.dataTypeListeners.get(listener); - if (restriction != null) { - restriction.removeAll(types); - if (restriction.size() == 0) { - this.dataTypeListeners.remove(listener); - } - } - } - - public Map> getInstanceListeners() { - return instanceListeners; - } - - public Map> getFeatureListeners() { - return featureListeners; - } - - public Map> getDataTypeListeners() { - return dataTypeListeners; - } - - /** - * @return the observedDataTypes - */ - public HashSet getObservedDataTypes() { - return observedDataTypes; - } - - /** - * These runnables will be called after updates by the manipulationListener at its own discretion. - * Can be used e.g. to check delta monitors. - */ - @Override - public Set getAfterUpdateCallbacks() { - return afterUpdateCallbacks; - } - /** - * This will run after updates. - */ -// * If there are any such, updates are settled before they are run. + +public class NavigationHelperImpl implements NavigationHelper { + + protected boolean inWildcardMode; + protected HashSet directlyObservedClasses; + protected HashSet allObservedClasses = null; // including subclasses + protected HashSet observedDataTypes; + protected HashSet observedFeatures; + + protected Notifier notifier; + protected Set modelRoots; + private boolean expansionAllowed; + // protected NavigationHelperVisitor visitor; + protected NavigationHelperContentAdapter contentAdapter; + + private final Logger logger; + + /** + * These global listeners will be called after updates. + */ + protected Set afterUpdateCallbacks; + + private final Map> instanceListeners; + private final Map> featureListeners; + private final Map> dataTypeListeners; + + /** + * Feature registration and model traversal is delayed while true + */ + protected boolean delayTraversals = false; + /** + * Classes to be registered once the coalescing period is over + */ + protected Set delayedClasses; + /** + * EStructuralFeatures to be registered once the coalescing period is over + */ + protected Set delayedFeatures; + /** + * EDataTypes to be registered once the coalescing period is over + */ + protected Set delayedDataTypes; + + private Set noClass() { + return Collections.emptySet(); + }; + + private Set noDataType() { + return Collections.emptySet(); + }; + + private Set noFeature() { + return Collections.emptySet(); + }; + + Set setMinus(Set a, Set b) { + Set result = new HashSet(a); + result.removeAll(b); + return result; + } + + Set resolveAll(Set a) { + Set result = new HashSet(a); + for (T t : a) { + if (t.eIsProxy()) + result.add((T) EcoreUtil.resolve(t, (ResourceSet) null)); + else + result.add(t); + } + return result; + } + + @Override + public boolean isInWildcardMode() { + return inWildcardMode; + } + + // @Override + // public void setInWildcardMode(boolean newWildcardMode) { + // if (inWildcardMode && !newWildcardMode) + // throw new UnsupportedOperationException(); + // if (!inWildcardMode && newWildcardMode) { + // this.inWildcardMode = true; + // + // this.allObservedClasses = null; + // this.directlyObservedClasses = null; + // this.observedDataTypes = null; + // this.observedFeatures = null; + // + // this.contentAdapter. // TODO lot of work because need to send proper notifications + // } + // + // } + + public NavigationHelperImpl(Notifier emfRoot, boolean wildcardMode, Logger logger) throws IncQueryBaseException { + this.logger = logger; + assert (logger != null); + + this.instanceListeners = new HashMap>(); + this.featureListeners = new HashMap>(); + this.dataTypeListeners = new HashMap>(); + this.directlyObservedClasses = new HashSet(); + this.observedFeatures = new HashSet(); + this.observedDataTypes = new HashSet(); + this.contentAdapter = new NavigationHelperContentAdapter(this); + // this.visitor = new NavigationHelperVisitor(this); + this.afterUpdateCallbacks = new HashSet(); + + this.notifier = emfRoot; + this.modelRoots = new HashSet(); + this.expansionAllowed = false; + this.inWildcardMode = wildcardMode; + + // if (this.navigationHelperType == NavigationHelperType.ALL) { + // visitor.visitModel(notifier, observedFeatures, observedClasses, observedDataTypes); + // } + if (emfRoot != null) + addRootInternal(emfRoot); + } + + public NavigationHelperContentAdapter getContentAdapter() { + return contentAdapter; + } + + public HashSet getObservedFeatures() { + return observedFeatures; + } + + // public NavigationHelperVisitor getVisitor() { + // return visitor; + // } + + @Override + public void dispose() { + for (Notifier root : modelRoots) { + contentAdapter.removeAdapter(root); + } + } + + @Override + public Collection getDataTypeInstances(EDataType type) { + Map valMap = contentAdapter.dataTypeMap.get(type); + if (valMap != null) { + return Collections.unmodifiableSet(valMap.keySet()); + } else { + return Collections.emptySet(); + } + } + + @Override + public Collection findByAttributeValue(Object value) { + Set retSet = new HashSet(); + Map> valMap = contentAdapter.featureMap.get(value); + + if (valMap != null) { + for (Entry> entry : valMap.entrySet()) { + for (EObject holder : entry.getValue()) { + retSet.add(new NavigationHelperSetting(entry.getKey(), holder, value)); + } + } + } + + return retSet; + } + + @Override + public Collection findByAttributeValue(Object value, Collection attributes) { + Set retSet = new HashSet(); + Map> valMap = contentAdapter.featureMap.get(value); + + if (valMap != null) { + for (EAttribute attr : attributes) { + if (valMap.get(attr) != null) { + for (EObject holder : valMap.get(attr)) { + retSet.add(new NavigationHelperSetting(attr, holder, value)); + } + } + } + } + + return retSet; + } + + @Override + public Collection findByAttributeValue(Object value, EAttribute attribute) { + Map> valMap = contentAdapter.featureMap.get(value); + if (valMap == null || valMap.get(attribute) == null) { + return Collections.emptySet(); + } else { + return Collections.unmodifiableSet(valMap.get(attribute)); + } + } + + // @Override + // public Collection findAllAttributeValuesByType(Class clazz) { + // Set retSet = new HashSet(); + // + // for (Object value : contentAdapter.featureMap.keySet()) { + // if (value.getClass().equals(clazz)) { + // for (EStructuralFeature attr : contentAdapter.featureMap.get(value).keySet()) { + // for (EObject holder : contentAdapter.featureMap.get(value).get(attr)) { + // retSet.add(new NavigationHelperSetting(attr, holder, value)); + // } + // } + // } + // } + // + // return retSet; + // } + + @Override + public Collection getInverseReferences(EObject target) { + Set retSet = new HashSet(); + Map> valMap = contentAdapter.featureMap.get(target); + + if (valMap != null) { + for (Entry> entry : valMap.entrySet()) { + for (EObject source : entry.getValue()) { + retSet.add(new NavigationHelperSetting(entry.getKey(), target, source)); + } + } + } + + return retSet; + } + + @Override + public Collection getInverseReferences(EObject target, Collection references) { + Set retSet = new HashSet(); + Map> valMap = contentAdapter.featureMap.get(target); + + if (valMap != null) { + for (EReference ref : references) { + if (valMap.get(ref) != null) { + for (EObject source : valMap.get(ref)) { + retSet.add(new NavigationHelperSetting(ref, target, source)); + } + } + } + } + + return retSet; + } + + @Override + public Collection getInverseReferences(EObject target, EReference reference) { + Map> valMap = contentAdapter.featureMap.get(target); + if (valMap == null || valMap.get(reference) == null) { + return Collections.emptySet(); + } else { + return Collections.unmodifiableSet(valMap.get(reference)); + } + } + + @Override + public Collection getDirectInstances(EClass type) { + Set valSet = contentAdapter.instanceMap.get(type); + if (valSet == null) { + return Collections.emptySet(); + } else { + return Collections.unmodifiableSet(valSet); + } + } + + @Override + public Collection getAllInstances(EClass type) { + Set retSet = new HashSet(); + + Set valSet = contentAdapter.subTypeMap.get(type); + if (valSet != null) { + for (EClass c : valSet) { + final Set instances = contentAdapter.instanceMap.get(c); + if (instances != null) + retSet.addAll(instances); + } + } + final Set instances = contentAdapter.instanceMap.get(type); + if (instances != null) + retSet.addAll(instances); + + return retSet; + } + + @Override + public Collection findByFeatureValue(Object value, EStructuralFeature feature) { + Set retSet = new HashSet(); + Map> valMap = contentAdapter.featureMap.get(value); + if (valMap != null && valMap.get(feature) != null) { + retSet.addAll(valMap.get(feature)); + } + return retSet; + } + + @Override + public Collection getHoldersOfFeature(EStructuralFeature feature) { + if (contentAdapter.getReversedFeatureMap().get(feature) == null) { + return Collections.emptySet(); + } else { + return Collections.unmodifiableSet(contentAdapter.getReversedFeatureMap().get(feature).elementSet()); + } + } + + @Override + public void registerInstanceListener(Collection classes, InstanceListener listener) { + Collection registered = this.instanceListeners.get(listener); + if (registered == null) { + registered = new HashSet(); + this.instanceListeners.put(listener, registered); + } + registered.addAll(classes); + } + + @Override + public void unregisterInstanceListener(Collection classes, InstanceListener listener) { + Collection restriction = this.instanceListeners.get(listener); + if (restriction != null) { + restriction.removeAll(classes); + if (restriction.size() == 0) { + this.instanceListeners.remove(listener); + } + } + } + + @Override + public void registerFeatureListener(Collection features, FeatureListener listener) { + Collection registered = this.featureListeners.get(listener); + if (registered == null) { + registered = new HashSet(); + this.featureListeners.put(listener, registered); + } + registered.addAll(features); + } + + @Override + public void unregisterFeatureListener(Collection features, FeatureListener listener) { + Collection restriction = this.featureListeners.get(listener); + if (restriction != null) { + restriction.removeAll(features); + if (restriction.size() == 0) { + this.featureListeners.remove(listener); + } + } + } + + @Override + public void registerDataTypeListener(Collection types, DataTypeListener listener) { + Collection registered = this.dataTypeListeners.get(listener); + if (registered == null) { + registered = new HashSet(); + this.dataTypeListeners.put(listener, registered); + } + registered.addAll(types); + } + + @Override + public void unregisterDataTypeListener(Collection types, DataTypeListener listener) { + Collection restriction = this.dataTypeListeners.get(listener); + if (restriction != null) { + restriction.removeAll(types); + if (restriction.size() == 0) { + this.dataTypeListeners.remove(listener); + } + } + } + + public Map> getInstanceListeners() { + return instanceListeners; + } + + public Map> getFeatureListeners() { + return featureListeners; + } + + public Map> getDataTypeListeners() { + return dataTypeListeners; + } + + /** + * @return the observedDataTypes + */ + public HashSet getObservedDataTypes() { + return observedDataTypes; + } + + /** + * These runnables will be called after updates by the manipulationListener at its own discretion. Can be used e.g. + * to check delta monitors. + */ + @Override + public Set getAfterUpdateCallbacks() { + return afterUpdateCallbacks; + } + + /** + * This will run after updates. + */ + // * If there are any such, updates are settled before they are run. public void runAfterUpdateCallbacks() { if (!afterUpdateCallbacks.isEmpty()) { // settle(); @@ -448,258 +451,268 @@ public void runAfterUpdateCallbacks() { } } } - - protected void considerForExpansion(EObject obj) { - if (expansionAllowed) { - Resource eResource = obj.eResource(); - if (eResource != null && eResource.getResourceSet() == null) { - expandToAdditionalRoot(eResource); - } - } - } - - protected void expandToAdditionalRoot(Notifier root) { - if (modelRoots.add(root)) { - if (root instanceof ResourceSet) expansionAllowed = true; - contentAdapter.addAdapter(root); - } - } - - /** - * @return the expansionAllowed - */ - public boolean isExpansionAllowed() { - return expansionAllowed; - } - - /** - * @return the directlyObservedClasses - */ - public HashSet getDirectlyObservedClasses() { - return directlyObservedClasses; - } - - public boolean isObserved(EClass clazz) { - return inWildcardMode || getAllObservedClasses().contains(clazz); - } - - /** - * not just the directly observed classes, but also their known subtypes - */ - public HashSet getAllObservedClasses() { - if (allObservedClasses == null) { - allObservedClasses = new HashSet(); - for (EClass eClass : directlyObservedClasses) { - allObservedClasses.add(eClass); - final Set subTypes = NavigationHelperContentAdapter.subTypeMap.get(eClass); - if (subTypes != null) { - allObservedClasses.addAll(subTypes); - } - } - } - return allObservedClasses; - } - - - @Override - public void registerEStructuralFeatures(Set features) { - if (inWildcardMode) throw new IllegalStateException(); - if (features != null) { - features = resolveAll(features); - if (delayTraversals) { - delayedFeatures.addAll(features); - } else { - features = setMinus(features, observedFeatures); - - observedFeatures.addAll(features); - final NavigationHelperVisitor visitor = - new NavigationHelperVisitor.TraversingVisitor(this, features, noClass(), noClass(), noDataType()); - traverse(visitor); - } - } - } - - - - @Override - public void unregisterEStructuralFeatures(Set features) { - if (inWildcardMode) throw new IllegalStateException(); - if (features != null) { - features = resolveAll(features); - observedFeatures.removeAll(features); - delayedFeatures.removeAll(features); - for (EStructuralFeature f : features) { - for (Object key : contentAdapter.featureMap.keySet()) { - contentAdapter.featureMap.get(key).remove(f); - // TODO proper notification - } - } - } - } - - @Override - public void registerEClasses(Set classes) { - if (inWildcardMode) throw new IllegalStateException(); - if (classes != null) { - classes = resolveAll(classes); - if (delayTraversals) { - delayedClasses.addAll(classes); - } else { - classes = setMinus(classes, directlyObservedClasses); - - final HashSet oldClasses = new HashSet(directlyObservedClasses); - startObservingClasses(classes); - final NavigationHelperVisitor visitor = - new NavigationHelperVisitor.TraversingVisitor(this, noFeature(), classes, oldClasses, noDataType()); - traverse(visitor); - } - } - } - /** - * @param classes - */ - protected void startObservingClasses(Set classes) { - directlyObservedClasses.addAll(classes); - getAllObservedClasses().addAll(classes); - for (EClass eClass : classes) { - final Set subTypes = NavigationHelperContentAdapter.subTypeMap.get(eClass); - if (subTypes != null) { - allObservedClasses.addAll(subTypes); - } - } - } - - @Override - public void unregisterEClasses(Set classes) { - if (inWildcardMode) throw new IllegalStateException(); - if (classes != null) { - classes = resolveAll(classes); - directlyObservedClasses.removeAll(classes); - allObservedClasses = null; - delayedClasses.removeAll(classes); - for (EClass c : classes) { - contentAdapter.instanceMap.remove(c); - } - } - } - - @Override - public void registerEDataTypes(Set dataTypes) { - if (inWildcardMode) throw new IllegalStateException(); - if (dataTypes != null) { - dataTypes = resolveAll(dataTypes); - if (delayTraversals) { - delayedDataTypes.addAll(dataTypes); - } else { - dataTypes = setMinus(dataTypes, observedDataTypes); - - observedDataTypes.addAll(dataTypes); - final NavigationHelperVisitor visitor = - new NavigationHelperVisitor.TraversingVisitor(this, noFeature(), noClass(), noClass(), dataTypes); - traverse(visitor); - - } - } - } - - @Override - public void unregisterEDataTypes(Set dataTypes) { - if (inWildcardMode) throw new IllegalStateException(); - if (dataTypes != null) { - dataTypes = resolveAll(dataTypes); - observedDataTypes.removeAll(dataTypes); - delayedDataTypes.removeAll(dataTypes); - for (EDataType dt : dataTypes) { - contentAdapter.dataTypeMap.remove(dt); - } - } - } - - @Override - public V coalesceTraversals(Callable callable) throws InvocationTargetException { - if(delayTraversals) { // reentrant case, no special action needed - V result = null; - try { - result = callable.call(); - } catch (Exception e) { - throw new InvocationTargetException(e); - } - return result; - } - - delayedClasses = new HashSet(); - delayedFeatures = new HashSet(); - delayedDataTypes = new HashSet(); - - V result = null; - try { - try { - delayTraversals = true; - result = callable.call(); - } finally { - delayTraversals = false; - - delayedFeatures = setMinus(delayedFeatures, observedFeatures); - delayedClasses = setMinus(delayedClasses, directlyObservedClasses); - delayedDataTypes = setMinus(delayedDataTypes, observedDataTypes); - - boolean classesWarrantTraversal = !setMinus(delayedClasses, getAllObservedClasses()).isEmpty(); - - if (!delayedClasses.isEmpty() || !delayedFeatures.isEmpty() || !delayedDataTypes.isEmpty()) { - final HashSet oldClasses = new HashSet(directlyObservedClasses); - startObservingClasses(delayedClasses); - observedFeatures.addAll(delayedFeatures); - observedDataTypes.addAll(delayedDataTypes); - - // make copies and clean original accumulators, for the rare case that a coalesced - // traversal is invoked during visitation, e.g. by a derived feature implementation - final HashSet toGatherClasses = new HashSet(delayedClasses); - final HashSet toGatherFeatures = new HashSet(delayedFeatures); - final HashSet toGatherDataTypes = new HashSet(delayedDataTypes); - delayedFeatures.clear(); - delayedClasses.clear(); - delayedDataTypes.clear(); - - if (classesWarrantTraversal || !toGatherFeatures.isEmpty() || !toGatherDataTypes.isEmpty()) { - final NavigationHelperVisitor visitor = - new NavigationHelperVisitor.TraversingVisitor(this, toGatherFeatures, toGatherClasses, oldClasses, toGatherDataTypes); - traverse(visitor); - } - } - } - } catch (Exception e) { - getLogger().fatal("EMF-IncQuery Base encountered an error while traversing the EMF model to gather new information. " , e); - throw new InvocationTargetException(e); - } - return result; - } - - private void traverse(final NavigationHelperVisitor visitor) { - for (Notifier root : modelRoots) { - EMFModelComprehension.traverseModel(visitor, root); - } - runAfterUpdateCallbacks(); - } - /** - * @return the logger - */ - public Logger getLogger() { - return logger; - } - - @Override - public void addRoot(Notifier emfRoot) throws IncQueryBaseException { - addRootInternal(emfRoot); - } - /** - * @param emfRoot - * @throws IncQueryBaseException - */ - private void addRootInternal(Notifier emfRoot) throws IncQueryBaseException { - if (!((emfRoot instanceof EObject) || (emfRoot instanceof Resource) || (emfRoot instanceof ResourceSet))) { - throw new IncQueryBaseException(IncQueryBaseException.INVALID_EMFROOT); - } - expandToAdditionalRoot(emfRoot); - } - -} + + protected void considerForExpansion(EObject obj) { + if (expansionAllowed) { + Resource eResource = obj.eResource(); + if (eResource != null && eResource.getResourceSet() == null) { + expandToAdditionalRoot(eResource); + } + } + } + + protected void expandToAdditionalRoot(Notifier root) { + if (modelRoots.add(root)) { + if (root instanceof ResourceSet) + expansionAllowed = true; + contentAdapter.addAdapter(root); + } + } + + /** + * @return the expansionAllowed + */ + public boolean isExpansionAllowed() { + return expansionAllowed; + } + + /** + * @return the directlyObservedClasses + */ + public HashSet getDirectlyObservedClasses() { + return directlyObservedClasses; + } + + public boolean isObserved(EClass clazz) { + return inWildcardMode || getAllObservedClasses().contains(clazz); + } + + /** + * not just the directly observed classes, but also their known subtypes + */ + public HashSet getAllObservedClasses() { + if (allObservedClasses == null) { + allObservedClasses = new HashSet(); + for (EClass eClass : directlyObservedClasses) { + allObservedClasses.add(eClass); + final Set subTypes = NavigationHelperContentAdapter.subTypeMap.get(eClass); + if (subTypes != null) { + allObservedClasses.addAll(subTypes); + } + } + } + return allObservedClasses; + } + + @Override + public void registerEStructuralFeatures(Set features) { + if (inWildcardMode) + throw new IllegalStateException(); + if (features != null) { + features = resolveAll(features); + if (delayTraversals) { + delayedFeatures.addAll(features); + } else { + features = setMinus(features, observedFeatures); + + observedFeatures.addAll(features); + final NavigationHelperVisitor visitor = new NavigationHelperVisitor.TraversingVisitor(this, features, + noClass(), noClass(), noDataType()); + traverse(visitor); + } + } + } + + @Override + public void unregisterEStructuralFeatures(Set features) { + if (inWildcardMode) + throw new IllegalStateException(); + if (features != null) { + features = resolveAll(features); + observedFeatures.removeAll(features); + delayedFeatures.removeAll(features); + for (EStructuralFeature f : features) { + for (Object key : contentAdapter.featureMap.keySet()) { + contentAdapter.featureMap.get(key).remove(f); + // TODO proper notification + } + } + } + } + + @Override + public void registerEClasses(Set classes) { + if (inWildcardMode) + throw new IllegalStateException(); + if (classes != null) { + classes = resolveAll(classes); + if (delayTraversals) { + delayedClasses.addAll(classes); + } else { + classes = setMinus(classes, directlyObservedClasses); + + final HashSet oldClasses = new HashSet(directlyObservedClasses); + startObservingClasses(classes); + final NavigationHelperVisitor visitor = new NavigationHelperVisitor.TraversingVisitor(this, + noFeature(), classes, oldClasses, noDataType()); + traverse(visitor); + } + } + } + + /** + * @param classes + */ + protected void startObservingClasses(Set classes) { + directlyObservedClasses.addAll(classes); + getAllObservedClasses().addAll(classes); + for (EClass eClass : classes) { + final Set subTypes = NavigationHelperContentAdapter.subTypeMap.get(eClass); + if (subTypes != null) { + allObservedClasses.addAll(subTypes); + } + } + } + + @Override + public void unregisterEClasses(Set classes) { + if (inWildcardMode) + throw new IllegalStateException(); + if (classes != null) { + classes = resolveAll(classes); + directlyObservedClasses.removeAll(classes); + allObservedClasses = null; + delayedClasses.removeAll(classes); + for (EClass c : classes) { + contentAdapter.instanceMap.remove(c); + } + } + } + + @Override + public void registerEDataTypes(Set dataTypes) { + if (inWildcardMode) + throw new IllegalStateException(); + if (dataTypes != null) { + dataTypes = resolveAll(dataTypes); + if (delayTraversals) { + delayedDataTypes.addAll(dataTypes); + } else { + dataTypes = setMinus(dataTypes, observedDataTypes); + + observedDataTypes.addAll(dataTypes); + final NavigationHelperVisitor visitor = new NavigationHelperVisitor.TraversingVisitor(this, + noFeature(), noClass(), noClass(), dataTypes); + traverse(visitor); + + } + } + } + + @Override + public void unregisterEDataTypes(Set dataTypes) { + if (inWildcardMode) + throw new IllegalStateException(); + if (dataTypes != null) { + dataTypes = resolveAll(dataTypes); + observedDataTypes.removeAll(dataTypes); + delayedDataTypes.removeAll(dataTypes); + for (EDataType dt : dataTypes) { + contentAdapter.dataTypeMap.remove(dt); + } + } + } + + @Override + public V coalesceTraversals(Callable callable) throws InvocationTargetException { + if (delayTraversals) { // reentrant case, no special action needed + V result = null; + try { + result = callable.call(); + } catch (Exception e) { + throw new InvocationTargetException(e); + } + return result; + } + + delayedClasses = new HashSet(); + delayedFeatures = new HashSet(); + delayedDataTypes = new HashSet(); + + V result = null; + try { + try { + delayTraversals = true; + result = callable.call(); + } finally { + delayTraversals = false; + + delayedFeatures = setMinus(delayedFeatures, observedFeatures); + delayedClasses = setMinus(delayedClasses, directlyObservedClasses); + delayedDataTypes = setMinus(delayedDataTypes, observedDataTypes); + + boolean classesWarrantTraversal = !setMinus(delayedClasses, getAllObservedClasses()).isEmpty(); + + if (!delayedClasses.isEmpty() || !delayedFeatures.isEmpty() || !delayedDataTypes.isEmpty()) { + final HashSet oldClasses = new HashSet(directlyObservedClasses); + startObservingClasses(delayedClasses); + observedFeatures.addAll(delayedFeatures); + observedDataTypes.addAll(delayedDataTypes); + + // make copies and clean original accumulators, for the rare case that a coalesced + // traversal is invoked during visitation, e.g. by a derived feature implementation + final HashSet toGatherClasses = new HashSet(delayedClasses); + final HashSet toGatherFeatures = new HashSet( + delayedFeatures); + final HashSet toGatherDataTypes = new HashSet(delayedDataTypes); + delayedFeatures.clear(); + delayedClasses.clear(); + delayedDataTypes.clear(); + + if (classesWarrantTraversal || !toGatherFeatures.isEmpty() || !toGatherDataTypes.isEmpty()) { + final NavigationHelperVisitor visitor = new NavigationHelperVisitor.TraversingVisitor(this, + toGatherFeatures, toGatherClasses, oldClasses, toGatherDataTypes); + traverse(visitor); + } + } + } + } catch (Exception e) { + getLogger() + .fatal("EMF-IncQuery Base encountered an error while traversing the EMF model to gather new information. ", + e); + throw new InvocationTargetException(e); + } + return result; + } + + private void traverse(final NavigationHelperVisitor visitor) { + for (Notifier root : modelRoots) { + EMFModelComprehension.traverseModel(visitor, root); + } + runAfterUpdateCallbacks(); + } + + /** + * @return the logger + */ + public Logger getLogger() { + return logger; + } + + @Override + public void addRoot(Notifier emfRoot) throws IncQueryBaseException { + addRootInternal(emfRoot); + } + + /** + * @param emfRoot + * @throws IncQueryBaseException + */ + private void addRootInternal(Notifier emfRoot) throws IncQueryBaseException { + if (!((emfRoot instanceof EObject) || (emfRoot instanceof Resource) || (emfRoot instanceof ResourceSet))) { + throw new IncQueryBaseException(IncQueryBaseException.INVALID_EMFROOT); + } + expandToAdditionalRoot(emfRoot); + } + +} diff --git a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/NavigationHelperSetting.java b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/NavigationHelperSetting.java index e0329d03..3e94cf9f 100644 --- a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/NavigationHelperSetting.java +++ b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/NavigationHelperSetting.java @@ -9,69 +9,69 @@ * Tamas Szabo, Gabor Bergmann - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.core; - +package org.eclipse.incquery.runtime.base.core; + import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.EStructuralFeature.Setting; - -/** - * EStructuralFeature.Setting implementation for the NavigationHelper. - * - * @author Tamás Szabó - * - */ -public class NavigationHelperSetting implements Setting { - - private EStructuralFeature feature; - private EObject holder; - private Object value; - - public NavigationHelperSetting() { - super(); - } - - public NavigationHelperSetting(EStructuralFeature feature, EObject holder, Object value) { - super(); - this.feature = feature; - this.holder = holder; - this.value = value; - } - - @Override - public EObject getEObject() { - return holder; - } - - @Override - public EStructuralFeature getEStructuralFeature() { - return feature; - } - - @Override - public Object get(boolean resolve) { - return value; - } - - @Override - public void set(Object newValue) { - this.value = newValue; - } - - @Override - public boolean isSet() { - if (value != null) - return true; - return false; - } - - @Override - public void unset() { - this.value = null; - } - - @Override - public String toString() { - return "feature = "+feature+" holder = "+holder+" value = "+value; - } -} + +/** + * EStructuralFeature.Setting implementation for the NavigationHelper. + * + * @author Tamás Szabó + * + */ +public class NavigationHelperSetting implements Setting { + + private EStructuralFeature feature; + private EObject holder; + private Object value; + + public NavigationHelperSetting() { + super(); + } + + public NavigationHelperSetting(EStructuralFeature feature, EObject holder, Object value) { + super(); + this.feature = feature; + this.holder = holder; + this.value = value; + } + + @Override + public EObject getEObject() { + return holder; + } + + @Override + public EStructuralFeature getEStructuralFeature() { + return feature; + } + + @Override + public Object get(boolean resolve) { + return value; + } + + @Override + public void set(Object newValue) { + this.value = newValue; + } + + @Override + public boolean isSet() { + if (value != null) + return true; + return false; + } + + @Override + public void unset() { + this.value = null; + } + + @Override + public String toString() { + return "feature = " + feature + " holder = " + holder + " value = " + value; + } +} diff --git a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/NavigationHelperType.java b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/NavigationHelperType.java index 3ac08f41..003cf437 100644 --- a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/NavigationHelperType.java +++ b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/NavigationHelperType.java @@ -9,9 +9,8 @@ * Tamas Szabo, Gabor Bergmann - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.core; - -public enum NavigationHelperType { - REGISTER, - ALL -} +package org.eclipse.incquery.runtime.base.core; + +public enum NavigationHelperType { + REGISTER, ALL +} diff --git a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/NavigationHelperVisitor.java b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/NavigationHelperVisitor.java index 39ddc1db..3f159d0e 100644 --- a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/NavigationHelperVisitor.java +++ b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/NavigationHelperVisitor.java @@ -9,8 +9,8 @@ * Tamas Szabo, Gabor Bergmann - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.core; - +package org.eclipse.incquery.runtime.base.core; + import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -27,284 +27,298 @@ import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.incquery.runtime.base.comprehension.EMFVisitor; - -public abstract class NavigationHelperVisitor extends EMFVisitor { - - /** - * A visitor for processing a single change event. Does not traverse the model. Uses all the observed types. - */ - public static class ChangeVisitor extends NavigationHelperVisitor { - // local copies to save actual state, in case visitor has to be saved for later due unresolvable proxies - private final boolean wildcardMode; - private final HashSet allObservedClasses; - private final HashSet observedDataTypes; - private final HashSet observedFeatures; - - public ChangeVisitor(NavigationHelperImpl navigationHelper, boolean isInsertion) { - super(navigationHelper, isInsertion, false); - wildcardMode = navigationHelper.isInWildcardMode(); - allObservedClasses = new HashSet(navigationHelper.getAllObservedClasses()); - observedDataTypes = new HashSet(navigationHelper.getObservedDataTypes()); - observedFeatures = new HashSet(navigationHelper.getObservedFeatures()); - } - - @Override - protected boolean observesClass(EClass eClass) { - return wildcardMode || allObservedClasses.contains(eClass); - } - @Override - protected boolean observesDataType(EDataType type) { - return wildcardMode || observedDataTypes.contains(type); - } - @Override - protected boolean observesFeature(EStructuralFeature feature) { - return wildcardMode || observedFeatures.contains(feature); - } - } - - /** - * A visitor for a single-pass traversal of the whole model, processing only the given types and inserting them. - */ - public static class TraversingVisitor extends NavigationHelperVisitor { - private final boolean wildcardMode; - Set features; - Set newClasses; - Set oldClasses; // if decends from an old class, no need to add! - Map classObservationMap; // true for a class even if only a supertype is included in classes; - Set dataTypes; - - - public TraversingVisitor ( - NavigationHelperImpl navigationHelper, - Set features, Set newClasses, Set oldClasses, Set dataTypes) - { - super(navigationHelper, true, true); - wildcardMode = navigationHelper.isInWildcardMode(); - this.features = features; - this.newClasses = newClasses; - this.oldClasses = oldClasses; - this.classObservationMap = new HashMap(); - this.dataTypes = dataTypes; - } - - @Override - protected boolean observesClass(EClass eClass) { - if (navigationHelper.isInWildcardMode()) return true; - Boolean observed = classObservationMap.get(eClass); - if (observed == null) { - final EList eAllSuperTypes = eClass.getEAllSuperTypes(); - final boolean overApprox = - newClasses.contains(eClass) || - newClasses.contains(NavigationHelperContentAdapter.eObjectClass) || - !Collections.disjoint(eAllSuperTypes, newClasses); - observed = overApprox && - !oldClasses.contains(eClass) && - !oldClasses.contains(NavigationHelperContentAdapter.eObjectClass) && - Collections.disjoint(eAllSuperTypes, oldClasses); - classObservationMap.put(eClass, observed); - } - return observed; - } - @Override - protected boolean observesDataType(EDataType type) { - return wildcardMode || dataTypes.contains(type); - } - @Override - protected boolean observesFeature(EStructuralFeature feature) { - return wildcardMode || features.contains(feature); - } - - } - - protected NavigationHelperImpl navigationHelper; - private NavigationHelperContentAdapter store; - boolean isInsertion; - boolean descendHierarchy; - - NavigationHelperVisitor(NavigationHelperImpl navigationHelper, boolean isInsertion, boolean descendHierarchy) { - super(); - this.navigationHelper = navigationHelper; - this.store = navigationHelper.getContentAdapter(); - this.isInsertion = isInsertion; - this.descendHierarchy = descendHierarchy; - } - -// public void visitModel(Notifier emfRoot, Set features, Set classes, Set dataTypes) { -// if (emfRoot instanceof EObject) { -// visitEObjectRoot((EObject) emfRoot, features, classes, dataTypes); -// } -// else if (emfRoot instanceof Resource) { -// visitResourceRoot((Resource) emfRoot, features, classes, dataTypes); -// } -// else if (emfRoot instanceof ResourceSet) { -// visitResourceSetRoot((ResourceSet) emfRoot, features, classes, dataTypes); -// } -// } -// -// private void visitResourceSetRoot(ResourceSet resourceSet, Set features, Set classes, Set dataTypes) { -// for (Resource r : resourceSet.getResources()) { -// visitResourceRoot(r, features, classes, dataTypes); -// } -// } -// -// private void visitResourceRoot(Resource resource, Set features, Set classes, Set dataTypes) { -// for (EObject obj : resource.getContents()) { -// visitEObjectRoot(obj, features, classes, dataTypes); -// } -// } -// -// private void visitEObjectRoot(EObject root, Set features, Set classes, Set dataTypes) { -// visitObject(root, features, classes, dataTypes); -// TreeIterator it = root.eAllContents(); -// -// while (it.hasNext()) { -// visitObject(it.next(), features, classes, dataTypes); -// } -// } - - @Override - public boolean pruneSubtrees(EObject source) { - return !descendHierarchy; - } - - @Override - public boolean pruneSubtrees(Resource source) { - return !descendHierarchy; - } - - @Override - public boolean pruneFeature(EStructuralFeature feature) { - if (observesFeature(feature)) return false; - if (feature instanceof EAttribute && observesDataType(((EAttribute)feature).getEAttributeType())) return false; - if (isInsertion && navigationHelper.isExpansionAllowed() && feature instanceof EReference && !((EReference)feature).isContainment()) return false; - return true; - } - - - protected abstract boolean observesFeature(EStructuralFeature feature); - protected abstract boolean observesDataType(EDataType type); - protected abstract boolean observesClass(EClass eClass); - - @Override - public void visitElement(EObject source) { - EClass eClass = source.eClass(); - if(eClass.eIsProxy()) eClass = (EClass) EcoreUtil.resolve(eClass, source); - - store.maintainTypeHierarchy(eClass); - if (observesClass(eClass)){ - if (isInsertion) { - store.insertInstanceTuple(eClass, source); - } else { - store.removeInstanceTuple(eClass, source); - } - } - } - - @Override - public void visitAttribute(EObject source, EAttribute feature, Object target) { - final EDataType eAttributeType = feature.getEAttributeType(); - if (observesFeature(feature)) { - if (isInsertion) { - store.insertFeatureTuple(feature, target, source); - } - else { - store.removeFeatureTuple(feature, target, source); - } - } - if (observesDataType(eAttributeType)) store.dataTypeInstanceUpdate(eAttributeType, target, isInsertion); - }; - - @Override - public void visitInternalContainment(EObject source, EReference feature, EObject target) { - visitReference(source, feature, target); - } - - @Override - public void visitNonContainmentReference(EObject source, EReference feature, EObject target) { - visitReference(source, feature, target); - if (isInsertion) navigationHelper.considerForExpansion(target); - }; - - private void visitReference(EObject source, EReference feature, EObject target) { - if (observesFeature(feature)) { - if (isInsertion) - store.insertFeatureTuple(feature, target, source); - else - store.removeFeatureTuple(feature, target, source); - } - } - - @Override - public void visitUnresolvableProxyFeature(EObject source, EReference reference, EObject target) { - store.suspendVisitorOnUnresolvableFeature(this, source, reference, target, isInsertion); - } - - @Override - public void visitUnresolvableProxyObject(EObject source) { - store.suspendVisitorOnUnresolvableObject(this, source, isInsertion); - } - @Override - public boolean forceProxyResolution() { - return isInsertion; - } - -// private void visitObject(EObject obj, Set features, Set classes, Set dataTypes) { -// if (obj != null) { -// -// if (classes != null) { -// if (navigationHelper.isInWildcardMode() || classes.contains(obj.eClass())) { -// store.insertInstanceTuple(obj.eClass(), obj); -// } -// } -// -// if (features != null) { -// for (EReference ref : obj.eClass().getEAllReferences()) { -// if (navigationHelper.isInWildcardMode() || features.contains(ref)) { -// Object o = obj.eGet(ref); -// -// if (o != null) { -// if (o instanceof EObjectEList) { -// @SuppressWarnings("unchecked") -// EObjectEList list = (EObjectEList) o; -// Iterator it = list.iterator(); -// while (it.hasNext()) { -// store.insertFeatureTuple(ref, it.next(), obj); -// } -// } else { -// store.insertFeatureTuple(ref, o, obj); -// } -// } -// } -// } -// -// visitObjectForEAttribute(obj, features, dataTypes, true); -// } -// } -// } - -// // visit all the attributes of the given EObject and insert them to the -// // cache -// public void visitObjectForEAttribute(EObject obj, Set features, Set dataTypes, boolean isInsertion) { -// if (obj != null) { -// for (EAttribute attr : obj.eClass().getEAllAttributes()) { -// final EDataType eAttributeType = attr.getEAttributeType(); -// if (navigationHelper.isInWildcardMode() || features.contains(attr) || dataTypes.contains(eAttributeType)) { -// if (attr.isMany()) { -// Collection values = (Collection) obj.eGet(attr); -// for (Object value : values) { -// visitAttributeValue(obj, features, dataTypes, -// isInsertion, attr, eAttributeType, value); -// } -// } else { -// Object value = obj.eGet(attr); -// if (value != null) { -// visitAttributeValue(obj, features, dataTypes, -// isInsertion, attr, eAttributeType, value); -// } -// } -// } -// } -// } -// } - -} + +public abstract class NavigationHelperVisitor extends EMFVisitor { + + /** + * A visitor for processing a single change event. Does not traverse the model. Uses all the observed types. + */ + public static class ChangeVisitor extends NavigationHelperVisitor { + // local copies to save actual state, in case visitor has to be saved for later due unresolvable proxies + private final boolean wildcardMode; + private final HashSet allObservedClasses; + private final HashSet observedDataTypes; + private final HashSet observedFeatures; + + public ChangeVisitor(NavigationHelperImpl navigationHelper, boolean isInsertion) { + super(navigationHelper, isInsertion, false); + wildcardMode = navigationHelper.isInWildcardMode(); + allObservedClasses = new HashSet(navigationHelper.getAllObservedClasses()); + observedDataTypes = new HashSet(navigationHelper.getObservedDataTypes()); + observedFeatures = new HashSet(navigationHelper.getObservedFeatures()); + } + + @Override + protected boolean observesClass(EClass eClass) { + return wildcardMode || allObservedClasses.contains(eClass); + } + + @Override + protected boolean observesDataType(EDataType type) { + return wildcardMode || observedDataTypes.contains(type); + } + + @Override + protected boolean observesFeature(EStructuralFeature feature) { + return wildcardMode || observedFeatures.contains(feature); + } + } + + /** + * A visitor for a single-pass traversal of the whole model, processing only the given types and inserting them. + */ + public static class TraversingVisitor extends NavigationHelperVisitor { + private final boolean wildcardMode; + Set features; + Set newClasses; + Set oldClasses; // if decends from an old class, no need to add! + Map classObservationMap; // true for a class even if only a supertype is included in classes; + Set dataTypes; + + public TraversingVisitor(NavigationHelperImpl navigationHelper, Set features, + Set newClasses, Set oldClasses, Set dataTypes) { + super(navigationHelper, true, true); + wildcardMode = navigationHelper.isInWildcardMode(); + this.features = features; + this.newClasses = newClasses; + this.oldClasses = oldClasses; + this.classObservationMap = new HashMap(); + this.dataTypes = dataTypes; + } + + @Override + protected boolean observesClass(EClass eClass) { + if (navigationHelper.isInWildcardMode()) + return true; + Boolean observed = classObservationMap.get(eClass); + if (observed == null) { + final EList eAllSuperTypes = eClass.getEAllSuperTypes(); + final boolean overApprox = newClasses.contains(eClass) + || newClasses.contains(NavigationHelperContentAdapter.eObjectClass) + || !Collections.disjoint(eAllSuperTypes, newClasses); + observed = overApprox && !oldClasses.contains(eClass) + && !oldClasses.contains(NavigationHelperContentAdapter.eObjectClass) + && Collections.disjoint(eAllSuperTypes, oldClasses); + classObservationMap.put(eClass, observed); + } + return observed; + } + + @Override + protected boolean observesDataType(EDataType type) { + return wildcardMode || dataTypes.contains(type); + } + + @Override + protected boolean observesFeature(EStructuralFeature feature) { + return wildcardMode || features.contains(feature); + } + + } + + protected NavigationHelperImpl navigationHelper; + private NavigationHelperContentAdapter store; + boolean isInsertion; + boolean descendHierarchy; + + NavigationHelperVisitor(NavigationHelperImpl navigationHelper, boolean isInsertion, boolean descendHierarchy) { + super(); + this.navigationHelper = navigationHelper; + this.store = navigationHelper.getContentAdapter(); + this.isInsertion = isInsertion; + this.descendHierarchy = descendHierarchy; + } + + // public void visitModel(Notifier emfRoot, Set features, Set classes, Set + // dataTypes) { + // if (emfRoot instanceof EObject) { + // visitEObjectRoot((EObject) emfRoot, features, classes, dataTypes); + // } + // else if (emfRoot instanceof Resource) { + // visitResourceRoot((Resource) emfRoot, features, classes, dataTypes); + // } + // else if (emfRoot instanceof ResourceSet) { + // visitResourceSetRoot((ResourceSet) emfRoot, features, classes, dataTypes); + // } + // } + // + // private void visitResourceSetRoot(ResourceSet resourceSet, Set features, Set classes, + // Set dataTypes) { + // for (Resource r : resourceSet.getResources()) { + // visitResourceRoot(r, features, classes, dataTypes); + // } + // } + // + // private void visitResourceRoot(Resource resource, Set features, Set classes, + // Set dataTypes) { + // for (EObject obj : resource.getContents()) { + // visitEObjectRoot(obj, features, classes, dataTypes); + // } + // } + // + // private void visitEObjectRoot(EObject root, Set features, Set classes, Set + // dataTypes) { + // visitObject(root, features, classes, dataTypes); + // TreeIterator it = root.eAllContents(); + // + // while (it.hasNext()) { + // visitObject(it.next(), features, classes, dataTypes); + // } + // } + + @Override + public boolean pruneSubtrees(EObject source) { + return !descendHierarchy; + } + + @Override + public boolean pruneSubtrees(Resource source) { + return !descendHierarchy; + } + + @Override + public boolean pruneFeature(EStructuralFeature feature) { + if (observesFeature(feature)) + return false; + if (feature instanceof EAttribute && observesDataType(((EAttribute) feature).getEAttributeType())) + return false; + if (isInsertion && navigationHelper.isExpansionAllowed() && feature instanceof EReference + && !((EReference) feature).isContainment()) + return false; + return true; + } + + protected abstract boolean observesFeature(EStructuralFeature feature); + + protected abstract boolean observesDataType(EDataType type); + + protected abstract boolean observesClass(EClass eClass); + + @Override + public void visitElement(EObject source) { + EClass eClass = source.eClass(); + if (eClass.eIsProxy()) + eClass = (EClass) EcoreUtil.resolve(eClass, source); + + store.maintainTypeHierarchy(eClass); + if (observesClass(eClass)) { + if (isInsertion) { + store.insertInstanceTuple(eClass, source); + } else { + store.removeInstanceTuple(eClass, source); + } + } + } + + @Override + public void visitAttribute(EObject source, EAttribute feature, Object target) { + final EDataType eAttributeType = feature.getEAttributeType(); + if (observesFeature(feature)) { + if (isInsertion) { + store.insertFeatureTuple(feature, target, source); + } else { + store.removeFeatureTuple(feature, target, source); + } + } + if (observesDataType(eAttributeType)) + store.dataTypeInstanceUpdate(eAttributeType, target, isInsertion); + }; + + @Override + public void visitInternalContainment(EObject source, EReference feature, EObject target) { + visitReference(source, feature, target); + } + + @Override + public void visitNonContainmentReference(EObject source, EReference feature, EObject target) { + visitReference(source, feature, target); + if (isInsertion) + navigationHelper.considerForExpansion(target); + }; + + private void visitReference(EObject source, EReference feature, EObject target) { + if (observesFeature(feature)) { + if (isInsertion) + store.insertFeatureTuple(feature, target, source); + else + store.removeFeatureTuple(feature, target, source); + } + } + + @Override + public void visitUnresolvableProxyFeature(EObject source, EReference reference, EObject target) { + store.suspendVisitorOnUnresolvableFeature(this, source, reference, target, isInsertion); + } + + @Override + public void visitUnresolvableProxyObject(EObject source) { + store.suspendVisitorOnUnresolvableObject(this, source, isInsertion); + } + + @Override + public boolean forceProxyResolution() { + return isInsertion; + } + + // private void visitObject(EObject obj, Set features, Set classes, Set + // dataTypes) { + // if (obj != null) { + // + // if (classes != null) { + // if (navigationHelper.isInWildcardMode() || classes.contains(obj.eClass())) { + // store.insertInstanceTuple(obj.eClass(), obj); + // } + // } + // + // if (features != null) { + // for (EReference ref : obj.eClass().getEAllReferences()) { + // if (navigationHelper.isInWildcardMode() || features.contains(ref)) { + // Object o = obj.eGet(ref); + // + // if (o != null) { + // if (o instanceof EObjectEList) { + // @SuppressWarnings("unchecked") + // EObjectEList list = (EObjectEList) o; + // Iterator it = list.iterator(); + // while (it.hasNext()) { + // store.insertFeatureTuple(ref, it.next(), obj); + // } + // } else { + // store.insertFeatureTuple(ref, o, obj); + // } + // } + // } + // } + // + // visitObjectForEAttribute(obj, features, dataTypes, true); + // } + // } + // } + + // // visit all the attributes of the given EObject and insert them to the + // // cache + // public void visitObjectForEAttribute(EObject obj, Set features, Set dataTypes, + // boolean isInsertion) { + // if (obj != null) { + // for (EAttribute attr : obj.eClass().getEAllAttributes()) { + // final EDataType eAttributeType = attr.getEAttributeType(); + // if (navigationHelper.isInWildcardMode() || features.contains(attr) || dataTypes.contains(eAttributeType)) { + // if (attr.isMany()) { + // Collection values = (Collection) obj.eGet(attr); + // for (Object value : values) { + // visitAttributeValue(obj, features, dataTypes, + // isInsertion, attr, eAttributeType, value); + // } + // } else { + // Object value = obj.eGet(attr); + // if (value != null) { + // visitAttributeValue(obj, features, dataTypes, + // isInsertion, attr, eAttributeType, value); + // } + // } + // } + // } + // } + // } + +} diff --git a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/TransitiveClosureHelperImpl.java b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/TransitiveClosureHelperImpl.java index d8710987..744dd82a 100644 --- a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/TransitiveClosureHelperImpl.java +++ b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/TransitiveClosureHelperImpl.java @@ -9,9 +9,8 @@ * Tamas Szabo, Gabor Bergmann - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.core; - - +package org.eclipse.incquery.runtime.base.core; + import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -29,203 +28,195 @@ import org.eclipse.incquery.runtime.base.exception.IncQueryBaseException; import org.eclipse.incquery.runtime.base.itc.alg.incscc.IncSCCAlg; import org.eclipse.incquery.runtime.base.itc.igraph.ITcObserver; - -/** - * Implementation class for the transitive closure. - * The class is a wrapper for the tc algorithms on an emf model. - * - * @author Tamas Szabo - * - */ -public class TransitiveClosureHelperImpl extends EContentAdapter implements - TransitiveClosureHelper, ITcObserver { - - private IncSCCAlg sccAlg; - private Set refToObserv; - private EMFDataSource dataSource; - private ArrayList> observers; - private Notifier notifier; - - public TransitiveClosureHelperImpl(Notifier emfRoot, - Set refToObserv) throws IncQueryBaseException { - this.refToObserv = refToObserv; - this.notifier = emfRoot; - this.observers = new ArrayList>(); - - if (emfRoot instanceof EObject) { - dataSource = new EMFDataSource.ForEObject((EObject) emfRoot, refToObserv); - } - else if (emfRoot instanceof Resource) { - dataSource = new EMFDataSource.ForResource((Resource) emfRoot, refToObserv); - } - else if (emfRoot instanceof ResourceSet) { - dataSource = new EMFDataSource.ForResourceSet((ResourceSet) emfRoot, refToObserv); - } - else { - throw new IncQueryBaseException(IncQueryBaseException.INVALID_EMFROOT); - } - - this.sccAlg = new IncSCCAlg(dataSource); - this.sccAlg.attachObserver(this); - emfRoot.eAdapters().add(this); - } - - /** - * The method visits an {@link EObject} for the registered references in order to - * explore the potential nodes and edges that should be inserted and deleted. - * - * Multiple node deletion and insertion must be avoided! - * - * @param source - * @param isInsert - */ - private void visitObjectForEReference(EObject source, boolean isInsert) { - for (EReference ref : source.eClass().getEReferences()) { - if (refToObserv.contains(ref)) { - Object o = source.eGet(ref); - - if (o instanceof EObjectEList) { - @SuppressWarnings("unchecked") - List list = (EObjectEList) o; - Iterator it = list.iterator(); - - while (it.hasNext()) { - EObject target = it.next(); - if (isInsert) { - if (!target.equals(source)) nodeInserted(target); - edgeInserted(source, target); - } else { - edgeDeleted(source, target); - if (!target.equals(source)) nodeDeleted(target); - } - } - } else { - EObject target = (EObject) o; - if (isInsert) { - if (!target.equals(source)) nodeInserted(target); - edgeInserted(source, target); - } else { - edgeDeleted(source, target); - if (!target.equals(source)) nodeDeleted(target); - } - } - } - } - } - - @Override - public void notifyChanged(Notification notification) { - super.notifyChanged(notification); - Object feature = notification.getFeature(); - Object oldValue = notification.getOldValue(); - Object newValue = notification.getNewValue(); - Object notifier = notification.getNotifier(); - - //System.out.println(notification); - if (feature instanceof EReference && - (oldValue == null || oldValue instanceof EObject) && - (newValue == null || newValue instanceof EObject) && - (notifier == null || notifier instanceof EObject)) { - - EReference ref = (EReference) feature; - EObject oldValueObj = (EObject) oldValue; - EObject newValueObj = (EObject) newValue; - EObject notifierObj = (EObject) notifier; - - if (ref.isContainment()) { - // Inserting nodes - if (notification.getEventType() == Notification.ADD - && oldValueObj == null && newValueObj != null) { - nodeInserted(newValueObj); - visitObjectForEReference(newValueObj, true); - } - if (notification.getEventType() == Notification.REMOVE - && newValueObj == null && oldValueObj != null) { - visitObjectForEReference(oldValueObj, false); - nodeDeleted(oldValueObj); - } - } else // Inserting edges (excusively -> edge or node modification) - if (refToObserv.contains(ref)) { - - if (notification.getEventType() == Notification.ADD - && newValueObj != null) { - edgeInserted(notifierObj, newValueObj); - } - else if (notification.getEventType() == Notification.REMOVE - && oldValueObj != null) { - edgeDeleted(notifierObj, oldValueObj); - } - else if (notification.getEventType() == Notification.SET) { - if (oldValueObj != null) { - edgeDeleted(notifierObj, oldValueObj); - } - - if (newValueObj != null) { - edgeInserted(notifierObj, newValueObj); - } - } - } - } - } - - private void edgeInserted(EObject source, EObject target) { - dataSource.notifyEdgeInserted(source, target); - } - - private void edgeDeleted(EObject source, EObject target) { - dataSource.notifyEdgeDeleted(source, target); - } - - private void nodeInserted(EObject node) { - dataSource.notifyNodeInserted(node); - } - - private void nodeDeleted(EObject node) { - dataSource.notifyNodeDeleted(node); - } - - @Override - public void attachObserver(ITcObserver to) { - this.observers.add(to); - } - - @Override - public void detachObserver(ITcObserver to) { - this.observers.remove(to); - } - - @Override - public Set getAllReachableTargets(EObject source) { - return this.sccAlg.getAllReachableTargets(source); - } - - @Override - public Set getAllReachableSources(EObject target) { - return this.sccAlg.getAllReachableSources(target); - } - - @Override - public boolean isReachable(EObject source, EObject target) { - return this.sccAlg.isReachable(source, target); - } - - @Override - public void tupleInserted(EObject source, EObject target) { - for (ITcObserver to : observers) { - to.tupleInserted(source, target); - } - } - - @Override - public void tupleDeleted(EObject source, EObject target) { - for (ITcObserver to : observers) { - to.tupleDeleted(source, target); - } - } - - @Override - public void dispose() { - this.sccAlg.dispose(); - this.notifier.eAdapters().remove(this); - } -} + +/** + * Implementation class for the transitive closure. The class is a wrapper for the tc algorithms on an emf model. + * + * @author Tamas Szabo + * + */ +public class TransitiveClosureHelperImpl extends EContentAdapter implements TransitiveClosureHelper, + ITcObserver { + + private IncSCCAlg sccAlg; + private Set refToObserv; + private EMFDataSource dataSource; + private ArrayList> observers; + private Notifier notifier; + + public TransitiveClosureHelperImpl(Notifier emfRoot, Set refToObserv) throws IncQueryBaseException { + this.refToObserv = refToObserv; + this.notifier = emfRoot; + this.observers = new ArrayList>(); + + if (emfRoot instanceof EObject) { + dataSource = new EMFDataSource.ForEObject((EObject) emfRoot, refToObserv); + } else if (emfRoot instanceof Resource) { + dataSource = new EMFDataSource.ForResource((Resource) emfRoot, refToObserv); + } else if (emfRoot instanceof ResourceSet) { + dataSource = new EMFDataSource.ForResourceSet((ResourceSet) emfRoot, refToObserv); + } else { + throw new IncQueryBaseException(IncQueryBaseException.INVALID_EMFROOT); + } + + this.sccAlg = new IncSCCAlg(dataSource); + this.sccAlg.attachObserver(this); + emfRoot.eAdapters().add(this); + } + + /** + * The method visits an {@link EObject} for the registered references in order to explore the potential nodes and + * edges that should be inserted and deleted. + * + * Multiple node deletion and insertion must be avoided! + * + * @param source + * @param isInsert + */ + private void visitObjectForEReference(EObject source, boolean isInsert) { + for (EReference ref : source.eClass().getEReferences()) { + if (refToObserv.contains(ref)) { + Object o = source.eGet(ref); + + if (o instanceof EObjectEList) { + @SuppressWarnings("unchecked") + List list = (EObjectEList) o; + Iterator it = list.iterator(); + + while (it.hasNext()) { + EObject target = it.next(); + if (isInsert) { + if (!target.equals(source)) + nodeInserted(target); + edgeInserted(source, target); + } else { + edgeDeleted(source, target); + if (!target.equals(source)) + nodeDeleted(target); + } + } + } else { + EObject target = (EObject) o; + if (isInsert) { + if (!target.equals(source)) + nodeInserted(target); + edgeInserted(source, target); + } else { + edgeDeleted(source, target); + if (!target.equals(source)) + nodeDeleted(target); + } + } + } + } + } + + @Override + public void notifyChanged(Notification notification) { + super.notifyChanged(notification); + Object feature = notification.getFeature(); + Object oldValue = notification.getOldValue(); + Object newValue = notification.getNewValue(); + Object notifier = notification.getNotifier(); + + // System.out.println(notification); + if (feature instanceof EReference && (oldValue == null || oldValue instanceof EObject) + && (newValue == null || newValue instanceof EObject) + && (notifier == null || notifier instanceof EObject)) { + + EReference ref = (EReference) feature; + EObject oldValueObj = (EObject) oldValue; + EObject newValueObj = (EObject) newValue; + EObject notifierObj = (EObject) notifier; + + if (ref.isContainment()) { + // Inserting nodes + if (notification.getEventType() == Notification.ADD && oldValueObj == null && newValueObj != null) { + nodeInserted(newValueObj); + visitObjectForEReference(newValueObj, true); + } + if (notification.getEventType() == Notification.REMOVE && newValueObj == null && oldValueObj != null) { + visitObjectForEReference(oldValueObj, false); + nodeDeleted(oldValueObj); + } + } else // Inserting edges (excusively -> edge or node modification) + if (refToObserv.contains(ref)) { + + if (notification.getEventType() == Notification.ADD && newValueObj != null) { + edgeInserted(notifierObj, newValueObj); + } else if (notification.getEventType() == Notification.REMOVE && oldValueObj != null) { + edgeDeleted(notifierObj, oldValueObj); + } else if (notification.getEventType() == Notification.SET) { + if (oldValueObj != null) { + edgeDeleted(notifierObj, oldValueObj); + } + + if (newValueObj != null) { + edgeInserted(notifierObj, newValueObj); + } + } + } + } + } + + private void edgeInserted(EObject source, EObject target) { + dataSource.notifyEdgeInserted(source, target); + } + + private void edgeDeleted(EObject source, EObject target) { + dataSource.notifyEdgeDeleted(source, target); + } + + private void nodeInserted(EObject node) { + dataSource.notifyNodeInserted(node); + } + + private void nodeDeleted(EObject node) { + dataSource.notifyNodeDeleted(node); + } + + @Override + public void attachObserver(ITcObserver to) { + this.observers.add(to); + } + + @Override + public void detachObserver(ITcObserver to) { + this.observers.remove(to); + } + + @Override + public Set getAllReachableTargets(EObject source) { + return this.sccAlg.getAllReachableTargets(source); + } + + @Override + public Set getAllReachableSources(EObject target) { + return this.sccAlg.getAllReachableSources(target); + } + + @Override + public boolean isReachable(EObject source, EObject target) { + return this.sccAlg.isReachable(source, target); + } + + @Override + public void tupleInserted(EObject source, EObject target) { + for (ITcObserver to : observers) { + to.tupleInserted(source, target); + } + } + + @Override + public void tupleDeleted(EObject source, EObject target) { + for (ITcObserver to : observers) { + to.tupleDeleted(source, target); + } + } + + @Override + public void dispose() { + this.sccAlg.dispose(); + this.notifier.eAdapters().remove(this); + } +} diff --git a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/exception/IncQueryBaseException.java b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/exception/IncQueryBaseException.java index 0a6f421d..ebe142df 100644 --- a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/exception/IncQueryBaseException.java +++ b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/exception/IncQueryBaseException.java @@ -9,19 +9,17 @@ * Tamas Szabo, Gabor Bergmann - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.base.exception; - - -public class IncQueryBaseException extends Exception -{ - - private static final long serialVersionUID = -5145445047912938251L; - - public static String EMPTY_REF_LIST = "At least one EReference must be provided!"; - public static String INVALID_EMFROOT = "Emf navigation helper can only be attached on the contents of an EMF EObject, Resource, or ResourceSet."; - - public IncQueryBaseException(String s) { - super(s); - } - -} +package org.eclipse.incquery.runtime.base.exception; + +public class IncQueryBaseException extends Exception { + + private static final long serialVersionUID = -5145445047912938251L; + + public static String EMPTY_REF_LIST = "At least one EReference must be provided!"; + public static String INVALID_EMFROOT = "Emf navigation helper can only be attached on the contents of an EMF EObject, Resource, or ResourceSet."; + + public IncQueryBaseException(String s) { + super(s); + } + +} diff --git a/plugins/org.eclipse.incquery.runtime.gmf/src/org/eclipse/incquery/runtime/gmf/Activator.java b/plugins/org.eclipse.incquery.runtime.gmf/src/org/eclipse/incquery/runtime/gmf/Activator.java index de90bc70..f03c66ea 100644 --- a/plugins/org.eclipse.incquery.runtime.gmf/src/org/eclipse/incquery/runtime/gmf/Activator.java +++ b/plugins/org.eclipse.incquery.runtime.gmf/src/org/eclipse/incquery/runtime/gmf/Activator.java @@ -19,45 +19,47 @@ */ public class Activator extends AbstractUIPlugin { - // The plug-in ID - public static final String PLUGIN_ID = "org.eclipse.incquery.runtime.gmf"; //$NON-NLS-1$ - - // The shared instance - private static Activator plugin; - - /** - * The constructor - */ - public Activator() { - } - - /* - * (non-Javadoc) - * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) - */ - @Override + // The plug-in ID + public static final String PLUGIN_ID = "org.eclipse.incquery.runtime.gmf"; //$NON-NLS-1$ + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() { + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + @Override public void start(BundleContext context) throws Exception { - super.start(context); - plugin = this; - } - - /* - * (non-Javadoc) - * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) - */ - @Override + super.start(context); + plugin = this; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + @Override public void stop(BundleContext context) throws Exception { - plugin = null; - super.stop(context); - } - - /** - * Returns the shared instance - * - * @return the shared instance - */ - public static Activator getDefault() { - return plugin; - } + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } } diff --git a/plugins/org.eclipse.incquery.runtime.gmf/src/org/eclipse/incquery/runtime/gmf/handlers/InitValidatorsHandler.java b/plugins/org.eclipse.incquery.runtime.gmf/src/org/eclipse/incquery/runtime/gmf/handlers/InitValidatorsHandler.java index 498bc49e..8591fe6b 100644 --- a/plugins/org.eclipse.incquery.runtime.gmf/src/org/eclipse/incquery/runtime/gmf/handlers/InitValidatorsHandler.java +++ b/plugins/org.eclipse.incquery.runtime.gmf/src/org/eclipse/incquery/runtime/gmf/handlers/InitValidatorsHandler.java @@ -56,7 +56,7 @@ public Object execute(ExecutionEvent event) throws ExecutionException { // FIXME should go through ValidationInitUtil! ValidationUtil.addNotifier(activeEditor, notifier); activeEditor.getEditorSite().getPage().addPartListener(ValidationPartListener.getInstance()); - + return null; } diff --git a/plugins/org.eclipse.incquery.runtime.gmf/src/org/eclipse/incquery/runtime/gmf/util/GMFModelConnector.java b/plugins/org.eclipse.incquery.runtime.gmf/src/org/eclipse/incquery/runtime/gmf/util/GMFModelConnector.java index 9f088afb..838f959b 100644 --- a/plugins/org.eclipse.incquery.runtime.gmf/src/org/eclipse/incquery/runtime/gmf/util/GMFModelConnector.java +++ b/plugins/org.eclipse.incquery.runtime.gmf/src/org/eclipse/incquery/runtime/gmf/util/GMFModelConnector.java @@ -26,41 +26,41 @@ /** * @author Tamas Szabo - * + * */ public class GMFModelConnector extends EMFModelConnector { - public GMFModelConnector(MatcherTreeViewerRootKey key) { - super(key); - } + public GMFModelConnector(MatcherTreeViewerRootKey key) { + super(key); + } + + @Override + protected TreePath createTreePath(IEditorPart editor, EObject obj) { + if (editor instanceof DiagramDocumentEditor) { + DiagramDocumentEditor providerEditor = (DiagramDocumentEditor) editor; + EditPart epBegin = providerEditor.getDiagramEditPart().getPrimaryChildEditPart(); + if (epBegin instanceof GraphicalEditPart) { + List nodes = new ArrayList(); + epBegin = ((GraphicalEditPart) epBegin).findEditPart(epBegin.getRoot(), obj); + if (epBegin != null) { + nodes.add(epBegin); + return new TreePath(nodes.toArray()); + } + } + } + return null; + } - @Override - protected TreePath createTreePath(IEditorPart editor, EObject obj) { - if (editor instanceof DiagramDocumentEditor) { - DiagramDocumentEditor providerEditor = (DiagramDocumentEditor) editor; - EditPart epBegin = providerEditor.getDiagramEditPart().getPrimaryChildEditPart(); - if(epBegin instanceof GraphicalEditPart) { - List nodes = new ArrayList(); - epBegin = ((GraphicalEditPart) epBegin).findEditPart(epBegin.getRoot() , obj); - if(epBegin != null) { - nodes.add(epBegin); - return new TreePath(nodes.toArray()); - } - } - } - return null; - } - - @Override - protected void navigateToElements(IEditorPart editorPart, IStructuredSelection selection) { - super.navigateToElements(editorPart, selection); - if (editorPart instanceof DiagramDocumentEditor) { - DiagramDocumentEditor providerEditor = (DiagramDocumentEditor) editorPart; - IDiagramGraphicalViewer viewer = providerEditor.getDiagramGraphicalViewer(); - if (selection.getFirstElement() instanceof GraphicalEditPart) { - GraphicalEditPart part = (GraphicalEditPart) selection.getFirstElement(); - viewer.reveal(part); - } - } - } + @Override + protected void navigateToElements(IEditorPart editorPart, IStructuredSelection selection) { + super.navigateToElements(editorPart, selection); + if (editorPart instanceof DiagramDocumentEditor) { + DiagramDocumentEditor providerEditor = (DiagramDocumentEditor) editorPart; + IDiagramGraphicalViewer viewer = providerEditor.getDiagramGraphicalViewer(); + if (selection.getFirstElement() instanceof GraphicalEditPart) { + GraphicalEditPart part = (GraphicalEditPart) selection.getFirstElement(); + viewer.reveal(part); + } + } + } } diff --git a/plugins/org.eclipse.incquery.runtime.graphiti/src/org/eclipse/incquery/runtime/graphiti/handlers/GraphitiEditorLoadModelHandler.java b/plugins/org.eclipse.incquery.runtime.graphiti/src/org/eclipse/incquery/runtime/graphiti/handlers/GraphitiEditorLoadModelHandler.java index 5f54e881..72e5daa8 100644 --- a/plugins/org.eclipse.incquery.runtime.graphiti/src/org/eclipse/incquery/runtime/graphiti/handlers/GraphitiEditorLoadModelHandler.java +++ b/plugins/org.eclipse.incquery.runtime.graphiti/src/org/eclipse/incquery/runtime/graphiti/handlers/GraphitiEditorLoadModelHandler.java @@ -25,21 +25,21 @@ public class GraphitiEditorLoadModelHandler extends LoadModelHandler { - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - IEditorPart editorPart = HandlerUtil.getActiveEditor(event); - - if (editorPart instanceof DiagramEditor) { - DiagramEditor providerEditor = (DiagramEditor) editorPart; - ResourceSet resourceSet = providerEditor.getEditingDomain().getResourceSet(); - if (resourceSet.getResources().size() > 0) { - MatcherTreeViewerRootKey key = new MatcherTreeViewerRootKey(editorPart, resourceSet); - ModelConnector contentModel = new GraphitiModelConnector(key); - QueryExplorer.getInstance().getModelConnectorMap().put(key, contentModel); - contentModel.loadModel(); - } - } - return null; - } + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + IEditorPart editorPart = HandlerUtil.getActiveEditor(event); + + if (editorPart instanceof DiagramEditor) { + DiagramEditor providerEditor = (DiagramEditor) editorPart; + ResourceSet resourceSet = providerEditor.getEditingDomain().getResourceSet(); + if (resourceSet.getResources().size() > 0) { + MatcherTreeViewerRootKey key = new MatcherTreeViewerRootKey(editorPart, resourceSet); + ModelConnector contentModel = new GraphitiModelConnector(key); + QueryExplorer.getInstance().getModelConnectorMap().put(key, contentModel); + contentModel.loadModel(); + } + } + return null; + } } diff --git a/plugins/org.eclipse.incquery.runtime.graphiti/src/org/eclipse/incquery/runtime/graphiti/handlers/GraphitiEditorLoadResourceHandler.java b/plugins/org.eclipse.incquery.runtime.graphiti/src/org/eclipse/incquery/runtime/graphiti/handlers/GraphitiEditorLoadResourceHandler.java index 3d630464..bd52e003 100644 --- a/plugins/org.eclipse.incquery.runtime.graphiti/src/org/eclipse/incquery/runtime/graphiti/handlers/GraphitiEditorLoadResourceHandler.java +++ b/plugins/org.eclipse.incquery.runtime.graphiti/src/org/eclipse/incquery/runtime/graphiti/handlers/GraphitiEditorLoadResourceHandler.java @@ -27,25 +27,26 @@ public class GraphitiEditorLoadResourceHandler extends LoadModelHandler { - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - IEditorPart editorPart = HandlerUtil.getActiveEditor(event); - - if (editorPart instanceof DiagramEditor) { - DiagramEditor providerEditor = (DiagramEditor) editorPart; - - PictogramElement[] selectedElements = providerEditor.getSelectedPictogramElements(); - - if (selectedElements.length > 0) { - PictogramElement element = selectedElements[0]; - Resource resource = Graphiti.getLinkService().getBusinessObjectForLinkedPictogramElement(element).eResource(); - MatcherTreeViewerRootKey key = new MatcherTreeViewerRootKey(providerEditor, resource); - ModelConnector contentModel = new GraphitiModelConnector(key); - QueryExplorer.getInstance().getModelConnectorMap().put(key, contentModel); - contentModel.loadModel(); - } - } - return null; - } + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + IEditorPart editorPart = HandlerUtil.getActiveEditor(event); + + if (editorPart instanceof DiagramEditor) { + DiagramEditor providerEditor = (DiagramEditor) editorPart; + + PictogramElement[] selectedElements = providerEditor.getSelectedPictogramElements(); + + if (selectedElements.length > 0) { + PictogramElement element = selectedElements[0]; + Resource resource = Graphiti.getLinkService().getBusinessObjectForLinkedPictogramElement(element) + .eResource(); + MatcherTreeViewerRootKey key = new MatcherTreeViewerRootKey(providerEditor, resource); + ModelConnector contentModel = new GraphitiModelConnector(key); + QueryExplorer.getInstance().getModelConnectorMap().put(key, contentModel); + contentModel.loadModel(); + } + } + return null; + } } diff --git a/plugins/org.eclipse.incquery.runtime.graphiti/src/org/eclipse/incquery/runtime/graphiti/util/GraphitiEditorPartListener.java b/plugins/org.eclipse.incquery.runtime.graphiti/src/org/eclipse/incquery/runtime/graphiti/util/GraphitiEditorPartListener.java index 329ac237..2cffe9f5 100644 --- a/plugins/org.eclipse.incquery.runtime.graphiti/src/org/eclipse/incquery/runtime/graphiti/util/GraphitiEditorPartListener.java +++ b/plugins/org.eclipse.incquery.runtime.graphiti/src/org/eclipse/incquery/runtime/graphiti/util/GraphitiEditorPartListener.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi, Abel Hegedus - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.graphiti.util; - +package org.eclipse.incquery.runtime.graphiti.util; + import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.graphiti.ui.editor.DiagramEditor; import org.eclipse.incquery.tooling.ui.queryexplorer.QueryExplorer; @@ -18,42 +18,42 @@ import org.eclipse.incquery.tooling.ui.queryexplorer.util.BasePartListener; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbenchPart; - -/** - * The PartListener is used to observe EditorPart close actions on Graphiti editors. - * - * @author Tamas Szabo - * - */ -public class GraphitiEditorPartListener extends BasePartListener { - - private static GraphitiEditorPartListener instance; - - protected GraphitiEditorPartListener() { - - } - - public synchronized static GraphitiEditorPartListener getInstance() { - if (instance == null) { - instance = new GraphitiEditorPartListener(); - } - return instance; - } - - @Override - public void partClosed(IWorkbenchPart part) { - - if (part != null && part instanceof IEditorPart) { - IEditorPart closedEditor = (IEditorPart) part; - if (closedEditor instanceof DiagramEditor) { - DiagramEditor providerEditor = (DiagramEditor) closedEditor; - ResourceSet resourceSet = providerEditor.getEditingDomain().getResourceSet(); - if (resourceSet.getResources().size() > 0) { - MatcherTreeViewerRootKey key = new MatcherTreeViewerRootKey(providerEditor, resourceSet); - QueryExplorer.getInstance().getModelConnectorMap().get(key).unloadModel(); - } - } - } - - } -} + +/** + * The PartListener is used to observe EditorPart close actions on Graphiti editors. + * + * @author Tamas Szabo + * + */ +public class GraphitiEditorPartListener extends BasePartListener { + + private static GraphitiEditorPartListener instance; + + protected GraphitiEditorPartListener() { + + } + + public synchronized static GraphitiEditorPartListener getInstance() { + if (instance == null) { + instance = new GraphitiEditorPartListener(); + } + return instance; + } + + @Override + public void partClosed(IWorkbenchPart part) { + + if (part != null && part instanceof IEditorPart) { + IEditorPart closedEditor = (IEditorPart) part; + if (closedEditor instanceof DiagramEditor) { + DiagramEditor providerEditor = (DiagramEditor) closedEditor; + ResourceSet resourceSet = providerEditor.getEditingDomain().getResourceSet(); + if (resourceSet.getResources().size() > 0) { + MatcherTreeViewerRootKey key = new MatcherTreeViewerRootKey(providerEditor, resourceSet); + QueryExplorer.getInstance().getModelConnectorMap().get(key).unloadModel(); + } + } + } + + } +} diff --git a/plugins/org.eclipse.incquery.runtime.graphiti/src/org/eclipse/incquery/runtime/graphiti/util/GraphitiModelConnector.java b/plugins/org.eclipse.incquery.runtime.graphiti/src/org/eclipse/incquery/runtime/graphiti/util/GraphitiModelConnector.java index c7c21861..ba6a1088 100644 --- a/plugins/org.eclipse.incquery.runtime.graphiti/src/org/eclipse/incquery/runtime/graphiti/util/GraphitiModelConnector.java +++ b/plugins/org.eclipse.incquery.runtime.graphiti/src/org/eclipse/incquery/runtime/graphiti/util/GraphitiModelConnector.java @@ -9,8 +9,8 @@ * Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.runtime.graphiti.util; - +package org.eclipse.incquery.runtime.graphiti.util; + import java.util.ArrayList; import java.util.List; @@ -27,65 +27,65 @@ import org.eclipse.jface.viewers.TreePath; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbenchPage; - -public class GraphitiModelConnector extends EMFModelConnector { - - private IWorkbenchPage workbenchPage; - - public GraphitiModelConnector(MatcherTreeViewerRootKey key) { - super(key); - this.workbenchPage = key.getEditorPart().getSite().getPage(); - } - - @Override - public void loadModel() { - workbenchPage.addPartListener(GraphitiEditorPartListener.getInstance()); - if (QueryExplorer.getInstance() != null) { - QueryExplorer.getInstance().getMatcherTreeViewerRoot().addPatternMatcherRoot(key); - } - } - - @Override - public void unloadModel() { - workbenchPage.removePartListener(GraphitiEditorPartListener.getInstance()); - if (QueryExplorer.getInstance() != null) { - QueryExplorer.getInstance().getMatcherTreeViewerRoot().removePatternMatcherRoot(key); - } - } - - @Override - public void showLocation(Object[] locationObjects) { - //reflective set selection is not needed - IStructuredSelection preparedSelection = prepareSelection(locationObjects); - navigateToElements(key.getEditorPart(), preparedSelection); - workbenchPage.bringToTop(key.getEditorPart()); - } - - @Override - protected TreePath createTreePath(IEditorPart editor, EObject obj) { - if (editor instanceof DiagramEditor) { - Diagram diagram = ((DiagramEditor) editor).getDiagramTypeProvider().getDiagram(); - List pictogramElements = Graphiti.getLinkService().getPictogramElements(diagram, obj); - if (!pictogramElements.isEmpty()) { - List parts = new ArrayList(); - for (PictogramElement element : pictogramElements) { - EditPart part = ((DiagramEditor) editor).getEditPartForPictogramElement(element); - if (part != null) { - parts.add(part); - } - } - return new TreePath(parts.toArray()); - } - } - return null; - } - - @Override - protected void navigateToElements(IEditorPart editorPart, IStructuredSelection selection) { - if (editorPart instanceof DiagramEditor) { - DiagramEditor providerEditor = (DiagramEditor) editorPart; - providerEditor.getGraphicalViewer().setSelection(selection); - } - } - -} + +public class GraphitiModelConnector extends EMFModelConnector { + + private IWorkbenchPage workbenchPage; + + public GraphitiModelConnector(MatcherTreeViewerRootKey key) { + super(key); + this.workbenchPage = key.getEditorPart().getSite().getPage(); + } + + @Override + public void loadModel() { + workbenchPage.addPartListener(GraphitiEditorPartListener.getInstance()); + if (QueryExplorer.getInstance() != null) { + QueryExplorer.getInstance().getMatcherTreeViewerRoot().addPatternMatcherRoot(key); + } + } + + @Override + public void unloadModel() { + workbenchPage.removePartListener(GraphitiEditorPartListener.getInstance()); + if (QueryExplorer.getInstance() != null) { + QueryExplorer.getInstance().getMatcherTreeViewerRoot().removePatternMatcherRoot(key); + } + } + + @Override + public void showLocation(Object[] locationObjects) { + // reflective set selection is not needed + IStructuredSelection preparedSelection = prepareSelection(locationObjects); + navigateToElements(key.getEditorPart(), preparedSelection); + workbenchPage.bringToTop(key.getEditorPart()); + } + + @Override + protected TreePath createTreePath(IEditorPart editor, EObject obj) { + if (editor instanceof DiagramEditor) { + Diagram diagram = ((DiagramEditor) editor).getDiagramTypeProvider().getDiagram(); + List pictogramElements = Graphiti.getLinkService().getPictogramElements(diagram, obj); + if (!pictogramElements.isEmpty()) { + List parts = new ArrayList(); + for (PictogramElement element : pictogramElements) { + EditPart part = ((DiagramEditor) editor).getEditPartForPictogramElement(element); + if (part != null) { + parts.add(part); + } + } + return new TreePath(parts.toArray()); + } + } + return null; + } + + @Override + protected void navigateToElements(IEditorPart editorPart, IStructuredSelection selection) { + if (editorPart instanceof DiagramEditor) { + DiagramEditor providerEditor = (DiagramEditor) editorPart; + providerEditor.getGraphicalViewer().setSelection(selection); + } + } + +} diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/Activator.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/Activator.java index 19e5f267..ece98709 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/Activator.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/Activator.java @@ -18,45 +18,47 @@ */ public class Activator extends Plugin { - // The plug-in ID - public static final String PLUGIN_ID = "org.eclipse.incquery.runtime.rete"; - - // The shared instance - private static Activator plugin; - - /** - * The constructor - */ - public Activator() { - } - - /* - * (non-Javadoc) - * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext) - */ - @Override - public void start(BundleContext context) throws Exception { - super.start(context); - plugin = this; - } - - /* - * (non-Javadoc) - * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) - */ - @Override - public void stop(BundleContext context) throws Exception { - plugin = null; - super.stop(context); - } - - /** - * Returns the shared instance - * - * @return the shared instance - */ - public static Activator getDefault() { - return plugin; - } + // The plug-in ID + public static final String PLUGIN_ID = "org.eclipse.incquery.runtime.rete"; + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() { + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext) + */ + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) + */ + @Override + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/AbstractEvaluator.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/AbstractEvaluator.java index 68dd5556..4f08219d 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/AbstractEvaluator.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/AbstractEvaluator.java @@ -16,27 +16,27 @@ import org.eclipse.incquery.runtime.rete.tuple.Tuple; - /** * Depicts an abstract evaluator that evaluates tuples to Objects. Used inside evaluator nodes. + * * @author Bergmann Gábor - * + * */ public abstract class AbstractEvaluator { - /** - * Each tuple represents a trace of the activity during evaluation. - * Change notifications received on these traces will be used to trigger re-evaluation. - */ - Set traces = new HashSet(); - - public abstract Object doEvaluate(Tuple tuple) throws Throwable; - - final Object evaluate(Tuple tuple) throws Throwable { - traces.clear(); - return doEvaluate(tuple); - } + /** + * Each tuple represents a trace of the activity during evaluation. Change notifications received on these traces + * will be used to trigger re-evaluation. + */ + Set traces = new HashSet(); + + public abstract Object doEvaluate(Tuple tuple) throws Throwable; + + final Object evaluate(Tuple tuple) throws Throwable { + traces.clear(); + return doEvaluate(tuple); + } - public Set getTraces() { - return traces; - } + public Set getTraces() { + return traces; + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/ContainmentFeeder.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/ContainmentFeeder.java index d11d0e14..4f0ad4b0 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/ContainmentFeeder.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/ContainmentFeeder.java @@ -16,26 +16,23 @@ import org.eclipse.incquery.runtime.rete.network.Receiver; import org.eclipse.incquery.runtime.rete.remote.Address; - - public class ContainmentFeeder extends Feeder { - /** - * @param receiver - * @param context - * @param network - * @param boundary - */ - public ContainmentFeeder(Address receiver, - IPatternMatcherRuntimeContext context, Network network, - ReteBoundary boundary) { - super(receiver, context, network, boundary); - // TODO Auto-generated constructor stub - } - - @Override - public void feed() { - context.enumerateAllUnaryContainments(pairCrawler()); - } + /** + * @param receiver + * @param context + * @param network + * @param boundary + */ + public ContainmentFeeder(Address receiver, IPatternMatcherRuntimeContext context, + Network network, ReteBoundary boundary) { + super(receiver, context, network, boundary); + // TODO Auto-generated constructor stub + } + + @Override + public void feed() { + context.enumerateAllUnaryContainments(pairCrawler()); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/Disconnectable.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/Disconnectable.java index 87630a27..70905706 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/Disconnectable.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/Disconnectable.java @@ -23,6 +23,6 @@ public interface Disconnectable { * Disconnects this rete engine component from the underlying model. Disconnecting enables the garbage collection * mechanisms to dispose of the rete network. */ - void disconnect(); + void disconnect(); } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/EntityFeeder.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/EntityFeeder.java index 263e58bb..9ccfd5db 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/EntityFeeder.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/EntityFeeder.java @@ -17,34 +17,32 @@ import org.eclipse.incquery.runtime.rete.network.Receiver; import org.eclipse.incquery.runtime.rete.remote.Address; - public class EntityFeeder extends Feeder { - protected Object typeObject; + protected Object typeObject; + + /** + * @param receiver + * @param context + * @param network + * @param boundary + * @param typeObject + */ + public EntityFeeder(Address receiver, IPatternMatcherRuntimeContext context, + Network network, ReteBoundary boundary, Object typeObject) { + super(receiver, context, network, boundary); + this.typeObject = typeObject; + } - /** - * @param receiver - * @param context - * @param network - * @param boundary - * @param typeObject - */ - public EntityFeeder(Address receiver, - IPatternMatcherRuntimeContext context, Network network, - ReteBoundary boundary, Object typeObject) { - super(receiver, context, network, boundary); - this.typeObject = typeObject; - } + @Override + public void feed() { + if (typeObject != null) { + if (context.allowedGeneralizationQueryDirection() == GeneralizationQueryDirection.BOTH) + context.enumerateDirectUnaryInstances(typeObject, unaryCrawler()); + else + context.enumerateAllUnaryInstances(typeObject, unaryCrawler()); + } else { + context.enumerateAllUnaries(unaryCrawler()); + } + } - @Override - public void feed() { - if (typeObject != null) { - if (context.allowedGeneralizationQueryDirection() == GeneralizationQueryDirection.BOTH) - context.enumerateDirectUnaryInstances(typeObject, unaryCrawler()); - else - context.enumerateAllUnaryInstances(typeObject, unaryCrawler()); - } else { - context.enumerateAllUnaries(unaryCrawler()); - } - } - } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/Feeder.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/Feeder.java index 82a634a0..bfa74601 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/Feeder.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/Feeder.java @@ -21,64 +21,60 @@ /** * @author Bergmann Gábor - * + * */ public abstract class Feeder { - protected Address receiver; - protected IPatternMatcherRuntimeContext context; - protected Network network; - protected ReteBoundary boundary; + protected Address receiver; + protected IPatternMatcherRuntimeContext context; + protected Network network; + protected ReteBoundary boundary; + + /** + * @param receiver + * @param context + * @param network + * @param boundary + */ + public Feeder(Address receiver, IPatternMatcherRuntimeContext context, Network network, + ReteBoundary boundary) { + super(); + this.receiver = receiver; + this.context = context; + this.network = network; + this.boundary = boundary; + } + + public abstract void feed(); + + protected void emit(Tuple tuple) { + network.sendConstructionUpdate(receiver, Direction.INSERT, tuple); + } - /** - * @param receiver - * @param context - * @param network - * @param boundary - */ - public Feeder(Address receiver, - IPatternMatcherRuntimeContext context, Network network, - ReteBoundary boundary) { - super(); - this.receiver = receiver; - this.context = context; - this.network = network; - this.boundary = boundary; - } + protected IPatternMatcherRuntimeContext.ModelElementCrawler unaryCrawler() { + return new IPatternMatcherRuntimeContext.ModelElementCrawler() { + public void crawl(Object element) { + emit(new FlatTuple(boundary.wrapElement(element))); + } + }; + } - public abstract void feed(); - - protected void emit(Tuple tuple) { - network.sendConstructionUpdate(receiver, Direction.INSERT, tuple); - } - - protected IPatternMatcherRuntimeContext.ModelElementCrawler unaryCrawler() { - return new IPatternMatcherRuntimeContext.ModelElementCrawler() { - public void crawl(Object element) { - emit(new FlatTuple(boundary.wrapElement(element))); - } - }; - } + protected IPatternMatcherRuntimeContext.ModelElementPairCrawler pairCrawler() { + return new IPatternMatcherRuntimeContext.ModelElementPairCrawler() { + public void crawl(Object first, Object second) { + emit(new FlatTuple(boundary.wrapElement(first), boundary.wrapElement(second))); + } + }; + } - protected IPatternMatcherRuntimeContext.ModelElementPairCrawler pairCrawler() { - return new IPatternMatcherRuntimeContext.ModelElementPairCrawler() { - public void crawl(Object first, Object second) { - emit(new FlatTuple(boundary.wrapElement(first), boundary.wrapElement(second))); - } - }; - } - - protected IPatternMatcherRuntimeContext.ModelElementCrawler ternaryCrawler() { - return new IPatternMatcherRuntimeContext.ModelElementCrawler() { - public void crawl(Object element) { - Object relation = element; - Object from = context.ternaryEdgeSource(relation); - Object to = context.ternaryEdgeTarget(relation); - emit(new FlatTuple( - boundary.wrapElement(relation), - boundary.wrapElement(from), - boundary.wrapElement(to))); - } - }; - } + protected IPatternMatcherRuntimeContext.ModelElementCrawler ternaryCrawler() { + return new IPatternMatcherRuntimeContext.ModelElementCrawler() { + public void crawl(Object element) { + Object relation = element; + Object from = context.ternaryEdgeSource(relation); + Object to = context.ternaryEdgeTarget(relation); + emit(new FlatTuple(boundary.wrapElement(relation), boundary.wrapElement(from), boundary.wrapElement(to))); + } + }; + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/GeneralizationFeeder.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/GeneralizationFeeder.java index 299cbcb2..4669a8fb 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/GeneralizationFeeder.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/GeneralizationFeeder.java @@ -16,25 +16,23 @@ import org.eclipse.incquery.runtime.rete.network.Receiver; import org.eclipse.incquery.runtime.rete.remote.Address; - public class GeneralizationFeeder extends Feeder { - /** - * @param receiver - * @param context - * @param network - * @param boundary - */ - public GeneralizationFeeder(Address receiver, - IPatternMatcherRuntimeContext context, Network network, - ReteBoundary boundary) { - super(receiver, context, network, boundary); - // TODO Auto-generated constructor stub - } + /** + * @param receiver + * @param context + * @param network + * @param boundary + */ + public GeneralizationFeeder(Address receiver, IPatternMatcherRuntimeContext context, + Network network, ReteBoundary boundary) { + super(receiver, context, network, boundary); + // TODO Auto-generated constructor stub + } - @Override - public void feed() { - context.enumerateAllGeneralizations(pairCrawler()); - } + @Override + public void feed() { + context.enumerateAllGeneralizations(pairCrawler()); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/IManipulationListener.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/IManipulationListener.java index 67b8863b..22a189af 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/IManipulationListener.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/IManipulationListener.java @@ -13,22 +13,20 @@ /** * @author Bergmann Gábor - * + * */ public interface IManipulationListener extends Disconnectable { - - /** - * @param element - * @param termEvaluatorNode - */ - void registerSensitiveTerm(Object element, - PredicateEvaluatorNode termEvaluatorNode); - /** - * @param element - * @param termEvaluatorNode - */ - void unregisterSensitiveTerm(Object element, - PredicateEvaluatorNode termEvaluatorNode); + /** + * @param element + * @param termEvaluatorNode + */ + void registerSensitiveTerm(Object element, PredicateEvaluatorNode termEvaluatorNode); + + /** + * @param element + * @param termEvaluatorNode + */ + void unregisterSensitiveTerm(Object element, PredicateEvaluatorNode termEvaluatorNode); } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/IPredicateTraceListener.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/IPredicateTraceListener.java index 2d762432..b5721061 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/IPredicateTraceListener.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/IPredicateTraceListener.java @@ -14,14 +14,16 @@ import org.eclipse.incquery.runtime.rete.tuple.Tuple; /** - * Collects traces of predicate evaluation, and notifies the predicate evaluator node to re-evaluate predicates when these traces are influenced by changes. + * Collects traces of predicate evaluation, and notifies the predicate evaluator node to re-evaluate predicates when + * these traces are influenced by changes. + * * @author Bergmann Gábor - * + * */ public interface IPredicateTraceListener extends Disconnectable { - public void registerSensitiveTrace(Tuple trace, PredicateEvaluatorNode node); + public void registerSensitiveTrace(Tuple trace, PredicateEvaluatorNode node); - public void unregisterSensitiveTrace(Tuple trace, PredicateEvaluatorNode node); + public void unregisterSensitiveTrace(Tuple trace, PredicateEvaluatorNode node); } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/InstantiationFeeder.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/InstantiationFeeder.java index 7ef5b772..0ee033e1 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/InstantiationFeeder.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/InstantiationFeeder.java @@ -16,24 +16,22 @@ import org.eclipse.incquery.runtime.rete.network.Receiver; import org.eclipse.incquery.runtime.rete.remote.Address; - public class InstantiationFeeder extends Feeder { - - /** - * @param receiver - * @param context - * @param network - * @param boundary - */ - public InstantiationFeeder(Address receiver, - IPatternMatcherRuntimeContext context, Network network, - ReteBoundary boundary) { - super(receiver, context, network, boundary); - // TODO Auto-generated constructor stub - } - @Override - public void feed() { - context.enumerateAllInstantiations(pairCrawler()); - } + /** + * @param receiver + * @param context + * @param network + * @param boundary + */ + public InstantiationFeeder(Address receiver, IPatternMatcherRuntimeContext context, + Network network, ReteBoundary boundary) { + super(receiver, context, network, boundary); + // TODO Auto-generated constructor stub + } + + @Override + public void feed() { + context.enumerateAllInstantiations(pairCrawler()); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/PredicateEvaluatorNode.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/PredicateEvaluatorNode.java index 8dd172b0..beffa5f5 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/PredicateEvaluatorNode.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/PredicateEvaluatorNode.java @@ -32,7 +32,6 @@ import org.eclipse.incquery.runtime.rete.tuple.TupleMemory; import org.eclipse.incquery.runtime.rete.util.Options; - /** * @author Gabor Bergmann * @@ -51,312 +50,307 @@ public class PredicateEvaluatorNode extends SingleInputNode { - protected ReteEngine engine; - protected ReteBoundary boundary; - protected Integer rhsIndex; - protected int[] affectedIndices; - protected Set outgoing; - protected MemoryNullIndexer memoryNullIndexer; - protected MemoryIdentityIndexer memoryIdentityIndexer; - protected Map> elementOccurences; - protected Map> invoker2traces; - protected Map> trace2invokers; - protected Address asmFunctionTraceNotifier; - protected Address elementChangeNotifier; - protected AbstractEvaluator evaluator; - - private final int tupleWidth; - private final TupleMask nullMask; - private final TupleMask identityMask; - - /** - * @param rhsIndex - * the index of the element in the Tuple that should equals the - * result of the evaluation; if null, the right-hand-side will be the - * Boolean true. - * @param variableIndices - * maps variable names to values. - */ - public PredicateEvaluatorNode(ReteEngine engine, ReteContainer container, - Integer rhsIndex, int[] affectedIndices, int tupleWidth, - AbstractEvaluator evaluator) { - super(container); - this.engine = engine; - this.boundary = engine.getBoundary(); - this.rhsIndex = rhsIndex; - this.affectedIndices = affectedIndices; - this.tupleWidth = tupleWidth; - this.evaluator = evaluator; - - this.elementOccurences = new HashMap>(); - this.outgoing = new HashSet(); - this.invoker2traces = new HashMap>(); - this.trace2invokers = new HashMap>(); - // extractASMFunctions(); - this.asmFunctionTraceNotifier = Address - .of(new ASMFunctionTraceNotifierNode(reteContainer)); - this.elementChangeNotifier = Address.of(new ElementChangeNotifierNode( - reteContainer)); - - nullMask = TupleMask.linear(0, tupleWidth); - identityMask = TupleMask.identity(tupleWidth); -// if (Options.employTrivialIndexers) { -// memoryNullIndexer = new MemoryNullIndexer(reteContainer, tupleWidth, outgoing, this, this); -// reteContainer.getLibrary().registerSpecializedProjectionIndexer(this, memoryNullIndexer); -// memoryIdentityIndexer = new MemoryIdentityIndexer(reteContainer, tupleWidth, outgoing, this, this); -// reteContainer.getLibrary().registerSpecializedProjectionIndexer(this, memoryIdentityIndexer); -// } - - } - - @Override - public ProjectionIndexer constructIndex(TupleMask mask) { - if (Options.employTrivialIndexers) { - if (nullMask.equals(mask)) return getNullIndexer(); - if (identityMask.equals(mask)) return getIdentityIndexer(); - } - return super.constructIndex(mask); - } - - - @Override + protected ReteEngine engine; + protected ReteBoundary boundary; + protected Integer rhsIndex; + protected int[] affectedIndices; + protected Set outgoing; + protected MemoryNullIndexer memoryNullIndexer; + protected MemoryIdentityIndexer memoryIdentityIndexer; + protected Map> elementOccurences; + protected Map> invoker2traces; + protected Map> trace2invokers; + protected Address asmFunctionTraceNotifier; + protected Address elementChangeNotifier; + protected AbstractEvaluator evaluator; + + private final int tupleWidth; + private final TupleMask nullMask; + private final TupleMask identityMask; + + /** + * @param rhsIndex + * the index of the element in the Tuple that should equals the result of the evaluation; if null, the + * right-hand-side will be the Boolean true. + * @param variableIndices + * maps variable names to values. + */ + public PredicateEvaluatorNode(ReteEngine engine, ReteContainer container, Integer rhsIndex, + int[] affectedIndices, int tupleWidth, AbstractEvaluator evaluator) { + super(container); + this.engine = engine; + this.boundary = engine.getBoundary(); + this.rhsIndex = rhsIndex; + this.affectedIndices = affectedIndices; + this.tupleWidth = tupleWidth; + this.evaluator = evaluator; + + this.elementOccurences = new HashMap>(); + this.outgoing = new HashSet(); + this.invoker2traces = new HashMap>(); + this.trace2invokers = new HashMap>(); + // extractASMFunctions(); + this.asmFunctionTraceNotifier = Address.of(new ASMFunctionTraceNotifierNode(reteContainer)); + this.elementChangeNotifier = Address.of(new ElementChangeNotifierNode(reteContainer)); + + nullMask = TupleMask.linear(0, tupleWidth); + identityMask = TupleMask.identity(tupleWidth); + // if (Options.employTrivialIndexers) { + // memoryNullIndexer = new MemoryNullIndexer(reteContainer, tupleWidth, outgoing, this, this); + // reteContainer.getLibrary().registerSpecializedProjectionIndexer(this, memoryNullIndexer); + // memoryIdentityIndexer = new MemoryIdentityIndexer(reteContainer, tupleWidth, outgoing, this, this); + // reteContainer.getLibrary().registerSpecializedProjectionIndexer(this, memoryIdentityIndexer); + // } + + } + + @Override + public ProjectionIndexer constructIndex(TupleMask mask) { + if (Options.employTrivialIndexers) { + if (nullMask.equals(mask)) + return getNullIndexer(); + if (identityMask.equals(mask)) + return getIdentityIndexer(); + } + return super.constructIndex(mask); + } + + @Override public void pullInto(Collection collector) { - for (Tuple ps : outgoing) - collector.add(boundary.wrapTuple(ps)); - - } + for (Tuple ps : outgoing) + collector.add(boundary.wrapTuple(ps)); + + } - @Override + @Override public void update(Direction direction, Tuple wrappers) { - Tuple updateElement = boundary.unwrapTuple(wrappers); - updateOccurences(direction, updateElement); - if (direction == Direction.REVOKE) { - if (outgoing.remove(updateElement)) { - clearTraces(updateElement); - propagateUpdate(Direction.REVOKE, wrappers); - } - } else /* (direction == Direction.INSERT) */ - { - check(updateElement); - } - } - - protected void notifyASMFunctionValueChanged(Tuple trace) { - // System.out.println("TEN notified"); - Set invokers = trace2invokers.get(trace); - if (invokers != null) { - LinkedList copy = new LinkedList(invokers); - for (Tuple ps : copy) - check(ps); - } - } - - protected void notifyElementChange(Object element) { - for (Tuple ps : elementOccurences.get(element)) - check(ps); - } - - protected void updateOccurences(Direction direction, Tuple ps) { - for (Integer i : affectedIndices) { - Object element = ps.get(i); - //if (element instanceof IModelElement) { - updateElementOccurence(direction, ps, element); - //} - } - } - - protected void updateElementOccurence(Direction direction, Tuple ps, - Object element) { - Collection occurences; - if (direction == Direction.INSERT) { - occurences = elementOccurences.get(element); - boolean change = occurences == null; - if (change) { - occurences = new TupleMemory(); - elementOccurences.put(element, occurences); - engine.getManipulationListener().registerSensitiveTerm(element, this); - } - occurences.add(ps); - } else // REVOKE - { - occurences = elementOccurences.get(element); - occurences.remove(ps); - boolean change = occurences.isEmpty(); - if (change) { - elementOccurences.remove(element); - engine.getManipulationListener().unregisterSensitiveTerm(element, - this); - } - } - } - - protected void check(Tuple ps) { - boolean result = evaluateExpression(ps); - if (result) /* expression evaluates to true */ - { - if (outgoing.add(ps)) - propagateUpdate(Direction.INSERT, boundary.wrapTuple(ps)); - } else /* expression evaluates to false */ - { - if (outgoing.remove(ps)) - propagateUpdate(Direction.REVOKE, boundary.wrapTuple(ps)); - } - } - - protected boolean evaluateExpression(Tuple ps) { - Object termResult = evaluateTerm(ps); - - if (rhsIndex != null) { - Object rightHandSide = ps.get(rhsIndex); - return rightHandSide.equals(termResult); - } else { - if (Boolean.FALSE.equals(termResult)) - return false; - else if (Boolean.TRUE.equals(termResult)) - return true; - engine.getContext().logWarning(String.format( - "The incremental pattern matcher encountered a type compatibility problem during check() evaluation over variables %s: expression evaluated to type %s instead of java.lang.Boolean. (Developer note: result was %s in %s)", - prettyPrintTuple(ps), - termResult == null? null : termResult.getClass().getName(), - termResult, - this - )); - return false; - } - } - - public Object evaluateTerm(Tuple ps) { - // clearing ASMfunction traces - clearTraces(ps); - - // actual evaluation - Object result = null; - try { - result = evaluator.evaluate(ps); - } catch (Throwable e) { //NOPMD - if (e instanceof Error) throw (Error)e; - engine.getContext().logWarning(String.format( - "The incremental pattern matcher encountered an error during %s evaluation over variables %s. Error message: %s. (Developer note: %s in %s)", - rhsIndex == null ? "check()" : "eval()", - prettyPrintTuple(ps), - e.getMessage(), - e.getClass().getSimpleName(), - this - ), e); -// engine.logEvaluatorException(e); - - result = Boolean.FALSE; - } - - // saving ASMFunction traces - saveTraces(ps, evaluator.getTraces()); - - return result; - } - - protected String prettyPrintTuple(Tuple ps) { - return ps.toString(); - } - - protected void clearTraces(Tuple invoker) { - Set traces = invoker2traces.get(invoker); - if (traces != null) { - invoker2traces.remove(invoker); - for (Tuple trace : traces) { - Set invokers = trace2invokers.get(trace); - invokers.remove(invoker); - if (invokers.isEmpty()) { - trace2invokers.remove(trace); - engine.geTraceListener().unregisterSensitiveTrace(trace, - this); - } - } - } - } - - protected void saveTraces(Tuple invoker, Set traces) { - if (traces != null && !traces.isEmpty()) { - invoker2traces.put(invoker, traces); - - for (Tuple trace : traces) { - Set invokers = trace2invokers.get(trace); - if (invokers == null) { - invokers = new HashSet(); - trace2invokers.put(trace, invokers); - engine.geTraceListener().registerSensitiveTrace(trace, - this); - } - invokers.add(invoker); - } - } - } - - @Override - protected void propagateUpdate(Direction direction, Tuple updateElement) { - super.propagateUpdate(direction, updateElement); - if (memoryIdentityIndexer != null) memoryIdentityIndexer.propagate(direction, updateElement); - if (memoryNullIndexer != null) memoryNullIndexer.propagate(direction, updateElement); - } - - /** - * @return the asmFunctionTraceNotifier - */ - public Address getAsmFunctionTraceNotifier() { - return asmFunctionTraceNotifier; - } - - /** - * @return the elementChangeNotifier - */ - public Address getElementChangeNotifier() { - return elementChangeNotifier; - } - - /** - * @return the engine - */ - public ReteEngine getEngine() { - return engine; - } - - public MemoryNullIndexer getNullIndexer() { - if (memoryNullIndexer == null) memoryNullIndexer = new MemoryNullIndexer(reteContainer, tupleWidth, outgoing, this, this); - return memoryNullIndexer; - } - - public MemoryIdentityIndexer getIdentityIndexer() { - if (memoryIdentityIndexer == null) memoryIdentityIndexer = new MemoryIdentityIndexer(reteContainer, tupleWidth, outgoing, this, this); - return memoryIdentityIndexer; - } - - class ASMFunctionTraceNotifierNode extends SingleInputNode { - public ASMFunctionTraceNotifierNode(ReteContainer reteContainer) { - super(reteContainer); - } - - @Override + Tuple updateElement = boundary.unwrapTuple(wrappers); + updateOccurences(direction, updateElement); + if (direction == Direction.REVOKE) { + if (outgoing.remove(updateElement)) { + clearTraces(updateElement); + propagateUpdate(Direction.REVOKE, wrappers); + } + } else /* (direction == Direction.INSERT) */ + { + check(updateElement); + } + } + + protected void notifyASMFunctionValueChanged(Tuple trace) { + // System.out.println("TEN notified"); + Set invokers = trace2invokers.get(trace); + if (invokers != null) { + LinkedList copy = new LinkedList(invokers); + for (Tuple ps : copy) + check(ps); + } + } + + protected void notifyElementChange(Object element) { + for (Tuple ps : elementOccurences.get(element)) + check(ps); + } + + protected void updateOccurences(Direction direction, Tuple ps) { + for (Integer i : affectedIndices) { + Object element = ps.get(i); + // if (element instanceof IModelElement) { + updateElementOccurence(direction, ps, element); + // } + } + } + + protected void updateElementOccurence(Direction direction, Tuple ps, Object element) { + Collection occurences; + if (direction == Direction.INSERT) { + occurences = elementOccurences.get(element); + boolean change = occurences == null; + if (change) { + occurences = new TupleMemory(); + elementOccurences.put(element, occurences); + engine.getManipulationListener().registerSensitiveTerm(element, this); + } + occurences.add(ps); + } else // REVOKE + { + occurences = elementOccurences.get(element); + occurences.remove(ps); + boolean change = occurences.isEmpty(); + if (change) { + elementOccurences.remove(element); + engine.getManipulationListener().unregisterSensitiveTerm(element, this); + } + } + } + + protected void check(Tuple ps) { + boolean result = evaluateExpression(ps); + if (result) /* expression evaluates to true */ + { + if (outgoing.add(ps)) + propagateUpdate(Direction.INSERT, boundary.wrapTuple(ps)); + } else /* expression evaluates to false */ + { + if (outgoing.remove(ps)) + propagateUpdate(Direction.REVOKE, boundary.wrapTuple(ps)); + } + } + + protected boolean evaluateExpression(Tuple ps) { + Object termResult = evaluateTerm(ps); + + if (rhsIndex != null) { + Object rightHandSide = ps.get(rhsIndex); + return rightHandSide.equals(termResult); + } else { + if (Boolean.FALSE.equals(termResult)) + return false; + else if (Boolean.TRUE.equals(termResult)) + return true; + engine.getContext() + .logWarning( + String.format( + "The incremental pattern matcher encountered a type compatibility problem during check() evaluation over variables %s: expression evaluated to type %s instead of java.lang.Boolean. (Developer note: result was %s in %s)", + prettyPrintTuple(ps), termResult == null ? null : termResult.getClass().getName(), + termResult, this)); + return false; + } + } + + public Object evaluateTerm(Tuple ps) { + // clearing ASMfunction traces + clearTraces(ps); + + // actual evaluation + Object result = null; + try { + result = evaluator.evaluate(ps); + } catch (Throwable e) { // NOPMD + if (e instanceof Error) + throw (Error) e; + engine.getContext() + .logWarning( + String.format( + "The incremental pattern matcher encountered an error during %s evaluation over variables %s. Error message: %s. (Developer note: %s in %s)", + rhsIndex == null ? "check()" : "eval()", prettyPrintTuple(ps), e.getMessage(), e + .getClass().getSimpleName(), this), e); + // engine.logEvaluatorException(e); + + result = Boolean.FALSE; + } + + // saving ASMFunction traces + saveTraces(ps, evaluator.getTraces()); + + return result; + } + + protected String prettyPrintTuple(Tuple ps) { + return ps.toString(); + } + + protected void clearTraces(Tuple invoker) { + Set traces = invoker2traces.get(invoker); + if (traces != null) { + invoker2traces.remove(invoker); + for (Tuple trace : traces) { + Set invokers = trace2invokers.get(trace); + invokers.remove(invoker); + if (invokers.isEmpty()) { + trace2invokers.remove(trace); + engine.geTraceListener().unregisterSensitiveTrace(trace, this); + } + } + } + } + + protected void saveTraces(Tuple invoker, Set traces) { + if (traces != null && !traces.isEmpty()) { + invoker2traces.put(invoker, traces); + + for (Tuple trace : traces) { + Set invokers = trace2invokers.get(trace); + if (invokers == null) { + invokers = new HashSet(); + trace2invokers.put(trace, invokers); + engine.geTraceListener().registerSensitiveTrace(trace, this); + } + invokers.add(invoker); + } + } + } + + @Override + protected void propagateUpdate(Direction direction, Tuple updateElement) { + super.propagateUpdate(direction, updateElement); + if (memoryIdentityIndexer != null) + memoryIdentityIndexer.propagate(direction, updateElement); + if (memoryNullIndexer != null) + memoryNullIndexer.propagate(direction, updateElement); + } + + /** + * @return the asmFunctionTraceNotifier + */ + public Address getAsmFunctionTraceNotifier() { + return asmFunctionTraceNotifier; + } + + /** + * @return the elementChangeNotifier + */ + public Address getElementChangeNotifier() { + return elementChangeNotifier; + } + + /** + * @return the engine + */ + public ReteEngine getEngine() { + return engine; + } + + public MemoryNullIndexer getNullIndexer() { + if (memoryNullIndexer == null) + memoryNullIndexer = new MemoryNullIndexer(reteContainer, tupleWidth, outgoing, this, this); + return memoryNullIndexer; + } + + public MemoryIdentityIndexer getIdentityIndexer() { + if (memoryIdentityIndexer == null) + memoryIdentityIndexer = new MemoryIdentityIndexer(reteContainer, tupleWidth, outgoing, this, this); + return memoryIdentityIndexer; + } + + class ASMFunctionTraceNotifierNode extends SingleInputNode { + public ASMFunctionTraceNotifierNode(ReteContainer reteContainer) { + super(reteContainer); + } + + @Override public void pullInto(Collection collector) { - } + } - @Override + @Override public void update(Direction direction, Tuple updateElement) { - notifyASMFunctionValueChanged(updateElement); - } - } + notifyASMFunctionValueChanged(updateElement); + } + } - class ElementChangeNotifierNode extends SingleInputNode { - public ElementChangeNotifierNode(ReteContainer reteContainer) { - super(reteContainer); - } + class ElementChangeNotifierNode extends SingleInputNode { + public ElementChangeNotifierNode(ReteContainer reteContainer) { + super(reteContainer); + } - @Override + @Override public void pullInto(Collection collector) { - } + } - @Override + @Override public void update(Direction direction, Tuple updateElement) { - notifyElementChange(updateElement.get(0)); - } - } + notifyElementChange(updateElement.get(0)); + } + } } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/ReferenceFeeder.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/ReferenceFeeder.java index 5b92f58c..a3331c56 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/ReferenceFeeder.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/ReferenceFeeder.java @@ -17,35 +17,33 @@ import org.eclipse.incquery.runtime.rete.network.Receiver; import org.eclipse.incquery.runtime.rete.remote.Address; - public class ReferenceFeeder extends Feeder { - protected Object typeObject; + protected Object typeObject; + + /** + * @param receiver + * @param context + * @param network + * @param boundary + * @param typeObject + */ + public ReferenceFeeder(Address receiver, IPatternMatcherRuntimeContext context, + Network network, ReteBoundary boundary, Object typeObject) { + super(receiver, context, network, boundary); + this.typeObject = typeObject; + } - /** - * @param receiver - * @param context - * @param network - * @param boundary - * @param typeObject - */ - public ReferenceFeeder(Address receiver, - IPatternMatcherRuntimeContext context, Network network, - ReteBoundary boundary, Object typeObject) { - super(receiver, context, network, boundary); - this.typeObject = typeObject; - } + @Override + public void feed() { + if (typeObject != null) { + if (context.allowedGeneralizationQueryDirection() == GeneralizationQueryDirection.BOTH) + context.enumerateDirectBinaryEdgeInstances(typeObject, pairCrawler()); + else + context.enumerateAllBinaryEdgeInstances(typeObject, pairCrawler()); + } else { + context.enumerateAllBinaryEdges(pairCrawler()); + } + } - @Override - public void feed() { - if (typeObject != null) { - if (context.allowedGeneralizationQueryDirection() == GeneralizationQueryDirection.BOTH) - context.enumerateDirectBinaryEdgeInstances(typeObject, pairCrawler()); - else - context.enumerateAllBinaryEdgeInstances(typeObject, pairCrawler()); - } else { - context.enumerateAllBinaryEdges(pairCrawler()); - } - } - } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/RelationFeeder.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/RelationFeeder.java index 7b1d10ca..86bcc1d2 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/RelationFeeder.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/RelationFeeder.java @@ -17,39 +17,33 @@ import org.eclipse.incquery.runtime.rete.network.Receiver; import org.eclipse.incquery.runtime.rete.remote.Address; - public class RelationFeeder extends Feeder { - protected Object typeObject; - - /** - * @param receiver - * @param context - * @param network - * @param boundary - * @param typeObject - */ - public RelationFeeder(Address receiver, - IPatternMatcherRuntimeContext context, Network network, - ReteBoundary boundary, Object typeObject) { - super(receiver, context, network, boundary); - this.typeObject = typeObject; - } - - - - @Override - public void feed() { - if (typeObject != null) { - if (context.allowedGeneralizationQueryDirection() == GeneralizationQueryDirection.BOTH) - context.enumerateDirectTernaryEdgeInstances(typeObject, ternaryCrawler()); - else - context.enumerateAllTernaryEdgeInstances(typeObject, ternaryCrawler()); - } else { - context.enumerateAllTernaryEdges(ternaryCrawler()); - } - } - - + protected Object typeObject; + + /** + * @param receiver + * @param context + * @param network + * @param boundary + * @param typeObject + */ + public RelationFeeder(Address receiver, IPatternMatcherRuntimeContext context, + Network network, ReteBoundary boundary, Object typeObject) { + super(receiver, context, network, boundary); + this.typeObject = typeObject; + } + + @Override + public void feed() { + if (typeObject != null) { + if (context.allowedGeneralizationQueryDirection() == GeneralizationQueryDirection.BOTH) + context.enumerateDirectTernaryEdgeInstances(typeObject, ternaryCrawler()); + else + context.enumerateAllTernaryEdgeInstances(typeObject, ternaryCrawler()); + } else { + context.enumerateAllTernaryEdges(ternaryCrawler()); + } + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/ReteBoundary.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/ReteBoundary.java index 9068e903..88dbf8f5 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/ReteBoundary.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/boundary/ReteBoundary.java @@ -40,656 +40,612 @@ import org.eclipse.incquery.runtime.rete.tuple.Tuple; import org.eclipse.incquery.runtime.rete.tuple.TupleMask; - /** - * Responsible for the storage, maintenance and communication of the nodes of the network - * that are accessible form the outside for various reasons. + * Responsible for the storage, maintenance and communication of the nodes of the network that are accessible form the + * outside for various reasons. * * @author Bergmann Gábor - * + * * @param */ public class ReteBoundary { - protected ReteEngine engine; - protected Network network; - protected ReteContainer headContainer; - - public ReteContainer getHeadContainer() { - return headContainer; - } - - protected IPatternMatcherRuntimeContext context; - IPatternMatcherContext.GeneralizationQueryDirection generalizationQueryDirection; - - /* - * arity:1 - * used as simple entity constraints - * label is the object representing the type - * null label means all entities regardless of type (global supertype), if allowed - */ - protected Map> unaryRoots; - /* - * arity:3 (rel, from, to) - * used as VPM relation constraints - * null label means all relations regardless of type (global supertype) - */ - protected Map> ternaryEdgeRoots; - /* - * arity:2 (from, to) - * not used over VPM; can be used as EMF references for instance - * label is the object representing the type - * null label means all entities regardless of type if allowed (global supertype), if allowed - */ - protected Map> binaryEdgeRoots; - - protected Map> productions; - //protected Map, Address>> productionsScoped; // (pattern, scopemap) -> production - - protected Address containmentRoot; - protected Address containmentTransitiveRoot; - protected Address instantiationRoot; - protected Address instantiationTransitiveRoot; - protected Address generalizationRoot; - protected Address generalizationTransitiveRoot; - - /** - * Stubs of parent nodes that have the key node as their child. - * For RETE --> Stub traceability, mainly at production nodes. - */ - protected Map, Set>>> parentStubsOfReceiver; - - /** - * Prerequisite: engine has its network and framework fields initialized - * - * @param headContainer - */ - public ReteBoundary(ReteEngine engine) { - super(); - this.engine = engine; - this.network = engine.getReteNet(); - this.headContainer = network.getHeadContainer(); - - this.context = engine.getContext(); - this.generalizationQueryDirection = this.context.allowedGeneralizationQueryDirection(); - this.parentStubsOfReceiver = new HashMap, Set>>>(); - - unaryRoots = new HashMap>(); - ternaryEdgeRoots = new HashMap>(); - binaryEdgeRoots = new HashMap>(); - - productions = new HashMap>(); - //productionsScoped = new HashMap,Address>>(); - - containmentRoot = null; - containmentTransitiveRoot = null; - instantiationRoot = null; - generalizationRoot = null; - generalizationTransitiveRoot = null; - } - - /** - * Wraps the element into a form suitable for entering the network - * model element -> internal object - */ - public Object wrapElement(Object element) { - return element;// .getID(); - } - - /** - * Unwraps the element into its original form - * internal object -> model element - */ - public Object unwrapElement(Object wrapper) { - return wrapper;// modelManager.getElementByID((String) - // wrapper); - } - - /** - * Unwraps the tuple of elements into a form suitable for entering the - * network - */ - public Tuple wrapTuple(Tuple unwrapped) { - // int size = unwrapped.getSize(); - // Object[] elements = new Object[size]; - // for (int i=0; i getUnaryRoot(Object label) { - return unaryRoots.get(label); - } - - public Collection> getAllUnaryRoots() { - return unaryRoots.values(); - } - - /** - * fetches the relation Root node under specified label; returns null if it - * doesn't exist yet - */ - public Address getTernaryEdgeRoot(Object label) { - return ternaryEdgeRoots.get(label); - } - - public Collection> getAllTernaryEdgeRoots() { - return ternaryEdgeRoots.values(); - } - - public Collection> getAllProductionNodes() { - return productions.values(); - } - - /** - * accesses the entity Root node under specified label; creates the node if - * it doesn't exist yet - */ - public Address accessUnaryRoot(Object typeObject) { - Address tn; - tn = unaryRoots.get(typeObject); - if (tn == null) { - tn = headContainer.getLibrary().newUniquenessEnforcerNode(1, typeObject); - unaryRoots.put(typeObject, tn); - - - new EntityFeeder(tn, context, network, this, typeObject).feed(); - - if (typeObject != null && generalizationQueryDirection == GeneralizationQueryDirection.BOTH) { - Collection subTypes = context.enumerateDirectUnarySubtypes(typeObject); - - for (Object subType : subTypes) { - Address subRoot = accessUnaryRoot(subType); - network.connectRemoteNodes(subRoot, tn, true); - } - } - - } - return tn; - } - - /** - * accesses the relation Root node under specified label; creates the node - * if it doesn't exist yet - */ - public Address accessTernaryEdgeRoot(Object typeObject) { - Address tn; - tn = ternaryEdgeRoots.get(typeObject); - if (tn == null) { - tn = headContainer.getLibrary().newUniquenessEnforcerNode(3, typeObject); - ternaryEdgeRoots.put(typeObject, tn); - - new RelationFeeder(tn, context, network, this, typeObject).feed(); - - if (typeObject != null && generalizationQueryDirection == GeneralizationQueryDirection.BOTH) { - Collection subTypes = context.enumerateDirectTernaryEdgeSubtypes(typeObject); - - for (Object subType : subTypes) { - Address subRoot = accessTernaryEdgeRoot(subType); - network.connectRemoteNodes(subRoot, tn, true); - } - } - } - return tn; - } - - - - /** - * accesses the reference Root node under specified label; creates the node - * if it doesn't exist yet - */ - public Address accessBinaryEdgeRoot(Object typeObject) { - Address tn; - tn = binaryEdgeRoots.get(typeObject); - if (tn == null) { - tn = headContainer.getLibrary().newUniquenessEnforcerNode(2, typeObject); - binaryEdgeRoots.put(typeObject, tn); - - new ReferenceFeeder(tn, context, network, this, typeObject).feed(); - - if (typeObject != null && generalizationQueryDirection == GeneralizationQueryDirection.BOTH) { - Collection subTypes = context.enumerateDirectBinaryEdgeSubtypes(typeObject); - - for (Object subType : subTypes) { - Address subRoot = accessBinaryEdgeRoot(subType); - network.connectRemoteNodes(subRoot, tn, true); - } - } - } - return tn; - } - - /** - * accesses the special direct containment relation Root node; creates the - * node if it doesn't exist yet - */ - public Address accessContainmentRoot() { - if (containmentRoot == null) { - // containment: relation quasi-type - containmentRoot = headContainer.getLibrary() - .newUniquenessEnforcerNode(2, "$containment"); - - new ContainmentFeeder(containmentRoot, context, network, this).feed(); - } - return containmentRoot; - } - - /** - * accesses the special transitive containment relation Root node; creates - * the node if it doesn't exist yet - */ - public Address accessContainmentTransitiveRoot() { - if (containmentTransitiveRoot == null) { - // transitive containment: derived - Address containmentTransitiveRoot = headContainer - .getLibrary().newUniquenessEnforcerNode(2, "$containmentTransitive"); - network.connectRemoteNodes(accessContainmentRoot(), - containmentTransitiveRoot, true); - - final int[] actLI = { 1 }; - final int arcLIw = 2; - final int[] actRI = { 0 }; - final int arcRIw = 2; - Address jPrimarySlot = headContainer.getLibrary() - .accessProjectionIndexer(accessContainmentRoot(), - new TupleMask(actLI, arcLIw)); - Address jSecondarySlot = headContainer.getLibrary() - .accessProjectionIndexer(containmentTransitiveRoot, - new TupleMask(actRI, arcRIw)); - - final int[] actRIcomp = { 1 }; - final int arcRIwcomp = 2; - TupleMask complementerMask = new TupleMask(actRIcomp, arcRIwcomp); - - Address andCT = headContainer.getLibrary() - .accessJoinNode(jPrimarySlot, jSecondarySlot, - complementerMask); - - final int[] mask = { 0, 2 }; - final int maskw = 3; - Address tr = headContainer.getLibrary() - .accessTrimmerNode(andCT, new TupleMask(mask, maskw)); - network.connectRemoteNodes(tr, containmentTransitiveRoot, true); - - this.containmentTransitiveRoot = containmentTransitiveRoot; // cast - // back - // to - // Supplier - } - return containmentTransitiveRoot; - } - - /** - * accesses the special instantiation relation Root node; creates the node - * if it doesn't exist yet - */ - public Address accessInstantiationRoot() { - if (instantiationRoot == null) { - // instantiation: relation quasi-type - instantiationRoot = headContainer.getLibrary() - .newUniquenessEnforcerNode(2, "$instantiation"); - - new InstantiationFeeder(instantiationRoot, context, network, this).feed(); - } - return instantiationRoot; - } - - /** - * accesses the special transitive instantiation relation Root node; creates - * the node if it doesn't exist yet InstantiationTransitive = Instantiation - * o (Generalization)^* - */ - public Address accessInstantiationTransitiveRoot() { - if (instantiationTransitiveRoot == null) { - // transitive instantiation: derived - Address instantiationTransitiveRoot = headContainer - .getLibrary().newUniquenessEnforcerNode(2, "$instantiationTransitive"); - network.connectRemoteNodes(accessInstantiationRoot(), - instantiationTransitiveRoot, true); - - final int[] actLI = { 1 }; - final int arcLIw = 2; - final int[] actRI = { 0 }; - final int arcRIw = 2; - Address jPrimarySlot = headContainer.getLibrary() - .accessProjectionIndexer(accessGeneralizationRoot(), - new TupleMask(actLI, arcLIw)); - Address jSecondarySlot = headContainer.getLibrary() - .accessProjectionIndexer(instantiationTransitiveRoot, - new TupleMask(actRI, arcRIw)); - - final int[] actRIcomp = { 1 }; - final int arcRIwcomp = 2; - TupleMask complementerMask = new TupleMask(actRIcomp, arcRIwcomp); - - Address andCT = headContainer.getLibrary() - .accessJoinNode(jPrimarySlot, jSecondarySlot, - complementerMask); - - final int[] mask = { 0, 2 }; - final int maskw = 3; - Address tr = headContainer.getLibrary() - .accessTrimmerNode(andCT, new TupleMask(mask, maskw)); - network.connectRemoteNodes(tr, instantiationTransitiveRoot, true); - - this.instantiationTransitiveRoot = instantiationTransitiveRoot; // cast - // back - // to - // Supplier - } - return instantiationTransitiveRoot; - } - - /** - * accesses the special generalization relation Root node; creates the node - * if it doesn't exist yet - */ - public Address accessGeneralizationRoot() { - if (generalizationRoot == null) { - // generalization: relation quasi-type - generalizationRoot = headContainer.getLibrary() - .newUniquenessEnforcerNode(2, "$generalization"); - - new GeneralizationFeeder(generalizationRoot, context, network, this).feed(); - } - return generalizationRoot; - } - - /** - * accesses the special transitive containment relation Root node; creates - * the node if it doesn't exist yet - */ - public Address accessGeneralizationTransitiveRoot() { - if (generalizationTransitiveRoot == null) { - // transitive generalization: derived - Address generalizationTransitiveRoot = headContainer - .getLibrary().newUniquenessEnforcerNode(2, "$generalizationTransitive"); - network.connectRemoteNodes(accessGeneralizationRoot(), - generalizationTransitiveRoot, true); - - final int[] actLI = { 1 }; - final int arcLIw = 2; - final int[] actRI = { 0 }; - final int arcRIw = 2; - Address jPrimarySlot = headContainer.getLibrary() - .accessProjectionIndexer(accessGeneralizationRoot(), - new TupleMask(actLI, arcLIw)); - Address jSecondarySlot = headContainer.getLibrary() - .accessProjectionIndexer(generalizationTransitiveRoot, - new TupleMask(actRI, arcRIw)); - - final int[] actRIcomp = { 1 }; - final int arcRIwcomp = 2; - TupleMask complementerMask = new TupleMask(actRIcomp, arcRIwcomp); - - Address andCT = headContainer.getLibrary() - .accessJoinNode(jPrimarySlot, jSecondarySlot, - complementerMask); - - final int[] mask = { 0, 2 }; - final int maskw = 3; - Address tr = headContainer.getLibrary() - .accessTrimmerNode(andCT, new TupleMask(mask, maskw)); - network.connectRemoteNodes(tr, generalizationTransitiveRoot, true); - - this.generalizationTransitiveRoot = generalizationTransitiveRoot; // cast - // back - // to - // Supplier - } - return generalizationTransitiveRoot; - } - - // /** - // * Registers and publishes a supplier under specified label. - // */ - // public void publishSupplier(Supplier s, Object label) - // { - // publishedSuppliers.put(label, s); - // } - // - // /** - // * fetches the production node under specified label; - // * returns null if it doesn't exist yet - // */ - // public Production getProductionNode(Object label) - // { - // return productions.get(label); - // } - // - // /** - // * fetches the published supplier under specified label; - // * returns null if it doesn't exist yet - // */ - // public Supplier getPublishedSupplier(Object label) - // { - // return publishedSuppliers.get(label); - // } - - /** - * accesses the production node for specified pattern; builds pattern matcher if it doesn't exist yet - */ - public synchronized Address accessProduction(PatternDescription gtPattern) throws RetePatternBuildException { - Address pn; - pn = productions.get(gtPattern); - if (pn == null) { - construct(gtPattern); - pn = productions.get(gtPattern); - if (pn == null) { - String[] args = {gtPattern.toString()}; - throw new RetePatternBuildException("Unsuccessful creation of RETE production node for pattern {1}", args, - "Could not create RETE production node.", gtPattern); - } - } - return pn; - } - - /** - * creates the production node for the specified pattern - * Contract: only call from the builder (through Buildable) responsible for building this pattern - * @throws PatternMatcherCompileTimeException if production node is already created - */ - public synchronized Address createProductionInternal(PatternDescription gtPattern) - throws RetePatternBuildException { - if (productions.containsKey(gtPattern)) { - String[] args = {gtPattern.toString()}; - throw new RetePatternBuildException("Multiple creation attempts of production node for {1}", args, - "Duplicate RETE production node.", gtPattern); - } - - HashMap posMapping = engine.getBuilder().getPosMapping(gtPattern); - Address pn = headContainer.getLibrary().newProductionNode(posMapping, gtPattern); - productions.put(gtPattern, pn); - context.reportPatternDependency(gtPattern); - - return pn; - } - -// /** -// * accesses the production node for specified pattern and scope map; creates the node if -// * it doesn't exist yet -// */ -// public synchronized Address accessProductionScoped( -// GTPattern gtPattern, Map additionalScopeMap) throws PatternMatcherCompileTimeException { -// if (additionalScopeMap.isEmpty()) return accessProduction(gtPattern); -// -// Address pn; -// -// Map, Address> scopes = productionsScoped.get(gtPattern); -// if (scopes == null) { -// scopes = new HashMap, Address>(); -// productionsScoped.put(gtPattern, scopes); -// } -// -// pn = scopes.get(additionalScopeMap); -// if (pn == null) { -// Address unscopedProduction = accessProduction(gtPattern); -// -// HashMap posMapping = headContainer.resolveLocal(unscopedProduction).getPosMapping(); -// pn = headContainer.getLibrary().newProductionNode(posMapping); -// scopes.put(additionalScopeMap, pn); -// -// constructScoper(unscopedProduction, additionalScopeMap, pn); -// } -// return pn; -// } - - - - /** - * @pre: builder is set - */ - protected void construct(PatternDescription gtPattern) - throws RetePatternBuildException { - engine.getReteNet().waitForReteTermination(); - engine.getBuilder().construct(gtPattern); - // production.setDirty(false); - } - -// protected void constructScoper( -// Address unscopedProduction, -// Map additionalScopeMap, -// Address production) -// throws PatternMatcherCompileTimeException { -// engine.reteNet.waitForReteTermination(); -// engine.builder.constructScoper(unscopedProduction, additionalScopeMap, production); -// } - - // /** - // * Invalidates the subnet constructed for the recognition of a given - // pattern. - // * The pattern matcher will have to be rebuilt. - // * @param gtPattern the pattern whose matcher subnet should be invalidated - // */ - // public void invalidatePattern(GTPattern gtPattern) { - // Production production = null; - // try { - // production = accessProduction(gtPattern); - // } catch (PatternMatcherCompileTimeException e) { - // // this should not occur here, since we already have a production node - // e.printStackTrace(); - // } - // - // production.tearOff(); - // //production.setDirty(true); - // } - - // updaters for change notification - // if the corresponding rete input isn't created yet, call is ignored - public void updateUnary(Direction direction, Object entity, Object typeObject) { - Address root = unaryRoots.get(typeObject); - if (root != null) { - network.sendExternalUpdate(root, direction, new FlatTuple(wrapElement(entity))); - if (!engine.isParallelExecutionEnabled()) - network.waitForReteTermination(); - } - if (typeObject!=null && generalizationQueryDirection == GeneralizationQueryDirection.SUPERTYPE_ONLY) { - for (Object superType: context.enumerateDirectUnarySupertypes(typeObject)) { - updateUnary(direction, entity, superType); - } - } - } - - public void updateTernaryEdge(Direction direction, Object relation, - Object from, Object to, Object typeObject) { - Address root = ternaryEdgeRoots.get(typeObject); - if (root != null) { - network.sendExternalUpdate(root, direction, new FlatTuple( - wrapElement(relation), wrapElement(from), wrapElement(to))); - if (!engine.isParallelExecutionEnabled()) - network.waitForReteTermination(); - } - if (typeObject!=null && generalizationQueryDirection == GeneralizationQueryDirection.SUPERTYPE_ONLY) { - for (Object superType: context.enumerateDirectTernaryEdgeSupertypes(typeObject)) { - updateTernaryEdge(direction, relation, from, to, superType); - } - } - } - - public void updateBinaryEdge(Direction direction, - Object from, Object to, Object typeObject) { - Address root = binaryEdgeRoots.get(typeObject); - if (root != null) { - network.sendExternalUpdate(root, direction, new FlatTuple( - wrapElement(from), wrapElement(to))); - if (!engine.isParallelExecutionEnabled()) - network.waitForReteTermination(); - } - if (typeObject!=null && generalizationQueryDirection == GeneralizationQueryDirection.SUPERTYPE_ONLY) { - for (Object superType: context.enumerateDirectBinaryEdgeSupertypes(typeObject)) { - updateBinaryEdge(direction, from, to, superType); - } - } - } - - public void updateContainment(Direction direction, Object container, - Object element) { - if (containmentRoot != null) { - network.sendExternalUpdate(containmentRoot, direction, - new FlatTuple(wrapElement(container), - wrapElement(element))); - if (!engine.isParallelExecutionEnabled()) - network.waitForReteTermination(); - } - } - - public void updateInstantiation(Direction direction, Object parent, - Object child) { - if (instantiationRoot != null) { - network.sendExternalUpdate(instantiationRoot, direction, - new FlatTuple(wrapElement(parent), wrapElement(child))); - if (!engine.isParallelExecutionEnabled()) - network.waitForReteTermination(); - } - } - - public void updateGeneralization(Direction direction, Object parent, - Object child) { - if (generalizationRoot != null) { - network.sendExternalUpdate(generalizationRoot, direction, - new FlatTuple(wrapElement(parent), wrapElement(child))); - if (!engine.isParallelExecutionEnabled()) - network.waitForReteTermination(); - } - } - - // no wrapping needed! - public void notifyEvaluator(Address receiver, - Tuple tuple) { - network.sendExternalUpdate(receiver, Direction.INSERT, tuple); - if (!engine.isParallelExecutionEnabled()) - network.waitForReteTermination(); - } - - public void registerParentStubForReceiver(Address receiver, Stub> parentStub) { - Set>> parents = parentStubsOfReceiver.get(receiver); - if (parents == null) { - parents = new HashSet>>(); - parentStubsOfReceiver.put(receiver, parents); - } - parents.add(parentStub); - } - public Set>> getParentStubsOfReceiver(Address receiver) { - Set>> parents = parentStubsOfReceiver.get(receiver); - if (parents == null) parents = Collections.emptySet(); - return parents; - } + protected ReteEngine engine; + protected Network network; + protected ReteContainer headContainer; + + public ReteContainer getHeadContainer() { + return headContainer; + } + + protected IPatternMatcherRuntimeContext context; + IPatternMatcherContext.GeneralizationQueryDirection generalizationQueryDirection; + + /* + * arity:1 used as simple entity constraints label is the object representing the type null label means all entities + * regardless of type (global supertype), if allowed + */ + protected Map> unaryRoots; + /* + * arity:3 (rel, from, to) used as VPM relation constraints null label means all relations regardless of type + * (global supertype) + */ + protected Map> ternaryEdgeRoots; + /* + * arity:2 (from, to) not used over VPM; can be used as EMF references for instance label is the object representing + * the type null label means all entities regardless of type if allowed (global supertype), if allowed + */ + protected Map> binaryEdgeRoots; + + protected Map> productions; + // protected Map, Address>> productionsScoped; // + // (pattern, scopemap) -> production + + protected Address containmentRoot; + protected Address containmentTransitiveRoot; + protected Address instantiationRoot; + protected Address instantiationTransitiveRoot; + protected Address generalizationRoot; + protected Address generalizationTransitiveRoot; + + /** + * Stubs of parent nodes that have the key node as their child. For RETE --> Stub traceability, mainly at production + * nodes. + */ + protected Map, Set>>> parentStubsOfReceiver; + + /** + * Prerequisite: engine has its network and framework fields initialized + * + * @param headContainer + */ + public ReteBoundary(ReteEngine engine) { + super(); + this.engine = engine; + this.network = engine.getReteNet(); + this.headContainer = network.getHeadContainer(); + + this.context = engine.getContext(); + this.generalizationQueryDirection = this.context.allowedGeneralizationQueryDirection(); + this.parentStubsOfReceiver = new HashMap, Set>>>(); + + unaryRoots = new HashMap>(); + ternaryEdgeRoots = new HashMap>(); + binaryEdgeRoots = new HashMap>(); + + productions = new HashMap>(); + // productionsScoped = new HashMap,Address>>(); + + containmentRoot = null; + containmentTransitiveRoot = null; + instantiationRoot = null; + generalizationRoot = null; + generalizationTransitiveRoot = null; + } + + /** + * Wraps the element into a form suitable for entering the network model element -> internal object + */ + public Object wrapElement(Object element) { + return element;// .getID(); + } + + /** + * Unwraps the element into its original form internal object -> model element + */ + public Object unwrapElement(Object wrapper) { + return wrapper;// modelManager.getElementByID((String) + // wrapper); + } + + /** + * Unwraps the tuple of elements into a form suitable for entering the network + */ + public Tuple wrapTuple(Tuple unwrapped) { + // int size = unwrapped.getSize(); + // Object[] elements = new Object[size]; + // for (int i=0; i getUnaryRoot(Object label) { + return unaryRoots.get(label); + } + + public Collection> getAllUnaryRoots() { + return unaryRoots.values(); + } + + /** + * fetches the relation Root node under specified label; returns null if it doesn't exist yet + */ + public Address getTernaryEdgeRoot(Object label) { + return ternaryEdgeRoots.get(label); + } + + public Collection> getAllTernaryEdgeRoots() { + return ternaryEdgeRoots.values(); + } + + public Collection> getAllProductionNodes() { + return productions.values(); + } + + /** + * accesses the entity Root node under specified label; creates the node if it doesn't exist yet + */ + public Address accessUnaryRoot(Object typeObject) { + Address tn; + tn = unaryRoots.get(typeObject); + if (tn == null) { + tn = headContainer.getLibrary().newUniquenessEnforcerNode(1, typeObject); + unaryRoots.put(typeObject, tn); + + new EntityFeeder(tn, context, network, this, typeObject).feed(); + + if (typeObject != null && generalizationQueryDirection == GeneralizationQueryDirection.BOTH) { + Collection subTypes = context.enumerateDirectUnarySubtypes(typeObject); + + for (Object subType : subTypes) { + Address subRoot = accessUnaryRoot(subType); + network.connectRemoteNodes(subRoot, tn, true); + } + } + + } + return tn; + } + + /** + * accesses the relation Root node under specified label; creates the node if it doesn't exist yet + */ + public Address accessTernaryEdgeRoot(Object typeObject) { + Address tn; + tn = ternaryEdgeRoots.get(typeObject); + if (tn == null) { + tn = headContainer.getLibrary().newUniquenessEnforcerNode(3, typeObject); + ternaryEdgeRoots.put(typeObject, tn); + + new RelationFeeder(tn, context, network, this, typeObject).feed(); + + if (typeObject != null && generalizationQueryDirection == GeneralizationQueryDirection.BOTH) { + Collection subTypes = context.enumerateDirectTernaryEdgeSubtypes(typeObject); + + for (Object subType : subTypes) { + Address subRoot = accessTernaryEdgeRoot(subType); + network.connectRemoteNodes(subRoot, tn, true); + } + } + } + return tn; + } + + /** + * accesses the reference Root node under specified label; creates the node if it doesn't exist yet + */ + public Address accessBinaryEdgeRoot(Object typeObject) { + Address tn; + tn = binaryEdgeRoots.get(typeObject); + if (tn == null) { + tn = headContainer.getLibrary().newUniquenessEnforcerNode(2, typeObject); + binaryEdgeRoots.put(typeObject, tn); + + new ReferenceFeeder(tn, context, network, this, typeObject).feed(); + + if (typeObject != null && generalizationQueryDirection == GeneralizationQueryDirection.BOTH) { + Collection subTypes = context.enumerateDirectBinaryEdgeSubtypes(typeObject); + + for (Object subType : subTypes) { + Address subRoot = accessBinaryEdgeRoot(subType); + network.connectRemoteNodes(subRoot, tn, true); + } + } + } + return tn; + } + + /** + * accesses the special direct containment relation Root node; creates the node if it doesn't exist yet + */ + public Address accessContainmentRoot() { + if (containmentRoot == null) { + // containment: relation quasi-type + containmentRoot = headContainer.getLibrary().newUniquenessEnforcerNode(2, "$containment"); + + new ContainmentFeeder(containmentRoot, context, network, this).feed(); + } + return containmentRoot; + } + + /** + * accesses the special transitive containment relation Root node; creates the node if it doesn't exist yet + */ + public Address accessContainmentTransitiveRoot() { + if (containmentTransitiveRoot == null) { + // transitive containment: derived + Address containmentTransitiveRoot = headContainer.getLibrary().newUniquenessEnforcerNode( + 2, "$containmentTransitive"); + network.connectRemoteNodes(accessContainmentRoot(), containmentTransitiveRoot, true); + + final int[] actLI = { 1 }; + final int arcLIw = 2; + final int[] actRI = { 0 }; + final int arcRIw = 2; + Address jPrimarySlot = headContainer.getLibrary().accessProjectionIndexer( + accessContainmentRoot(), new TupleMask(actLI, arcLIw)); + Address jSecondarySlot = headContainer.getLibrary().accessProjectionIndexer( + containmentTransitiveRoot, new TupleMask(actRI, arcRIw)); + + final int[] actRIcomp = { 1 }; + final int arcRIwcomp = 2; + TupleMask complementerMask = new TupleMask(actRIcomp, arcRIwcomp); + + Address andCT = headContainer.getLibrary().accessJoinNode(jPrimarySlot, jSecondarySlot, + complementerMask); + + final int[] mask = { 0, 2 }; + final int maskw = 3; + Address tr = headContainer.getLibrary().accessTrimmerNode(andCT, new TupleMask(mask, maskw)); + network.connectRemoteNodes(tr, containmentTransitiveRoot, true); + + this.containmentTransitiveRoot = containmentTransitiveRoot; // cast + // back + // to + // Supplier + } + return containmentTransitiveRoot; + } + + /** + * accesses the special instantiation relation Root node; creates the node if it doesn't exist yet + */ + public Address accessInstantiationRoot() { + if (instantiationRoot == null) { + // instantiation: relation quasi-type + instantiationRoot = headContainer.getLibrary().newUniquenessEnforcerNode(2, "$instantiation"); + + new InstantiationFeeder(instantiationRoot, context, network, this).feed(); + } + return instantiationRoot; + } + + /** + * accesses the special transitive instantiation relation Root node; creates the node if it doesn't exist yet + * InstantiationTransitive = Instantiation o (Generalization)^* + */ + public Address accessInstantiationTransitiveRoot() { + if (instantiationTransitiveRoot == null) { + // transitive instantiation: derived + Address instantiationTransitiveRoot = headContainer.getLibrary() + .newUniquenessEnforcerNode(2, "$instantiationTransitive"); + network.connectRemoteNodes(accessInstantiationRoot(), instantiationTransitiveRoot, true); + + final int[] actLI = { 1 }; + final int arcLIw = 2; + final int[] actRI = { 0 }; + final int arcRIw = 2; + Address jPrimarySlot = headContainer.getLibrary().accessProjectionIndexer( + accessGeneralizationRoot(), new TupleMask(actLI, arcLIw)); + Address jSecondarySlot = headContainer.getLibrary().accessProjectionIndexer( + instantiationTransitiveRoot, new TupleMask(actRI, arcRIw)); + + final int[] actRIcomp = { 1 }; + final int arcRIwcomp = 2; + TupleMask complementerMask = new TupleMask(actRIcomp, arcRIwcomp); + + Address andCT = headContainer.getLibrary().accessJoinNode(jPrimarySlot, jSecondarySlot, + complementerMask); + + final int[] mask = { 0, 2 }; + final int maskw = 3; + Address tr = headContainer.getLibrary().accessTrimmerNode(andCT, + new TupleMask(mask, maskw)); + network.connectRemoteNodes(tr, instantiationTransitiveRoot, true); + + this.instantiationTransitiveRoot = instantiationTransitiveRoot; // cast + // back + // to + // Supplier + } + return instantiationTransitiveRoot; + } + + /** + * accesses the special generalization relation Root node; creates the node if it doesn't exist yet + */ + public Address accessGeneralizationRoot() { + if (generalizationRoot == null) { + // generalization: relation quasi-type + generalizationRoot = headContainer.getLibrary().newUniquenessEnforcerNode(2, "$generalization"); + + new GeneralizationFeeder(generalizationRoot, context, network, this).feed(); + } + return generalizationRoot; + } + + /** + * accesses the special transitive containment relation Root node; creates the node if it doesn't exist yet + */ + public Address accessGeneralizationTransitiveRoot() { + if (generalizationTransitiveRoot == null) { + // transitive generalization: derived + Address generalizationTransitiveRoot = headContainer.getLibrary() + .newUniquenessEnforcerNode(2, "$generalizationTransitive"); + network.connectRemoteNodes(accessGeneralizationRoot(), generalizationTransitiveRoot, true); + + final int[] actLI = { 1 }; + final int arcLIw = 2; + final int[] actRI = { 0 }; + final int arcRIw = 2; + Address jPrimarySlot = headContainer.getLibrary().accessProjectionIndexer( + accessGeneralizationRoot(), new TupleMask(actLI, arcLIw)); + Address jSecondarySlot = headContainer.getLibrary().accessProjectionIndexer( + generalizationTransitiveRoot, new TupleMask(actRI, arcRIw)); + + final int[] actRIcomp = { 1 }; + final int arcRIwcomp = 2; + TupleMask complementerMask = new TupleMask(actRIcomp, arcRIwcomp); + + Address andCT = headContainer.getLibrary().accessJoinNode(jPrimarySlot, jSecondarySlot, + complementerMask); + + final int[] mask = { 0, 2 }; + final int maskw = 3; + Address tr = headContainer.getLibrary().accessTrimmerNode(andCT, new TupleMask(mask, maskw)); + network.connectRemoteNodes(tr, generalizationTransitiveRoot, true); + + this.generalizationTransitiveRoot = generalizationTransitiveRoot; // cast + // back + // to + // Supplier + } + return generalizationTransitiveRoot; + } + + // /** + // * Registers and publishes a supplier under specified label. + // */ + // public void publishSupplier(Supplier s, Object label) + // { + // publishedSuppliers.put(label, s); + // } + // + // /** + // * fetches the production node under specified label; + // * returns null if it doesn't exist yet + // */ + // public Production getProductionNode(Object label) + // { + // return productions.get(label); + // } + // + // /** + // * fetches the published supplier under specified label; + // * returns null if it doesn't exist yet + // */ + // public Supplier getPublishedSupplier(Object label) + // { + // return publishedSuppliers.get(label); + // } + + /** + * accesses the production node for specified pattern; builds pattern matcher if it doesn't exist yet + */ + public synchronized Address accessProduction(PatternDescription gtPattern) + throws RetePatternBuildException { + Address pn; + pn = productions.get(gtPattern); + if (pn == null) { + construct(gtPattern); + pn = productions.get(gtPattern); + if (pn == null) { + String[] args = { gtPattern.toString() }; + throw new RetePatternBuildException("Unsuccessful creation of RETE production node for pattern {1}", + args, "Could not create RETE production node.", gtPattern); + } + } + return pn; + } + + /** + * creates the production node for the specified pattern Contract: only call from the builder (through Buildable) + * responsible for building this pattern + * + * @throws PatternMatcherCompileTimeException + * if production node is already created + */ + public synchronized Address createProductionInternal(PatternDescription gtPattern) + throws RetePatternBuildException { + if (productions.containsKey(gtPattern)) { + String[] args = { gtPattern.toString() }; + throw new RetePatternBuildException("Multiple creation attempts of production node for {1}", args, + "Duplicate RETE production node.", gtPattern); + } + + HashMap posMapping = engine.getBuilder().getPosMapping(gtPattern); + Address pn = headContainer.getLibrary().newProductionNode(posMapping, gtPattern); + productions.put(gtPattern, pn); + context.reportPatternDependency(gtPattern); + + return pn; + } + + // /** + // * accesses the production node for specified pattern and scope map; creates the node if + // * it doesn't exist yet + // */ + // public synchronized Address accessProductionScoped( + // GTPattern gtPattern, Map additionalScopeMap) throws PatternMatcherCompileTimeException { + // if (additionalScopeMap.isEmpty()) return accessProduction(gtPattern); + // + // Address pn; + // + // Map, Address> scopes = productionsScoped.get(gtPattern); + // if (scopes == null) { + // scopes = new HashMap, Address>(); + // productionsScoped.put(gtPattern, scopes); + // } + // + // pn = scopes.get(additionalScopeMap); + // if (pn == null) { + // Address unscopedProduction = accessProduction(gtPattern); + // + // HashMap posMapping = headContainer.resolveLocal(unscopedProduction).getPosMapping(); + // pn = headContainer.getLibrary().newProductionNode(posMapping); + // scopes.put(additionalScopeMap, pn); + // + // constructScoper(unscopedProduction, additionalScopeMap, pn); + // } + // return pn; + // } + + /** + * @pre: builder is set + */ + protected void construct(PatternDescription gtPattern) throws RetePatternBuildException { + engine.getReteNet().waitForReteTermination(); + engine.getBuilder().construct(gtPattern); + // production.setDirty(false); + } + + // protected void constructScoper( + // Address unscopedProduction, + // Map additionalScopeMap, + // Address production) + // throws PatternMatcherCompileTimeException { + // engine.reteNet.waitForReteTermination(); + // engine.builder.constructScoper(unscopedProduction, additionalScopeMap, production); + // } + + // /** + // * Invalidates the subnet constructed for the recognition of a given + // pattern. + // * The pattern matcher will have to be rebuilt. + // * @param gtPattern the pattern whose matcher subnet should be invalidated + // */ + // public void invalidatePattern(GTPattern gtPattern) { + // Production production = null; + // try { + // production = accessProduction(gtPattern); + // } catch (PatternMatcherCompileTimeException e) { + // // this should not occur here, since we already have a production node + // e.printStackTrace(); + // } + // + // production.tearOff(); + // //production.setDirty(true); + // } + + // updaters for change notification + // if the corresponding rete input isn't created yet, call is ignored + public void updateUnary(Direction direction, Object entity, Object typeObject) { + Address root = unaryRoots.get(typeObject); + if (root != null) { + network.sendExternalUpdate(root, direction, new FlatTuple(wrapElement(entity))); + if (!engine.isParallelExecutionEnabled()) + network.waitForReteTermination(); + } + if (typeObject != null && generalizationQueryDirection == GeneralizationQueryDirection.SUPERTYPE_ONLY) { + for (Object superType : context.enumerateDirectUnarySupertypes(typeObject)) { + updateUnary(direction, entity, superType); + } + } + } + + public void updateTernaryEdge(Direction direction, Object relation, Object from, Object to, Object typeObject) { + Address root = ternaryEdgeRoots.get(typeObject); + if (root != null) { + network.sendExternalUpdate(root, direction, new FlatTuple(wrapElement(relation), wrapElement(from), + wrapElement(to))); + if (!engine.isParallelExecutionEnabled()) + network.waitForReteTermination(); + } + if (typeObject != null && generalizationQueryDirection == GeneralizationQueryDirection.SUPERTYPE_ONLY) { + for (Object superType : context.enumerateDirectTernaryEdgeSupertypes(typeObject)) { + updateTernaryEdge(direction, relation, from, to, superType); + } + } + } + + public void updateBinaryEdge(Direction direction, Object from, Object to, Object typeObject) { + Address root = binaryEdgeRoots.get(typeObject); + if (root != null) { + network.sendExternalUpdate(root, direction, new FlatTuple(wrapElement(from), wrapElement(to))); + if (!engine.isParallelExecutionEnabled()) + network.waitForReteTermination(); + } + if (typeObject != null && generalizationQueryDirection == GeneralizationQueryDirection.SUPERTYPE_ONLY) { + for (Object superType : context.enumerateDirectBinaryEdgeSupertypes(typeObject)) { + updateBinaryEdge(direction, from, to, superType); + } + } + } + + public void updateContainment(Direction direction, Object container, Object element) { + if (containmentRoot != null) { + network.sendExternalUpdate(containmentRoot, direction, new FlatTuple(wrapElement(container), + wrapElement(element))); + if (!engine.isParallelExecutionEnabled()) + network.waitForReteTermination(); + } + } + + public void updateInstantiation(Direction direction, Object parent, Object child) { + if (instantiationRoot != null) { + network.sendExternalUpdate(instantiationRoot, direction, new FlatTuple(wrapElement(parent), + wrapElement(child))); + if (!engine.isParallelExecutionEnabled()) + network.waitForReteTermination(); + } + } + + public void updateGeneralization(Direction direction, Object parent, Object child) { + if (generalizationRoot != null) { + network.sendExternalUpdate(generalizationRoot, direction, new FlatTuple(wrapElement(parent), + wrapElement(child))); + if (!engine.isParallelExecutionEnabled()) + network.waitForReteTermination(); + } + } + + // no wrapping needed! + public void notifyEvaluator(Address receiver, Tuple tuple) { + network.sendExternalUpdate(receiver, Direction.INSERT, tuple); + if (!engine.isParallelExecutionEnabled()) + network.waitForReteTermination(); + } + + public void registerParentStubForReceiver(Address receiver, + Stub> parentStub) { + Set>> parents = parentStubsOfReceiver.get(receiver); + if (parents == null) { + parents = new HashSet>>(); + parentStubsOfReceiver.put(receiver, parents); + } + parents.add(parentStub); + } + + public Set>> getParentStubsOfReceiver(Address receiver) { + Set>> parents = parentStubsOfReceiver.get(receiver); + if (parents == null) + parents = Collections.emptySet(); + return parents; + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/Buildable.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/Buildable.java index 4cc14066..ca4e5071 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/Buildable.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/Buildable.java @@ -17,55 +17,80 @@ /** * @author Bergmann Gábor - * - * An implicit common parameter is the "effort" PatternDescription. This indicates that the build request is part - * of an effort to build the matcher of the given pattern; it it important to record this during code generation - * so that the generated code can be separated according to patterns. - * - * @param the description of a pattern - * @param the handle of a continuable supplier-like RETE ending with associated semantics - * @param the handle of a receiver-like RETE ending to which stubs can be connected + * + * An implicit common parameter is the "effort" PatternDescription. This indicates that the build request is + * part of an effort to build the matcher of the given pattern; it it important to record this during code + * generation so that the generated code can be separated according to patterns. + * + * @param + * the description of a pattern + * @param + * the handle of a continuable supplier-like RETE ending with associated semantics + * @param + * the handle of a receiver-like RETE ending to which stubs can be connected */ public interface Buildable { - - public Collector patternCollector(PatternDescription pattern) throws RetePatternBuildException; - public Stub patternCallStub(Tuple nodes, PatternDescription supplierKey) throws RetePatternBuildException; - - public Stub instantiationTransitiveStub(Tuple nodes); - public Stub instantiationDirectStub(Tuple nodes); - public Stub generalizationTransitiveStub(Tuple nodes); - public Stub generalizationDirectStub(Tuple nodes); - public Stub containmentTransitiveStub(Tuple nodes); - public Stub containmentDirectStub(Tuple nodes); - public Stub binaryEdgeTypeStub(Tuple nodes, Object supplierKey); - public Stub ternaryEdgeTypeStub(Tuple nodes, Object supplierKey); - public Stub unaryTypeStub(Tuple nodes, Object supplierKey); - - public void buildConnection(Stub stub, Collector collector); - - public Stub buildStartStub(Object[] constantValues, Object[] constantNames); - public Stub buildEqualityChecker(Stub stub, int[] indices); - public Stub buildInjectivityChecker(Stub stub, int subject, int[] inequalIndices); - public Stub buildTransitiveClosure(Stub stub); - public Stub buildTrimmer(Stub stub, TupleMask trimMask); - public Stub buildBetaNode(Stub primaryStub, Stub sideStub, TupleMask primaryMask, - TupleMask sideMask, TupleMask complementer, boolean negative); - public Stub buildCounterBetaNode(Stub primaryStub, Stub sideStub, - TupleMask primaryMask, TupleMask originalSideMask, TupleMask complementer, Object aggregateResultCalibrationElement); - public Stub buildCountCheckBetaNode(Stub primaryStub, Stub sideStub, - TupleMask primaryMask, TupleMask originalSideMask, int resultPositionInSignature); - public Stub buildScopeConstrainer(Stub stub, boolean transitive, Object unwrappedContainer, int constrainedIndex); - public Stub buildPredicateChecker(AbstractEvaluator evaluator, Integer rhsIndex, int[] affectedIndices, Stub stub); - - - /** - * @return a buildable that potentially acts on a separate container - */ - public Buildable getNextContainer(); - /** - * @return a buildable that puts build actions on the tab of the given pattern - */ - public Buildable putOnTab(PatternDescription effort); - - public void reinitialize(); + + public Collector patternCollector(PatternDescription pattern) throws RetePatternBuildException; + + public Stub patternCallStub(Tuple nodes, PatternDescription supplierKey) + throws RetePatternBuildException; + + public Stub instantiationTransitiveStub(Tuple nodes); + + public Stub instantiationDirectStub(Tuple nodes); + + public Stub generalizationTransitiveStub(Tuple nodes); + + public Stub generalizationDirectStub(Tuple nodes); + + public Stub containmentTransitiveStub(Tuple nodes); + + public Stub containmentDirectStub(Tuple nodes); + + public Stub binaryEdgeTypeStub(Tuple nodes, Object supplierKey); + + public Stub ternaryEdgeTypeStub(Tuple nodes, Object supplierKey); + + public Stub unaryTypeStub(Tuple nodes, Object supplierKey); + + public void buildConnection(Stub stub, Collector collector); + + public Stub buildStartStub(Object[] constantValues, Object[] constantNames); + + public Stub buildEqualityChecker(Stub stub, int[] indices); + + public Stub buildInjectivityChecker(Stub stub, int subject, int[] inequalIndices); + + public Stub buildTransitiveClosure(Stub stub); + + public Stub buildTrimmer(Stub stub, TupleMask trimMask); + + public Stub buildBetaNode(Stub primaryStub, Stub sideStub, + TupleMask primaryMask, TupleMask sideMask, TupleMask complementer, boolean negative); + + public Stub buildCounterBetaNode(Stub primaryStub, Stub sideStub, + TupleMask primaryMask, TupleMask originalSideMask, TupleMask complementer, + Object aggregateResultCalibrationElement); + + public Stub buildCountCheckBetaNode(Stub primaryStub, Stub sideStub, + TupleMask primaryMask, TupleMask originalSideMask, int resultPositionInSignature); + + public Stub buildScopeConstrainer(Stub stub, boolean transitive, Object unwrappedContainer, + int constrainedIndex); + + public Stub buildPredicateChecker(AbstractEvaluator evaluator, Integer rhsIndex, int[] affectedIndices, + Stub stub); + + /** + * @return a buildable that potentially acts on a separate container + */ + public Buildable getNextContainer(); + + /** + * @return a buildable that puts build actions on the tab of the given pattern + */ + public Buildable putOnTab(PatternDescription effort); + + public void reinitialize(); } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/CodegenRecorderBuildable.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/CodegenRecorderBuildable.java index a98201b4..290909e6 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/CodegenRecorderBuildable.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/CodegenRecorderBuildable.java @@ -17,407 +17,374 @@ import org.eclipse.incquery.runtime.rete.tuple.TupleMask; import org.eclipse.incquery.runtime.rete.util.Options; - /** - * Lightweight class that generates Java code of a builder method from the build actions. - * Code is sent to a coordinator to be collected in string buffers there. + * Lightweight class that generates Java code of a builder method from the build actions. Code is sent to a coordinator + * to be collected in string buffers there. + * * @author Bergmann Gábor */ -public abstract class CodegenRecorderBuildable - implements Buildable -{ - public CodegenRecordingCoordinator coordinator; - public PatternDescription effort; - public String myName; - public String baseName; - public String indent; - /** - * @param code - * @param indent - * @param myName - */ - public CodegenRecorderBuildable(CodegenRecordingCoordinator coordinator, - PatternDescription effort, String indent, String baseName, String instanceSuffix) - { - super(); - this.coordinator = coordinator; - this.effort = effort; - this.indent = indent; - this.baseName = baseName; - this.myName = baseName+instanceSuffix; - } - - public void reinitialize() { - throw new UnsupportedOperationException(); - } - - - protected String prettyPrintStringArray(String[] elements, String separator) { - if (elements.length == 0) return ""; - else { - StringBuilder result = new StringBuilder(elements[0]); - for (int i=1; i stub) { - return stub.getHandle(); - } - protected String gen(boolean bool) { - return bool? "true": "false"; - } - protected String gen(Integer integer) { - return integer == null ? "null" : integer.toString(); - } - protected String gen(int[] ints) { - // return declareNewValue("int[]", "{"+prettyPrintIntArray(ints)+"}"); - return "new int[] {" + prettyPrintIntArray(ints) + "}"; - } - protected String gen(TupleMask mask) { - return declareNewValue("TupleMask", "new TupleMask("+gen(mask.indices)+", " + gen(mask.sourceWidth)+ ")"); - } - protected String gen(Object o, boolean strict) { - if (o instanceof Number) return o.toString(); - if (o instanceof String) return "\"" + o.toString() + "\""; - if (!strict) return "\"" + o.toString() + "\""; - throw new UnsupportedOperationException( - "Cannot currently generate code from an " + o.getClass() + " instance: " + o.toString()); - } - protected String gen(Object[] o, boolean strict) { - // return declareNewValue("Object[]", "{"+prettyPrintObjectArray(o, strict)+"}"); - return "new Object[] {" + prettyPrintObjectArray(o, strict) + "}"; - } - protected String gen(Tuple tuple, boolean strict) { - return "new FlatTuple(" + gen(tuple.getElements(), strict) + ")"; - } - public String genCalibrationElement(Object calibrationElement) { - return gen(calibrationElement, false);//calibrationElement.toString(); - } - -// public String genUnaryType(Object type) { -// return type==null? "null" : "context.retrieveUnaryType(\"" + coordinator.targetContext.retrieveUnaryTypeFQN(type) + "\")"; -// } -// -// public String genTernaryEdgeType(Object type) { -// return type==null? "null" : "context.retrieveTernaryEdgeType(\"" + coordinator.targetContext.retrieveBinaryEdgeTypeFQN(type) + "\")"; -// -// } -// public String genBinaryEdgeType(Object type) { -// return type==null? "null" : "context.retrieveBinaryEdgeType(\"" + coordinator.targetContext.retrieveTernaryEdgeTypeFQN(type) + "\")"; -// } - - public abstract String genUnaryType(Object type); - public abstract String genTernaryEdgeType(Object type); - public abstract String genBinaryEdgeType(Object type); - - public abstract String genPattern(PatternDescription desc); - //public abstract String genPosMap(PatternDescription desc); - - public String declareNextContainerVariable() { - return declareNewBuildable(call("getNextContainer", "")); - } -// public String declarePutOnTabVariable(PatternDescription effort) { -// return declareNewBuildable(call("putOnTab", genPattern(effort))); -// } - //////////////////////////////////// - // * BL - //////////////////////////////////// - - - - public Stub buildBetaNode(Stub primaryStub, Stub sideStub, - TupleMask primaryMask, TupleMask sideMask, - TupleMask complementer, boolean negative) - { - String[] arguments = { - gen(primaryStub), gen(sideStub), - gen(primaryMask), gen(sideMask), - gen(complementer), gen(negative) - }; - String resultVar = emitFunctionCall(coordinator.stubType, "buildBetaNode", arguments); - - if (negative) { - return new Stub(primaryStub, resultVar); - } else { - Tuple newCalibrationPattern = negative ? - primaryStub.getVariablesTuple() : - complementer.combine(primaryStub.getVariablesTuple(), sideStub.getVariablesTuple(), Options.enableInheritance, true); - - return new Stub(primaryStub, sideStub, newCalibrationPattern, resultVar); - } - } - - - public Stub buildCountCheckBetaNode(Stub primaryStub, - Stub sideStub, TupleMask primaryMask, - TupleMask originalSideMask, int resultPositionInSignature) - { - String[] arguments = { - gen(primaryStub), gen(sideStub), - gen(primaryMask), gen(originalSideMask), - gen(resultPositionInSignature) - }; - String resultVar = emitFunctionCall(coordinator.stubType, "buildCountCheckBetaNode", arguments); - - return new Stub(primaryStub, primaryStub.getVariablesTuple(), resultVar); - } - - public Stub buildCounterBetaNode(Stub primaryStub, - Stub sideStub, TupleMask primaryMask, - TupleMask originalSideMask, TupleMask complementer, - Object aggregateResultCalibrationElement) - { - String[] arguments = { - gen(primaryStub), gen(sideStub), - gen(primaryMask), gen(originalSideMask), - gen(complementer), - genCalibrationElement(aggregateResultCalibrationElement) - }; - String resultVar = emitFunctionCall(coordinator.stubType, "buildCounterBetaNode", arguments); - - Object[] newCalibrationElement = {aggregateResultCalibrationElement}; - Tuple newCalibrationPattern = new LeftInheritanceTuple(primaryStub.getVariablesTuple(), newCalibrationElement); - - return new Stub(primaryStub, newCalibrationPattern, resultVar); - } - public void buildConnection(Stub stub, String collector) { - String[] arguments = { - gen(stub), collector - }; - emitProcedureCall("buildConnection", arguments); - } - - public Stub buildEqualityChecker(Stub stub, int[] indices) { - String[] arguments = { - gen(stub), - gen(indices) - }; - String resultVar = emitFunctionCall(coordinator.stubType, "buildEqualityChecker", arguments); - return new Stub(stub, resultVar); - } - - public Stub buildInjectivityChecker(Stub stub, int subject, int[] inequalIndices) { - String[] arguments = { - gen(stub), gen(subject), - gen(inequalIndices) - }; - String resultVar = emitFunctionCall(coordinator.stubType, "buildInjectivityChecker", arguments); - return new Stub(stub, resultVar); - } - - @Override - public Stub buildTransitiveClosure(Stub stub) { - String[] arguments = { - gen(stub) - }; - String resultVar = emitFunctionCall(coordinator.stubType, "buildTransitiveClosure", arguments); - return new Stub(stub, resultVar); - } - - public Stub buildScopeConstrainer(Stub stub, boolean transitive, - Object unwrappedContainer, int constrainedIndex) { - throw new UnsupportedOperationException("Code generation does not support external scoping as of now"); - } - - public Stub buildStartStub(Object[] constantValues, Object[] constantNames) { - String[] arguments = { - gen(constantValues, true), - gen(constantNames, false), - }; - String resultVar = emitFunctionCall(coordinator.stubType, "buildStartStub", arguments); - return new Stub(new FlatTuple(constantNames), resultVar); - } - - - public Stub buildTrimmer(Stub stub, TupleMask trimMask) { - String[] arguments = { - gen(stub), gen(trimMask) - }; - String resultVar = emitFunctionCall(coordinator.stubType, "buildTrimmer", arguments); - return new Stub(stub, trimMask.transform(stub.getVariablesTuple()), resultVar); - } - - - public Stub containmentDirectStub(Tuple nodes) { - String[] arguments = { - gen(nodes, false) - }; - String resultVar = emitFunctionCall(coordinator.stubType, "containmentDirectStub", arguments); - return new Stub(nodes, resultVar); - } - - - public Stub containmentTransitiveStub(Tuple nodes) { - String[] arguments = { - gen(nodes, false) - }; - String resultVar = emitFunctionCall(coordinator.stubType, "containmentTransitiveStub", arguments); - return new Stub(nodes, resultVar); - } - - - public Stub unaryTypeStub(Tuple nodes, Object supplierKey) { - String[] arguments = { - gen(nodes, false), declareNewValue("Object", genUnaryType(supplierKey)) - }; - String resultVar = emitFunctionCall(coordinator.stubType, "unaryTypeStub", arguments); - return new Stub(nodes, resultVar); - } - - - public Stub generalizationDirectStub(Tuple nodes) { - String[] arguments = { - gen(nodes, false) - }; - String resultVar = emitFunctionCall(coordinator.stubType, "generalizationDirectStub", arguments); - return new Stub(nodes, resultVar); - } - - - public Stub generalizationTransitiveStub(Tuple nodes) { - String[] arguments = { - gen(nodes, false) - }; - String resultVar = emitFunctionCall(coordinator.stubType, "generalizationTransitiveStub", arguments); - return new Stub(nodes, resultVar); - } - - public Stub instantiationDirectStub(Tuple nodes) { - String[] arguments = { - gen(nodes, false) - }; - String resultVar = emitFunctionCall(coordinator.stubType, "instantiationDirectStub", arguments); - return new Stub(nodes, resultVar); - } - - - public Stub instantiationTransitiveStub(Tuple nodes) { - String[] arguments = { - gen(nodes, false) - }; - String resultVar = emitFunctionCall(coordinator.stubType, "instantiationTransitiveStub", arguments); - return new Stub(nodes, resultVar); - } - - - public Stub patternCallStub(Tuple nodes, PatternDescription supplierKey) - { - //if (!coordinator.collectors.containsKey(supplierKey)) coordinator.unbuilt.add(supplierKey); - String[] arguments = { - gen(nodes, false), genPattern(supplierKey) - }; - String resultVar = emitFunctionCall(coordinator.stubType, "patternCallStub", arguments); - return new Stub(nodes, resultVar); - } - - - public Stub binaryEdgeTypeStub(Tuple nodes, Object supplierKey) { - String[] arguments = { - gen(nodes, false), declareNewValue("Object", genBinaryEdgeType(supplierKey)) - }; - String resultVar = emitFunctionCall(coordinator.stubType, "binaryEdgeTypeStub", arguments); - return new Stub(nodes, resultVar); - } - - - public Stub ternaryEdgeTypeStub(Tuple nodes, Object supplierKey) { - String[] arguments = { - gen(nodes, false), declareNewValue("Object", genTernaryEdgeType(supplierKey)) - }; - String resultVar = emitFunctionCall(coordinator.stubType, "ternaryEdgeTypeStub", arguments); - return new Stub(nodes, resultVar); - } - - public String patternCollector(PatternDescription pattern) { - String patternName = genPattern(pattern); - String[] arguments = {patternName}; - return emitFunctionCall(coordinator.collectorType, "patternCollector", arguments); - // return coordinator.allocateNewCollector(pattern); - } - -// /** -// * @pre coordinator.isComplete() -// */ -// public void printInitializer(String collectorsMap, String posMappingMap) { -// for (Entry entry : coordinator.collectors.entrySet()) { -// String patternName = genPattern(entry.getKey()); -// emitLine("// "+patternName); -// emitLine(posMappingMap + ".put(" + patternName + ", " +genPosMap(entry.getKey()) + ");"); -// String[] arguments = {patternName}; -// String resultVar = emitFunctionCall(coordinator.collectorType, "patternCollector", arguments); -// emitLine(entry.getValue() + " = " + resultVar + ";"); -// emitLine(collectorsMap + ".put(" + patternName + ", " +entry.getValue() + ");"); -// } -// } +public abstract class CodegenRecorderBuildable implements + Buildable { + public CodegenRecordingCoordinator coordinator; + public PatternDescription effort; + public String myName; + public String baseName; + public String indent; + + /** + * @param code + * @param indent + * @param myName + */ + public CodegenRecorderBuildable(CodegenRecordingCoordinator coordinator, + PatternDescription effort, String indent, String baseName, String instanceSuffix) { + super(); + this.coordinator = coordinator; + this.effort = effort; + this.indent = indent; + this.baseName = baseName; + this.myName = baseName + instanceSuffix; + } + + public void reinitialize() { + throw new UnsupportedOperationException(); + } + + protected String prettyPrintStringArray(String[] elements, String separator) { + if (elements.length == 0) + return ""; + else { + StringBuilder result = new StringBuilder(elements[0]); + for (int i = 1; i < elements.length; ++i) { + result.append(", "); + result.append(elements[i]); + } + return result.toString(); + } + } + + protected String prettyPrintStringArray(String[] elements) { + return prettyPrintStringArray(elements, ", "); + } + + protected String prettyPrintIntArray(int[] elements, String separator) { + if (elements.length == 0) + return ""; + else { + StringBuilder result = new StringBuilder(); + result.append(elements[0]); + for (int i = 1; i < elements.length; ++i) { + result.append(", "); + result.append(elements[i]); + } + return result.toString(); + } + } + + protected String prettyPrintIntArray(int[] elements) { + return prettyPrintIntArray(elements, ", "); + } + + protected String prettyPrintObjectArray(Object[] elements, String separator, boolean strict) { + if (elements.length == 0) + return ""; + else { + StringBuilder result = new StringBuilder(gen(elements[0], strict)); + for (int i = 1; i < elements.length; ++i) { + result.append(separator); + result.append(gen(elements[i], strict)); + } + return result.toString(); + } + } + + protected String prettyPrintObjectArray(Object[] constantValues, boolean strict) { + return prettyPrintObjectArray(constantValues, ", ", strict); + } + + protected void emitLine(String line) { + coordinator.emitPatternBuilderLine(effort, indent, line); + } + + protected String call(String methodName, String arguments) { + return (myName + "." + methodName + "(" + arguments + ")"); + } + + protected String call(String methodName, String[] arguments) { + return call(methodName, prettyPrintStringArray(arguments)); + } + + protected String emitFunctionCall(String resultType, String methodName, String arguments) { + return declareNewValue(resultType, call(methodName, arguments)); + } + + protected String emitFunctionCall(String resultType, String methodName, String[] arguments) { + return declareNewValue(resultType, call(methodName, arguments)); + } + + protected void emitProcedureCall(String methodName, String arguments) { + emitLine(call(methodName, arguments) + ";"); + } + + protected void emitProcedureCall(String methodName, String[] arguments) { + emitLine(call(methodName, arguments) + ";"); + } + + protected void declareNew(String type, String identifier, String value, boolean isFinal) { + emitLine((isFinal ? "final " : "") + type + " " + identifier + " = " + value + ";"); + } + + protected String declareNewValue(String type, String value) { + String name = coordinator.newVariableIdentifier(); + declareNew(type, name, value, true); + return name; + } + + protected String declareNewBuildable(String value) { + String name = coordinator.newBuildableIdentifier(); + declareNew(coordinator.buildableType, name, value, true); + return name; + } + + protected String gen(Stub stub) { + return stub.getHandle(); + } + + protected String gen(boolean bool) { + return bool ? "true" : "false"; + } + + protected String gen(Integer integer) { + return integer == null ? "null" : integer.toString(); + } + + protected String gen(int[] ints) { + // return declareNewValue("int[]", "{"+prettyPrintIntArray(ints)+"}"); + return "new int[] {" + prettyPrintIntArray(ints) + "}"; + } + + protected String gen(TupleMask mask) { + return declareNewValue("TupleMask", "new TupleMask(" + gen(mask.indices) + ", " + gen(mask.sourceWidth) + ")"); + } + + protected String gen(Object o, boolean strict) { + if (o instanceof Number) + return o.toString(); + if (o instanceof String) + return "\"" + o.toString() + "\""; + if (!strict) + return "\"" + o.toString() + "\""; + throw new UnsupportedOperationException("Cannot currently generate code from an " + o.getClass() + + " instance: " + o.toString()); + } + + protected String gen(Object[] o, boolean strict) { + // return declareNewValue("Object[]", "{"+prettyPrintObjectArray(o, strict)+"}"); + return "new Object[] {" + prettyPrintObjectArray(o, strict) + "}"; + } + + protected String gen(Tuple tuple, boolean strict) { + return "new FlatTuple(" + gen(tuple.getElements(), strict) + ")"; + } + + public String genCalibrationElement(Object calibrationElement) { + return gen(calibrationElement, false);// calibrationElement.toString(); + } + + // public String genUnaryType(Object type) { + // return type==null? "null" : "context.retrieveUnaryType(\"" + coordinator.targetContext.retrieveUnaryTypeFQN(type) + // + "\")"; + // } + // + // public String genTernaryEdgeType(Object type) { + // return type==null? "null" : "context.retrieveTernaryEdgeType(\"" + + // coordinator.targetContext.retrieveBinaryEdgeTypeFQN(type) + "\")"; + // + // } + // public String genBinaryEdgeType(Object type) { + // return type==null? "null" : "context.retrieveBinaryEdgeType(\"" + + // coordinator.targetContext.retrieveTernaryEdgeTypeFQN(type) + "\")"; + // } + + public abstract String genUnaryType(Object type); + + public abstract String genTernaryEdgeType(Object type); + + public abstract String genBinaryEdgeType(Object type); + + public abstract String genPattern(PatternDescription desc); + + // public abstract String genPosMap(PatternDescription desc); + + public String declareNextContainerVariable() { + return declareNewBuildable(call("getNextContainer", "")); + } + + // public String declarePutOnTabVariable(PatternDescription effort) { + // return declareNewBuildable(call("putOnTab", genPattern(effort))); + // } + // ////////////////////////////////// + // * BL + // ////////////////////////////////// + + public Stub buildBetaNode(Stub primaryStub, Stub sideStub, TupleMask primaryMask, + TupleMask sideMask, TupleMask complementer, boolean negative) { + String[] arguments = { gen(primaryStub), gen(sideStub), gen(primaryMask), gen(sideMask), gen(complementer), + gen(negative) }; + String resultVar = emitFunctionCall(coordinator.stubType, "buildBetaNode", arguments); + + if (negative) { + return new Stub(primaryStub, resultVar); + } else { + Tuple newCalibrationPattern = negative ? primaryStub.getVariablesTuple() : complementer.combine( + primaryStub.getVariablesTuple(), sideStub.getVariablesTuple(), Options.enableInheritance, true); + + return new Stub(primaryStub, sideStub, newCalibrationPattern, resultVar); + } + } + + public Stub buildCountCheckBetaNode(Stub primaryStub, Stub sideStub, TupleMask primaryMask, + TupleMask originalSideMask, int resultPositionInSignature) { + String[] arguments = { gen(primaryStub), gen(sideStub), gen(primaryMask), gen(originalSideMask), + gen(resultPositionInSignature) }; + String resultVar = emitFunctionCall(coordinator.stubType, "buildCountCheckBetaNode", arguments); + + return new Stub(primaryStub, primaryStub.getVariablesTuple(), resultVar); + } + + public Stub buildCounterBetaNode(Stub primaryStub, Stub sideStub, TupleMask primaryMask, + TupleMask originalSideMask, TupleMask complementer, Object aggregateResultCalibrationElement) { + String[] arguments = { gen(primaryStub), gen(sideStub), gen(primaryMask), gen(originalSideMask), + gen(complementer), genCalibrationElement(aggregateResultCalibrationElement) }; + String resultVar = emitFunctionCall(coordinator.stubType, "buildCounterBetaNode", arguments); + + Object[] newCalibrationElement = { aggregateResultCalibrationElement }; + Tuple newCalibrationPattern = new LeftInheritanceTuple(primaryStub.getVariablesTuple(), newCalibrationElement); + + return new Stub(primaryStub, newCalibrationPattern, resultVar); + } + + public void buildConnection(Stub stub, String collector) { + String[] arguments = { gen(stub), collector }; + emitProcedureCall("buildConnection", arguments); + } + + public Stub buildEqualityChecker(Stub stub, int[] indices) { + String[] arguments = { gen(stub), gen(indices) }; + String resultVar = emitFunctionCall(coordinator.stubType, "buildEqualityChecker", arguments); + return new Stub(stub, resultVar); + } + + public Stub buildInjectivityChecker(Stub stub, int subject, int[] inequalIndices) { + String[] arguments = { gen(stub), gen(subject), gen(inequalIndices) }; + String resultVar = emitFunctionCall(coordinator.stubType, "buildInjectivityChecker", arguments); + return new Stub(stub, resultVar); + } + + @Override + public Stub buildTransitiveClosure(Stub stub) { + String[] arguments = { gen(stub) }; + String resultVar = emitFunctionCall(coordinator.stubType, "buildTransitiveClosure", arguments); + return new Stub(stub, resultVar); + } + + public Stub buildScopeConstrainer(Stub stub, boolean transitive, Object unwrappedContainer, + int constrainedIndex) { + throw new UnsupportedOperationException("Code generation does not support external scoping as of now"); + } + + public Stub buildStartStub(Object[] constantValues, Object[] constantNames) { + String[] arguments = { gen(constantValues, true), gen(constantNames, false), }; + String resultVar = emitFunctionCall(coordinator.stubType, "buildStartStub", arguments); + return new Stub(new FlatTuple(constantNames), resultVar); + } + + public Stub buildTrimmer(Stub stub, TupleMask trimMask) { + String[] arguments = { gen(stub), gen(trimMask) }; + String resultVar = emitFunctionCall(coordinator.stubType, "buildTrimmer", arguments); + return new Stub(stub, trimMask.transform(stub.getVariablesTuple()), resultVar); + } + + public Stub containmentDirectStub(Tuple nodes) { + String[] arguments = { gen(nodes, false) }; + String resultVar = emitFunctionCall(coordinator.stubType, "containmentDirectStub", arguments); + return new Stub(nodes, resultVar); + } + + public Stub containmentTransitiveStub(Tuple nodes) { + String[] arguments = { gen(nodes, false) }; + String resultVar = emitFunctionCall(coordinator.stubType, "containmentTransitiveStub", arguments); + return new Stub(nodes, resultVar); + } + + public Stub unaryTypeStub(Tuple nodes, Object supplierKey) { + String[] arguments = { gen(nodes, false), declareNewValue("Object", genUnaryType(supplierKey)) }; + String resultVar = emitFunctionCall(coordinator.stubType, "unaryTypeStub", arguments); + return new Stub(nodes, resultVar); + } + + public Stub generalizationDirectStub(Tuple nodes) { + String[] arguments = { gen(nodes, false) }; + String resultVar = emitFunctionCall(coordinator.stubType, "generalizationDirectStub", arguments); + return new Stub(nodes, resultVar); + } + + public Stub generalizationTransitiveStub(Tuple nodes) { + String[] arguments = { gen(nodes, false) }; + String resultVar = emitFunctionCall(coordinator.stubType, "generalizationTransitiveStub", arguments); + return new Stub(nodes, resultVar); + } + + public Stub instantiationDirectStub(Tuple nodes) { + String[] arguments = { gen(nodes, false) }; + String resultVar = emitFunctionCall(coordinator.stubType, "instantiationDirectStub", arguments); + return new Stub(nodes, resultVar); + } + + public Stub instantiationTransitiveStub(Tuple nodes) { + String[] arguments = { gen(nodes, false) }; + String resultVar = emitFunctionCall(coordinator.stubType, "instantiationTransitiveStub", arguments); + return new Stub(nodes, resultVar); + } + + public Stub patternCallStub(Tuple nodes, PatternDescription supplierKey) { + // if (!coordinator.collectors.containsKey(supplierKey)) coordinator.unbuilt.add(supplierKey); + String[] arguments = { gen(nodes, false), genPattern(supplierKey) }; + String resultVar = emitFunctionCall(coordinator.stubType, "patternCallStub", arguments); + return new Stub(nodes, resultVar); + } + + public Stub binaryEdgeTypeStub(Tuple nodes, Object supplierKey) { + String[] arguments = { gen(nodes, false), declareNewValue("Object", genBinaryEdgeType(supplierKey)) }; + String resultVar = emitFunctionCall(coordinator.stubType, "binaryEdgeTypeStub", arguments); + return new Stub(nodes, resultVar); + } + + public Stub ternaryEdgeTypeStub(Tuple nodes, Object supplierKey) { + String[] arguments = { gen(nodes, false), declareNewValue("Object", genTernaryEdgeType(supplierKey)) }; + String resultVar = emitFunctionCall(coordinator.stubType, "ternaryEdgeTypeStub", arguments); + return new Stub(nodes, resultVar); + } + + public String patternCollector(PatternDescription pattern) { + String patternName = genPattern(pattern); + String[] arguments = { patternName }; + return emitFunctionCall(coordinator.collectorType, "patternCollector", arguments); + // return coordinator.allocateNewCollector(pattern); + } + + // /** + // * @pre coordinator.isComplete() + // */ + // public void printInitializer(String collectorsMap, String posMappingMap) { + // for (Entry entry : coordinator.collectors.entrySet()) { + // String patternName = genPattern(entry.getKey()); + // emitLine("// "+patternName); + // emitLine(posMappingMap + ".put(" + patternName + ", " +genPosMap(entry.getKey()) + ");"); + // String[] arguments = {patternName}; + // String resultVar = emitFunctionCall(coordinator.collectorType, "patternCollector", arguments); + // emitLine(entry.getValue() + " = " + resultVar + ";"); + // emitLine(collectorsMap + ".put(" + patternName + ", " +entry.getValue() + ");"); + // } + // } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/CodegenRecordingCoordinator.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/CodegenRecordingCoordinator.java index a2ee59c2..1db80d4d 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/CodegenRecordingCoordinator.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/CodegenRecordingCoordinator.java @@ -21,104 +21,105 @@ /** * * @author Bergmann Gábor - * + * */ public class CodegenRecordingCoordinator { - protected static final String varPrefix = "var"; - protected static final String buildablePrefix = "buildable"; - protected static final String collectorPrefix = "production"; - - public Long nextIdentifier; /**/ - public String stubType; /**/ - public String collectorType; /**/ - public String buildableType; /**/ - HashMap builderCode; /**/ - // HashMap collectors; /**/ - // LinkedHashSet unbuilt; /**/ - public IPatternMatcherContext targetContext; /**/ - - public CodegenRecordingCoordinator(IPatternMatcherContext targetContext, - String stubType, String collectorType, String buildableType) - { - super(); - this.targetContext = targetContext; - this.nextIdentifier = 0L; - this.stubType = stubType; - this.collectorType = collectorType; - this.buildableType = buildableType; - - this.builderCode = new HashMap(); - //this.collectors = new HashMap(); - //this.unbuilt = new LinkedHashSet(); - - } - - String newIdentifier(String prefix){ - return prefix + "_"+(nextIdentifier++).toString(); - } - - String newVariableIdentifier(){ - return newIdentifier(varPrefix); - } - String newBuildableIdentifier(){ - return newIdentifier(buildablePrefix); - } - String newCollectorIdentifier(){ - return newIdentifier(collectorPrefix); - } - - public void emitPatternBuilderLine(PatternDescription effort, String indent, String line) { - StringBuilder sb = getBuilder(effort); - emitLine(sb, indent, line); - } - - - StringBuilder getBuilder(PatternDescription effort) { - if (effort == null) - throw new UnsupportedOperationException("Build actions must be put on the tab of a pattern"); - StringBuilder result = builderCode.get(effort); - if (result == null) { - result = new StringBuilder(); - builderCode.put(effort, result); - } - return result; - } - - private void emitLine(StringBuilder where, String indent, String line) { - where.append(indent); - where.append(line); - where.append(System.getProperty("line.separator")); - } - - public String getFinishedBuilderCode(PatternDescription pattern) { - return builderCode.get(pattern).toString(); - } - public Set getBuiltPatterns() { - return builderCode.keySet(); - } - -// String allocateNewCollector(PatternDescription pattern) { -// if (collectors.containsKey(pattern)) -// throw new UnsupportedOperationException("Duplicate production nodes unsupported in RETE code generation"); -// String prod = newCollectorIdentifier(); -// collectors.put(pattern, prod); -// unbuilt.remove(pattern); -// return prod; -// } - -// /** -// * @pre isComplete() -// */ -// public void printMembers(StringBuilder where, String indent) { -// for (String collector : collectors.values()) { -// emitLine(where, indent, collectorType + " " + collector + ";"); -// } -// } - -// public boolean isComplete() { -// return unbuilt.isEmpty(); -// } -// public PatternDescription nextUnbuilt() { -// return unbuilt.iterator().next(); -// } + protected static final String varPrefix = "var"; + protected static final String buildablePrefix = "buildable"; + protected static final String collectorPrefix = "production"; + + public Long nextIdentifier; /**/ + public String stubType; /**/ + public String collectorType; /**/ + public String buildableType; /**/ + HashMap builderCode; /**/ + // HashMap collectors; /**/ + // LinkedHashSet unbuilt; /**/ + public IPatternMatcherContext targetContext; /**/ + + public CodegenRecordingCoordinator(IPatternMatcherContext targetContext, String stubType, + String collectorType, String buildableType) { + super(); + this.targetContext = targetContext; + this.nextIdentifier = 0L; + this.stubType = stubType; + this.collectorType = collectorType; + this.buildableType = buildableType; + + this.builderCode = new HashMap(); + // this.collectors = new HashMap(); + // this.unbuilt = new LinkedHashSet(); + + } + + String newIdentifier(String prefix) { + return prefix + "_" + (nextIdentifier++).toString(); + } + + String newVariableIdentifier() { + return newIdentifier(varPrefix); + } + + String newBuildableIdentifier() { + return newIdentifier(buildablePrefix); + } + + String newCollectorIdentifier() { + return newIdentifier(collectorPrefix); + } + + public void emitPatternBuilderLine(PatternDescription effort, String indent, String line) { + StringBuilder sb = getBuilder(effort); + emitLine(sb, indent, line); + } + + StringBuilder getBuilder(PatternDescription effort) { + if (effort == null) + throw new UnsupportedOperationException("Build actions must be put on the tab of a pattern"); + StringBuilder result = builderCode.get(effort); + if (result == null) { + result = new StringBuilder(); + builderCode.put(effort, result); + } + return result; + } + + private void emitLine(StringBuilder where, String indent, String line) { + where.append(indent); + where.append(line); + where.append(System.getProperty("line.separator")); + } + + public String getFinishedBuilderCode(PatternDescription pattern) { + return builderCode.get(pattern).toString(); + } + + public Set getBuiltPatterns() { + return builderCode.keySet(); + } + + // String allocateNewCollector(PatternDescription pattern) { + // if (collectors.containsKey(pattern)) + // throw new UnsupportedOperationException("Duplicate production nodes unsupported in RETE code generation"); + // String prod = newCollectorIdentifier(); + // collectors.put(pattern, prod); + // unbuilt.remove(pattern); + // return prod; + // } + + // /** + // * @pre isComplete() + // */ + // public void printMembers(StringBuilder where, String indent) { + // for (String collector : collectors.values()) { + // emitLine(where, indent, collectorType + " " + collector + ";"); + // } + // } + + // public boolean isComplete() { + // return unbuilt.isEmpty(); + // } + // public PatternDescription nextUnbuilt() { + // return unbuilt.iterator().next(); + // } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/IReteLayoutStrategy.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/IReteLayoutStrategy.java index 5796cd1c..bc810771 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/IReteLayoutStrategy.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/IReteLayoutStrategy.java @@ -14,11 +14,12 @@ import org.eclipse.incquery.runtime.rete.construction.psystem.PSystem; /** - * An algorithm that builds a RETE net based on a PSystem. + * An algorithm that builds a RETE net based on a PSystem. + * * @author Bergmann Gábor - * + * */ public interface IReteLayoutStrategy { - public Stub layout(PSystem pSystem) - throws RetePatternBuildException; + public Stub layout(PSystem pSystem) + throws RetePatternBuildException; } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/IRetePatternBuilder.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/IRetePatternBuilder.java index 181c2a3c..96cf9a8d 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/IRetePatternBuilder.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/IRetePatternBuilder.java @@ -15,69 +15,63 @@ import org.eclipse.incquery.runtime.rete.matcher.IPatternMatcherContext; - - /** - * Exchangeable component of ReteEngine, responsible for building pattern - * matcher rete subnets. + * Exchangeable component of ReteEngine, responsible for building pattern matcher rete subnets. * * @author Gabor Bergmann */ public interface IRetePatternBuilder { - /** - * Builds a part of the rete network that will match occurences of a given - * pattern. - * - * @param gtPattern - * the pattern whose matcher subnet has to be built. - * @return production. - * the Production node that should store matchings of - * the given pattern. - * @throws RetePatternBuildException - * if construction fails. - */ - Collector construct(PatternDescription gtPattern) throws RetePatternBuildException; - - /** - * Extract the position mapping of the graph pattern. - */ - HashMap getPosMapping(PatternDescription gtPattern); - -// /** -// * Extends the rete network beyond a production node to -// * further constrain the symbolic parameters with containment scopes. -// * -// * @param unscopedProduction -// * the production node to be extended. -// * @param additionalScopeMap -// * maps the indices of a subset of the symbolic variables to -// * the scopes that are to be applied on those variables -// * @param production -// * the now-empty Production node that should store matchings of -// * the given pattern. -// * @return production. -// * @throws PatternMatcherCompileTimeException -// * if construction fails. -// */ -// Collector constructScoper( -// Address unscopedProduction, -// Map additionalScopeMap, -// Collector production) -// throws PatternMatcherCompileTimeException; - -// /** -// * Returns the buildable associated with this builder. -// */ -// public Buildable getBuildable(); - /** - * Returns the context associated with this builder. - */ - public IPatternMatcherContext getContext(); - /** - * After the ReteEngine is reinitialized, the pattern builder has to be - * notified about the change. - */ - void refresh(); + /** + * Builds a part of the rete network that will match occurences of a given pattern. + * + * @param gtPattern + * the pattern whose matcher subnet has to be built. + * @return production. the Production node that should store matchings of the given pattern. + * @throws RetePatternBuildException + * if construction fails. + */ + Collector construct(PatternDescription gtPattern) throws RetePatternBuildException; + + /** + * Extract the position mapping of the graph pattern. + */ + HashMap getPosMapping(PatternDescription gtPattern); + + // /** + // * Extends the rete network beyond a production node to + // * further constrain the symbolic parameters with containment scopes. + // * + // * @param unscopedProduction + // * the production node to be extended. + // * @param additionalScopeMap + // * maps the indices of a subset of the symbolic variables to + // * the scopes that are to be applied on those variables + // * @param production + // * the now-empty Production node that should store matchings of + // * the given pattern. + // * @return production. + // * @throws PatternMatcherCompileTimeException + // * if construction fails. + // */ + // Collector constructScoper( + // Address unscopedProduction, + // Map additionalScopeMap, + // Collector production) + // throws PatternMatcherCompileTimeException; + + // /** + // * Returns the buildable associated with this builder. + // */ + // public Buildable getBuildable(); + /** + * Returns the context associated with this builder. + */ + public IPatternMatcherContext getContext(); + + /** + * After the ReteEngine is reinitialized, the pattern builder has to be notified about the change. + */ + void refresh(); } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/ReteContainerBuildable.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/ReteContainerBuildable.java index f9ad7529..a88864d2 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/ReteContainerBuildable.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/ReteContainerBuildable.java @@ -34,255 +34,240 @@ import org.eclipse.incquery.runtime.rete.tuple.TupleMask; import org.eclipse.incquery.runtime.rete.util.Options; - /** * The buildable interface of a rete container. * * @author Bergmann Gábor - * + * */ -public class ReteContainerBuildable implements Buildable, Address> { - - protected Library library; - protected ReteContainer targetContainer; - protected Network reteNet; - protected ReteBoundary boundary; - protected ReteEngine engine; - protected boolean headAttached = false; - - /** - * Constructs the builder attached to a specified container. - * Prerequisite: engine has its network and boundary fields initialized. - * @param targetContainer - */ - public ReteContainerBuildable(ReteEngine engine, ReteContainer targetContainer) { - super(); - this.engine = engine; - this.reteNet = engine.getReteNet(); - this.boundary = engine.getBoundary(); - this.targetContainer = targetContainer; - this.library = targetContainer.getLibrary(); - this.headAttached = false; - } - /** - * Constructs the builder attached to the head container. - * Prerequisite: engine has its network and boundary fields initialized - */ - public ReteContainerBuildable(ReteEngine engine) { - super(); - this.engine = engine; - this.reteNet = engine.getReteNet(); - this.boundary = engine.getBoundary(); - this.targetContainer = reteNet.getHeadContainer(); - this.library = targetContainer.getLibrary(); - this.headAttached = true; - } - public void reinitialize() { - this.reteNet = engine.getReteNet(); - this.boundary = engine.getBoundary(); - this.targetContainer = headAttached ? reteNet.getHeadContainer() : reteNet.getNextContainer(); - this.library = targetContainer.getLibrary(); - } - - public Stub> buildTrimmer(Stub> stub, TupleMask trimMask) { - Address bodyTerminator = library.accessTrimmerNode(stub.getHandle(), trimMask); - return new Stub>(stub, trimMask.transform(stub.getVariablesTuple()), bodyTerminator); - } - - public void buildConnection(Stub> stub, Address collector) { - reteNet.connectRemoteNodes(stub.getHandle(), collector, true); - boundary.registerParentStubForReceiver(collector, stub); - } - - public Stub> buildStartStub(Object[] constantValues, Object[] constantNames) { - return new Stub>(new FlatTuple(constantNames), - library.accessConstantNode(boundary.wrapTuple(new FlatTuple(constantValues)))); - } - - public Stub> buildEqualityChecker(Stub> stub, int[] indices) { - Address checker = library.accessEqualityFilterNode(stub.getHandle(), indices); - return new Stub>(stub, checker); - } - - public Stub> buildInjectivityChecker(Stub> stub, int subject, int[] inequalIndices) - { - Address checker = - library.accessInequalityFilterNode(stub.getHandle(), subject, - new TupleMask(inequalIndices, stub.getVariablesTuple().getSize())); - return new Stub>(stub, checker); - } - - @Override - public Stub> buildTransitiveClosure(Stub> stub) { - Address checker = library.accessTransitiveClosureNode(stub.getHandle()); - return new Stub>(stub, checker); - } - - public Stub> patternCallStub(Tuple nodes, PatternDescription supplierKey) - throws RetePatternBuildException - { - return new Stub>(nodes, boundary.accessProduction(supplierKey)); - } - - public Stub> instantiationTransitiveStub(Tuple nodes) { - return new Stub>(nodes, boundary.accessInstantiationTransitiveRoot()); - } - - public Stub> instantiationDirectStub(Tuple nodes) { - return new Stub>(nodes, boundary.accessInstantiationRoot()); - } - - public Stub> generalizationTransitiveStub(Tuple nodes) { - return new Stub>(nodes, boundary.accessGeneralizationTransitiveRoot()); - } - - public Stub> generalizationDirectStub(Tuple nodes) { - return new Stub>(nodes, boundary.accessGeneralizationRoot()); - } - - public Stub> containmentTransitiveStub(Tuple nodes) { - return new Stub>(nodes, boundary.accessContainmentTransitiveRoot()); - } - - public Stub> containmentDirectStub(Tuple nodes) { - return new Stub>(nodes, boundary.accessContainmentRoot()); - } - - public Stub> binaryEdgeTypeStub(Tuple nodes, Object supplierKey) { - return new Stub>(nodes, boundary.accessBinaryEdgeRoot(supplierKey)); - } - - public Stub> ternaryEdgeTypeStub(Tuple nodes, Object supplierKey) { - return new Stub>(nodes, boundary.accessTernaryEdgeRoot(supplierKey)); - } - - public Stub> unaryTypeStub(Tuple nodes, Object supplierKey) { - return new Stub>(nodes, boundary.accessUnaryRoot(supplierKey)); - } - - public Stub> buildBetaNode( - Stub> primaryStub, - Stub> sideStub, - TupleMask primaryMask, - TupleMask sideMask, - TupleMask complementer, - boolean negative) - { - Address primarySlot = library.accessProjectionIndexer(primaryStub.getHandle(),primaryMask); - Address sideSlot = library.accessProjectionIndexer(sideStub.getHandle(), sideMask); - - if (negative) { - Address checker = library.accessExistenceNode(primarySlot, sideSlot, true); - return new Stub>(primaryStub, checker); - } else { - Address checker = library.accessJoinNode(primarySlot, sideSlot, complementer); - Tuple newCalibrationPattern = complementer.combine( - primaryStub.getVariablesTuple(), - sideStub.getVariablesTuple(), - Options.enableInheritance, true); - return new Stub>(primaryStub, sideStub, newCalibrationPattern, checker); - } - } - - public Stub> buildCounterBetaNode( - Stub> primaryStub, - Stub> sideStub, - TupleMask primaryMask, - TupleMask originalSideMask, - TupleMask complementer, - Object aggregateResultCalibrationElement) - { - Address primarySlot = library.accessProjectionIndexer(primaryStub.getHandle(),primaryMask); - Address sideSlot = library.accessCountOuterIndexer(sideStub.getHandle(), originalSideMask); - - Address checker = library - .accessJoinNode(primarySlot, sideSlot, - TupleMask.selectSingle(originalSideMask.indices.length, originalSideMask.indices.length+1)); - - Object[] newCalibrationElement = {aggregateResultCalibrationElement}; - Tuple newCalibrationPattern = new LeftInheritanceTuple(primaryStub.getVariablesTuple(), newCalibrationElement); - - Stub> result = new Stub>(primaryStub, newCalibrationPattern, checker); - - return result; - } - public Stub> buildCountCheckBetaNode( - Stub> primaryStub, - Stub> sideStub, - TupleMask primaryMask, - TupleMask originalSideMask, - int resultPositionInSignature) - { - Address primarySlot = library.accessProjectionIndexer(primaryStub.getHandle(),primaryMask); - Address sideSlot = library.accessCountOuterIdentityIndexer(sideStub.getHandle(), originalSideMask, resultPositionInSignature); - - Address checker = library - .accessJoinNode(primarySlot, sideSlot, TupleMask.empty(originalSideMask.indices.length+1)); - - Tuple newCalibrationPattern = primaryStub.getVariablesTuple(); - - Stub> result = new Stub>(primaryStub, newCalibrationPattern, checker); - - return result; - } - - public Stub> buildPredicateChecker( - AbstractEvaluator evaluator, - Integer rhsIndex, - int[] affectedIndices, - Stub> stub - ) - { - PredicateEvaluatorNode ten = new PredicateEvaluatorNode(engine, targetContainer, - rhsIndex, affectedIndices, stub.getVariablesTuple().getSize(), evaluator); - Address checker = Address.of(ten); - - reteNet.connectRemoteNodes(stub.getHandle(), checker, true); - - Stub> result = new Stub>(stub, checker); - - return result; - } - - /** - * @return a buildable that potentially acts on a separate container - */ - public ReteContainerBuildable getNextContainer() { - return new ReteContainerBuildable(engine, reteNet.getNextContainer()); - } - - public Stub> buildScopeConstrainer(Stub> stub, boolean transitive, - Object unwrappedContainer, int constrainedIndex) { - Address root = (transitive) ? - boundary.accessContainmentTransitiveRoot() : - boundary.accessContainmentRoot(); - // bind the container element - Address filteredRoot = - targetContainer.getLibrary().accessValueBinderFilterNode(root, 0/*container*/, boundary.wrapElement(unwrappedContainer)); - // build secondary indexer - int[] secondaryIndices = {1/*contained element*/}; - Address secondary = - targetContainer.getLibrary().accessProjectionIndexer(filteredRoot, new TupleMask(secondaryIndices, 2)); - // build primary indexer - int[] primaryIndices = {constrainedIndex}; - TupleMask primaryMask = new TupleMask(primaryIndices, stub.getVariablesTuple().getSize()); - Address primary = targetContainer.getLibrary().accessProjectionIndexer(stub.getHandle(), primaryMask); - // build checker - stub = new Stub>(stub, targetContainer.getLibrary().accessExistenceNode(primary, secondary, false)); - return stub; - } - - - public Address patternCollector(PatternDescription pattern) throws RetePatternBuildException { - return engine.getBoundary().createProductionInternal(pattern); - } - - /** - * No need to distinguish - */ - public ReteContainerBuildable putOnTab(PatternDescription effort) { - return this; - } - - +public class ReteContainerBuildable implements + Buildable, Address> { + + protected Library library; + protected ReteContainer targetContainer; + protected Network reteNet; + protected ReteBoundary boundary; + protected ReteEngine engine; + protected boolean headAttached = false; + + /** + * Constructs the builder attached to a specified container. Prerequisite: engine has its network and boundary + * fields initialized. + * + * @param targetContainer + */ + public ReteContainerBuildable(ReteEngine engine, ReteContainer targetContainer) { + super(); + this.engine = engine; + this.reteNet = engine.getReteNet(); + this.boundary = engine.getBoundary(); + this.targetContainer = targetContainer; + this.library = targetContainer.getLibrary(); + this.headAttached = false; + } + + /** + * Constructs the builder attached to the head container. Prerequisite: engine has its network and boundary fields + * initialized + */ + public ReteContainerBuildable(ReteEngine engine) { + super(); + this.engine = engine; + this.reteNet = engine.getReteNet(); + this.boundary = engine.getBoundary(); + this.targetContainer = reteNet.getHeadContainer(); + this.library = targetContainer.getLibrary(); + this.headAttached = true; + } + + public void reinitialize() { + this.reteNet = engine.getReteNet(); + this.boundary = engine.getBoundary(); + this.targetContainer = headAttached ? reteNet.getHeadContainer() : reteNet.getNextContainer(); + this.library = targetContainer.getLibrary(); + } + + public Stub> buildTrimmer(Stub> stub, TupleMask trimMask) { + Address bodyTerminator = library.accessTrimmerNode(stub.getHandle(), trimMask); + return new Stub>(stub, trimMask.transform(stub.getVariablesTuple()), bodyTerminator); + } + + public void buildConnection(Stub> stub, Address collector) { + reteNet.connectRemoteNodes(stub.getHandle(), collector, true); + boundary.registerParentStubForReceiver(collector, stub); + } + + public Stub> buildStartStub(Object[] constantValues, Object[] constantNames) { + return new Stub>(new FlatTuple(constantNames), library.accessConstantNode(boundary + .wrapTuple(new FlatTuple(constantValues)))); + } + + public Stub> buildEqualityChecker(Stub> stub, int[] indices) { + Address checker = library.accessEqualityFilterNode(stub.getHandle(), indices); + return new Stub>(stub, checker); + } + + public Stub> buildInjectivityChecker(Stub> stub, + int subject, int[] inequalIndices) { + Address checker = library.accessInequalityFilterNode(stub.getHandle(), subject, + new TupleMask(inequalIndices, stub.getVariablesTuple().getSize())); + return new Stub>(stub, checker); + } + + @Override + public Stub> buildTransitiveClosure(Stub> stub) { + Address checker = library.accessTransitiveClosureNode(stub.getHandle()); + return new Stub>(stub, checker); + } + + public Stub> patternCallStub(Tuple nodes, PatternDescription supplierKey) + throws RetePatternBuildException { + return new Stub>(nodes, boundary.accessProduction(supplierKey)); + } + + public Stub> instantiationTransitiveStub(Tuple nodes) { + return new Stub>(nodes, boundary.accessInstantiationTransitiveRoot()); + } + + public Stub> instantiationDirectStub(Tuple nodes) { + return new Stub>(nodes, boundary.accessInstantiationRoot()); + } + + public Stub> generalizationTransitiveStub(Tuple nodes) { + return new Stub>(nodes, boundary.accessGeneralizationTransitiveRoot()); + } + + public Stub> generalizationDirectStub(Tuple nodes) { + return new Stub>(nodes, boundary.accessGeneralizationRoot()); + } + + public Stub> containmentTransitiveStub(Tuple nodes) { + return new Stub>(nodes, boundary.accessContainmentTransitiveRoot()); + } + + public Stub> containmentDirectStub(Tuple nodes) { + return new Stub>(nodes, boundary.accessContainmentRoot()); + } + + public Stub> binaryEdgeTypeStub(Tuple nodes, Object supplierKey) { + return new Stub>(nodes, boundary.accessBinaryEdgeRoot(supplierKey)); + } + + public Stub> ternaryEdgeTypeStub(Tuple nodes, Object supplierKey) { + return new Stub>(nodes, boundary.accessTernaryEdgeRoot(supplierKey)); + } + + public Stub> unaryTypeStub(Tuple nodes, Object supplierKey) { + return new Stub>(nodes, boundary.accessUnaryRoot(supplierKey)); + } + + public Stub> buildBetaNode(Stub> primaryStub, + Stub> sideStub, TupleMask primaryMask, TupleMask sideMask, + TupleMask complementer, boolean negative) { + Address primarySlot = library.accessProjectionIndexer(primaryStub.getHandle(), + primaryMask); + Address sideSlot = library.accessProjectionIndexer(sideStub.getHandle(), sideMask); + + if (negative) { + Address checker = library.accessExistenceNode(primarySlot, sideSlot, true); + return new Stub>(primaryStub, checker); + } else { + Address checker = library.accessJoinNode(primarySlot, sideSlot, complementer); + Tuple newCalibrationPattern = complementer.combine(primaryStub.getVariablesTuple(), + sideStub.getVariablesTuple(), Options.enableInheritance, true); + return new Stub>(primaryStub, sideStub, newCalibrationPattern, checker); + } + } + + public Stub> buildCounterBetaNode(Stub> primaryStub, + Stub> sideStub, TupleMask primaryMask, TupleMask originalSideMask, + TupleMask complementer, Object aggregateResultCalibrationElement) { + Address primarySlot = library.accessProjectionIndexer(primaryStub.getHandle(), + primaryMask); + Address sideSlot = library.accessCountOuterIndexer(sideStub.getHandle(), originalSideMask); + + Address checker = library.accessJoinNode(primarySlot, sideSlot, + TupleMask.selectSingle(originalSideMask.indices.length, originalSideMask.indices.length + 1)); + + Object[] newCalibrationElement = { aggregateResultCalibrationElement }; + Tuple newCalibrationPattern = new LeftInheritanceTuple(primaryStub.getVariablesTuple(), newCalibrationElement); + + Stub> result = new Stub>(primaryStub, + newCalibrationPattern, checker); + + return result; + } + + public Stub> buildCountCheckBetaNode(Stub> primaryStub, + Stub> sideStub, TupleMask primaryMask, TupleMask originalSideMask, + int resultPositionInSignature) { + Address primarySlot = library.accessProjectionIndexer(primaryStub.getHandle(), + primaryMask); + Address sideSlot = library.accessCountOuterIdentityIndexer(sideStub.getHandle(), + originalSideMask, resultPositionInSignature); + + Address checker = library.accessJoinNode(primarySlot, sideSlot, + TupleMask.empty(originalSideMask.indices.length + 1)); + + Tuple newCalibrationPattern = primaryStub.getVariablesTuple(); + + Stub> result = new Stub>(primaryStub, + newCalibrationPattern, checker); + + return result; + } + + public Stub> buildPredicateChecker(AbstractEvaluator evaluator, Integer rhsIndex, + int[] affectedIndices, Stub> stub) { + PredicateEvaluatorNode ten = new PredicateEvaluatorNode(engine, targetContainer, rhsIndex, affectedIndices, + stub.getVariablesTuple().getSize(), evaluator); + Address checker = Address.of(ten); + + reteNet.connectRemoteNodes(stub.getHandle(), checker, true); + + Stub> result = new Stub>(stub, checker); + + return result; + } + + /** + * @return a buildable that potentially acts on a separate container + */ + public ReteContainerBuildable getNextContainer() { + return new ReteContainerBuildable(engine, reteNet.getNextContainer()); + } + + public Stub> buildScopeConstrainer(Stub> stub, + boolean transitive, Object unwrappedContainer, int constrainedIndex) { + Address root = (transitive) ? boundary.accessContainmentTransitiveRoot() : boundary + .accessContainmentRoot(); + // bind the container element + Address filteredRoot = targetContainer.getLibrary().accessValueBinderFilterNode(root, + 0/* container */, boundary.wrapElement(unwrappedContainer)); + // build secondary indexer + int[] secondaryIndices = { 1 /* contained element */}; + Address secondary = targetContainer.getLibrary().accessProjectionIndexer(filteredRoot, + new TupleMask(secondaryIndices, 2)); + // build primary indexer + int[] primaryIndices = { constrainedIndex }; + TupleMask primaryMask = new TupleMask(primaryIndices, stub.getVariablesTuple().getSize()); + Address primary = targetContainer.getLibrary().accessProjectionIndexer( + stub.getHandle(), primaryMask); + // build checker + stub = new Stub>(stub, targetContainer.getLibrary().accessExistenceNode(primary, + secondary, false)); + return stub; + } + + public Address patternCollector(PatternDescription pattern) throws RetePatternBuildException { + return engine.getBoundary().createProductionInternal(pattern); + } + + /** + * No need to distinguish + */ + public ReteContainerBuildable putOnTab(PatternDescription effort) { + return this; + } + } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/RetePatternBuildException.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/RetePatternBuildException.java index 20c2a3c7..b790231d 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/RetePatternBuildException.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/RetePatternBuildException.java @@ -11,90 +11,100 @@ package org.eclipse.incquery.runtime.rete.construction; - - /** * A problem has occured during the construction of the RETE net. * * @author Bergmann Gábor - * + * */ public class RetePatternBuildException extends Exception { - /** + /** * */ - private static final long serialVersionUID = -2424538150959407887L; + private static final long serialVersionUID = -2424538150959407887L; - private Object patternDescription; - private String templateMessage; - private String[] templateContext; - private String shortMessage; - - /** - * @param message The template of the exception message - * @param context The data elements to be used to instantiate the template. Can be null if no context parameter is defined - * @param patternDescription the PatternDescription where the exception occurred - */ - public RetePatternBuildException(String message, String[] context, String shortMessage, Object patternDescription) { - super(bind(message, context)); - this.patternDescription = patternDescription; - this.templateMessage = message; - this.templateContext = context; - this.shortMessage = shortMessage; - } - - /** - * @param message The template of the exception message - * @param context The data elements to be used to instantiate the template. Can be null if no context parameter is defined - * @param patternDescription the PatternDescription where the exception occurred - */ - public RetePatternBuildException(String message, String[] context, String shortMessage, Object patternDescription, Throwable cause) { - super(bind(message, context), cause); - this.patternDescription = patternDescription; - this.templateMessage = message; - this.templateContext = context; - this.shortMessage = shortMessage; - } + private Object patternDescription; + private String templateMessage; + private String[] templateContext; + private String shortMessage; - public Object getPatternDescription() { - return patternDescription; - } - public void setPatternDescription(Object patternDescription) { - this.patternDescription = patternDescription; - } + /** + * @param message + * The template of the exception message + * @param context + * The data elements to be used to instantiate the template. Can be null if no context parameter is + * defined + * @param patternDescription + * the PatternDescription where the exception occurred + */ + public RetePatternBuildException(String message, String[] context, String shortMessage, Object patternDescription) { + super(bind(message, context)); + this.patternDescription = patternDescription; + this.templateMessage = message; + this.templateContext = context; + this.shortMessage = shortMessage; + } - public String getTemplateMessage() { - return templateMessage; - } + /** + * @param message + * The template of the exception message + * @param context + * The data elements to be used to instantiate the template. Can be null if no context parameter is + * defined + * @param patternDescription + * the PatternDescription where the exception occurred + */ + public RetePatternBuildException(String message, String[] context, String shortMessage, Object patternDescription, + Throwable cause) { + super(bind(message, context), cause); + this.patternDescription = patternDescription; + this.templateMessage = message; + this.templateContext = context; + this.shortMessage = shortMessage; + } - public String[] getTemplateContext() { - return templateContext; - } - + public Object getPatternDescription() { + return patternDescription; + } - /** - * Binding the '{n}' (n = 1..N) strings to contextual conditions in 'context' - * @param context : array of context-sensitive Strings - */ - private static String bind(String message, String[] context) { - String additionalError = ""; - - if(context == null) return message; - - for(int i = 0; i>"); -// //error handling in case there is a null value in the context array -// if(context[i] == null) -// additionalError = "[INTERNAL ERROR] A name value in the GTASM model is null. \n\n"; - } - return additionalError+message; - } + public void setPatternDescription(Object patternDescription) { + this.patternDescription = patternDescription; + } - /** - * @return the shortMessage - */ - public String getShortMessage() { - return shortMessage; - } + public String getTemplateMessage() { + return templateMessage; + } + + public String[] getTemplateContext() { + return templateContext; + } + + /** + * Binding the '{n}' (n = 1..N) strings to contextual conditions in 'context' + * + * @param context + * : array of context-sensitive Strings + */ + private static String bind(String message, String[] context) { + String additionalError = ""; + + if (context == null) + return message; + + for (int i = 0; i < context.length; i++) { + message = message.replace("{" + (i + 1) + "}", context[i] != null ? context[i] : "<>"); + // //error handling in case there is a null value in the context array + // if(context[i] == null) + // additionalError = "[INTERNAL ERROR] A name value in the GTASM model is null. \n\n"; + } + return additionalError + message; + } + + /** + * @return the shortMessage + */ + public String getShortMessage() { + return shortMessage; + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/Stub.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/Stub.java index c81a9769..3e918e8f 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/Stub.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/Stub.java @@ -18,117 +18,137 @@ import org.eclipse.incquery.runtime.rete.construction.psystem.PConstraint; import org.eclipse.incquery.runtime.rete.tuple.Tuple; - /** * * @author Bergmann Gábor - * - * @param the buildable-specific representation of RETE node handle this stub type will augment + * + * @param + * the buildable-specific representation of RETE node handle this stub type will augment */ public class Stub { - private HandleType handle; - private Tuple variablesTuple; - private Map variablesIndex; - private Set constraints; - private Stub primaryParentStub; - private Stub secondaryParentStub; - - private Stub(Map variablesIndex, Tuple variablesTuple, HandleType handle) { - super(); - this.variablesIndex = variablesIndex; - this.variablesTuple = variablesTuple; - this.handle = handle; - this.constraints = new HashSet(); - } - public Stub(Tuple variablesTuple, HandleType handle) { - this(variablesTuple.invertIndex(), variablesTuple, handle); - } -// public Stub(Stub template) { -// this(template.variablesIndex, template.variablesTuple, template.getHandle()); -// } - public Stub(Stub primaryParent, HandleType handle) { - this(primaryParent.variablesIndex, primaryParent.variablesTuple, handle); - this.primaryParentStub = primaryParent; - constraints.addAll(primaryParent.getAllEnforcedConstraints()); - } - public Stub(Stub primaryParent, Tuple variablesTuple, HandleType handle) { - this(variablesTuple.invertIndex(), variablesTuple, handle); - this.primaryParentStub = primaryParent; - constraints.addAll(primaryParent.getAllEnforcedConstraints()); - } - public Stub(Stub primaryParent, Stub secondaryParent, Tuple variablesTuple, HandleType handle) { - this(variablesTuple.invertIndex(), variablesTuple, handle); - this.primaryParentStub = primaryParent; - this.secondaryParentStub = secondaryParent; - constraints.addAll(primaryParent.getAllEnforcedConstraints()); - constraints.addAll(secondaryParent.getAllEnforcedConstraints()); - } - /* (non-Javadoc) - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - StringBuilder sb = new StringBuilder("Stub("+getVariablesTuple()+"@"+getHandle()+"|"); - for (PConstraint constraint : constraints) sb.append(constraint.toString() + "&"); - sb.append(")"); - return sb.toString(); - } - /** - * @return the tuple of variables that define the schame emanating from the handle - */ - public Tuple getVariablesTuple() { - return variablesTuple; - } - /** - * @return the handle of a RETE supplier node that hosts a certain relation (set of tuples) - */ - public HandleType getHandle() { - return handle; - } - /** - * @return the index of the variable within variablesTuple - */ - public Map getVariablesIndex() { - return variablesIndex; - } - /** - * @return the set of variables involved - */ - public Set getVariablesSet() { - return variablesIndex.keySet(); - } - /** - * @return all constraints already enforced at this handle - */ - public Set getAllEnforcedConstraints() { - return constraints; - } - /** - * @return the new constraints enforced at this handle, that aren't yet enforced at parents - */ - public Set getDeltaEnforcedConstraints() { - Set result = new HashSet(constraints); - if (primaryParentStub != null) result.removeAll(primaryParentStub.getAllEnforcedConstraints()); - if (secondaryParentStub != null) result.removeAll(secondaryParentStub.getAllEnforcedConstraints()); - return result; - } - /** - * @return the constraints - */ - public void addConstraint(PConstraint constraint) { - constraints.add(constraint); - } - /** - * @return the primaryParentStub - */ - public Stub getPrimaryParentStub() { - return primaryParentStub; - } - /** - * @return the secondaryParentStub - */ - public Stub getSecondaryParentStub() { - return secondaryParentStub; - } - + private HandleType handle; + private Tuple variablesTuple; + private Map variablesIndex; + private Set constraints; + private Stub primaryParentStub; + private Stub secondaryParentStub; + + private Stub(Map variablesIndex, Tuple variablesTuple, HandleType handle) { + super(); + this.variablesIndex = variablesIndex; + this.variablesTuple = variablesTuple; + this.handle = handle; + this.constraints = new HashSet(); + } + + public Stub(Tuple variablesTuple, HandleType handle) { + this(variablesTuple.invertIndex(), variablesTuple, handle); + } + + // public Stub(Stub template) { + // this(template.variablesIndex, template.variablesTuple, template.getHandle()); + // } + public Stub(Stub primaryParent, HandleType handle) { + this(primaryParent.variablesIndex, primaryParent.variablesTuple, handle); + this.primaryParentStub = primaryParent; + constraints.addAll(primaryParent.getAllEnforcedConstraints()); + } + + public Stub(Stub primaryParent, Tuple variablesTuple, HandleType handle) { + this(variablesTuple.invertIndex(), variablesTuple, handle); + this.primaryParentStub = primaryParent; + constraints.addAll(primaryParent.getAllEnforcedConstraints()); + } + + public Stub(Stub primaryParent, Stub secondaryParent, Tuple variablesTuple, + HandleType handle) { + this(variablesTuple.invertIndex(), variablesTuple, handle); + this.primaryParentStub = primaryParent; + this.secondaryParentStub = secondaryParent; + constraints.addAll(primaryParent.getAllEnforcedConstraints()); + constraints.addAll(secondaryParent.getAllEnforcedConstraints()); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder("Stub(" + getVariablesTuple() + "@" + getHandle() + "|"); + for (PConstraint constraint : constraints) + sb.append(constraint.toString() + "&"); + sb.append(")"); + return sb.toString(); + } + + /** + * @return the tuple of variables that define the schame emanating from the handle + */ + public Tuple getVariablesTuple() { + return variablesTuple; + } + + /** + * @return the handle of a RETE supplier node that hosts a certain relation (set of tuples) + */ + public HandleType getHandle() { + return handle; + } + + /** + * @return the index of the variable within variablesTuple + */ + public Map getVariablesIndex() { + return variablesIndex; + } + + /** + * @return the set of variables involved + */ + public Set getVariablesSet() { + return variablesIndex.keySet(); + } + + /** + * @return all constraints already enforced at this handle + */ + public Set getAllEnforcedConstraints() { + return constraints; + } + + /** + * @return the new constraints enforced at this handle, that aren't yet enforced at parents + */ + public Set getDeltaEnforcedConstraints() { + Set result = new HashSet(constraints); + if (primaryParentStub != null) + result.removeAll(primaryParentStub.getAllEnforcedConstraints()); + if (secondaryParentStub != null) + result.removeAll(secondaryParentStub.getAllEnforcedConstraints()); + return result; + } + + /** + * @return the constraints + */ + public void addConstraint(PConstraint constraint) { + constraints.add(constraint); + } + + /** + * @return the primaryParentStub + */ + public Stub getPrimaryParentStub() { + return primaryParentStub; + } + + /** + * @return the secondaryParentStub + */ + public Stub getSecondaryParentStub() { + return secondaryParentStub; + } + } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/basiclinear/BasicLinearLayout.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/basiclinear/BasicLinearLayout.java index 86ec47c9..380b9866 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/basiclinear/BasicLinearLayout.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/basiclinear/BasicLinearLayout.java @@ -29,104 +29,99 @@ import org.eclipse.incquery.runtime.rete.util.Options; /** - * Basic layout that builds a linear RETE net based on a heuristic ordering of constraints. + * Basic layout that builds a linear RETE net based on a heuristic ordering of constraints. + * * @author Bergmann Gábor - * + * */ -public class BasicLinearLayout implements IReteLayoutStrategy { - - @Override - public Stub layout(final PSystem pSystem) - throws RetePatternBuildException - { - PatternDescription pattern = pSystem.getPattern(); - IPatternMatcherContext context = pSystem.getContext(); - Buildable buildable = pSystem.getBuildable(); - try { - - context.logDebug(getClass().getSimpleName() + ": patternbody build started"); - - // UNIFICATION AND WEAK INEQUALITY ELMINATION - LayoutHelper.unifyVariablesAlongEqualities(pSystem); - LayoutHelper.eliminateWeakInequalities(pSystem); - - // UNARY ELIMINATION WITH TYPE INFERENCE - if (Options.calcImpliedTypes) { - LayoutHelper.eliminateInferrableUnaryTypes(pSystem, context); - } - - // PREVENTIVE CHECKS - LayoutHelper.checkSanity(pSystem); - - // STARTING THE LINE - Stub stub = buildable.buildStartStub(new Object[]{}, new Object[]{}); - -// Set constants = pSystem.getConstraintsOfType(ConstantValue.class); -// for (ConstantValue pConstraint : constants) { -// Stub sideStub = pConstraint.doCreateStub(); -// stub = BuildHelper.naturalJoin(buildable, stub, sideStub); -// } - - Set pQueue = new HashSet(pSystem.getConstraints()); //TreeSet(new OrderingHeuristics()); -// pQueue.addAll(pSystem.getConstraintsOfType(EnumerablePConstraint.class)); -// pQueue.addAll(pSystem.getConstraintsOfType(DeferredPConstraint.class)); -// // omitted: symbolic & equality -- not anymore - - // MAIN LOOP - while (!pQueue.isEmpty()) { - PConstraint pConstraint = - Collections.min(pQueue, - new OrderingHeuristics(stub)); //pQueue.iterator().next(); - pQueue.remove(pConstraint); - - if (pConstraint instanceof EnumerablePConstraint) { - EnumerablePConstraint enumerable = - (EnumerablePConstraint) pConstraint; - Stub sideStub = enumerable.getStub(); - stub = BuildHelper.naturalJoin(buildable, stub, sideStub); - } else { - DeferredPConstraint deferred = - (DeferredPConstraint) pConstraint; - if (deferred.isReadyAt(stub)) { - stub = deferred.checkOn(stub); - } else { - deferred.raiseForeverDeferredError(stub); - } - } - } - - // FINAL CHECK, whether all exported variables are present - LayoutHelper.finalCheck(pSystem, stub); - - -// // output -// int paramNum = patternScaffold.gtPattern.getSymParameters().size(); -// int[] tI = new int[paramNum]; -// int tiW = stub.getVariablesTuple().getSize(); -// for (int i = 0; i < paramNum; i++) { -// PatternVariable variable = patternScaffold.gtPattern.getSymParameters().get(i); -// // for (Object o : variable.getElementInPattern()) // in all bodies -// // { -// PatternNodeBase pNode = pGraph.getPNode(variable); -// // if (stub.calibrationIndex.containsKey(pNode)) -// tI[i] = stub.getVariablesIndex().get(pNode); -// // } -// } -// TupleMask trim = new TupleMask(tI, tiW); -// Stub trimmer = buildable.buildTrimmer(stub, trim); -// buildable.buildConnection(trimmer, collector); - - context.logDebug(getClass().getSimpleName() + ": patternbody build concluded"); - - return stub; - - } catch (RetePatternBuildException ex) { - ex.setPatternDescription(pattern); - throw ex; - } - } +public class BasicLinearLayout implements + IReteLayoutStrategy { + + @Override + public Stub layout(final PSystem pSystem) + throws RetePatternBuildException { + PatternDescription pattern = pSystem.getPattern(); + IPatternMatcherContext context = pSystem.getContext(); + Buildable buildable = pSystem.getBuildable(); + try { + + context.logDebug(getClass().getSimpleName() + ": patternbody build started"); + + // UNIFICATION AND WEAK INEQUALITY ELMINATION + LayoutHelper.unifyVariablesAlongEqualities(pSystem); + LayoutHelper.eliminateWeakInequalities(pSystem); + + // UNARY ELIMINATION WITH TYPE INFERENCE + if (Options.calcImpliedTypes) { + LayoutHelper.eliminateInferrableUnaryTypes(pSystem, context); + } + + // PREVENTIVE CHECKS + LayoutHelper.checkSanity(pSystem); + + // STARTING THE LINE + Stub stub = buildable.buildStartStub(new Object[] {}, new Object[] {}); + + // Set constants = pSystem.getConstraintsOfType(ConstantValue.class); + // for (ConstantValue pConstraint : constants) { + // Stub sideStub = pConstraint.doCreateStub(); + // stub = BuildHelper.naturalJoin(buildable, stub, sideStub); + // } + + Set pQueue = new HashSet(pSystem.getConstraints()); // TreeSet(new + // OrderingHeuristics()); + // pQueue.addAll(pSystem.getConstraintsOfType(EnumerablePConstraint.class)); + // pQueue.addAll(pSystem.getConstraintsOfType(DeferredPConstraint.class)); + // // omitted: symbolic & equality -- not anymore + + // MAIN LOOP + while (!pQueue.isEmpty()) { + PConstraint pConstraint = Collections.min(pQueue, + new OrderingHeuristics(stub)); // pQueue.iterator().next(); + pQueue.remove(pConstraint); + + if (pConstraint instanceof EnumerablePConstraint) { + EnumerablePConstraint enumerable = (EnumerablePConstraint) pConstraint; + Stub sideStub = enumerable.getStub(); + stub = BuildHelper.naturalJoin(buildable, stub, sideStub); + } else { + DeferredPConstraint deferred = (DeferredPConstraint) pConstraint; + if (deferred.isReadyAt(stub)) { + stub = deferred.checkOn(stub); + } else { + deferred.raiseForeverDeferredError(stub); + } + } + } + + // FINAL CHECK, whether all exported variables are present + LayoutHelper.finalCheck(pSystem, stub); + + // // output + // int paramNum = patternScaffold.gtPattern.getSymParameters().size(); + // int[] tI = new int[paramNum]; + // int tiW = stub.getVariablesTuple().getSize(); + // for (int i = 0; i < paramNum; i++) { + // PatternVariable variable = patternScaffold.gtPattern.getSymParameters().get(i); + // // for (Object o : variable.getElementInPattern()) // in all bodies + // // { + // PatternNodeBase pNode = pGraph.getPNode(variable); + // // if (stub.calibrationIndex.containsKey(pNode)) + // tI[i] = stub.getVariablesIndex().get(pNode); + // // } + // } + // TupleMask trim = new TupleMask(tI, tiW); + // Stub trimmer = buildable.buildTrimmer(stub, trim); + // buildable.buildConnection(trimmer, collector); + context.logDebug(getClass().getSimpleName() + ": patternbody build concluded"); + return stub; + } catch (RetePatternBuildException ex) { + ex.setPatternDescription(pattern); + throw ex; + } + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/basiclinear/OrderingHeuristics.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/basiclinear/OrderingHeuristics.java index e9f20c37..513b04db 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/basiclinear/OrderingHeuristics.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/basiclinear/OrderingHeuristics.java @@ -25,71 +25,71 @@ /** * @author Bergmann Gábor - * + * */ -public class OrderingHeuristics implements Comparator { - private Stub stub; +public class OrderingHeuristics implements Comparator { + private Stub stub; + + /** + * @param stub + */ + public OrderingHeuristics(Stub stub) { + super(); + this.stub = stub; + } + + /* + * (non-Javadoc) + * + * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) + */ + @Override + public int compare(PConstraint o1, PConstraint o2) { + return new OrderingCompareAgent(o1, o2) { + @Override + protected void doCompare() { + boolean temp = true && consider(preferTrue(isConstant(a), isConstant(b))) + && consider(preferTrue(isReady(a), isReady(b))); + if (!temp) + return; + + Set bound1 = boundVariables(a); + Set bound2 = boundVariables(b); + swallowBoolean(temp && consider(preferTrue(isBound(a, bound1), isBound(b, bound2))) + && consider(preferMore(degreeBound(a, bound1), degreeBound(b, bound2))) + && consider(preferLess(degreeFree(a, bound1), degreeFree(b, bound2))) + + && consider(preferLess(a.toString(), b.toString()))); + } + }.compare(); + } + + boolean isConstant(PConstraint o) { + return (o instanceof ConstantValue); + } + + boolean isReady(PConstraint o) { + return (o instanceof EnumerablePConstraint) + || (o instanceof DeferredPConstraint && ((DeferredPConstraint) o) + .isReadyAt(stub)); + } + + Set boundVariables(PConstraint o) { + Set boundVariables = new HashSet(o.getAffectedVariables()); + boundVariables.retainAll(stub.getVariablesIndex().keySet()); + return boundVariables; + } - /** - * @param stub - */ - public OrderingHeuristics(Stub stub) { - super(); - this.stub = stub; - } - - /* (non-Javadoc) - * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) - */ - @Override - public int compare(PConstraint o1, PConstraint o2) { - return new OrderingCompareAgent(o1, o2) { - @Override - protected void doCompare() { - boolean temp = true - && consider(preferTrue(isConstant(a), isConstant(b))) - && consider(preferTrue(isReady(a), isReady(b))) - ; - if (!temp) return; - - Set bound1 = boundVariables(a); - Set bound2 = boundVariables(b); - swallowBoolean(temp - && consider(preferTrue(isBound(a, bound1), isBound(b, bound2))) - && consider(preferMore(degreeBound(a, bound1), degreeBound(b, bound2))) - && consider(preferLess(degreeFree(a, bound1), degreeFree(b, bound2))) - - && consider(preferLess(a.toString(), b.toString())) - ); - } - }.compare(); - } + boolean isBound(PConstraint o, Set boundVariables) { + return boundVariables.size() == o.getAffectedVariables().size(); + } + int degreeBound(PConstraint o, Set boundVariables) { + return boundVariables.size(); + } - - boolean isConstant(PConstraint o) { - return (o instanceof ConstantValue); - } - boolean isReady(PConstraint o) { - return - (o instanceof EnumerablePConstraint) || - (o instanceof DeferredPConstraint && - ((DeferredPConstraint) o).isReadyAt(stub)); - } - Set boundVariables(PConstraint o) { - Set boundVariables = new HashSet(o.getAffectedVariables()); - boundVariables.retainAll(stub.getVariablesIndex().keySet()); - return boundVariables; - } - boolean isBound(PConstraint o, Set boundVariables) { - return boundVariables.size() == o.getAffectedVariables().size(); - } - int degreeBound(PConstraint o, Set boundVariables) { - return boundVariables.size(); - } - int degreeFree(PConstraint o, Set boundVariables) { - return o.getAffectedVariables().size() - boundVariables.size(); - } + int degreeFree(PConstraint o, Set boundVariables) { + return o.getAffectedVariables().size() - boundVariables.size(); + } - } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/helpers/BuildHelper.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/helpers/BuildHelper.java index 27e38a4d..ce75ff41 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/helpers/BuildHelper.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/helpers/BuildHelper.java @@ -23,139 +23,130 @@ /** * @author Bergmann Gábor - * + * */ public class BuildHelper { - /** - * If two or more variables are the same in the variablesTuple of the stub, then a checker node is built to enforce their equality. - * @return the derived stub that contains the additional checkers, or the original if no action was neccessary. - */ - public static Stub enforceVariableCoincidences(Buildable buildable, Stub stub) { - Map> indexWithMupliplicity = - stub.getVariablesTuple().invertIndexWithMupliplicity(); - for (Map.Entry> pVariableIndices : indexWithMupliplicity.entrySet()) { - List indices = pVariableIndices.getValue(); - if (indices.size() > 1) { - int[] indexArray = new int[indices.size()]; - int m = 0; - for (Integer index : indices) - indexArray[m++] = index; - stub = buildable.buildEqualityChecker(stub, indexArray); - // TODO also trim here? - } - } - return stub; - - } - - /** - * Trims the results in the stub into a collector, by selecting exported variables in a particular order. - * @return the derived stub that contains the additional checkers, or the original if no action was neccessary. - */ - public static void projectIntoCollector( - Buildable buildable, - Stub stub, Collector collector, - PVariable[] selectedVariables) - { - int paramNum = selectedVariables.length; - int[] tI = new int[paramNum]; - for (int i = 0; i < paramNum; i++) { - tI[i] = stub.getVariablesIndex().get(selectedVariables[i]); - } - int tiW = stub.getVariablesTuple().getSize(); - TupleMask trim = new TupleMask(tI, tiW); - Stub trimmer = buildable.buildTrimmer(stub, trim); - buildable.buildConnection(trimmer, collector); - } - - /** - * Calculated index mappings for a join, based on the common variables of the two parent stubs. - * @author Bergmann Gábor - * - */ - public static class JoinHelper { - private TupleMask primaryMask; - private TupleMask secondaryMask; - private TupleMask complementerMask; - - /** - * @pre enforceVariableCoincidences() has been called on both sides. - * @param primaryStub - * @param secondaryStub - */ - public JoinHelper(Stub primaryStub, Stub secondaryStub) { - super(); - - Set primaryVariables = - primaryStub.getVariablesTuple().getDistinctElements(); - Set secondaryVariables = - secondaryStub.getVariablesTuple().getDistinctElements(); - int oldNodes = 0; - Set introducingSecondaryIndices = new TreeSet(); - for (PVariable var : secondaryVariables) { - if (primaryVariables.contains(var)) oldNodes++; - else introducingSecondaryIndices.add(secondaryStub.getVariablesIndex().get(var)); - } - int[] primaryIndices = new int[oldNodes]; - final int[] secondaryIndices = new int[oldNodes]; - int k = 0; - for (PVariable var : secondaryVariables) { - if (primaryVariables.contains(var)) { - primaryIndices[k] = primaryStub.getVariablesIndex().get(var); - secondaryIndices[k] = secondaryStub.getVariablesIndex().get(var); - k++; - } - } - int[] complementerIndices = new int[introducingSecondaryIndices.size()]; - int l = 0; - for (Integer integer : introducingSecondaryIndices) { - complementerIndices[l++] = integer; - } - primaryMask = new TupleMask( - primaryIndices, - primaryStub.getVariablesTuple().getSize()); - secondaryMask = new TupleMask( - secondaryIndices, - secondaryStub.getVariablesTuple().getSize()); - complementerMask = new TupleMask( - complementerIndices, - secondaryStub.getVariablesTuple().getSize()); - - } - /** - * @return the primaryMask - */ - public TupleMask getPrimaryMask() { - return primaryMask; - } - /** - * @return the secondaryMask - */ - public TupleMask getSecondaryMask() { - return secondaryMask; - } - /** - * @return the complementerMask - */ - public TupleMask getComplementerMask() { - return complementerMask; - } - - } - - public static Stub naturalJoin( - Buildable buildable, - Stub primaryStub, Stub secondaryStub) - { - JoinHelper joinHelper = new JoinHelper(primaryStub, secondaryStub); - return buildable.buildBetaNode( - primaryStub, secondaryStub, - joinHelper.getPrimaryMask(), - joinHelper.getSecondaryMask(), - joinHelper.getComplementerMask(), - false); - } - - + /** + * If two or more variables are the same in the variablesTuple of the stub, then a checker node is built to enforce + * their equality. + * + * @return the derived stub that contains the additional checkers, or the original if no action was neccessary. + */ + public static Stub enforceVariableCoincidences(Buildable buildable, + Stub stub) { + Map> indexWithMupliplicity = stub.getVariablesTuple().invertIndexWithMupliplicity(); + for (Map.Entry> pVariableIndices : indexWithMupliplicity.entrySet()) { + List indices = pVariableIndices.getValue(); + if (indices.size() > 1) { + int[] indexArray = new int[indices.size()]; + int m = 0; + for (Integer index : indices) + indexArray[m++] = index; + stub = buildable.buildEqualityChecker(stub, indexArray); + // TODO also trim here? + } + } + return stub; + + } + + /** + * Trims the results in the stub into a collector, by selecting exported variables in a particular order. + * + * @return the derived stub that contains the additional checkers, or the original if no action was neccessary. + */ + public static void projectIntoCollector(Buildable buildable, + Stub stub, Collector collector, PVariable[] selectedVariables) { + int paramNum = selectedVariables.length; + int[] tI = new int[paramNum]; + for (int i = 0; i < paramNum; i++) { + tI[i] = stub.getVariablesIndex().get(selectedVariables[i]); + } + int tiW = stub.getVariablesTuple().getSize(); + TupleMask trim = new TupleMask(tI, tiW); + Stub trimmer = buildable.buildTrimmer(stub, trim); + buildable.buildConnection(trimmer, collector); + } + + /** + * Calculated index mappings for a join, based on the common variables of the two parent stubs. + * + * @author Bergmann Gábor + * + */ + public static class JoinHelper { + private TupleMask primaryMask; + private TupleMask secondaryMask; + private TupleMask complementerMask; + + /** + * @pre enforceVariableCoincidences() has been called on both sides. + * @param primaryStub + * @param secondaryStub + */ + public JoinHelper(Stub primaryStub, Stub secondaryStub) { + super(); + + Set primaryVariables = primaryStub.getVariablesTuple().getDistinctElements(); + Set secondaryVariables = secondaryStub.getVariablesTuple().getDistinctElements(); + int oldNodes = 0; + Set introducingSecondaryIndices = new TreeSet(); + for (PVariable var : secondaryVariables) { + if (primaryVariables.contains(var)) + oldNodes++; + else + introducingSecondaryIndices.add(secondaryStub.getVariablesIndex().get(var)); + } + int[] primaryIndices = new int[oldNodes]; + final int[] secondaryIndices = new int[oldNodes]; + int k = 0; + for (PVariable var : secondaryVariables) { + if (primaryVariables.contains(var)) { + primaryIndices[k] = primaryStub.getVariablesIndex().get(var); + secondaryIndices[k] = secondaryStub.getVariablesIndex().get(var); + k++; + } + } + int[] complementerIndices = new int[introducingSecondaryIndices.size()]; + int l = 0; + for (Integer integer : introducingSecondaryIndices) { + complementerIndices[l++] = integer; + } + primaryMask = new TupleMask(primaryIndices, primaryStub.getVariablesTuple().getSize()); + secondaryMask = new TupleMask(secondaryIndices, secondaryStub.getVariablesTuple().getSize()); + complementerMask = new TupleMask(complementerIndices, secondaryStub.getVariablesTuple().getSize()); + + } + + /** + * @return the primaryMask + */ + public TupleMask getPrimaryMask() { + return primaryMask; + } + + /** + * @return the secondaryMask + */ + public TupleMask getSecondaryMask() { + return secondaryMask; + } + + /** + * @return the complementerMask + */ + public TupleMask getComplementerMask() { + return complementerMask; + } + + } + + public static Stub naturalJoin(Buildable buildable, + Stub primaryStub, Stub secondaryStub) { + JoinHelper joinHelper = new JoinHelper(primaryStub, secondaryStub); + return buildable.buildBetaNode(primaryStub, secondaryStub, joinHelper.getPrimaryMask(), + joinHelper.getSecondaryMask(), joinHelper.getComplementerMask(), false); + } + } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/helpers/LayoutHelper.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/helpers/LayoutHelper.java index 771e23e1..b4226938 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/helpers/LayoutHelper.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/helpers/LayoutHelper.java @@ -28,127 +28,123 @@ /** * @author Bergmann Gábor - * + * */ public class LayoutHelper { - /** - * Unifies allVariables along equalities so that they can be handled as one. - * @param pSystem - */ - public static void unifyVariablesAlongEqualities( - PSystem pSystem) - { - Set equals = pSystem.getConstraintsOfType(Equality.class); - for (Equality equality : equals) { - if (!equality.isMoot()) { - equality.getWho().unifyInto(equality.getWithWhom()); - } - // equality.delete(); - } - } + /** + * Unifies allVariables along equalities so that they can be handled as one. + * + * @param pSystem + */ + public static void unifyVariablesAlongEqualities( + PSystem pSystem) { + Set equals = pSystem.getConstraintsOfType(Equality.class); + for (Equality equality : equals) { + if (!equality.isMoot()) { + equality.getWho().unifyInto(equality.getWithWhom()); + } + // equality.delete(); + } + } + + /** + * Eliminates weak inequalities if they are not substantiated. + * + * @param pSystem + */ + public static void eliminateWeakInequalities( + PSystem pSystem) { + for (Inequality inequality : pSystem.getConstraintsOfType(Inequality.class)) + inequality.eliminateWeak(); + } + + /** + * Eliminates all unary type constraints that are inferrable from other constraints. + */ + public static void eliminateInferrableUnaryTypes( + final PSystem pSystem, + IPatternMatcherContext context) { + Set constraintsOfType = pSystem.getConstraintsOfType(TypeUnary.class); + for (TypeUnary typeUnary : constraintsOfType) { + PVariable var = (PVariable) typeUnary.getVariablesTuple().get(0); + Object expressedType = typeUnary.getTypeInfo(var); + Set typeRestrictors = var + .getReferringConstraintsOfType(ITypeInfoProviderConstraint.class); + typeRestrictors.remove(typeUnary); + for (ITypeInfoProviderConstraint iTypeRestriction : typeRestrictors) { + Object typeInfo = iTypeRestriction.getTypeInfo(var); + if (typeInfo != ITypeInfoProviderConstraint.TypeInfoSpecials.NO_TYPE_INFO_PROVIDED) { + Set typeClosure = TypeHelper.typeClosure(Collections.singleton(typeInfo), context); + if (typeClosure.contains(expressedType)) { + typeUnary.delete(); + break; + } + } + } + } + } - /** - * Eliminates weak inequalities if they are not substantiated. - * @param pSystem - */ - public static void eliminateWeakInequalities( - PSystem pSystem) - { - for (Inequality inequality : pSystem.getConstraintsOfType(Inequality.class)) inequality.eliminateWeak(); - } - - /** - * Eliminates all unary type constraints that are inferrable from other constraints. - */ - public static void eliminateInferrableUnaryTypes( - final PSystem pSystem, - IPatternMatcherContext context) - { - Set constraintsOfType = pSystem.getConstraintsOfType(TypeUnary.class); - for (TypeUnary typeUnary : constraintsOfType) { - PVariable var = (PVariable) typeUnary.getVariablesTuple().get(0); - Object expressedType = typeUnary.getTypeInfo(var); - Set typeRestrictors = var.getReferringConstraintsOfType(ITypeInfoProviderConstraint.class); - typeRestrictors.remove(typeUnary); - for (ITypeInfoProviderConstraint iTypeRestriction : typeRestrictors) { - Object typeInfo = iTypeRestriction.getTypeInfo(var); - if (typeInfo != ITypeInfoProviderConstraint.TypeInfoSpecials.NO_TYPE_INFO_PROVIDED) { - Set typeClosure = - TypeHelper.typeClosure(Collections.singleton(typeInfo), context); - if (typeClosure.contains(expressedType)) { - typeUnary.delete(); - break; - } - } - } - } - } - - /** - * Verifies the sanity of all constraints. Should be issued as a preventive check before layouting. - * @param pSystem - * @throws RetePatternBuildException - */ - public static void checkSanity( - PSystem pSystem) throws RetePatternBuildException - { - for (PConstraint pConstraint : pSystem.getConstraints()) pConstraint.checkSanity(); - } - - /** - * Finds an arbitrary constraint that is not enforced at the given stub. - * @param - * @param - * @param - * @param pSystem - * @param stub - * @return a PConstraint that is not enforced, if any, or null if all are enforced - */ - public static PConstraint getAnyUnenforcedConstraint( - PSystem pSystem, - Stub stub) - { - Set allEnforcedConstraints = stub.getAllEnforcedConstraints(); - Set constraints = pSystem.getConstraints(); - for (PConstraint pConstraint : constraints) { - if (!allEnforcedConstraints.contains(pConstraint)) return pConstraint; - } - return null; - } + /** + * Verifies the sanity of all constraints. Should be issued as a preventive check before layouting. + * + * @param pSystem + * @throws RetePatternBuildException + */ + public static void checkSanity( + PSystem pSystem) throws RetePatternBuildException { + for (PConstraint pConstraint : pSystem.getConstraints()) + pConstraint.checkSanity(); + } - - /** - * Verifies whether all constraints are enforced and exported parameters are present. - * @param pSystem - * @param stub - * @throws RetePatternBuildException - */ - public static void finalCheck( - final PSystem pSystem, - Stub stub) - throws RetePatternBuildException - { - PConstraint unenforcedConstraint = getAnyUnenforcedConstraint(pSystem, stub); - if (unenforcedConstraint != null) { - throw new RetePatternBuildException( - "Pattern matcher construction terminated without successfully enforcing constraint {1}." + - " Could be caused if the value of some variables can not be deduced, e.g. by circularity of pattern constraints.", - new String[]{unenforcedConstraint.toString()}, - "Could not enforce a pattern constraint", null); - } - for (ExportedParameter export : - pSystem.getConstraintsOfType(ExportedParameter.class)) - { - if (!export.isReadyAt(stub)) { - throw new RetePatternBuildException( - "Exported pattern parameter {1} could not be deduced during pattern matcher construction." + - " A pattern constraint is required to positively deduce its value.", - new String[]{export.getParameterName().toString()}, - "Could not calculate pattern parameter", null); - } - } - } + /** + * Finds an arbitrary constraint that is not enforced at the given stub. + * + * @param + * @param + * @param + * @param pSystem + * @param stub + * @return a PConstraint that is not enforced, if any, or null if all are enforced + */ + public static PConstraint getAnyUnenforcedConstraint( + PSystem pSystem, Stub stub) { + Set allEnforcedConstraints = stub.getAllEnforcedConstraints(); + Set constraints = pSystem.getConstraints(); + for (PConstraint pConstraint : constraints) { + if (!allEnforcedConstraints.contains(pConstraint)) + return pConstraint; + } + return null; + } + /** + * Verifies whether all constraints are enforced and exported parameters are present. + * + * @param pSystem + * @param stub + * @throws RetePatternBuildException + */ + public static void finalCheck( + final PSystem pSystem, Stub stub) + throws RetePatternBuildException { + PConstraint unenforcedConstraint = getAnyUnenforcedConstraint(pSystem, stub); + if (unenforcedConstraint != null) { + throw new RetePatternBuildException( + "Pattern matcher construction terminated without successfully enforcing constraint {1}." + + " Could be caused if the value of some variables can not be deduced, e.g. by circularity of pattern constraints.", + new String[] { unenforcedConstraint.toString() }, "Could not enforce a pattern constraint", null); + } + for (ExportedParameter export : pSystem + .getConstraintsOfType(ExportedParameter.class)) { + if (!export.isReadyAt(stub)) { + throw new RetePatternBuildException( + "Exported pattern parameter {1} could not be deduced during pattern matcher construction." + + " A pattern constraint is required to positively deduce its value.", + new String[] { export.getParameterName().toString() }, "Could not calculate pattern parameter", + null); + } + } + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/helpers/TypeHelper.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/helpers/TypeHelper.java index 24139c24..14440076 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/helpers/TypeHelper.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/helpers/TypeHelper.java @@ -22,68 +22,76 @@ /** * @author Bergmann Gábor - * + * */ public class TypeHelper { - /** - * Infers type information for the given variable, based on the given constraints. - * Generalization and subsumptions are not taken into account. - * @param pVariable the variable to infer types for - * @param constraints the set of constraints to extract type info from - */ - public static Set inferTypes(PVariable pVariable, Set constraints) { - Set inferredTypes = new HashSet(); - for (PConstraint pConstraint : constraints) { - if (pConstraint instanceof ITypeInfoProviderConstraint) { - Object typeInfo = ((ITypeInfoProviderConstraint) pConstraint).getTypeInfo(pVariable); - if (typeInfo != ITypeInfoProviderConstraint.TypeInfoSpecials.NO_TYPE_INFO_PROVIDED) - inferredTypes.add(typeInfo); - } - } - return inferredTypes; - } + /** + * Infers type information for the given variable, based on the given constraints. Generalization and subsumptions + * are not taken into account. + * + * @param pVariable + * the variable to infer types for + * @param constraints + * the set of constraints to extract type info from + */ + public static Set inferTypes(PVariable pVariable, Set constraints) { + Set inferredTypes = new HashSet(); + for (PConstraint pConstraint : constraints) { + if (pConstraint instanceof ITypeInfoProviderConstraint) { + Object typeInfo = ((ITypeInfoProviderConstraint) pConstraint).getTypeInfo(pVariable); + if (typeInfo != ITypeInfoProviderConstraint.TypeInfoSpecials.NO_TYPE_INFO_PROVIDED) + inferredTypes.add(typeInfo); + } + } + return inferredTypes; + } - /** - * Calculates the closure of a set of types, with respect to supertyping. - * @return the set of all types in typesToClose and all their direct and indirect supertypes - */ - public static Set typeClosure(Set typesToClose, IPatternMatcherContext context) { - Set closure = new HashSet(typesToClose); - Set delta = closure; - while(!delta.isEmpty()) { - Set newTypes = new HashSet(); - for (Object deltaType : delta) { - if (deltaType instanceof ITypeInfoProviderConstraint.TypeInfoSpecials) continue; - if (context.isUnaryType(deltaType)) newTypes.add(ITypeInfoProviderConstraint.TypeInfoSpecials.ANY_UNARY); - if (context.isTernaryEdgeType(deltaType)) newTypes.add(ITypeInfoProviderConstraint.TypeInfoSpecials.ANY_TERNARY); - Collection directSupertypes = context.enumerateDirectSupertypes(deltaType); - if (directSupertypes!=null) { - newTypes.addAll(directSupertypes); - } - } - newTypes.removeAll(closure); - delta = newTypes; - closure.addAll(delta); - } - return closure; - } + /** + * Calculates the closure of a set of types, with respect to supertyping. + * + * @return the set of all types in typesToClose and all their direct and indirect supertypes + */ + public static Set typeClosure(Set typesToClose, IPatternMatcherContext context) { + Set closure = new HashSet(typesToClose); + Set delta = closure; + while (!delta.isEmpty()) { + Set newTypes = new HashSet(); + for (Object deltaType : delta) { + if (deltaType instanceof ITypeInfoProviderConstraint.TypeInfoSpecials) + continue; + if (context.isUnaryType(deltaType)) + newTypes.add(ITypeInfoProviderConstraint.TypeInfoSpecials.ANY_UNARY); + if (context.isTernaryEdgeType(deltaType)) + newTypes.add(ITypeInfoProviderConstraint.TypeInfoSpecials.ANY_TERNARY); + Collection directSupertypes = context.enumerateDirectSupertypes(deltaType); + if (directSupertypes != null) { + newTypes.addAll(directSupertypes); + } + } + newTypes.removeAll(closure); + delta = newTypes; + closure.addAll(delta); + } + return closure; + } - /** - * Calculates a remainder set of types from a larger set, that are not subsumed by a given set of subsuming types. - * @param subsumableTypes a set of types from which some may be implied by the subsming types - * @param subsumingTypes a set of types that may imply some of the subsming types - * @return the collection of types in subsumableTypes that are NOT identical to or supertypes of any type in subsumingTypes. - */ - public static Set subsumeTypes( - Set subsumableTypes, - Set subsumingTypes, - IPatternMatcherContext context) - { - Set closure = typeClosure(subsumingTypes, context); - Set subsumed = new HashSet(subsumableTypes); - subsumed.removeAll(closure); - return subsumed; - } + /** + * Calculates a remainder set of types from a larger set, that are not subsumed by a given set of subsuming types. + * + * @param subsumableTypes + * a set of types from which some may be implied by the subsming types + * @param subsumingTypes + * a set of types that may imply some of the subsming types + * @return the collection of types in subsumableTypes that are NOT identical to or supertypes of any type in + * subsumingTypes. + */ + public static Set subsumeTypes(Set subsumableTypes, Set subsumingTypes, + IPatternMatcherContext context) { + Set closure = typeClosure(subsumingTypes, context); + Set subsumed = new HashSet(subsumableTypes); + subsumed.removeAll(closure); + return subsumed; + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/BasePConstraint.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/BasePConstraint.java index 8935a65c..b796c281 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/BasePConstraint.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/BasePConstraint.java @@ -19,57 +19,61 @@ /** * @author Bergmann Gábor - * + * */ public abstract class BasePConstraint implements PConstraint { - protected PSystem pSystem; - protected Buildable buildable; - private final Set affectedVariables; + protected PSystem pSystem; + protected Buildable buildable; + private final Set affectedVariables; + + /** + * @param affectedVariables + */ + public BasePConstraint(PSystem pSystem, Set affectedVariables) { + super(); + this.pSystem = pSystem; + this.buildable = pSystem.getBuildable(); + this.affectedVariables = new HashSet(affectedVariables); + + for (PVariable pVariable : affectedVariables) { + pVariable.refer(this); + } + pSystem.registerConstraint(this); + } + + @Override + public String toString() { + return "PC[" + getClass().getSimpleName() + ":" + toStringRest() + "]"; + } + + protected abstract String toStringRest(); + + @Override + public Set getAffectedVariables() { + return affectedVariables; + } + + @Override + public void replaceVariable(PVariable obsolete, PVariable replacement) { + if (affectedVariables.remove(obsolete)) { + affectedVariables.add(replacement); + obsolete.unrefer(this); + replacement.refer(this); + doReplaceVariable(obsolete, replacement); + } + } + + protected abstract void doReplaceVariable(PVariable obsolete, PVariable replacement); - /** - * @param affectedVariables - */ - public BasePConstraint(PSystem pSystem, Set affectedVariables) { - super(); - this.pSystem = pSystem; - this.buildable = pSystem.getBuildable(); - this.affectedVariables = new HashSet(affectedVariables); - - for (PVariable pVariable : affectedVariables) { - pVariable.refer(this); - } - pSystem.registerConstraint(this); - } - @Override - public String toString() { - return "PC["+getClass().getSimpleName()+":"+toStringRest()+"]"; - } - protected abstract String toStringRest(); + @Override + public void delete() { + for (PVariable pVariable : affectedVariables) { + pVariable.unrefer(this); + } + pSystem.unregisterConstraint(this); + } - @Override - public Set getAffectedVariables() { - return affectedVariables; - } - - @Override - public void replaceVariable(PVariable obsolete, PVariable replacement) { - if (affectedVariables.remove(obsolete)) { - affectedVariables.add(replacement); - obsolete.unrefer(this); - replacement.refer(this); - doReplaceVariable(obsolete, replacement); - } - } - protected abstract void doReplaceVariable(PVariable obsolete, PVariable replacement); - - @Override - public void delete() { - for (PVariable pVariable : affectedVariables) { - pVariable.unrefer(this); - } - pSystem.unregisterConstraint(this); - } - - @Override - public void checkSanity() throws RetePatternBuildException {} + @Override + public void checkSanity() throws RetePatternBuildException { + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/DeferredPConstraint.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/DeferredPConstraint.java index b21c2654..b3a78ef6 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/DeferredPConstraint.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/DeferredPConstraint.java @@ -18,32 +18,36 @@ /** * Any constraint that can only be checked on certain stubs (e.g. those stubs that already contain some variables). + * * @author Bergmann Gábor - * + * */ -public abstract class DeferredPConstraint extends BasePConstraint { - - public DeferredPConstraint(PSystem pSystem, Set affectedVariables) { - super(pSystem, affectedVariables); - } - - public abstract boolean isReadyAt(Stub stub); - - /** - * @pre this.isReadyAt(stub); - */ - public Stub checkOn(Stub stub) throws RetePatternBuildException { - Stub newStub = doCheckOn(stub); - newStub.addConstraint(this); - return newStub; - } - protected abstract Stub doCheckOn(Stub stub) throws RetePatternBuildException; - - /** - * Called when the constraint is not ready, but cannot be deferred further. - * @param stub - * @throws RetePatternBuildException to indicate the error in detail. - * PRE: !isReady(stub) - */ - public abstract void raiseForeverDeferredError(Stub stub) throws RetePatternBuildException; +public abstract class DeferredPConstraint extends + BasePConstraint { + + public DeferredPConstraint(PSystem pSystem, Set affectedVariables) { + super(pSystem, affectedVariables); + } + + public abstract boolean isReadyAt(Stub stub); + + /** + * @pre this.isReadyAt(stub); + */ + public Stub checkOn(Stub stub) throws RetePatternBuildException { + Stub newStub = doCheckOn(stub); + newStub.addConstraint(this); + return newStub; + } + + protected abstract Stub doCheckOn(Stub stub) throws RetePatternBuildException; + + /** + * Called when the constraint is not ready, but cannot be deferred further. + * + * @param stub + * @throws RetePatternBuildException + * to indicate the error in detail. PRE: !isReady(stub) + */ + public abstract void raiseForeverDeferredError(Stub stub) throws RetePatternBuildException; } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/EnumerablePConstraint.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/EnumerablePConstraint.java index 1f48cd40..abb8c8b3 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/EnumerablePConstraint.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/EnumerablePConstraint.java @@ -20,58 +20,59 @@ /** * A constraint for which all satisfying tuples of variable values can be enumerated at any point during run-time. + * * @author Bergmann Gábor - * + * */ -public abstract class EnumerablePConstraint extends BasePConstraint { - protected Tuple variablesTuple; - private Stub stub; - - protected EnumerablePConstraint(PSystem pSystem, Tuple variablesTuple) { - super(pSystem, variablesTuple.getDistinctElements()); - this.variablesTuple = variablesTuple; - } - - public Stub getStub() throws RetePatternBuildException { - if (stub == null) { - stub = doCreateStub(); - stub.addConstraint(this); - - // check for any variable coincidences and enforce them - stub = BuildHelper.enforceVariableCoincidences(buildable, stub); - } - return stub; - } - - public abstract Stub doCreateStub() throws RetePatternBuildException; +public abstract class EnumerablePConstraint extends + BasePConstraint { + protected Tuple variablesTuple; + private Stub stub; + + protected EnumerablePConstraint(PSystem pSystem, Tuple variablesTuple) { + super(pSystem, variablesTuple. getDistinctElements()); + this.variablesTuple = variablesTuple; + } + + public Stub getStub() throws RetePatternBuildException { + if (stub == null) { + stub = doCreateStub(); + stub.addConstraint(this); + + // check for any variable coincidences and enforce them + stub = BuildHelper.enforceVariableCoincidences(buildable, stub); + } + return stub; + } + + public abstract Stub doCreateStub() throws RetePatternBuildException; + + @Override + public void doReplaceVariable(PVariable obsolete, PVariable replacement) { + variablesTuple = variablesTuple.replaceAll(obsolete, replacement); + } + + @Override + protected String toStringRest() { + String stringRestRest = toStringRestRest(); + String tupleString = "@" + variablesTuple.toString(); + return stringRestRest == null ? tupleString : ":" + stringRestRest + tupleString; + } - @Override - public void doReplaceVariable(PVariable obsolete, PVariable replacement) { - variablesTuple = variablesTuple.replaceAll(obsolete, replacement); - } + protected String toStringRestRest() { + return null; + } - @Override - protected String toStringRest() { - String stringRestRest = toStringRestRest(); - String tupleString = "@" + variablesTuple.toString(); - return stringRestRest == null ? tupleString : ":" + stringRestRest + tupleString; - } - protected String toStringRestRest() { - return null; - } + /** + * @return the variablesTuple + */ + public Tuple getVariablesTuple() { + return variablesTuple; + } - /** - * @return the variablesTuple - */ - public Tuple getVariablesTuple() { - return variablesTuple; - } - - @Override - public Set getDeducedVariables() { - return getAffectedVariables(); - } - - + @Override + public Set getDeducedVariables() { + return getAffectedVariables(); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/ITypeInfoProviderConstraint.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/ITypeInfoProviderConstraint.java index 45a19867..af0c1df6 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/ITypeInfoProviderConstraint.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/ITypeInfoProviderConstraint.java @@ -13,38 +13,42 @@ /** * @author Bergmann Gábor - * + * */ public interface ITypeInfoProviderConstraint { - - /** - * Returns type information that is known about the variable if this constraint holds. - * Null if no such information is discernible. - * @param variable - * @return the inferred type information, or TypeInfoSpecials.NO_TYPE_INFO_PROVIDED if no type information is inferrable. Never returns null. - */ - public Object getTypeInfo(PVariable variable); - - public static enum TypeInfoSpecials { - NO_TYPE_INFO_PROVIDED, - ANY_UNARY, - ANY_TERNARY; - - public static Object wrapUnary(Object typeKey) { - return typeKey == null ? ITypeInfoProviderConstraint.TypeInfoSpecials.ANY_UNARY : typeKey; - } - public static Object unwrapUnary(Object typeKey) { - return typeKey == ITypeInfoProviderConstraint.TypeInfoSpecials.ANY_UNARY ? null : typeKey; - } - public static Object wrapTernary(Object typeKey) { - return typeKey == null ? ITypeInfoProviderConstraint.TypeInfoSpecials.ANY_TERNARY : typeKey; - } - public static Object unwrapTernary(Object typeKey) { - return typeKey == ITypeInfoProviderConstraint.TypeInfoSpecials.ANY_TERNARY ? null : typeKey; - } - public static Object wrapAny(Object typeKey) { - return typeKey == null ? ITypeInfoProviderConstraint.TypeInfoSpecials.NO_TYPE_INFO_PROVIDED : typeKey; - } - } + + /** + * Returns type information that is known about the variable if this constraint holds. Null if no such information + * is discernible. + * + * @param variable + * @return the inferred type information, or TypeInfoSpecials.NO_TYPE_INFO_PROVIDED if no type information is + * inferrable. Never returns null. + */ + public Object getTypeInfo(PVariable variable); + + public static enum TypeInfoSpecials { + NO_TYPE_INFO_PROVIDED, ANY_UNARY, ANY_TERNARY; + + public static Object wrapUnary(Object typeKey) { + return typeKey == null ? ITypeInfoProviderConstraint.TypeInfoSpecials.ANY_UNARY : typeKey; + } + + public static Object unwrapUnary(Object typeKey) { + return typeKey == ITypeInfoProviderConstraint.TypeInfoSpecials.ANY_UNARY ? null : typeKey; + } + + public static Object wrapTernary(Object typeKey) { + return typeKey == null ? ITypeInfoProviderConstraint.TypeInfoSpecials.ANY_TERNARY : typeKey; + } + + public static Object unwrapTernary(Object typeKey) { + return typeKey == ITypeInfoProviderConstraint.TypeInfoSpecials.ANY_TERNARY ? null : typeKey; + } + + public static Object wrapAny(Object typeKey) { + return typeKey == null ? ITypeInfoProviderConstraint.TypeInfoSpecials.NO_TYPE_INFO_PROVIDED : typeKey; + } + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/KeyedEnumerablePConstraint.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/KeyedEnumerablePConstraint.java index 32b4ee81..7965f356 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/KeyedEnumerablePConstraint.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/KeyedEnumerablePConstraint.java @@ -15,40 +15,39 @@ /** * @author Bergmann Gábor - * + * */ -public abstract class KeyedEnumerablePConstraint - extends EnumerablePConstraint -{ - - protected KeyType supplierKey; - - /** - * @param variablesTuple - * @param buildable - * @param supplierKey - */ - public KeyedEnumerablePConstraint(PSystem pSystem, Tuple variablesTuple, KeyType supplierKey) { - super(pSystem, variablesTuple); - this.supplierKey = supplierKey; - } - - @Override - protected String toStringRestRest() { - return supplierKey == null ? "$any(null)" : keyToString(); - } - - /** - * @return - */ - protected abstract String keyToString(); - - /** - * @return the supplierKey - */ - public KeyType getSupplierKey() { - return supplierKey; - } - - +public abstract class KeyedEnumerablePConstraint extends + EnumerablePConstraint { + + protected KeyType supplierKey; + + /** + * @param variablesTuple + * @param buildable + * @param supplierKey + */ + public KeyedEnumerablePConstraint(PSystem pSystem, Tuple variablesTuple, + KeyType supplierKey) { + super(pSystem, variablesTuple); + this.supplierKey = supplierKey; + } + + @Override + protected String toStringRestRest() { + return supplierKey == null ? "$any(null)" : keyToString(); + } + + /** + * @return + */ + protected abstract String keyToString(); + + /** + * @return the supplierKey + */ + public KeyType getSupplierKey() { + return supplierKey; + } + } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/PConstraint.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/PConstraint.java index edd525e2..b4c0a605 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/PConstraint.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/PConstraint.java @@ -17,16 +17,17 @@ /** * @author Bergmann Gábor - * + * */ public interface PConstraint { - public Set getAffectedVariables(); - public Set getDeducedVariables(); - - public void replaceVariable(PVariable obsolete, PVariable replacement); - - public void delete(); - - public void checkSanity() throws RetePatternBuildException; + public Set getAffectedVariables(); + + public Set getDeducedVariables(); + + public void replaceVariable(PVariable obsolete, PVariable replacement); + + public void delete(); + + public void checkSanity() throws RetePatternBuildException; } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/PSystem.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/PSystem.java index e2a63b80..020ca8b0 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/PSystem.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/PSystem.java @@ -22,151 +22,158 @@ /** * @author Bergmann Gábor - * + * */ public class PSystem { - private PatternDescription pattern; - private IPatternMatcherContext context; - private Buildable buildable; - - private Set allVariables; - private Set uniqueVariables; - private Map variablesByName; - private Set constraints; - private int nextVirtualNodeID; - - /** + private PatternDescription pattern; + private IPatternMatcherContext context; + private Buildable buildable; + + private Set allVariables; + private Set uniqueVariables; + private Map variablesByName; + private Set constraints; + private int nextVirtualNodeID; + + /** * */ - public PSystem( - IPatternMatcherContext context, - Buildable buildable, - PatternDescription pattern) - { - super(); - this.pattern = pattern; - this.context = context; - this.buildable = buildable; - allVariables = new HashSet(); - uniqueVariables = new HashSet(); - variablesByName = new HashMap(); - constraints = new HashSet(); - } - /** - * @return whether the submission of the new variable was successful - */ - private boolean addVariable(PVariable var) { - Object name = var.getName(); - if (!variablesByName.containsKey(name)) { - allVariables.add(var); - if (var.isUnique()) uniqueVariables.add(var); - variablesByName.put(name, var); - return true; - } else { - return false; - } - } - /** - * Use this method to add a newly created constraint to the pSystem. - * @return whether the submission of the new constraint was successful - */ - boolean registerConstraint(PConstraint constraint) { - return constraints.add(constraint); - } - /** - * Use this method to remove an obsolete constraint from the pSystem. - * @return whether the removal of the constraint was successful - */ - boolean unregisterConstraint(PConstraint constraint) { - return constraints.remove(constraint); - } - - @SuppressWarnings("unchecked") - public Set getConstraintsOfType(Class constraintClass) { - Set result = new HashSet(); - for (PConstraint pConstraint : constraints) { - if (constraintClass.isInstance(pConstraint)) - result.add((ConstraintType) pConstraint); - } - return result; - } - - public PVariable newVirtualVariable() { - String name; - do { - name = ".virtual{" + nextVirtualNodeID++ + "}"; - } while (variablesByName.containsKey(name)); - PVariable var = new PVariable(this, name, true); - addVariable(var); - return var; - } - public PVariable newConstantVariable(Object value) { - PVariable virtual = newVirtualVariable(); - new ConstantValue(this, virtual, value); - return virtual; - } - - - /** - * @return the context - */ - public IPatternMatcherContext getContext() { - return context; - } - /** - * @return the buildable - */ - public Buildable getBuildable() { - return buildable; - } - /** - * @return the allVariables - */ - public Set getAllVariables() { - return allVariables; - } - /** - * @return the uniqueVariables - */ - public Set getUniqueVariables() { - return uniqueVariables; - } + public PSystem(IPatternMatcherContext context, + Buildable buildable, PatternDescription pattern) { + super(); + this.pattern = pattern; + this.context = context; + this.buildable = buildable; + allVariables = new HashSet(); + uniqueVariables = new HashSet(); + variablesByName = new HashMap(); + constraints = new HashSet(); + } - /** - * @return the variable by name - */ - private PVariable getVariableByName(Object name) { - return variablesByName.get(name).getUnifiedIntoRoot(); - } - /** - * @return the variable by name - */ - public PVariable getOrCreateVariableByName(Object name) { - if (!variablesByName.containsKey(name)) addVariable(new PVariable(this, name)); - return getVariableByName(name); - } - /** - * @return the constraints - */ - public Set getConstraints() { - return constraints; - } - /** - * @return the pattern - */ - public PatternDescription getPattern() { - return pattern; - } - /** - * @param pVariable - */ - void noLongerUnique(PVariable pVariable) { - assert(!pVariable.isUnique()); - uniqueVariables.remove(pVariable); - } + /** + * @return whether the submission of the new variable was successful + */ + private boolean addVariable(PVariable var) { + Object name = var.getName(); + if (!variablesByName.containsKey(name)) { + allVariables.add(var); + if (var.isUnique()) + uniqueVariables.add(var); + variablesByName.put(name, var); + return true; + } else { + return false; + } + } + + /** + * Use this method to add a newly created constraint to the pSystem. + * + * @return whether the submission of the new constraint was successful + */ + boolean registerConstraint(PConstraint constraint) { + return constraints.add(constraint); + } + + /** + * Use this method to remove an obsolete constraint from the pSystem. + * + * @return whether the removal of the constraint was successful + */ + boolean unregisterConstraint(PConstraint constraint) { + return constraints.remove(constraint); + } + + @SuppressWarnings("unchecked") + public Set getConstraintsOfType(Class constraintClass) { + Set result = new HashSet(); + for (PConstraint pConstraint : constraints) { + if (constraintClass.isInstance(pConstraint)) + result.add((ConstraintType) pConstraint); + } + return result; + } + + public PVariable newVirtualVariable() { + String name; + do { + name = ".virtual{" + nextVirtualNodeID++ + "}"; + } while (variablesByName.containsKey(name)); + PVariable var = new PVariable(this, name, true); + addVariable(var); + return var; + } + + public PVariable newConstantVariable(Object value) { + PVariable virtual = newVirtualVariable(); + new ConstantValue(this, virtual, value); + return virtual; + } + + /** + * @return the context + */ + public IPatternMatcherContext getContext() { + return context; + } + + /** + * @return the buildable + */ + public Buildable getBuildable() { + return buildable; + } + + /** + * @return the allVariables + */ + public Set getAllVariables() { + return allVariables; + } + + /** + * @return the uniqueVariables + */ + public Set getUniqueVariables() { + return uniqueVariables; + } + + /** + * @return the variable by name + */ + private PVariable getVariableByName(Object name) { + return variablesByName.get(name).getUnifiedIntoRoot(); + } + + /** + * @return the variable by name + */ + public PVariable getOrCreateVariableByName(Object name) { + if (!variablesByName.containsKey(name)) + addVariable(new PVariable(this, name)); + return getVariableByName(name); + } + + /** + * @return the constraints + */ + public Set getConstraints() { + return constraints; + } + /** + * @return the pattern + */ + public PatternDescription getPattern() { + return pattern; + } - - + /** + * @param pVariable + */ + void noLongerUnique(PVariable pVariable) { + assert (!pVariable.isUnique()); + uniqueVariables.remove(pVariable); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/PVariable.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/PVariable.java index ebe4e287..de41753d 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/PVariable.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/PVariable.java @@ -16,206 +16,209 @@ /** * @author Bergmann Gábor - * + * */ public class PVariable { - private PSystem pSystem; - /** - * The name of the pattern variable. This is the unique key of the pattern node. - */ - private Object name; - /** - * virtual pVariables are nodes that do not correspond to actual pattern - * variables; they represent constants or Term substitutes - */ - private boolean virtual; -// /** -// * whether this is an exported symbolic parameter -// */ -// private boolean exportedParameter; - - /** - * Set of constraints that mention this variable - */ - private Set referringConstraints; - - /** - * Determines whether there are any constraints that can deduce this variable - */ - private Boolean deducable; - - /** - * Another PVariable this variable has been unified into. - * Please use the other variable instead of this. - * Null iff this is still a first-class variable. - */ - private PVariable unifiedInto; - - - - PVariable(PSystem pSystem, Object name) { - this(pSystem, name, false); - } - - PVariable(PSystem pSystem, Object name, boolean virtual) { - super(); - this.pSystem = pSystem; - this.name = name; - this.virtual = virtual; - //this.exportedParameter = false; - this.referringConstraints = new HashSet(); - this.unifiedInto = null; - this.deducable = false; - } - - /** - * Replaces this variable with a given other, resulting in their unification. - * This variable will no longer be unique. - * @param constraint - */ - public void unifyInto(PVariable replacement) { - replacementCheck(); - replacement = replacement.getUnifiedIntoRoot(); - - if (this.equals(replacement)) return; - - if (!this.isVirtual() && replacement.isVirtual()) - replacement.unifyInto(this); - else { - //replacement.referringConstraints.addAll(this.referringConstraints); - //replacement.exportedParameter |= this.exportedParameter; - replacement.virtual &= this.virtual; - if (replacement.deducable != null && this.deducable != null) - replacement.deducable |= this.deducable; - else - replacement.deducable = null; - Set snapshotConstraints = // avoid ConcurrentModificationX - new HashSet(this.referringConstraints); - for (PConstraint constraint : snapshotConstraints) { - constraint.replaceVariable(this, replacement); - } - // replacementCheck() will fail from this point - this.unifiedInto = replacement; - pSystem.noLongerUnique(this); - } - } - - /** - * Determines whether there are any constraints that can deduce this variable - * @return - */ - public boolean isDeducable() { - replacementCheck(); - if (deducable == null) { - deducable = false; - for (PConstraint pConstraint : getReferringConstraints()) { - if (pConstraint.getDeducedVariables().contains(this)) { - deducable = true; - break; - } - } - } - return deducable; - } - - /** - * Register that this variable is referred by the given constraint. - * @param constraint - */ - public void refer(PConstraint constraint) { - replacementCheck(); - deducable = null; - referringConstraints.add(constraint); - } - - /** - * Register that this variable is no longer referred by the given constraint. - * @param constraint - */ - public void unrefer(PConstraint constraint) { - replacementCheck(); - deducable = null; - referringConstraints.remove(constraint); - } - - - /** - * @return the name of the pattern variable. This is the unique key of the pattern node. - */ - public Object getName() { - replacementCheck(); - return name; - } - - /** - * @return the virtual - */ - public boolean isVirtual() { - replacementCheck(); - return virtual; - } - - -// /** -// * @return the exportedParameter -// */ -// public boolean isExportedParameter() { -// replacementCheck(); -// return exportedParameter; -// } -// -// /** -// * @param exportedParameter the exportedParameter to set -// */ -// public void setExportedParameter(boolean exportedParameter) { -// replacementCheck(); -// this.exportedParameter = exportedParameter; -// } - - /** - * @return the referringConstraints - */ - public Set getReferringConstraints() { - replacementCheck(); - return referringConstraints; - } - - @SuppressWarnings("unchecked") - public Set getReferringConstraintsOfType(Class constraintClass) { - replacementCheck(); - Set result = new HashSet(); - for (PConstraint pConstraint : referringConstraints) { - if (constraintClass.isInstance(pConstraint)) - result.add((ConstraintType) pConstraint); - } - return result; - } - - - @Override - public String toString() { - // replacementCheck(); - return name.toString();// + ":PatternNode"; - } - - public PVariable getDirectUnifiedInto() { - return unifiedInto; - } - public PVariable getUnifiedIntoRoot() { - PVariable nextUnified = unifiedInto; - PVariable oldUnifiedInto = this; - while (nextUnified != null) { - oldUnifiedInto = nextUnified; - nextUnified = oldUnifiedInto.getDirectUnifiedInto(); - } - return oldUnifiedInto; //unifiedInto; - } - public boolean isUnique() { - return unifiedInto == null; - } - private void replacementCheck() { - if (unifiedInto != null) - throw new IllegalStateException("Illegal usage of variable " + name + " which has been replaced with " + unifiedInto.name); - } - + private PSystem pSystem; + /** + * The name of the pattern variable. This is the unique key of the pattern node. + */ + private Object name; + /** + * virtual pVariables are nodes that do not correspond to actual pattern variables; they represent constants or Term + * substitutes + */ + private boolean virtual; + // /** + // * whether this is an exported symbolic parameter + // */ + // private boolean exportedParameter; + + /** + * Set of constraints that mention this variable + */ + private Set referringConstraints; + + /** + * Determines whether there are any constraints that can deduce this variable + */ + private Boolean deducable; + + /** + * Another PVariable this variable has been unified into. Please use the other variable instead of this. Null iff + * this is still a first-class variable. + */ + private PVariable unifiedInto; + + PVariable(PSystem pSystem, Object name) { + this(pSystem, name, false); + } + + PVariable(PSystem pSystem, Object name, boolean virtual) { + super(); + this.pSystem = pSystem; + this.name = name; + this.virtual = virtual; + // this.exportedParameter = false; + this.referringConstraints = new HashSet(); + this.unifiedInto = null; + this.deducable = false; + } + + /** + * Replaces this variable with a given other, resulting in their unification. This variable will no longer be + * unique. + * + * @param constraint + */ + public void unifyInto(PVariable replacement) { + replacementCheck(); + replacement = replacement.getUnifiedIntoRoot(); + + if (this.equals(replacement)) + return; + + if (!this.isVirtual() && replacement.isVirtual()) + replacement.unifyInto(this); + else { + // replacement.referringConstraints.addAll(this.referringConstraints); + // replacement.exportedParameter |= this.exportedParameter; + replacement.virtual &= this.virtual; + if (replacement.deducable != null && this.deducable != null) + replacement.deducable |= this.deducable; + else + replacement.deducable = null; + Set snapshotConstraints = // avoid ConcurrentModificationX + new HashSet(this.referringConstraints); + for (PConstraint constraint : snapshotConstraints) { + constraint.replaceVariable(this, replacement); + } + // replacementCheck() will fail from this point + this.unifiedInto = replacement; + pSystem.noLongerUnique(this); + } + } + + /** + * Determines whether there are any constraints that can deduce this variable + * + * @return + */ + public boolean isDeducable() { + replacementCheck(); + if (deducable == null) { + deducable = false; + for (PConstraint pConstraint : getReferringConstraints()) { + if (pConstraint.getDeducedVariables().contains(this)) { + deducable = true; + break; + } + } + } + return deducable; + } + + /** + * Register that this variable is referred by the given constraint. + * + * @param constraint + */ + public void refer(PConstraint constraint) { + replacementCheck(); + deducable = null; + referringConstraints.add(constraint); + } + + /** + * Register that this variable is no longer referred by the given constraint. + * + * @param constraint + */ + public void unrefer(PConstraint constraint) { + replacementCheck(); + deducable = null; + referringConstraints.remove(constraint); + } + + /** + * @return the name of the pattern variable. This is the unique key of the pattern node. + */ + public Object getName() { + replacementCheck(); + return name; + } + + /** + * @return the virtual + */ + public boolean isVirtual() { + replacementCheck(); + return virtual; + } + + // /** + // * @return the exportedParameter + // */ + // public boolean isExportedParameter() { + // replacementCheck(); + // return exportedParameter; + // } + // + // /** + // * @param exportedParameter the exportedParameter to set + // */ + // public void setExportedParameter(boolean exportedParameter) { + // replacementCheck(); + // this.exportedParameter = exportedParameter; + // } + + /** + * @return the referringConstraints + */ + public Set getReferringConstraints() { + replacementCheck(); + return referringConstraints; + } + + @SuppressWarnings("unchecked") + public Set getReferringConstraintsOfType(Class constraintClass) { + replacementCheck(); + Set result = new HashSet(); + for (PConstraint pConstraint : referringConstraints) { + if (constraintClass.isInstance(pConstraint)) + result.add((ConstraintType) pConstraint); + } + return result; + } + + @Override + public String toString() { + // replacementCheck(); + return name.toString();// + ":PatternNode"; + } + + public PVariable getDirectUnifiedInto() { + return unifiedInto; + } + + public PVariable getUnifiedIntoRoot() { + PVariable nextUnified = unifiedInto; + PVariable oldUnifiedInto = this; + while (nextUnified != null) { + oldUnifiedInto = nextUnified; + nextUnified = oldUnifiedInto.getDirectUnifiedInto(); + } + return oldUnifiedInto; // unifiedInto; + } + + public boolean isUnique() { + return unifiedInto == null; + } + + private void replacementCheck() { + if (unifiedInto != null) + throw new IllegalStateException("Illegal usage of variable " + name + " which has been replaced with " + + unifiedInto.name); + } + } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/VariableDeferredPConstraint.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/VariableDeferredPConstraint.java index fb8ce252..36817a4e 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/VariableDeferredPConstraint.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/VariableDeferredPConstraint.java @@ -20,34 +20,38 @@ /** * A kind of deferred constraint that can only be checked when a set of deferring variables are all present in a stub. + * * @author Bergmann Gábor - * + * */ -public abstract class VariableDeferredPConstraint extends DeferredPConstraint { - /** - * @param affectedVariables - */ - public VariableDeferredPConstraint(PSystem pSystem, Set affectedVariables) { - super(pSystem, affectedVariables); - } - protected abstract Set getDeferringVariables(); - /** - * Refine further if needed - */ - @Override - public boolean isReadyAt(Stub stub) { - return stub.getVariablesIndex().keySet().containsAll(getDeferringVariables()); - } +public abstract class VariableDeferredPConstraint extends + DeferredPConstraint { + /** + * @param affectedVariables + */ + public VariableDeferredPConstraint(PSystem pSystem, + Set affectedVariables) { + super(pSystem, affectedVariables); + } + + protected abstract Set getDeferringVariables(); + + /** + * Refine further if needed + */ + @Override + public boolean isReadyAt(Stub stub) { + return stub.getVariablesIndex().keySet().containsAll(getDeferringVariables()); + } - @Override - public void raiseForeverDeferredError(Stub stub) - throws RetePatternBuildException { - Set missing = new HashSet(getDeferringVariables()); - missing.removeAll(stub.getVariablesIndex().keySet()); - String[] args = {toString(), Arrays.toString(missing.toArray())}; - String msg = "The checking of pattern constraint {1} requires the values of variables {2}, but it cannot be deferred further. " + - "HINT: the incremental matcher is not an equation solver, please make sure that all variable values are deducible."; - String shortMsg = "Could not check all constraints due to undeducible variables"; - throw new RetePatternBuildException(msg, args, shortMsg, null); - } + @Override + public void raiseForeverDeferredError(Stub stub) throws RetePatternBuildException { + Set missing = new HashSet(getDeferringVariables()); + missing.removeAll(stub.getVariablesIndex().keySet()); + String[] args = { toString(), Arrays.toString(missing.toArray()) }; + String msg = "The checking of pattern constraint {1} requires the values of variables {2}, but it cannot be deferred further. " + + "HINT: the incremental matcher is not an equation solver, please make sure that all variable values are deducible."; + String shortMsg = "Could not check all constraints due to undeducible variables"; + throw new RetePatternBuildException(msg, args, shortMsg, null); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicdeferred/BaseTypeSafePredicateCheck.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicdeferred/BaseTypeSafePredicateCheck.java index 79b32243..0198a5f8 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicdeferred/BaseTypeSafePredicateCheck.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicdeferred/BaseTypeSafePredicateCheck.java @@ -25,87 +25,82 @@ /** * @author Bergmann Gábor - * + * */ public abstract class BaseTypeSafePredicateCheck extends - VariableDeferredPConstraint -{ - private Map> allTypeRestrictions; + VariableDeferredPConstraint { + private Map> allTypeRestrictions; + + /** + * @param buildable + * @param affectedVariables + */ + public BaseTypeSafePredicateCheck(PSystem pSystem, + Set affectedVariables) { + super(pSystem, affectedVariables); + } - /** - * @param buildable - * @param affectedVariables - */ - public BaseTypeSafePredicateCheck( - PSystem pSystem, - Set affectedVariables) { - super(pSystem, affectedVariables); - } + @Override + public Set getDeducedVariables() { + return Collections.emptySet(); + } - @Override - public Set getDeducedVariables() { - return Collections.emptySet(); - } + @Override + protected Set getDeferringVariables() { + return getAffectedVariables(); + } - @Override - protected Set getDeferringVariables() { - return getAffectedVariables(); - } + @Override + public boolean isReadyAt(Stub stub) { + if (super.isReadyAt(stub)) { + return checkTypeSafety(stub) == null; + } + return false; + } - @Override - public boolean isReadyAt(Stub stub) { - if (super.isReadyAt(stub)) { - return checkTypeSafety(stub) == null; - } - return false; - } + /** + * Checks whether all type restrictions are already enforced on affected variables. + * + * @param stub + * @return a variable whose type safety is not enforced yet, or null if the stub is typesafe + */ + protected PVariable checkTypeSafety(Stub stub) { + for (PVariable pVariable : getAffectedVariables()) { + Set allTypeRestrictionsForVariable = getAllTypeRestrictions().get(pVariable); + Set checkedTypeRestrictions = TypeHelper.inferTypes(pVariable, stub.getAllEnforcedConstraints()); + Set uncheckedTypeRestrictions = TypeHelper.subsumeTypes(allTypeRestrictionsForVariable, + checkedTypeRestrictions, this.pSystem.getContext()); + if (!uncheckedTypeRestrictions.isEmpty()) + return pVariable; + } + return null; + } - /** - * Checks whether all type restrictions are already enforced on affected variables. - * @param stub - * @return a variable whose type safety is not enforced yet, or null if the stub is typesafe - */ - protected PVariable checkTypeSafety(Stub stub) { - for (PVariable pVariable : getAffectedVariables()) { - Set allTypeRestrictionsForVariable = getAllTypeRestrictions().get(pVariable); - Set checkedTypeRestrictions = TypeHelper.inferTypes(pVariable, stub.getAllEnforcedConstraints()); - Set uncheckedTypeRestrictions = - TypeHelper.subsumeTypes( - allTypeRestrictionsForVariable, - checkedTypeRestrictions, - this.pSystem.getContext()); - if (!uncheckedTypeRestrictions.isEmpty()) return pVariable; - } - return null; - } + /** + * @return the allTypeRestrictions + */ + public Map> getAllTypeRestrictions() { + if (allTypeRestrictions == null) { + allTypeRestrictions = new HashMap>(); + for (PVariable pVariable : getAffectedVariables()) { + allTypeRestrictions.put(pVariable, + TypeHelper.inferTypes(pVariable, pVariable.getReferringConstraints())); + } + } + return allTypeRestrictions; + } - /** - * @return the allTypeRestrictions - */ - public Map> getAllTypeRestrictions() { - if (allTypeRestrictions == null) { - allTypeRestrictions = new HashMap>(); - for (PVariable pVariable : getAffectedVariables()) { - allTypeRestrictions.put( - pVariable, - TypeHelper.inferTypes(pVariable, pVariable.getReferringConstraints())); - } - } - return allTypeRestrictions; - } + @Override + public void raiseForeverDeferredError(Stub stub) throws RetePatternBuildException { + if (!super.isReadyAt(stub)) { + super.raiseForeverDeferredError(stub); + } else { + String[] args = { toString(), checkTypeSafety(stub).toString() }; + String msg = "The checking of pattern constraint {1} cannot be deferred further, but variable {2} is still not type safe. " + + "HINT: the incremental matcher is not an equation solver, please make sure that all variable values are deducible."; + String shortMsg = "Could not check all constraints due to undeducible type restrictions"; + throw new RetePatternBuildException(msg, args, shortMsg, null); + } - @Override - public void raiseForeverDeferredError(Stub stub) - throws RetePatternBuildException { - if (!super.isReadyAt(stub)) { - super.raiseForeverDeferredError(stub); - } else { - String[] args = {toString(), checkTypeSafety(stub).toString()}; - String msg = "The checking of pattern constraint {1} cannot be deferred further, but variable {2} is still not type safe. " + - "HINT: the incremental matcher is not an equation solver, please make sure that all variable values are deducible."; - String shortMsg = "Could not check all constraints due to undeducible type restrictions"; - throw new RetePatternBuildException(msg, args, shortMsg, null); - } - - } + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicdeferred/Equality.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicdeferred/Equality.java index ec497c40..6f4bc44a 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicdeferred/Equality.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicdeferred/Equality.java @@ -23,97 +23,97 @@ /** * @author Bergmann Gábor - * + * */ -public class Equality extends - DeferredPConstraint { - - private PVariable who; - private PVariable withWhom; - - /** - * @param buildable - * @param affectedVariables - */ - public Equality(PSystem pSystem, - PVariable who, PVariable withWhom) { - super(pSystem, buildSet(who, withWhom)); - this.who = who; - this.withWhom = withWhom; - } - - - private static Set buildSet(PVariable who, PVariable withWhom) { - Set set = new HashSet(); - set.add(who); - set.add(withWhom); - return set; - } - - public boolean isMoot() { - return who.equals(withWhom); - } - - @Override - public void doReplaceVariable(PVariable obsolete, PVariable replacement) { - if (obsolete.equals(who)) who = replacement; - if (obsolete.equals(withWhom)) withWhom = replacement; - } - - @Override - protected String toStringRest() { - return who.getName() + "=" + withWhom.getName(); - } - - - /** - * @return the who - */ - public PVariable getWho() { - return who; - } - - /** - * @return the withWhom - */ - public PVariable getWithWhom() { - return withWhom; - } - - @Override - public Set getDeducedVariables() { - return Collections.emptySet(); - } - - @Override - public boolean isReadyAt(Stub stub) { - return isMoot() || - stub.getVariablesIndex().containsKey(who) && stub.getVariablesIndex().containsKey(withWhom); - // will be replaced by || if copierNode is available; - // until then, LayoutHelper.unifyVariablesAlongEqualities(PSystem) is recommended. - } - - @Override - protected Stub doCheckOn(Stub stub) throws RetePatternBuildException { - if (isMoot()) return stub; - - Integer index1 = stub.getVariablesIndex().get(who); - Integer index2 = stub.getVariablesIndex().get(withWhom); - if (index1 != null && index2 != null) { - if (index1.equals(index2)) return stub; - else return buildable.buildEqualityChecker(stub, new int[]{index1, index2}); - } - else if (index1 == null) { - // TODO build copierNode here - } - return null; - } - - @Override - public void raiseForeverDeferredError(Stub stub) throws RetePatternBuildException { - String[] args = {who.toString(), withWhom.toString()}; - String msg = "Cannot express equality of variables {1} and {2} if neither of them is deducable."; - String shortMsg = "Equality between undeducible variables."; - throw new RetePatternBuildException(msg, args, shortMsg, null); - } +public class Equality extends DeferredPConstraint { + + private PVariable who; + private PVariable withWhom; + + /** + * @param buildable + * @param affectedVariables + */ + public Equality(PSystem pSystem, PVariable who, PVariable withWhom) { + super(pSystem, buildSet(who, withWhom)); + this.who = who; + this.withWhom = withWhom; + } + + private static Set buildSet(PVariable who, PVariable withWhom) { + Set set = new HashSet(); + set.add(who); + set.add(withWhom); + return set; + } + + public boolean isMoot() { + return who.equals(withWhom); + } + + @Override + public void doReplaceVariable(PVariable obsolete, PVariable replacement) { + if (obsolete.equals(who)) + who = replacement; + if (obsolete.equals(withWhom)) + withWhom = replacement; + } + + @Override + protected String toStringRest() { + return who.getName() + "=" + withWhom.getName(); + } + + /** + * @return the who + */ + public PVariable getWho() { + return who; + } + + /** + * @return the withWhom + */ + public PVariable getWithWhom() { + return withWhom; + } + + @Override + public Set getDeducedVariables() { + return Collections.emptySet(); + } + + @Override + public boolean isReadyAt(Stub stub) { + return isMoot() || stub.getVariablesIndex().containsKey(who) && stub.getVariablesIndex().containsKey(withWhom); + // will be replaced by || if copierNode is available; + // until then, LayoutHelper.unifyVariablesAlongEqualities(PSystem) is + // recommended. + } + + @Override + protected Stub doCheckOn(Stub stub) throws RetePatternBuildException { + if (isMoot()) + return stub; + + Integer index1 = stub.getVariablesIndex().get(who); + Integer index2 = stub.getVariablesIndex().get(withWhom); + if (index1 != null && index2 != null) { + if (index1.equals(index2)) + return stub; + else + return buildable.buildEqualityChecker(stub, new int[] { index1, index2 }); + } else if (index1 == null) { + // TODO build copierNode here + } + return null; + } + + @Override + public void raiseForeverDeferredError(Stub stub) throws RetePatternBuildException { + String[] args = { who.toString(), withWhom.toString() }; + String msg = "Cannot express equality of variables {1} and {2} if neither of them is deducable."; + String shortMsg = "Equality between undeducible variables."; + throw new RetePatternBuildException(msg, args, shortMsg, null); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicdeferred/ExportedParameter.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicdeferred/ExportedParameter.java index 41e117e0..7b8506de 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicdeferred/ExportedParameter.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicdeferred/ExportedParameter.java @@ -22,94 +22,88 @@ /** * @author Bergmann Gábor - * + * */ -public class ExportedParameter extends - VariableDeferredPConstraint -{ - PVariable parameterVariable; - Object parameterName; - - - /** - * @param buildable - * @param parameterVariable - */ - public ExportedParameter( - PSystem pSystem, - PVariable parameterVariable, - String parameterName) { - super(pSystem, Collections.singleton(parameterVariable)); - this.parameterVariable = parameterVariable; - this.parameterName = parameterVariable.getName(); - //parameterVariable.setExportedParameter(true); - } - - @Override - public void doReplaceVariable(PVariable obsolete, PVariable replacement) { - if (obsolete.equals(parameterVariable)) parameterVariable = replacement; - } - - @Override - protected String toStringRest() { - Object varName = parameterVariable.getName(); - return parameterName.equals(varName) ? - parameterName.toString() : - parameterName + "(" + varName + ")" ; - } - - @Override - public Set getDeducedVariables() { - return Collections.emptySet(); - } - - /** - * @return the parameterName - */ - public Object getParameterName() { - return parameterName; - } - - /** - * @return the parameterVariable - */ - public PVariable getParameterVariable() { - return parameterVariable; - } - - @Override - protected Set getDeferringVariables() { - return Collections.singleton(parameterVariable); - } - - @Override - protected Stub doCheckOn(Stub stub) throws RetePatternBuildException { - return stub; - } - - @Override - public void checkSanity() throws RetePatternBuildException { - super.checkSanity(); - if (!parameterVariable.isDeducable()){ - String[] args = {parameterName.toString()}; - String msg = "Impossible to match pattern: " - + "exported pattern variable {1} can not be determined based on the pattern constraints. " - + "HINT: certain constructs (e.g. negative patterns or check expressions) cannot output symbolic parameters."; - String shortMsg = "Could not deduce value of parameter"; - throw new RetePatternBuildException(msg, args, shortMsg, null); - } - - } - - @Override - public void raiseForeverDeferredError(Stub stub) throws RetePatternBuildException - { - String[] args = {parameterName.toString()}; - String msg = "Pattern Graph Search terminated incompletely: " - + "exported pattern variable {1} could not be determined based on the pattern constraints. " - + "HINT: certain constructs (e.g. negative patterns or check expressions) cannot output symbolic parameters."; - String shortMsg = "Could not deduce value of parameter"; - throw new RetePatternBuildException(msg, args, shortMsg, null); - } - +public class ExportedParameter extends + VariableDeferredPConstraint { + PVariable parameterVariable; + Object parameterName; + + /** + * @param buildable + * @param parameterVariable + */ + public ExportedParameter(PSystem pSystem, PVariable parameterVariable, + String parameterName) { + super(pSystem, Collections.singleton(parameterVariable)); + this.parameterVariable = parameterVariable; + this.parameterName = parameterVariable.getName(); + // parameterVariable.setExportedParameter(true); + } + + @Override + public void doReplaceVariable(PVariable obsolete, PVariable replacement) { + if (obsolete.equals(parameterVariable)) + parameterVariable = replacement; + } + + @Override + protected String toStringRest() { + Object varName = parameterVariable.getName(); + return parameterName.equals(varName) ? parameterName.toString() : parameterName + "(" + varName + ")"; + } + + @Override + public Set getDeducedVariables() { + return Collections.emptySet(); + } + + /** + * @return the parameterName + */ + public Object getParameterName() { + return parameterName; + } + + /** + * @return the parameterVariable + */ + public PVariable getParameterVariable() { + return parameterVariable; + } + + @Override + protected Set getDeferringVariables() { + return Collections.singleton(parameterVariable); + } + + @Override + protected Stub doCheckOn(Stub stub) throws RetePatternBuildException { + return stub; + } + + @Override + public void checkSanity() throws RetePatternBuildException { + super.checkSanity(); + if (!parameterVariable.isDeducable()) { + String[] args = { parameterName.toString() }; + String msg = "Impossible to match pattern: " + + "exported pattern variable {1} can not be determined based on the pattern constraints. " + + "HINT: certain constructs (e.g. negative patterns or check expressions) cannot output symbolic parameters."; + String shortMsg = "Could not deduce value of parameter"; + throw new RetePatternBuildException(msg, args, shortMsg, null); + } + + } + + @Override + public void raiseForeverDeferredError(Stub stub) throws RetePatternBuildException { + String[] args = { parameterName.toString() }; + String msg = "Pattern Graph Search terminated incompletely: " + + "exported pattern variable {1} could not be determined based on the pattern constraints. " + + "HINT: certain constructs (e.g. negative patterns or check expressions) cannot output symbolic parameters."; + String shortMsg = "Could not deduce value of parameter"; + throw new RetePatternBuildException(msg, args, shortMsg, null); + } + } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicdeferred/Inequality.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicdeferred/Inequality.java index 079893b4..48688805 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicdeferred/Inequality.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicdeferred/Inequality.java @@ -25,136 +25,136 @@ /** * @author Bergmann Gábor - * + * */ -public class Inequality - extends VariableDeferredPConstraint -// implements IFoldablePConstraint +public class Inequality extends + VariableDeferredPConstraint +// implements IFoldablePConstraint { - private PVariable who; - private PVariable withWhom; -// private IFoldablePConstraint incorporator; - - /** - * The inequality constraint is weak if it can be ignored when who is the same as withWhom, or if any if them is undeducible. - */ - private boolean weak; - - - public Inequality( - PSystem pSystem, - PVariable who, PVariable withWhom) - { - this(pSystem, who, withWhom, false); - } - - public Inequality( - PSystem pSystem, - PVariable who, PVariable withWhom, - boolean weak) - { - super(pSystem, new HashSet(Arrays.asList(new PVariable[]{who, withWhom}))); - // this(pSystem, who, Collections.singleton(withWhom)); - this.who = who; - this.withWhom = withWhom; - this.weak = weak; - } - -// private Inequality( -// PSystem pSystem, -// PVariable subject, Set inequals) -// { -// super(pSystem, include(inequals, subject)); -// this.subject = subject; -// this.inequals = inequals; -// } - -// private static HashSet include(Set inequals, PVariable subject) { -// HashSet hashSet = new HashSet(inequals); -// hashSet.add(subject); -// return hashSet; -// } - - - @Override - protected Set getDeferringVariables() { - return getAffectedVariables(); - } - - @Override - protected Stub doCheckOn(Stub stub) throws RetePatternBuildException { - Map variablesIndex = stub.getVariablesIndex(); - return buildable.buildInjectivityChecker(stub, variablesIndex.get(who), new int[]{variablesIndex.get(withWhom)}); - } - -// private static int[] mapIndices(Map variablesIndex, Set keys) { -// int[] result = new int[keys.size()]; -// int k = 0; -// for (PVariable key : keys) { -// result[k++] = variablesIndex.get(key); -// } -// return result; -// } - -// @Override -// public IFoldablePConstraint getIncorporator() { -// return incorporator; -// } -// -// @Override -// public void registerIncorporatationInto(IFoldablePConstraint incorporator) { -// this.incorporator = incorporator; -// } -// -// @Override -// public boolean incorporate(IFoldablePConstraint other) { -// if (other instanceof Inequality) { -// Inequality other2 = (Inequality) other; -// if (subject.equals(other2.subject)) { -// Set newInequals = new HashSet(inequals); -// newInequals.addAll(other2.inequals); -// return new Inequality(buildable, subject, newInequals); -// } -// } else return false; -// } - - @Override - protected String toStringRest() { - return who.toString() + (isWeak() ? "!=?" : "!=") + withWhom.toString(); - } - - @Override - public void doReplaceVariable(PVariable obsolete, PVariable replacement) { - if (obsolete.equals(who)) who = replacement; - if (obsolete.equals(withWhom)) withWhom = replacement; - } - - @Override - public Set getDeducedVariables() { - return Collections.emptySet(); - } - - /** - * The inequality constraint is weak if it can be ignored when who is the same as withWhom, or if any if them is undeducible. - * @return the weak - */ - public boolean isWeak() { - return weak; - } - - /** - * A weak inequality constraint is eliminable if who is the same as withWhom, or if any if them is undeducible. - */ - public boolean isEliminable() { - return isWeak() && (who.equals(withWhom) || !who.isDeducable() || !withWhom.isDeducable()); - } - - /** - * Eliminates a weak inequality constraint if it can be ignored when who is the same as withWhom, or if any if them is undeducible. - */ - public void eliminateWeak() { - if (isEliminable()) delete(); - } - + private PVariable who; + private PVariable withWhom; + // private IFoldablePConstraint incorporator; + + /** + * The inequality constraint is weak if it can be ignored when who is the same as withWhom, or if any if them is + * undeducible. + */ + private boolean weak; + + public Inequality(PSystem pSystem, PVariable who, PVariable withWhom) { + this(pSystem, who, withWhom, false); + } + + public Inequality(PSystem pSystem, PVariable who, PVariable withWhom, + boolean weak) { + super(pSystem, new HashSet(Arrays.asList(new PVariable[] { who, withWhom }))); + // this(pSystem, who, Collections.singleton(withWhom)); + this.who = who; + this.withWhom = withWhom; + this.weak = weak; + } + + // private Inequality( + // PSystem pSystem, + // PVariable subject, Set inequals) + // { + // super(pSystem, include(inequals, subject)); + // this.subject = subject; + // this.inequals = inequals; + // } + + // private static HashSet include(Set inequals, PVariable subject) { + // HashSet hashSet = new HashSet(inequals); + // hashSet.add(subject); + // return hashSet; + // } + + @Override + protected Set getDeferringVariables() { + return getAffectedVariables(); + } + + @Override + protected Stub doCheckOn(Stub stub) throws RetePatternBuildException { + Map variablesIndex = stub.getVariablesIndex(); + return buildable.buildInjectivityChecker(stub, variablesIndex.get(who), + new int[] { variablesIndex.get(withWhom) }); + } + + // private static int[] mapIndices(Map variablesIndex, Set keys) { + // int[] result = new int[keys.size()]; + // int k = 0; + // for (PVariable key : keys) { + // result[k++] = variablesIndex.get(key); + // } + // return result; + // } + + // @Override + // public IFoldablePConstraint getIncorporator() { + // return incorporator; + // } + // + // @Override + // public void registerIncorporatationInto(IFoldablePConstraint incorporator) { + // this.incorporator = incorporator; + // } + // + // @Override + // public boolean incorporate(IFoldablePConstraint other) { + // if (other instanceof Inequality) { + // Inequality other2 = (Inequality) other; + // if (subject.equals(other2.subject)) { + // Set newInequals = new HashSet(inequals); + // newInequals.addAll(other2.inequals); + // return new Inequality(buildable, subject, newInequals); + // } + // } else return false; + // } + + @Override + protected String toStringRest() { + return who.toString() + (isWeak() ? "!=?" : "!=") + withWhom.toString(); + } + + @Override + public void doReplaceVariable(PVariable obsolete, PVariable replacement) { + if (obsolete.equals(who)) + who = replacement; + if (obsolete.equals(withWhom)) + withWhom = replacement; + } + + @Override + public Set getDeducedVariables() { + return Collections.emptySet(); + } + + /** + * The inequality constraint is weak if it can be ignored when who is the same as withWhom, or if any if them is + * undeducible. + * + * @return the weak + */ + public boolean isWeak() { + return weak; + } + + /** + * A weak inequality constraint is eliminable if who is the same as withWhom, or if any if them is undeducible. + */ + public boolean isEliminable() { + return isWeak() && (who.equals(withWhom) || !who.isDeducable() || !withWhom.isDeducable()); + } + + /** + * Eliminates a weak inequality constraint if it can be ignored when who is the same as withWhom, or if any if them + * is undeducible. + */ + public void eliminateWeak() { + if (isEliminable()) + delete(); + } + } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicdeferred/NegativePatternCall.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicdeferred/NegativePatternCall.java index 43ad3294..64174a1e 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicdeferred/NegativePatternCall.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicdeferred/NegativePatternCall.java @@ -23,53 +23,48 @@ /** * @author Bergmann Gábor - * + * */ public class NegativePatternCall extends - PatternCallBasedDeferred { - - /** - * @param buildable - * @param affectedVariables - */ - public NegativePatternCall( - PSystem pSystem, - Tuple actualParametersTuple, PatternDescription pattern) { - super(pSystem, actualParametersTuple, pattern); - } + PatternCallBasedDeferred { + + /** + * @param buildable + * @param affectedVariables + */ + public NegativePatternCall(PSystem pSystem, Tuple actualParametersTuple, + PatternDescription pattern) { + super(pSystem, actualParametersTuple, pattern); + } - @Override - public Set getDeducedVariables() { - return Collections.emptySet(); - } + @Override + public Set getDeducedVariables() { + return Collections.emptySet(); + } - /** - * @return all variables that may potentially be quantified they are not used anywhere else - */ - @Override - protected Set getCandidateQuantifiedVariables() { - return getAffectedVariables(); - } + /** + * @return all variables that may potentially be quantified they are not used anywhere else + */ + @Override + protected Set getCandidateQuantifiedVariables() { + return getAffectedVariables(); + } - @Override - protected Stub doCheckOn(Stub stub) throws RetePatternBuildException { - Stub sideStub = getSideStub(); - BuildHelper.JoinHelper joinHelper = getJoinHelper(stub, sideStub); - return buildable.buildBetaNode( - stub, sideStub, - joinHelper.getPrimaryMask(), - joinHelper.getSecondaryMask(), - joinHelper.getComplementerMask(), - true); - } + @Override + protected Stub doCheckOn(Stub stub) throws RetePatternBuildException { + Stub sideStub = getSideStub(); + BuildHelper.JoinHelper joinHelper = getJoinHelper(stub, sideStub); + return buildable.buildBetaNode(stub, sideStub, joinHelper.getPrimaryMask(), joinHelper.getSecondaryMask(), + joinHelper.getComplementerMask(), true); + } - @Override - protected void doDoReplaceVariables(PVariable obsolete, PVariable replacement) { - } - @Override - protected String toStringRest() { - return "!" + pSystem.getContext().printPattern(pattern) + "@" + actualParametersTuple.toString(); - } + @Override + protected void doDoReplaceVariables(PVariable obsolete, PVariable replacement) { + } + @Override + protected String toStringRest() { + return "!" + pSystem.getContext().printPattern(pattern) + "@" + actualParametersTuple.toString(); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicdeferred/PatternCallBasedDeferred.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicdeferred/PatternCallBasedDeferred.java index 9d537f77..c30af19a 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicdeferred/PatternCallBasedDeferred.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicdeferred/PatternCallBasedDeferred.java @@ -26,113 +26,105 @@ /** * @author Bergmann Gábor - * + * * @param * @param */ -public abstract class PatternCallBasedDeferred - extends VariableDeferredPConstraint { - - protected Tuple actualParametersTuple; - - protected abstract void doDoReplaceVariables(PVariable obsolete, PVariable replacement); - - protected abstract Set getCandidateQuantifiedVariables(); - - protected PatternDescription pattern; - private Set deferringVariables; - - /** - * @param buildable - * @param additionalAffectedVariables - */ - public PatternCallBasedDeferred( - PSystem pSystem, - Tuple actualParametersTuple, PatternDescription pattern, - Set additionalAffectedVariables) { - super(pSystem, union(actualParametersTuple.getDistinctElements(), additionalAffectedVariables)); - this.actualParametersTuple = actualParametersTuple; - this.pattern = pattern; - } - public PatternCallBasedDeferred( - PSystem pSystem, - Tuple actualParametersTuple, PatternDescription pattern) { - this(pSystem, actualParametersTuple, pattern, Collections.emptySet()); - } - - private static Set union( - Set a, - Set b) { - Set result = new HashSet(); - result.addAll(a); - result.addAll(b); - return result; - } - - @Override - protected Set getDeferringVariables() { - if (deferringVariables == null) { - deferringVariables = new HashSet(); - for (PVariable var : getCandidateQuantifiedVariables()) { - if (var.isDeducable()) deferringVariables.add(var); - } - } - return deferringVariables; - } - - @Override - public void checkSanity() throws RetePatternBuildException { - super.checkSanity(); - for (Object obj : this.actualParametersTuple.getDistinctElements()) { - PVariable var = (PVariable) obj; - if (!getDeferringVariables().contains(var)) { - // so this is a free variable of the NAC / aggregation? - for (PConstraint pConstraint : var.getReferringConstraints()) { - if ( - pConstraint!=this && - !( - pConstraint instanceof Equality && - ((Equality)pConstraint).isMoot() - ) - ) - throw new RetePatternBuildException( - "Variable {1} of constraint {2} is not a positively determined part of the pattern, yet it is also affected by {3}.", - new String[]{var.toString(), this.toString(), pConstraint.toString()}, - "Read-only variable can not be deduced", null); - } - } - } - - } - - /** - * @param stub - * @param sideStub - * @return - */ - protected BuildHelper.JoinHelper getJoinHelper(Stub stub, Stub sideStub) { - BuildHelper.JoinHelper joinHelper = new BuildHelper.JoinHelper(stub, sideStub); - return joinHelper; - } - - /** - * @return - * @throws RetePatternBuildException - */ - protected Stub getSideStub() throws RetePatternBuildException { - Stub sideStub = buildable.patternCallStub(actualParametersTuple, pattern); - sideStub = BuildHelper.enforceVariableCoincidences(buildable, sideStub); - return sideStub; - } - - @Override - protected void doReplaceVariable(PVariable obsolete, PVariable replacement) { - if (deferringVariables != null) { - throw new IllegalStateException("Cannot replace variables on " + this + - " when deferring variables have already been identified."); - } - actualParametersTuple.replaceAll(obsolete, replacement); - doDoReplaceVariables(obsolete, replacement); - } +public abstract class PatternCallBasedDeferred extends + VariableDeferredPConstraint { + + protected Tuple actualParametersTuple; + + protected abstract void doDoReplaceVariables(PVariable obsolete, PVariable replacement); + + protected abstract Set getCandidateQuantifiedVariables(); + + protected PatternDescription pattern; + private Set deferringVariables; + + /** + * @param buildable + * @param additionalAffectedVariables + */ + public PatternCallBasedDeferred(PSystem pSystem, Tuple actualParametersTuple, + PatternDescription pattern, Set additionalAffectedVariables) { + super(pSystem, union(actualParametersTuple. getDistinctElements(), additionalAffectedVariables)); + this.actualParametersTuple = actualParametersTuple; + this.pattern = pattern; + } + + public PatternCallBasedDeferred(PSystem pSystem, Tuple actualParametersTuple, + PatternDescription pattern) { + this(pSystem, actualParametersTuple, pattern, Collections. emptySet()); + } + + private static Set union(Set a, Set b) { + Set result = new HashSet(); + result.addAll(a); + result.addAll(b); + return result; + } + + @Override + protected Set getDeferringVariables() { + if (deferringVariables == null) { + deferringVariables = new HashSet(); + for (PVariable var : getCandidateQuantifiedVariables()) { + if (var.isDeducable()) + deferringVariables.add(var); + } + } + return deferringVariables; + } + + @Override + public void checkSanity() throws RetePatternBuildException { + super.checkSanity(); + for (Object obj : this.actualParametersTuple.getDistinctElements()) { + PVariable var = (PVariable) obj; + if (!getDeferringVariables().contains(var)) { + // so this is a free variable of the NAC / aggregation? + for (PConstraint pConstraint : var.getReferringConstraints()) { + if (pConstraint != this + && !(pConstraint instanceof Equality && ((Equality) pConstraint).isMoot())) + throw new RetePatternBuildException( + "Variable {1} of constraint {2} is not a positively determined part of the pattern, yet it is also affected by {3}.", + new String[] { var.toString(), this.toString(), pConstraint.toString() }, + "Read-only variable can not be deduced", null); + } + } + } + + } + + /** + * @param stub + * @param sideStub + * @return + */ + protected BuildHelper.JoinHelper getJoinHelper(Stub stub, Stub sideStub) { + BuildHelper.JoinHelper joinHelper = new BuildHelper.JoinHelper(stub, sideStub); + return joinHelper; + } + + /** + * @return + * @throws RetePatternBuildException + */ + protected Stub getSideStub() throws RetePatternBuildException { + Stub sideStub = buildable.patternCallStub(actualParametersTuple, pattern); + sideStub = BuildHelper.enforceVariableCoincidences(buildable, sideStub); + return sideStub; + } + + @Override + protected void doReplaceVariable(PVariable obsolete, PVariable replacement) { + if (deferringVariables != null) { + throw new IllegalStateException("Cannot replace variables on " + this + + " when deferring variables have already been identified."); + } + actualParametersTuple.replaceAll(obsolete, replacement); + doDoReplaceVariables(obsolete, replacement); + } } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicdeferred/PatternMatchCounter.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicdeferred/PatternMatchCounter.java index 16121bdd..3faafe71 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicdeferred/PatternMatchCounter.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicdeferred/PatternMatchCounter.java @@ -24,70 +24,62 @@ /** * @author Bergmann Gábor - * + * */ public class PatternMatchCounter extends - PatternCallBasedDeferred { + PatternCallBasedDeferred { + + private PVariable resultVariable; - private PVariable resultVariable; + /** + * @param buildable + * @param affectedVariables + */ + public PatternMatchCounter(PSystem pSystem, Tuple actualParametersTuple, + PatternDescription pattern, PVariable resultVariable) { + super(pSystem, actualParametersTuple, pattern, Collections.singleton(resultVariable)); + this.resultVariable = resultVariable; + } - /** - * @param buildable - * @param affectedVariables - */ - public PatternMatchCounter( - PSystem pSystem, - Tuple actualParametersTuple, PatternDescription pattern, PVariable resultVariable) { - super(pSystem, actualParametersTuple, pattern, Collections.singleton(resultVariable)); - this.resultVariable = resultVariable; - } + @Override + public Set getDeducedVariables() { + return Collections.singleton(resultVariable); + } - @Override - public Set getDeducedVariables() { - return Collections.singleton(resultVariable); - } + @Override + protected void doDoReplaceVariables(PVariable obsolete, PVariable replacement) { + if (resultVariable.equals(obsolete)) + resultVariable = replacement; + } - @Override - protected void doDoReplaceVariables(PVariable obsolete, PVariable replacement) { - if (resultVariable.equals(obsolete)) resultVariable = replacement; - } + @Override + protected Set getCandidateQuantifiedVariables() { + return actualParametersTuple. getDistinctElements(); + } - @Override - protected Set getCandidateQuantifiedVariables() { - return actualParametersTuple.getDistinctElements(); - } + @Override + protected Stub doCheckOn(Stub stub) throws RetePatternBuildException { + Stub sideStub = getSideStub(); + BuildHelper.JoinHelper joinHelper = getJoinHelper(stub, sideStub); + Integer resultPositionLeft = stub.getVariablesIndex().get(resultVariable); + TupleMask primaryMask = joinHelper.getPrimaryMask(); + TupleMask secondaryMask = joinHelper.getSecondaryMask(); + if (resultPositionLeft == null) { + return buildable.buildCounterBetaNode(stub, sideStub, primaryMask, secondaryMask, + joinHelper.getComplementerMask(), resultVariable); + } else { + int resultPositionFinal = primaryMask.indices.length; // append to the last position + primaryMask = TupleMask.append(primaryMask, + TupleMask.selectSingle(resultPositionLeft, primaryMask.sourceWidth)); + return buildable.buildCountCheckBetaNode(stub, sideStub, primaryMask, secondaryMask, resultPositionFinal); + } - @Override - protected Stub doCheckOn(Stub stub) throws RetePatternBuildException { - Stub sideStub = getSideStub(); - BuildHelper.JoinHelper joinHelper = getJoinHelper(stub, sideStub); - Integer resultPositionLeft = stub.getVariablesIndex().get(resultVariable); - TupleMask primaryMask = joinHelper.getPrimaryMask(); - TupleMask secondaryMask = joinHelper.getSecondaryMask(); - if (resultPositionLeft == null) { - return buildable.buildCounterBetaNode( - stub, - sideStub, - primaryMask, - secondaryMask, - joinHelper.getComplementerMask(), - resultVariable); - } else { - int resultPositionFinal = primaryMask.indices.length; // append to the last position - primaryMask = TupleMask.append(primaryMask, TupleMask.selectSingle(resultPositionLeft, primaryMask.sourceWidth)); - return buildable.buildCountCheckBetaNode( - stub, - sideStub, - primaryMask, - secondaryMask, - resultPositionFinal); - } - - } + } - @Override - protected String toStringRest() { - return pSystem.getContext().printPattern(pattern) + "@" + actualParametersTuple.toString() + "->" + resultVariable.toString(); - } + @Override + protected String toStringRest() { + return pSystem.getContext().printPattern(pattern) + "@" + actualParametersTuple.toString() + "->" + + resultVariable.toString(); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/BinaryTransitiveClosure.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/BinaryTransitiveClosure.java index c84fa012..1a61f53b 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/BinaryTransitiveClosure.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/BinaryTransitiveClosure.java @@ -19,32 +19,31 @@ /** * @author Bergmann Gábor - * - * For a binary base pattern, computes the irreflexive transitive closure (base)+ + * + * For a binary base pattern, computes the irreflexive transitive closure (base)+ */ -public class BinaryTransitiveClosure - extends KeyedEnumerablePConstraint { +public class BinaryTransitiveClosure extends + KeyedEnumerablePConstraint { - /** - * @param pSystem - * @param variablesTuple - * @param pattern - */ - public BinaryTransitiveClosure( - PSystem pSystem, - Tuple variablesTuple, PatternDescription pattern) { - super(pSystem, variablesTuple, pattern); - } + /** + * @param pSystem + * @param variablesTuple + * @param pattern + */ + public BinaryTransitiveClosure(PSystem pSystem, Tuple variablesTuple, + PatternDescription pattern) { + super(pSystem, variablesTuple, pattern); + } - @Override - public Stub doCreateStub() throws RetePatternBuildException { - Stub patternProduction = buildable.patternCallStub(variablesTuple, supplierKey); - return buildable.buildTransitiveClosure(patternProduction); - } + @Override + public Stub doCreateStub() throws RetePatternBuildException { + Stub patternProduction = buildable.patternCallStub(variablesTuple, supplierKey); + return buildable.buildTransitiveClosure(patternProduction); + } - @Override - protected String keyToString() { - return pSystem.getContext().printType(supplierKey)+"+"; - } + @Override + protected String keyToString() { + return pSystem.getContext().printType(supplierKey) + "+"; + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/ConstantValue.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/ConstantValue.java index 6bcc49ee..17b112a4 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/ConstantValue.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/ConstantValue.java @@ -20,32 +20,28 @@ /** * @author Bergmann Gábor - * + * */ -public class ConstantValue - extends - KeyedEnumerablePConstraint { +public class ConstantValue extends + KeyedEnumerablePConstraint { - /** - * @param buildable - * @param variablesTuple - * @param supplierKey - */ - public ConstantValue( - PSystem pSystem, - PVariable variable, Object value) - { - super(pSystem, new FlatTuple(variable), value); - } + /** + * @param buildable + * @param variablesTuple + * @param supplierKey + */ + public ConstantValue(PSystem pSystem, PVariable variable, Object value) { + super(pSystem, new FlatTuple(variable), value); + } - @Override - public Stub doCreateStub() throws RetePatternBuildException { - return buildable.buildStartStub(new Object[]{supplierKey}, this.variablesTuple.getElements()); - } + @Override + public Stub doCreateStub() throws RetePatternBuildException { + return buildable.buildStartStub(new Object[] { supplierKey }, this.variablesTuple.getElements()); + } - @Override - protected String keyToString() { - return supplierKey.toString(); - } + @Override + protected String keyToString() { + return supplierKey.toString(); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/Containment.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/Containment.java index f8c596e3..e4fc2545 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/Containment.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/Containment.java @@ -17,37 +17,32 @@ /** * @author Bergmann Gábor - * + * */ public class Containment extends CoreModelRelationship { - /** - * @param variablesTuple - */ - public Containment( - PSystem pSystem, - PVariable parent, - PVariable child, - boolean transitive) - { - super(pSystem, parent, child, transitive); - } + /** + * @param variablesTuple + */ + public Containment(PSystem pSystem, PVariable parent, PVariable child, + boolean transitive) { + super(pSystem, parent, child, transitive); + } + + /** + * @return + */ + @Override + protected Stub doCreateDirectStub() { + return buildable.containmentDirectStub(variablesTuple); + } - /** - * @return - */ - @Override - protected Stub doCreateDirectStub() { - return buildable.containmentDirectStub(variablesTuple); - } + /** + * @return + */ + @Override + protected Stub doCreateTransitiveStub() { + return buildable.containmentTransitiveStub(variablesTuple); + } - /** - * @return - */ - @Override - protected Stub doCreateTransitiveStub() { - return buildable.containmentTransitiveStub(variablesTuple); - } - - } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/CoreModelRelationship.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/CoreModelRelationship.java index c2f385c0..8e4a1e6b 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/CoreModelRelationship.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/CoreModelRelationship.java @@ -20,50 +20,44 @@ /** * @author Bergmann Gábor - * + * * @param * @param */ -public abstract class CoreModelRelationship - extends EnumerablePConstraint { - - protected boolean transitive; - - protected abstract Stub doCreateTransitiveStub(); - - protected abstract Stub doCreateDirectStub(); - - /** - * @param buildable - * @param variablesTuple - */ - public CoreModelRelationship( - PSystem pSystem, - PVariable parent, - PVariable child, - boolean transitive) - { - super(pSystem, new FlatTuple(parent, child)); - this.transitive = transitive; - } - - @Override - public Stub doCreateStub() throws RetePatternBuildException { - return isTransitive() ? - doCreateTransitiveStub() : - doCreateDirectStub(); - } - - @Override - protected String toStringRestRest() { - return transitive ? "transitive" : "direct"; - } - - /** - * @return the transitive - */ - public boolean isTransitive() { - return transitive; - } +public abstract class CoreModelRelationship extends + EnumerablePConstraint { + + protected boolean transitive; + + protected abstract Stub doCreateTransitiveStub(); + + protected abstract Stub doCreateDirectStub(); + + /** + * @param buildable + * @param variablesTuple + */ + public CoreModelRelationship(PSystem pSystem, PVariable parent, PVariable child, + boolean transitive) { + super(pSystem, new FlatTuple(parent, child)); + this.transitive = transitive; + } + + @Override + public Stub doCreateStub() throws RetePatternBuildException { + return isTransitive() ? doCreateTransitiveStub() : doCreateDirectStub(); + } + + @Override + protected String toStringRestRest() { + return transitive ? "transitive" : "direct"; + } + + /** + * @return the transitive + */ + public boolean isTransitive() { + return transitive; + } } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/Generalization.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/Generalization.java index 38fae683..eba381e1 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/Generalization.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/Generalization.java @@ -17,31 +17,30 @@ /** * @author Bergmann Gábor - * + * */ public class Generalization extends - CoreModelRelationship { + CoreModelRelationship { - /** - * @param buildable - * @param parent - * @param child - * @param transitive - */ - public Generalization( - PSystem pSystem, - PVariable parent, PVariable child, boolean transitive) { - super(pSystem, parent, child, transitive); - } + /** + * @param buildable + * @param parent + * @param child + * @param transitive + */ + public Generalization(PSystem pSystem, PVariable parent, PVariable child, + boolean transitive) { + super(pSystem, parent, child, transitive); + } - @Override - protected Stub doCreateTransitiveStub() { - return buildable.generalizationTransitiveStub(variablesTuple); - } + @Override + protected Stub doCreateTransitiveStub() { + return buildable.generalizationTransitiveStub(variablesTuple); + } - @Override - protected Stub doCreateDirectStub() { - return buildable.generalizationDirectStub(variablesTuple); - } + @Override + protected Stub doCreateDirectStub() { + return buildable.generalizationDirectStub(variablesTuple); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/Instantiation.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/Instantiation.java index 3e026ee0..70e76b71 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/Instantiation.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/Instantiation.java @@ -17,31 +17,30 @@ /** * @author Bergmann Gábor - * + * */ public class Instantiation extends - CoreModelRelationship { + CoreModelRelationship { - /** - * @param buildable - * @param parent - * @param child - * @param transitive - */ - public Instantiation( - PSystem pSystem, - PVariable parent, PVariable child, boolean transitive) { - super(pSystem, parent, child, transitive); - } + /** + * @param buildable + * @param parent + * @param child + * @param transitive + */ + public Instantiation(PSystem pSystem, PVariable parent, PVariable child, + boolean transitive) { + super(pSystem, parent, child, transitive); + } - @Override - protected Stub doCreateTransitiveStub() { - return buildable.instantiationTransitiveStub(variablesTuple); - } + @Override + protected Stub doCreateTransitiveStub() { + return buildable.instantiationTransitiveStub(variablesTuple); + } - @Override - protected Stub doCreateDirectStub() { - return buildable.instantiationDirectStub(variablesTuple); - } + @Override + protected Stub doCreateDirectStub() { + return buildable.instantiationDirectStub(variablesTuple); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/PositivePatternCall.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/PositivePatternCall.java index e7a28e07..a69e626f 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/PositivePatternCall.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/PositivePatternCall.java @@ -19,30 +19,28 @@ /** * @author Bergmann Gábor - * + * */ -public class PositivePatternCall - extends - KeyedEnumerablePConstraint { +public class PositivePatternCall extends + KeyedEnumerablePConstraint { - /** - * @param buildable - * @param variablesTuple - * @param pattern - */ - public PositivePatternCall( - PSystem pSystem, - Tuple variablesTuple, PatternDescription pattern) { - super(pSystem, variablesTuple, pattern); - } + /** + * @param buildable + * @param variablesTuple + * @param pattern + */ + public PositivePatternCall(PSystem pSystem, Tuple variablesTuple, + PatternDescription pattern) { + super(pSystem, variablesTuple, pattern); + } - @Override - public Stub doCreateStub() throws RetePatternBuildException { - return buildable.patternCallStub(variablesTuple, supplierKey); - } + @Override + public Stub doCreateStub() throws RetePatternBuildException { + return buildable.patternCallStub(variablesTuple, supplierKey); + } - @Override - protected String keyToString() { - return pSystem.getContext().printPattern(supplierKey); - } + @Override + protected String keyToString() { + return pSystem.getContext().printPattern(supplierKey); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/TypeBinary.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/TypeBinary.java index b964d392..7d9340d4 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/TypeBinary.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/TypeBinary.java @@ -21,43 +21,40 @@ /** * @author Bergmann Gábor - * + * */ -public class TypeBinary - extends KeyedEnumerablePConstraint - implements ITypeInfoProviderConstraint -{ - private final IPatternMatcherContext context; - - /** - * @param buildable - * @param variablesTuple - * @param typeKey - */ - public TypeBinary( - PSystem pSystem, - IPatternMatcherContext context, - PVariable source, PVariable target, - Object typeKey) { - super(pSystem, new FlatTuple(source, target), typeKey); - this.context = context; - } - - @Override - public Stub doCreateStub() { - return buildable.binaryEdgeTypeStub(variablesTuple, supplierKey); - } - - @Override - public Object getTypeInfo(PVariable variable) { - if (variable.equals(variablesTuple.get(0))) return context.binaryEdgeSourceType(supplierKey); - if (variable.equals(variablesTuple.get(1))) return context.binaryEdgeTargetType(supplierKey); - return ITypeInfoProviderConstraint.TypeInfoSpecials.NO_TYPE_INFO_PROVIDED; - } - - @Override - protected String keyToString() { - return pSystem.getContext().printType(supplierKey); - } - +public class TypeBinary extends + KeyedEnumerablePConstraint implements ITypeInfoProviderConstraint { + private final IPatternMatcherContext context; + + /** + * @param buildable + * @param variablesTuple + * @param typeKey + */ + public TypeBinary(PSystem pSystem, + IPatternMatcherContext context, PVariable source, PVariable target, Object typeKey) { + super(pSystem, new FlatTuple(source, target), typeKey); + this.context = context; + } + + @Override + public Stub doCreateStub() { + return buildable.binaryEdgeTypeStub(variablesTuple, supplierKey); + } + + @Override + public Object getTypeInfo(PVariable variable) { + if (variable.equals(variablesTuple.get(0))) + return context.binaryEdgeSourceType(supplierKey); + if (variable.equals(variablesTuple.get(1))) + return context.binaryEdgeTargetType(supplierKey); + return ITypeInfoProviderConstraint.TypeInfoSpecials.NO_TYPE_INFO_PROVIDED; + } + + @Override + protected String keyToString() { + return pSystem.getContext().printType(supplierKey); + } + } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/TypeTernary.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/TypeTernary.java index 5aa04639..727678a5 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/TypeTernary.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/TypeTernary.java @@ -21,44 +21,44 @@ /** * @author Bergmann Gábor - * + * */ -public class TypeTernary - extends KeyedEnumerablePConstraint - implements ITypeInfoProviderConstraint -{ - private final IPatternMatcherContext context; +public class TypeTernary extends + KeyedEnumerablePConstraint implements ITypeInfoProviderConstraint { + private final IPatternMatcherContext context; - /** - * @param buildable - * @param variablesTuple - * @param supplierKey type info - */ - public TypeTernary( - PSystem pSystem, - IPatternMatcherContext context, - PVariable edge, PVariable source, PVariable target, - Object supplierKey) { - super(pSystem, new FlatTuple(edge, source, target), supplierKey); - this.context = context; - } + /** + * @param buildable + * @param variablesTuple + * @param supplierKey + * type info + */ + public TypeTernary(PSystem pSystem, + IPatternMatcherContext context, PVariable edge, PVariable source, PVariable target, + Object supplierKey) { + super(pSystem, new FlatTuple(edge, source, target), supplierKey); + this.context = context; + } - @Override - public Stub doCreateStub() { - return buildable.ternaryEdgeTypeStub(variablesTuple, supplierKey); - } + @Override + public Stub doCreateStub() { + return buildable.ternaryEdgeTypeStub(variablesTuple, supplierKey); + } - @Override - public Object getTypeInfo(PVariable variable) { - if (variable.equals(variablesTuple.get(0))) return ITypeInfoProviderConstraint.TypeInfoSpecials.wrapTernary(supplierKey); - if (variable.equals(variablesTuple.get(1))) return ITypeInfoProviderConstraint.TypeInfoSpecials.wrapAny(context.ternaryEdgeSourceType(supplierKey)); - if (variable.equals(variablesTuple.get(2))) return ITypeInfoProviderConstraint.TypeInfoSpecials.wrapAny(context.ternaryEdgeTargetType(supplierKey)); - return ITypeInfoProviderConstraint.TypeInfoSpecials.NO_TYPE_INFO_PROVIDED; - } + @Override + public Object getTypeInfo(PVariable variable) { + if (variable.equals(variablesTuple.get(0))) + return ITypeInfoProviderConstraint.TypeInfoSpecials.wrapTernary(supplierKey); + if (variable.equals(variablesTuple.get(1))) + return ITypeInfoProviderConstraint.TypeInfoSpecials.wrapAny(context.ternaryEdgeSourceType(supplierKey)); + if (variable.equals(variablesTuple.get(2))) + return ITypeInfoProviderConstraint.TypeInfoSpecials.wrapAny(context.ternaryEdgeTargetType(supplierKey)); + return ITypeInfoProviderConstraint.TypeInfoSpecials.NO_TYPE_INFO_PROVIDED; + } - @Override - protected String keyToString() { - return pSystem.getContext().printType(supplierKey); - } + @Override + protected String keyToString() { + return pSystem.getContext().printType(supplierKey); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/TypeUnary.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/TypeUnary.java index 20e082ae..a39132e9 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/TypeUnary.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/psystem/basicenumerables/TypeUnary.java @@ -20,38 +20,34 @@ /** * @author Bergmann Gábor - * + * */ -public class TypeUnary - extends KeyedEnumerablePConstraint - implements ITypeInfoProviderConstraint -{ - /** - * @param buildable - * @param variable - * @param typeKey - */ - public TypeUnary( - PSystem pSystem, - PVariable variable, Object typeKey) { - super(pSystem, new FlatTuple(variable), typeKey); - } +public class TypeUnary extends + KeyedEnumerablePConstraint implements ITypeInfoProviderConstraint { + /** + * @param buildable + * @param variable + * @param typeKey + */ + public TypeUnary(PSystem pSystem, PVariable variable, Object typeKey) { + super(pSystem, new FlatTuple(variable), typeKey); + } + + @Override + public Stub doCreateStub() { + return buildable.unaryTypeStub(variablesTuple, supplierKey); + } + + @Override + public Object getTypeInfo(PVariable variable) { + if (variable.equals(variablesTuple.get(0))) + return ITypeInfoProviderConstraint.TypeInfoSpecials.wrapUnary(supplierKey); + return ITypeInfoProviderConstraint.TypeInfoSpecials.NO_TYPE_INFO_PROVIDED; + } - @Override - public Stub doCreateStub() { - return buildable.unaryTypeStub(variablesTuple, supplierKey); - } - - @Override - public Object getTypeInfo(PVariable variable) { - if (variable.equals(variablesTuple.get(0))) - return ITypeInfoProviderConstraint.TypeInfoSpecials.wrapUnary(supplierKey); - return ITypeInfoProviderConstraint.TypeInfoSpecials.NO_TYPE_INFO_PROVIDED; - } - - @Override - protected String keyToString() { - return pSystem.getContext().printType(supplierKey); - } + @Override + protected String keyToString() { + return pSystem.getContext().printType(supplierKey); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/quasitree/JoinCandidate.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/quasitree/JoinCandidate.java index f898b042..3f92c654 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/quasitree/JoinCandidate.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/quasitree/JoinCandidate.java @@ -18,68 +18,73 @@ /** * @author Bergmann Gábor - * + * */ class JoinCandidate { - Stub primary; - Stub secondary; - - Set varPrimary; - Set varSecondary; - - - JoinCandidate(Stub primary, Stub secondary) { - super(); - this.primary = primary; - this.secondary = secondary; - - varPrimary = getPrimary().getVariablesSet(); - varSecondary = getSecondary().getVariablesSet(); - - } - /** - * @return the a - */ - public Stub getPrimary() { - return primary; - } - /** - * @return the b - */ - public Stub getSecondary() { - return secondary; - } - - - - /* (non-Javadoc) - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return primary.toString() + " |x| " + secondary.toString(); - } - /** - * @return the varPrimary - */ - public Set getVarPrimary() { - return varPrimary; - } - /** - * @return the varSecondary - */ - public Set getVarSecondary() { - return varSecondary; - } - - public boolean isTrivial() { - return getPrimary().equals(getSecondary()); - } - public boolean isCheckOnly() { - return varPrimary.containsAll(varSecondary) || varSecondary.containsAll(varPrimary); - } - public boolean isDescartes() { - return Collections.disjoint(varPrimary, varSecondary); - } + Stub primary; + Stub secondary; + + Set varPrimary; + Set varSecondary; + + JoinCandidate(Stub primary, Stub secondary) { + super(); + this.primary = primary; + this.secondary = secondary; + + varPrimary = getPrimary().getVariablesSet(); + varSecondary = getSecondary().getVariablesSet(); + + } + + /** + * @return the a + */ + public Stub getPrimary() { + return primary; + } + + /** + * @return the b + */ + public Stub getSecondary() { + return secondary; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return primary.toString() + " |x| " + secondary.toString(); + } + + /** + * @return the varPrimary + */ + public Set getVarPrimary() { + return varPrimary; + } + + /** + * @return the varSecondary + */ + public Set getVarSecondary() { + return varSecondary; + } + + public boolean isTrivial() { + return getPrimary().equals(getSecondary()); + } + + public boolean isCheckOnly() { + return varPrimary.containsAll(varSecondary) || varSecondary.containsAll(varPrimary); + } + + public boolean isDescartes() { + return Collections.disjoint(varPrimary, varSecondary); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/quasitree/JoinOrderingHeuristics.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/quasitree/JoinOrderingHeuristics.java index ef5db6e7..03003c13 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/quasitree/JoinOrderingHeuristics.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/quasitree/JoinOrderingHeuristics.java @@ -17,32 +17,31 @@ /** * @author Bergmann Gábor - * + * */ -public class JoinOrderingHeuristics implements Comparator> { - - - /* (non-Javadoc) - * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) - */ - @Override - public int compare(JoinCandidate jc1, JoinCandidate jc2) { - return new OrderingCompareAgent>(jc1, jc2) { - @Override - protected void doCompare() { - swallowBoolean(true - && consider(preferTrue(a.isTrivial(), b.isTrivial())) - && consider(preferTrue(a.isCheckOnly(), b.isCheckOnly())) - && consider(preferFalse(a.isDescartes(), b.isDescartes())) - - // TODO main heuristic decisions - - && consider(preferLess(a.toString(), b.toString())) - ); - } - }.compare(); - - } - - +public class JoinOrderingHeuristics implements + Comparator> { + + /* + * (non-Javadoc) + * + * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) + */ + @Override + public int compare(JoinCandidate jc1, JoinCandidate jc2) { + return new OrderingCompareAgent>(jc1, jc2) { + @Override + protected void doCompare() { + swallowBoolean(true && consider(preferTrue(a.isTrivial(), b.isTrivial())) + && consider(preferTrue(a.isCheckOnly(), b.isCheckOnly())) + && consider(preferFalse(a.isDescartes(), b.isDescartes())) + + // TODO main heuristic decisions + + && consider(preferLess(a.toString(), b.toString()))); + } + }.compare(); + + } + } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/quasitree/QuasiTreeLayout.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/quasitree/QuasiTreeLayout.java index 1d9d7e91..c3b371b2 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/quasitree/QuasiTreeLayout.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/construction/quasitree/QuasiTreeLayout.java @@ -32,138 +32,128 @@ /** * Layout ideas * - * Order of preference - * - trivial joins (stub a = stub b) - * - high selectivity filters - * - supressed by joincandidate if already checked on other side - * - apply first to narrower stubs - * - aggregator quasijoins, let-expressions (?) - * - true joins - * - except cartesians - * - TBD: ranking based on what constraints the join will enable - * - low-selectivity filters (injectivity) - * - cartesian joins + * Order of preference - trivial joins (stub a = stub b) - high selectivity filters - supressed by joincandidate if + * already checked on other side - apply first to narrower stubs - aggregator quasijoins, let-expressions (?) - true + * joins - except cartesians - TBD: ranking based on what constraints the join will enable - low-selectivity filters + * (injectivity) - cartesian joins * * @author Bergmann Gábor - * + * */ -public class QuasiTreeLayout - implements - IReteLayoutStrategy { - - @Override - public Stub layout(PSystem pSystem) throws RetePatternBuildException { - return new Scaffold(pSystem).run(); - } - - public class Scaffold { - PSystem pSystem; - PatternDescription pattern; - IPatternMatcherContext context; - Buildable buildable; - - Set deferredConstraints = null; - Set> forefront = new LinkedHashSet>(); - - Scaffold(PSystem pSystem) { - this.pSystem = pSystem; - pattern = pSystem.getPattern(); - context = pSystem.getContext(); - buildable = pSystem.getBuildable(); - } - - /** - * @return - */ - public Stub run() throws RetePatternBuildException { - try { - context.logDebug(getClass().getSimpleName() + ": patternbody build started"); - - // UNIFICATION AND WEAK INEQUALITY ELMINATION - LayoutHelper.unifyVariablesAlongEqualities(pSystem); - LayoutHelper.eliminateWeakInequalities(pSystem); - - // UNARY ELIMINATION WITH TYPE INFERENCE - if (Options.calcImpliedTypes) { - LayoutHelper.eliminateInferrableUnaryTypes(pSystem, context); - } - - // PREVENTIVE CHECKS - LayoutHelper.checkSanity(pSystem); - - // PROCESS CONSTRAINTS - deferredConstraints = pSystem.getConstraintsOfType(DeferredPConstraint.class); - Set enumerables = - pSystem.getConstraintsOfType(EnumerablePConstraint.class); - for (EnumerablePConstraint enumerable : enumerables) { - Stub stub = enumerable.getStub(); - admitStub(stub); - } - if (enumerables.isEmpty()) { // EXTREME CASE - Stub stub = buildable.buildStartStub(new Object[]{}, new Object[]{}); - admitStub(stub); - } - - // JOIN FOREFRONT STUBS WHILE POSSIBLE - while (forefront.size() > 1) { - // TODO QUASI-TREE TRIVIAL JOINS? - - List> candidates = generateJoinCandidates(); - JoinOrderingHeuristics ordering = - new JoinOrderingHeuristics(); - JoinCandidate selectedJoin = Collections.min(candidates, ordering); - doJoin(selectedJoin.getPrimary(), selectedJoin.getSecondary()); - } - - // FINAL CHECK, whether all exported variables are present - assert(forefront.size() == 1); - Stub finalStub = forefront.iterator().next(); - LayoutHelper.finalCheck(pSystem, finalStub); - - context.logDebug(getClass().getSimpleName() + ": patternbody build concluded"); - return finalStub; - } catch (RetePatternBuildException ex) { - ex.setPatternDescription(pattern); - throw ex; - } - } - - public List> generateJoinCandidates() { - List> candidates = new ArrayList>(); - int bIndex = 0; - for (Stub b : forefront) { - int aIndex = 0; - for (Stub a : forefront) { - if (aIndex++ >= bIndex) break; - candidates.add(new JoinCandidate(a, b)); - } - bIndex++; - } - return candidates; - } - - - private void admitStub(Stub stub) throws RetePatternBuildException { - for (DeferredPConstraint deferred : deferredConstraints) { - if (!stub.getAllEnforcedConstraints().contains(deferred)) { - if (deferred.isReadyAt(stub)) { - admitStub(deferred.checkOn(stub)); - return; - } - } - } - forefront.add(stub); - } - - private void doJoin(Stub primaryStub, Stub secondaryStub) throws RetePatternBuildException { - Stub joinedStub = BuildHelper.naturalJoin(buildable, primaryStub, secondaryStub); - forefront.remove(primaryStub); - forefront.remove(secondaryStub); - admitStub(joinedStub); - } - - } - +public class QuasiTreeLayout implements + IReteLayoutStrategy { + + @Override + public Stub layout(PSystem pSystem) + throws RetePatternBuildException { + return new Scaffold(pSystem).run(); + } + + public class Scaffold { + PSystem pSystem; + PatternDescription pattern; + IPatternMatcherContext context; + Buildable buildable; + + Set deferredConstraints = null; + Set> forefront = new LinkedHashSet>(); + + Scaffold(PSystem pSystem) { + this.pSystem = pSystem; + pattern = pSystem.getPattern(); + context = pSystem.getContext(); + buildable = pSystem.getBuildable(); + } + + /** + * @return + */ + public Stub run() throws RetePatternBuildException { + try { + context.logDebug(getClass().getSimpleName() + ": patternbody build started"); + + // UNIFICATION AND WEAK INEQUALITY ELMINATION + LayoutHelper.unifyVariablesAlongEqualities(pSystem); + LayoutHelper.eliminateWeakInequalities(pSystem); + + // UNARY ELIMINATION WITH TYPE INFERENCE + if (Options.calcImpliedTypes) { + LayoutHelper.eliminateInferrableUnaryTypes(pSystem, context); + } + + // PREVENTIVE CHECKS + LayoutHelper.checkSanity(pSystem); + + // PROCESS CONSTRAINTS + deferredConstraints = pSystem.getConstraintsOfType(DeferredPConstraint.class); + Set enumerables = pSystem.getConstraintsOfType(EnumerablePConstraint.class); + for (EnumerablePConstraint enumerable : enumerables) { + Stub stub = enumerable.getStub(); + admitStub(stub); + } + if (enumerables.isEmpty()) { // EXTREME CASE + Stub stub = buildable.buildStartStub(new Object[] {}, new Object[] {}); + admitStub(stub); + } + + // JOIN FOREFRONT STUBS WHILE POSSIBLE + while (forefront.size() > 1) { + // TODO QUASI-TREE TRIVIAL JOINS? + + List> candidates = generateJoinCandidates(); + JoinOrderingHeuristics ordering = new JoinOrderingHeuristics(); + JoinCandidate selectedJoin = Collections.min(candidates, ordering); + doJoin(selectedJoin.getPrimary(), selectedJoin.getSecondary()); + } + + // FINAL CHECK, whether all exported variables are present + assert (forefront.size() == 1); + Stub finalStub = forefront.iterator().next(); + LayoutHelper.finalCheck(pSystem, finalStub); + + context.logDebug(getClass().getSimpleName() + ": patternbody build concluded"); + return finalStub; + } catch (RetePatternBuildException ex) { + ex.setPatternDescription(pattern); + throw ex; + } + } + + public List> generateJoinCandidates() { + List> candidates = new ArrayList>(); + int bIndex = 0; + for (Stub b : forefront) { + int aIndex = 0; + for (Stub a : forefront) { + if (aIndex++ >= bIndex) + break; + candidates.add(new JoinCandidate(a, b)); + } + bIndex++; + } + return candidates; + } + + private void admitStub(Stub stub) throws RetePatternBuildException { + for (DeferredPConstraint deferred : deferredConstraints) { + if (!stub.getAllEnforcedConstraints().contains(deferred)) { + if (deferred.isReadyAt(stub)) { + admitStub(deferred.checkOn(stub)); + return; + } + } + } + forefront.add(stub); + } + + private void doJoin(Stub primaryStub, Stub secondaryStub) + throws RetePatternBuildException { + Stub joinedStub = BuildHelper.naturalJoin(buildable, primaryStub, secondaryStub); + forefront.remove(primaryStub); + forefront.remove(secondaryStub); + admitStub(joinedStub); + } + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/AggregatorNode.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/AggregatorNode.java index b7965a03..606be5d9 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/AggregatorNode.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/AggregatorNode.java @@ -25,248 +25,261 @@ import org.eclipse.incquery.runtime.rete.tuple.TupleMask; /** - * A special node depending on a projection indexer to aggregate tuple groups with the same projection. - * Only propagates the aggregates of non-empty groups. Use the outer indexers to circumvent. + * A special node depending on a projection indexer to aggregate tuple groups with the same projection. Only propagates + * the aggregates of non-empty groups. Use the outer indexers to circumvent. + * * @author Bergmann Gábor - * + * */ public abstract class AggregatorNode extends StandardNode { - ProjectionIndexer projection; - AggregatorNode me; - int sourceWidth; - Map mainAggregates; - - AggregatorOuterIndexer aggregatorOuterIndexer = null; - AggregatorOuterIdentityIndexer[] aggregatorOuterIdentityIndexers = null; - - /** - * @param reteContainer - * @param projection the projection indexer whose tuple groups should be aggregated - */ - public AggregatorNode(ReteContainer reteContainer, ProjectionIndexer projection) { - super(reteContainer); - this.me = this; - mainAggregates = new HashMap(); - this.projection = projection; - this.sourceWidth = projection.getMask().indices.length; - for (Tuple signature : projection.getSignatures()) { - mainAggregates.put(signature, aggregateGroup(signature, projection.get(signature))); - } - projection.attachListener(new DefaultIndexerListener(this){ - @Override + ProjectionIndexer projection; + AggregatorNode me; + int sourceWidth; + Map mainAggregates; + + AggregatorOuterIndexer aggregatorOuterIndexer = null; + AggregatorOuterIdentityIndexer[] aggregatorOuterIdentityIndexers = null; + + /** + * @param reteContainer + * @param projection + * the projection indexer whose tuple groups should be aggregated + */ + public AggregatorNode(ReteContainer reteContainer, ProjectionIndexer projection) { + super(reteContainer); + this.me = this; + mainAggregates = new HashMap(); + this.projection = projection; + this.sourceWidth = projection.getMask().indices.length; + for (Tuple signature : projection.getSignatures()) { + mainAggregates.put(signature, aggregateGroup(signature, projection.get(signature))); + } + projection.attachListener(new DefaultIndexerListener(this) { + @Override public void notifyIndexerUpdate(Direction direction, Tuple updateElement, Tuple signature, boolean change) { - aggregateUpdate(direction, updateElement, signature, change); - } - }); - } - - /** - * Aggregates (reduces) a group of tuples. - * The group can be null. - */ - public abstract Object aggregateGroup(Tuple signature, Collection group); - - /** - * Aggregates (reduces) a group of tuples, having access to the previous aggregated value (before the update) and the update definition. - * Defaults to aggregateGroup(). Override to increase performance. - */ - public Object aggregateGroupAfterUpdate(Tuple signature, Collection currentGroup, Object oldAggregate, Direction direction, Tuple updateElement, boolean change) { - return aggregateGroup(signature, currentGroup); - } - - - protected Tuple aggregateAndPack(Tuple signature, Collection group) { - return packResult(signature, aggregateGroup(signature, group)); - } - - public AggregatorOuterIndexer getAggregatorOuterIndexer() { - if (aggregatorOuterIndexer==null) { - aggregatorOuterIndexer = new AggregatorOuterIndexer(); - //reteContainer.connectAndSynchronize(this, aggregatorOuterIndexer); - } - return aggregatorOuterIndexer; - } - - public AggregatorOuterIdentityIndexer getAggregatorOuterIdentityIndexer(int resultPositionInSignature) { - if (aggregatorOuterIdentityIndexers==null) - aggregatorOuterIdentityIndexers = new AggregatorOuterIdentityIndexer[sourceWidth + 1]; - if (aggregatorOuterIdentityIndexers[resultPositionInSignature]==null) { - aggregatorOuterIdentityIndexers[resultPositionInSignature] = new AggregatorOuterIdentityIndexer(resultPositionInSignature); - //reteContainer.connectAndSynchronize(this, aggregatorOuterIdentityIndexers[resultPositionInSignature]); - } - return aggregatorOuterIdentityIndexers[resultPositionInSignature]; - } - - @Override + aggregateUpdate(direction, updateElement, signature, change); + } + }); + } + + /** + * Aggregates (reduces) a group of tuples. The group can be null. + */ + public abstract Object aggregateGroup(Tuple signature, Collection group); + + /** + * Aggregates (reduces) a group of tuples, having access to the previous aggregated value (before the update) and + * the update definition. Defaults to aggregateGroup(). Override to increase performance. + */ + public Object aggregateGroupAfterUpdate(Tuple signature, Collection currentGroup, Object oldAggregate, + Direction direction, Tuple updateElement, boolean change) { + return aggregateGroup(signature, currentGroup); + } + + protected Tuple aggregateAndPack(Tuple signature, Collection group) { + return packResult(signature, aggregateGroup(signature, group)); + } + + public AggregatorOuterIndexer getAggregatorOuterIndexer() { + if (aggregatorOuterIndexer == null) { + aggregatorOuterIndexer = new AggregatorOuterIndexer(); + // reteContainer.connectAndSynchronize(this, aggregatorOuterIndexer); + } + return aggregatorOuterIndexer; + } + + public AggregatorOuterIdentityIndexer getAggregatorOuterIdentityIndexer(int resultPositionInSignature) { + if (aggregatorOuterIdentityIndexers == null) + aggregatorOuterIdentityIndexers = new AggregatorOuterIdentityIndexer[sourceWidth + 1]; + if (aggregatorOuterIdentityIndexers[resultPositionInSignature] == null) { + aggregatorOuterIdentityIndexers[resultPositionInSignature] = new AggregatorOuterIdentityIndexer( + resultPositionInSignature); + // reteContainer.connectAndSynchronize(this, aggregatorOuterIdentityIndexers[resultPositionInSignature]); + } + return aggregatorOuterIdentityIndexers[resultPositionInSignature]; + } + + @Override public void pullInto(Collection collector) { - for (Tuple signature: mainAggregates.keySet()) { - collector.add(packResult(signature, mainAggregates.get(signature))); - } - } - - protected Tuple packResult(Tuple signature, Object result) { - Object[] resultArray = {result}; - return new LeftInheritanceTuple(signature, resultArray); - } - - protected void aggregateUpdate(Direction direction, Tuple updateElement, Tuple signature, boolean change) { - Collection currentGroup = projection.get(signature); - // these will be null if group is empty - Object oldAggregate = mainAggregates.get(signature); - Object safeOldAggregate = oldAggregate == null? aggregateGroup(signature, null) : oldAggregate; - boolean empty = currentGroup==null || currentGroup.isEmpty(); - Object newAggregate = empty ? null : - aggregateGroupAfterUpdate(signature, currentGroup, safeOldAggregate/*non-null*/, direction, updateElement, change); - if (!empty) mainAggregates.put(signature, newAggregate); else mainAggregates.remove(signature); - Tuple oldTuple = packResult(signature, safeOldAggregate); - Tuple newTuple = packResult(signature, newAggregate == null? aggregateGroup(signature, null) : newAggregate); - if (oldAggregate != null) propagateUpdate(Direction.REVOKE, oldTuple); // direct outputs lack non-empty groups - if (newAggregate != null) propagateUpdate(Direction.INSERT, newTuple); // direct outputs lack non-empty groups - if (aggregatorOuterIndexer!=null) aggregatorOuterIndexer.propagate(signature, oldTuple, newTuple); - if (aggregatorOuterIdentityIndexers!=null) - for (AggregatorOuterIdentityIndexer aggregatorOuterIdentityIndexer : aggregatorOuterIdentityIndexers) - if (aggregatorOuterIdentityIndexer != null) - aggregatorOuterIdentityIndexer.propagate(signature, oldTuple, newTuple); - } - -// protected void propagate(Direction direction, Tuple packResult, Tuple signature) { -// propagateUpdate(direction, packResult); -// if (aggregatorOuterIndexer!=null) aggregatorOuterIndexer.propagate(direction, packResult, signature); -// if (aggregatorOuterIdentityIndexers!=null) -// for (AggregatorOuterIdentityIndexer aggregatorOuterIdentityIndexer : aggregatorOuterIdentityIndexers) -// aggregatorOuterIdentityIndexer.propagate(direction, packResult, signature); -// } - - private Object getAggregate(Tuple signature) { - Object aggregate = mainAggregates.get(signature); - return aggregate == null? aggregateGroup(signature, null) : aggregate; - } - - /** - * A special non-iterable index that retrieves the aggregated, packed result (signature+aggregate) for the original signature. - * @author Bergmann Gábor - */ - class AggregatorOuterIndexer extends StandardIndexer { - //private Map localAggregates; - - public AggregatorOuterIndexer() { - super(me.reteContainer, TupleMask.omit(sourceWidth, sourceWidth+1)); - this.parent = me; - //this.localAggregates = new HashMap(); -// -// for (Tuple signature: projection.getSignatures()) { -// localAggregates.put(signature, aggregateGroup(signature, projection.get(signature))); -// } - - } - - @Override - public Collection get(Tuple signature) { - return Collections.singleton(packResult(signature, getAggregate(signature))); - } - - public void propagate(Tuple signature, Tuple oldTuple, Tuple newTuple) { - propagate(Direction.INSERT, newTuple, signature, false); - propagate(Direction.REVOKE, oldTuple, signature, false); - } - -// @Override -// public void update(Direction direction, Tuple updateElement) { -// Tuple signature = mask.transform(updateElement); -// Tuple neutral = aggregateAndPack(signature, null); -// if (direction == Direction.INSERT) { -// propagate(Direction.INSERT, updateElement, signature, false); -// propagate(Direction.REVOKE, neutral, signature, false); -// localAggregates.put(signature, updateElement); -// } else { -// localAggregates.remove(signature); -// propagate(Direction.INSERT, neutral, signature, false); -// propagate(Direction.REVOKE, updateElement, signature, false); -// } -// } - -// private Object getLocalAggregate(Tuple signature) { -// Tuple resultTuple = localAggregates.get(signature); -// return resultTuple == null? aggregateGroup(signature, null) : resultTuple.get(sourceWidth); -// } - - @Override - public Node getActiveNode() { - return projection.getActiveNode(); - } - - } - /** - * A special non-iterable index that checks a suspected aggregate value for a given signature. - * The signature for this index is the original signature of the projection index, - * with the suspected result inserted at position resultPositionInSignature. - * @author Bergmann Gábor - */ - - class AggregatorOuterIdentityIndexer extends StandardIndexer /*implements Receiver*/ { -// private Map localAggregates; - int resultPositionInSignature; - TupleMask pruneResult; - TupleMask reorder; - - public AggregatorOuterIdentityIndexer(int resultPositionInSignature) { - super(me.reteContainer, TupleMask.displace(sourceWidth, resultPositionInSignature, sourceWidth+1)); - this.parent = me; -// this.localAggregates = new HashMap(); - this.resultPositionInSignature = resultPositionInSignature; - this.pruneResult = TupleMask.omit(resultPositionInSignature, sourceWidth+1); - if (resultPositionInSignature == sourceWidth) - this.reorder = null; - else - this.reorder = mask; - } - - @Override + for (Tuple signature : mainAggregates.keySet()) { + collector.add(packResult(signature, mainAggregates.get(signature))); + } + } + + protected Tuple packResult(Tuple signature, Object result) { + Object[] resultArray = { result }; + return new LeftInheritanceTuple(signature, resultArray); + } + + protected void aggregateUpdate(Direction direction, Tuple updateElement, Tuple signature, boolean change) { + Collection currentGroup = projection.get(signature); + // these will be null if group is empty + Object oldAggregate = mainAggregates.get(signature); + Object safeOldAggregate = oldAggregate == null ? aggregateGroup(signature, null) : oldAggregate; + boolean empty = currentGroup == null || currentGroup.isEmpty(); + Object newAggregate = empty ? null : aggregateGroupAfterUpdate(signature, currentGroup, safeOldAggregate/* + * non-null + */, + direction, updateElement, change); + if (!empty) + mainAggregates.put(signature, newAggregate); + else + mainAggregates.remove(signature); + Tuple oldTuple = packResult(signature, safeOldAggregate); + Tuple newTuple = packResult(signature, newAggregate == null ? aggregateGroup(signature, null) : newAggregate); + if (oldAggregate != null) + propagateUpdate(Direction.REVOKE, oldTuple); // direct outputs lack non-empty groups + if (newAggregate != null) + propagateUpdate(Direction.INSERT, newTuple); // direct outputs lack non-empty groups + if (aggregatorOuterIndexer != null) + aggregatorOuterIndexer.propagate(signature, oldTuple, newTuple); + if (aggregatorOuterIdentityIndexers != null) + for (AggregatorOuterIdentityIndexer aggregatorOuterIdentityIndexer : aggregatorOuterIdentityIndexers) + if (aggregatorOuterIdentityIndexer != null) + aggregatorOuterIdentityIndexer.propagate(signature, oldTuple, newTuple); + } + + // protected void propagate(Direction direction, Tuple packResult, Tuple signature) { + // propagateUpdate(direction, packResult); + // if (aggregatorOuterIndexer!=null) aggregatorOuterIndexer.propagate(direction, packResult, signature); + // if (aggregatorOuterIdentityIndexers!=null) + // for (AggregatorOuterIdentityIndexer aggregatorOuterIdentityIndexer : aggregatorOuterIdentityIndexers) + // aggregatorOuterIdentityIndexer.propagate(direction, packResult, signature); + // } + + private Object getAggregate(Tuple signature) { + Object aggregate = mainAggregates.get(signature); + return aggregate == null ? aggregateGroup(signature, null) : aggregate; + } + + /** + * A special non-iterable index that retrieves the aggregated, packed result (signature+aggregate) for the original + * signature. + * + * @author Bergmann Gábor + */ + class AggregatorOuterIndexer extends StandardIndexer { + // private Map localAggregates; + + public AggregatorOuterIndexer() { + super(me.reteContainer, TupleMask.omit(sourceWidth, sourceWidth + 1)); + this.parent = me; + // this.localAggregates = new HashMap(); + // + // for (Tuple signature: projection.getSignatures()) { + // localAggregates.put(signature, aggregateGroup(signature, projection.get(signature))); + // } + + } + + @Override + public Collection get(Tuple signature) { + return Collections.singleton(packResult(signature, getAggregate(signature))); + } + + public void propagate(Tuple signature, Tuple oldTuple, Tuple newTuple) { + propagate(Direction.INSERT, newTuple, signature, false); + propagate(Direction.REVOKE, oldTuple, signature, false); + } + + // @Override + // public void update(Direction direction, Tuple updateElement) { + // Tuple signature = mask.transform(updateElement); + // Tuple neutral = aggregateAndPack(signature, null); + // if (direction == Direction.INSERT) { + // propagate(Direction.INSERT, updateElement, signature, false); + // propagate(Direction.REVOKE, neutral, signature, false); + // localAggregates.put(signature, updateElement); + // } else { + // localAggregates.remove(signature); + // propagate(Direction.INSERT, neutral, signature, false); + // propagate(Direction.REVOKE, updateElement, signature, false); + // } + // } + + // private Object getLocalAggregate(Tuple signature) { + // Tuple resultTuple = localAggregates.get(signature); + // return resultTuple == null? aggregateGroup(signature, null) : resultTuple.get(sourceWidth); + // } + + @Override + public Node getActiveNode() { + return projection.getActiveNode(); + } + + } + + /** + * A special non-iterable index that checks a suspected aggregate value for a given signature. The signature for + * this index is the original signature of the projection index, with the suspected result inserted at position + * resultPositionInSignature. + * + * @author Bergmann Gábor + */ + + class AggregatorOuterIdentityIndexer extends StandardIndexer /* implements Receiver */{ + // private Map localAggregates; + int resultPositionInSignature; + TupleMask pruneResult; + TupleMask reorder; + + public AggregatorOuterIdentityIndexer(int resultPositionInSignature) { + super(me.reteContainer, TupleMask.displace(sourceWidth, resultPositionInSignature, sourceWidth + 1)); + this.parent = me; + // this.localAggregates = new HashMap(); + this.resultPositionInSignature = resultPositionInSignature; + this.pruneResult = TupleMask.omit(resultPositionInSignature, sourceWidth + 1); + if (resultPositionInSignature == sourceWidth) + this.reorder = null; + else + this.reorder = mask; + } + + @Override public Collection get(Tuple signatureWithResult) { - Tuple prunedSignature = pruneResult.transform(signatureWithResult); - Object result = getAggregate(prunedSignature); - if (signatureWithResult.get(resultPositionInSignature).equals(result)) - return Collections.singleton(signatureWithResult); - else - return null; - } - - public void propagate(Tuple signature, Tuple oldTuple, Tuple newTuple) { - propagate(Direction.INSERT, reorder(newTuple), signature, true); - propagate(Direction.REVOKE, reorder(oldTuple), signature, true); - } - -// @Override -// public void update(Direction direction, Tuple signatureWithResult) { -// Tuple prunedSignature = pruneResult.transform(signatureWithResult); -// if (direction == Direction.INSERT) -// localAggregates.put(prunedSignature, signatureWithResult); -// else -// localAggregates.remove(prunedSignature); -// Tuple transformed = reorder(signatureWithResult); -// propagate(direction, transformed, transformed, true); -// } - - - private Tuple reorder(Tuple signatureWithResult) { - Tuple transformed; - if (reorder == null) - transformed = signatureWithResult; - else - transformed = reorder.transform(signatureWithResult); - return transformed; - } - -// private Object getLocalAggregate(Tuple signature) { -// Tuple resultTuple = localAggregates.get(signature); -// return resultTuple == null? aggregateGroup(signature, null) : resultTuple.get(resultPositionInSignature); -// } - - @Override - public Node getActiveNode() { - return projection.getActiveNode(); - } - } + Tuple prunedSignature = pruneResult.transform(signatureWithResult); + Object result = getAggregate(prunedSignature); + if (signatureWithResult.get(resultPositionInSignature).equals(result)) + return Collections.singleton(signatureWithResult); + else + return null; + } + + public void propagate(Tuple signature, Tuple oldTuple, Tuple newTuple) { + propagate(Direction.INSERT, reorder(newTuple), signature, true); + propagate(Direction.REVOKE, reorder(oldTuple), signature, true); + } + + // @Override + // public void update(Direction direction, Tuple signatureWithResult) { + // Tuple prunedSignature = pruneResult.transform(signatureWithResult); + // if (direction == Direction.INSERT) + // localAggregates.put(prunedSignature, signatureWithResult); + // else + // localAggregates.remove(prunedSignature); + // Tuple transformed = reorder(signatureWithResult); + // propagate(direction, transformed, transformed, true); + // } + + private Tuple reorder(Tuple signatureWithResult) { + Tuple transformed; + if (reorder == null) + transformed = signatureWithResult; + else + transformed = reorder.transform(signatureWithResult); + return transformed; + } + + // private Object getLocalAggregate(Tuple signature) { + // Tuple resultTuple = localAggregates.get(signature); + // return resultTuple == null? aggregateGroup(signature, null) : resultTuple.get(resultPositionInSignature); + // } + + @Override + public Node getActiveNode() { + return projection.getActiveNode(); + } + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/CountNode.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/CountNode.java index e5c0faae..ad634175 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/CountNode.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/CountNode.java @@ -18,25 +18,23 @@ /** * An aggregation node that simply counts the number of tuples conforming to the signature. + * * @author Bergmann Gábor - * + * */ public class CountNode extends AggregatorNode { - - - public CountNode(ReteContainer reteContainer, ProjectionIndexer projection) { - super(reteContainer, projection); - } + public CountNode(ReteContainer reteContainer, ProjectionIndexer projection) { + super(reteContainer, projection); + } - int sizeOf(Collection group) { - return group==null ? 0 : group.size(); - } + int sizeOf(Collection group) { + return group == null ? 0 : group.size(); + } + @Override + public Object aggregateGroup(Tuple signature, Collection group) { + return sizeOf(group); + } - @Override - public Object aggregateGroup(Tuple signature, Collection group) { - return sizeOf(group); - } - } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/DefaultIndexerListener.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/DefaultIndexerListener.java index c3e55128..75c518c3 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/DefaultIndexerListener.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/DefaultIndexerListener.java @@ -16,19 +16,19 @@ /** * @author istvanrath - * + * */ public abstract class DefaultIndexerListener implements IndexerListener { - WeakReference owner; - - public DefaultIndexerListener(Node owner) { - this.owner = new WeakReference(owner); - } + WeakReference owner; + + public DefaultIndexerListener(Node owner) { + this.owner = new WeakReference(owner); + } - @Override - public Node getOwner() { - return owner.get(); - } + @Override + public Node getOwner() { + return owner.get(); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/DualInputNode.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/DualInputNode.java index 2615ee25..dec515b2 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/DualInputNode.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/DualInputNode.java @@ -20,213 +20,211 @@ import org.eclipse.incquery.runtime.rete.tuple.TupleMask; import org.eclipse.incquery.runtime.rete.util.Options; - /** - * Abstract superclass for nodes with two inputs that are matched against each - * other. + * Abstract superclass for nodes with two inputs that are matched against each other. * * @author Gabor Bergmann */ public abstract class DualInputNode extends StandardNode /* implements Pullable */{ - public IterableIndexer getPrimarySlot() { - return primarySlot; - } - - - public Indexer getSecondarySlot() { - return secondarySlot; - } - - /** - * @author Gabor Bergmann - * - */ - public enum Side { - PRIMARY, SECONDARY, BOTH; - - public Side opposite() { - switch (this) { - case PRIMARY: - return SECONDARY; - case SECONDARY: - return PRIMARY; - case BOTH: - return BOTH; - default: - return BOTH; - } - } - } - - /** - * Holds the primary input slot of this node. - */ - protected IterableIndexer primarySlot; - - /** - * Holds the secondary input slot of this node. - */ - protected Indexer secondarySlot; - - /** - * Optional complementer mask - */ - protected TupleMask complementerSecondaryMask; - - /** - * true if the primary and secondary slots coincide - */ - protected final boolean coincidence; - - /** - * @param reteContainer - */ - public DualInputNode(ReteContainer reteContainer, IterableIndexer primarySlot, - Indexer secondarySlot, TupleMask complementerSecondaryMask) { - super(reteContainer); - this.complementerSecondaryMask = complementerSecondaryMask; - this.primarySlot = primarySlot; - this.secondarySlot = secondarySlot; - coincidence = primarySlot.equals(secondarySlot); - final DualInputNode me = this; - if (!coincidence) { - primarySlot.attachListener(new DefaultIndexerListener(this) { - public void notifyIndexerUpdate(Direction direction, Tuple updateElement, Tuple signature, boolean change) { - notifyUpdate(Side.PRIMARY, direction, updateElement, signature, change); - } - @Override - public String toString() { - return "primary@"+me; - } - }); - secondarySlot.attachListener(new DefaultIndexerListener(this) { - public void notifyIndexerUpdate(Direction direction, Tuple updateElement, Tuple signature, boolean change) { - notifyUpdate(Side.SECONDARY, direction, updateElement, signature, change); - } - @Override - public String toString() { - return "secondary@"+me; - } - }); - } else { - primarySlot.attachListener(new DefaultIndexerListener(this) { - public void notifyIndexerUpdate(Direction direction, Tuple updateElement, Tuple signature, boolean change) { - notifyUpdate(Side.BOTH, direction, updateElement, signature, change); - } - @Override - public String toString() { - return "both@"+me; - } - }); - } - } - - - // public Indexer createPrimarySlot(TupleMask mask) - // { - // return accessSlot(mask, Side.PRIMARY); - // } - // - // public Indexer createSecondarySlot(TupleMask mask) - // { - // return accessSlot(mask, Side.SECONDARY); - // } - // - // public Indexer accessSlot(TupleMask mask, Side side) - // { - // Indexer slot = slots.get(side); - // if (slot == null) - // { - // slot = new Indexer(network, mask); - // slot.attachListener(this, side); - // slots.put(side, slot); - // } - // return slot; - // } - - /** - * Helper: retrieves all stored substitutions from the opposite side memory. - * The results are copied into a new collection; this step has a performance - * penalty, but avoids ConcurrentModificaton Exceptions when loops are - * present. - * - * @return the collection of opposite substitutions if any, or null if none - */ - protected Collection retrieveOpposites(Side side, Tuple signature) { - Collection opposites = getSlot(side.opposite()).get(signature); - return opposites; - // if (opposites!=null) return new LinkedList(opposites); - // else return null; - } - - /** - * Helper: unifies a left and right partial matching. - */ - protected Tuple unify(Tuple left, Tuple right) { -// if (complementerSecondaryMask == null) -// return secondarySlot.getMask().combine(left, right, -// Options.enableInheritance, false); -// else - return complementerSecondaryMask.combine(left, right, - Options.enableInheritance, true); - } - - /** - * Helper: unifies the a substitution from the specifies side with another - * substitution from the other side. - */ - protected Tuple unify(Side side, Tuple ps, Tuple opposite) { - switch (side) { - case PRIMARY: - return unify(ps, opposite); - case SECONDARY: - return unify(opposite, ps); - case BOTH: - return unify(ps, opposite); - default: - return null; - } - } - - /** - * Abstract handler for update event. - * - * @param side - * The side on which the event occured. - * @param direction - * The direction of the update. - * @param updateElement - * The partial matching that is inserted. - * @param signature - * Masked signature of updateElement. - * @param change - * Indicates whether this is/was the first/last instance of this - * signature in this slot. - */ - public abstract void notifyUpdate(Side side, Direction direction, - Tuple updateElement, Tuple signature, boolean change); - - /** - * Simulates the behaviour of the node for calibration purposes only. - */ - public abstract Tuple calibrate(Tuple primary, Tuple secondary); - - /** - * @param complementerSecondaryMask - * the complementerSecondaryMask to set - */ - public void setComplementerSecondaryMask( - TupleMask complementerSecondaryMask) { - this.complementerSecondaryMask = complementerSecondaryMask; - } - - /** - * Retrieves the slot corresponding to the specified side. - */ - protected Indexer getSlot(Side side) { - if (side==Side.SECONDARY) - return secondarySlot; - else return primarySlot; - } + public IterableIndexer getPrimarySlot() { + return primarySlot; + } + + public Indexer getSecondarySlot() { + return secondarySlot; + } + + /** + * @author Gabor Bergmann + * + */ + public enum Side { + PRIMARY, SECONDARY, BOTH; + + public Side opposite() { + switch (this) { + case PRIMARY: + return SECONDARY; + case SECONDARY: + return PRIMARY; + case BOTH: + return BOTH; + default: + return BOTH; + } + } + } + + /** + * Holds the primary input slot of this node. + */ + protected IterableIndexer primarySlot; + + /** + * Holds the secondary input slot of this node. + */ + protected Indexer secondarySlot; + + /** + * Optional complementer mask + */ + protected TupleMask complementerSecondaryMask; + + /** + * true if the primary and secondary slots coincide + */ + protected final boolean coincidence; + + /** + * @param reteContainer + */ + public DualInputNode(ReteContainer reteContainer, IterableIndexer primarySlot, Indexer secondarySlot, + TupleMask complementerSecondaryMask) { + super(reteContainer); + this.complementerSecondaryMask = complementerSecondaryMask; + this.primarySlot = primarySlot; + this.secondarySlot = secondarySlot; + coincidence = primarySlot.equals(secondarySlot); + final DualInputNode me = this; + if (!coincidence) { + primarySlot.attachListener(new DefaultIndexerListener(this) { + public void notifyIndexerUpdate(Direction direction, Tuple updateElement, Tuple signature, + boolean change) { + notifyUpdate(Side.PRIMARY, direction, updateElement, signature, change); + } + + @Override + public String toString() { + return "primary@" + me; + } + }); + secondarySlot.attachListener(new DefaultIndexerListener(this) { + public void notifyIndexerUpdate(Direction direction, Tuple updateElement, Tuple signature, + boolean change) { + notifyUpdate(Side.SECONDARY, direction, updateElement, signature, change); + } + + @Override + public String toString() { + return "secondary@" + me; + } + }); + } else { + primarySlot.attachListener(new DefaultIndexerListener(this) { + public void notifyIndexerUpdate(Direction direction, Tuple updateElement, Tuple signature, + boolean change) { + notifyUpdate(Side.BOTH, direction, updateElement, signature, change); + } + + @Override + public String toString() { + return "both@" + me; + } + }); + } + } + + // public Indexer createPrimarySlot(TupleMask mask) + // { + // return accessSlot(mask, Side.PRIMARY); + // } + // + // public Indexer createSecondarySlot(TupleMask mask) + // { + // return accessSlot(mask, Side.SECONDARY); + // } + // + // public Indexer accessSlot(TupleMask mask, Side side) + // { + // Indexer slot = slots.get(side); + // if (slot == null) + // { + // slot = new Indexer(network, mask); + // slot.attachListener(this, side); + // slots.put(side, slot); + // } + // return slot; + // } + + /** + * Helper: retrieves all stored substitutions from the opposite side memory. The results are copied into a new + * collection; this step has a performance penalty, but avoids ConcurrentModificaton Exceptions when loops are + * present. + * + * @return the collection of opposite substitutions if any, or null if none + */ + protected Collection retrieveOpposites(Side side, Tuple signature) { + Collection opposites = getSlot(side.opposite()).get(signature); + return opposites; + // if (opposites!=null) return new LinkedList(opposites); + // else return null; + } + + /** + * Helper: unifies a left and right partial matching. + */ + protected Tuple unify(Tuple left, Tuple right) { + // if (complementerSecondaryMask == null) + // return secondarySlot.getMask().combine(left, right, + // Options.enableInheritance, false); + // else + return complementerSecondaryMask.combine(left, right, Options.enableInheritance, true); + } + + /** + * Helper: unifies the a substitution from the specifies side with another substitution from the other side. + */ + protected Tuple unify(Side side, Tuple ps, Tuple opposite) { + switch (side) { + case PRIMARY: + return unify(ps, opposite); + case SECONDARY: + return unify(opposite, ps); + case BOTH: + return unify(ps, opposite); + default: + return null; + } + } + + /** + * Abstract handler for update event. + * + * @param side + * The side on which the event occured. + * @param direction + * The direction of the update. + * @param updateElement + * The partial matching that is inserted. + * @param signature + * Masked signature of updateElement. + * @param change + * Indicates whether this is/was the first/last instance of this signature in this slot. + */ + public abstract void notifyUpdate(Side side, Direction direction, Tuple updateElement, Tuple signature, + boolean change); + + /** + * Simulates the behaviour of the node for calibration purposes only. + */ + public abstract Tuple calibrate(Tuple primary, Tuple secondary); + + /** + * @param complementerSecondaryMask + * the complementerSecondaryMask to set + */ + public void setComplementerSecondaryMask(TupleMask complementerSecondaryMask) { + this.complementerSecondaryMask = complementerSecondaryMask; + } + + /** + * Retrieves the slot corresponding to the specified side. + */ + protected Indexer getSlot(Side side) { + if (side == Side.SECONDARY) + return secondarySlot; + else + return primarySlot; + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/ExistenceNode.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/ExistenceNode.java index 8f521692..a52b80ad 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/ExistenceNode.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/ExistenceNode.java @@ -17,78 +17,74 @@ import org.eclipse.incquery.runtime.rete.network.ReteContainer; import org.eclipse.incquery.runtime.rete.tuple.Tuple; - /** - * Propagates all substitutions arriving at the PRIMARY slot if and only if (a - * matching substitution on the SECONDARY is present) xor (NEGATIVE). + * Propagates all substitutions arriving at the PRIMARY slot if and only if (a matching substitution on the SECONDARY is + * present) xor (NEGATIVE). * - * The negative parameter specifies whether this node checks for existence or - * non-existence. + * The negative parameter specifies whether this node checks for existence or non-existence. * * @author Gabor Bergmann */ public class ExistenceNode extends DualInputNode { - protected boolean negative; + protected boolean negative; - /** - * @param reteContainer - * @param primarySlot - * @param secondarySlot - * @param negative - * if false, act as axistence checker, otherwise a - * nonexistence-checker - */ - public ExistenceNode(ReteContainer reteContainer, IterableIndexer primarySlot, - Indexer secondarySlot, boolean negative) { - super(reteContainer, primarySlot, secondarySlot, null); - this.negative = negative; - } + /** + * @param reteContainer + * @param primarySlot + * @param secondarySlot + * @param negative + * if false, act as axistence checker, otherwise a nonexistence-checker + */ + public ExistenceNode(ReteContainer reteContainer, IterableIndexer primarySlot, Indexer secondarySlot, + boolean negative) { + super(reteContainer, primarySlot, secondarySlot, null); + this.negative = negative; + } - @Override - public Tuple calibrate(Tuple primary, Tuple secondary) { - return primary; - } + @Override + public Tuple calibrate(Tuple primary, Tuple secondary) { + return primary; + } - @Override - public void notifyUpdate(Side side, Direction direction, - Tuple updateElement, Tuple signature, boolean change) { - switch (side) { - case PRIMARY: - if ((retrieveOpposites(side, signature) != null) ^ negative) - propagateUpdate(direction, updateElement); - break; - case SECONDARY: - if (change) { - Collection opposites = retrieveOpposites(side, signature); - if (opposites != null) - for (Tuple opposite : opposites) { - propagateUpdate((negative ? direction.opposite() - : direction), opposite); - } - } - break; - case BOTH: - // in case the slots coincide, - // negative --> always empty - // !positive --> identity - if (!negative) { - propagateUpdate(direction, updateElement); - } - break; - } - } + @Override + public void notifyUpdate(Side side, Direction direction, Tuple updateElement, Tuple signature, boolean change) { + switch (side) { + case PRIMARY: + if ((retrieveOpposites(side, signature) != null) ^ negative) + propagateUpdate(direction, updateElement); + break; + case SECONDARY: + if (change) { + Collection opposites = retrieveOpposites(side, signature); + if (opposites != null) + for (Tuple opposite : opposites) { + propagateUpdate((negative ? direction.opposite() : direction), opposite); + } + } + break; + case BOTH: + // in case the slots coincide, + // negative --> always empty + // !positive --> identity + if (!negative) { + propagateUpdate(direction, updateElement); + } + break; + } + } - @Override + @Override public void pullInto(Collection collector) { - reteContainer.flushUpdates(); + reteContainer.flushUpdates(); - for (Tuple signature : primarySlot.getSignatures()) { - Collection primaries = primarySlot.get(signature); // not null due to the contract of IterableIndex.getSignatures() - Collection opposites = secondarySlot.get(signature); - if ((opposites != null) ^ negative) - collector.addAll(primaries); - } - } + for (Tuple signature : primarySlot.getSignatures()) { + Collection primaries = primarySlot.get(signature); // not null due to the contract of + // IterableIndex.getSignatures() + Collection opposites = secondarySlot.get(signature); + if ((opposites != null) ^ negative) + collector.addAll(primaries); + } + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/GenericProjectionIndexer.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/GenericProjectionIndexer.java index 1e8058fa..2121ad27 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/GenericProjectionIndexer.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/GenericProjectionIndexer.java @@ -20,46 +20,46 @@ import org.eclipse.incquery.runtime.rete.tuple.Tuple; import org.eclipse.incquery.runtime.rete.tuple.TupleMask; - /** - * A generic Indexer capable of indexing along any valid TupleMask. - * Does not keep track of parents, because will not ever pull parents. + * A generic Indexer capable of indexing along any valid TupleMask. Does not keep track of parents, because will not + * ever pull parents. + * * @author Bergmann Gábor - * + * */ public class GenericProjectionIndexer extends IndexerWithMemory implements ProjectionIndexer { - /** - * @param side - * @param node - */ - public GenericProjectionIndexer(ReteContainer reteContainer, TupleMask mask) { - super(reteContainer, mask); - } + /** + * @param side + * @param node + */ + public GenericProjectionIndexer(ReteContainer reteContainer, TupleMask mask) { + super(reteContainer, mask); + } - @Override - protected void update(Direction direction, Tuple updateElement, Tuple signature, boolean change) { - propagate(direction, updateElement,signature, change); - } + @Override + protected void update(Direction direction, Tuple updateElement, Tuple signature, boolean change) { + propagate(direction, updateElement, signature, change); + } - @Override + @Override public Collection get(Tuple signature) { - return memory.get(signature); - } + return memory.get(signature); + } - @Override + @Override public Iterator iterator() { - return memory.iterator(); - } + return memory.iterator(); + } - @Override + @Override public Collection getSignatures() { - return memory.getSignatures(); - } + return memory.getSignatures(); + } + + @Override + public Receiver getActiveNode() { + return this; + } - @Override - public Receiver getActiveNode() { - return this; - } - } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/IdentityIndexer.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/IdentityIndexer.java index bbbcfb70..85b23278 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/IdentityIndexer.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/IdentityIndexer.java @@ -23,46 +23,49 @@ import org.eclipse.incquery.runtime.rete.tuple.TupleMask; /** - * Defines an abstract trivial indexer that identically projects the contents of some stateful node, and can therefore save space. - * Can only exist in connection with a stateful store, and must be operated by another node (the active node). Do not attach parents directly! + * Defines an abstract trivial indexer that identically projects the contents of some stateful node, and can therefore + * save space. Can only exist in connection with a stateful store, and must be operated by another node (the active + * node). Do not attach parents directly! + * * @author Bergmann Gábor */ public abstract class IdentityIndexer extends SpecializedProjectionIndexer { - protected abstract Collection getTuples(); + protected abstract Collection getTuples(); - /** - * @param reteContainer - * @param mask - */ - public IdentityIndexer(ReteContainer reteContainer, int tupleWidth, Supplier parent, Node activeNode) { - super(reteContainer, TupleMask.identity(tupleWidth), parent, activeNode); - } + /** + * @param reteContainer + * @param mask + */ + public IdentityIndexer(ReteContainer reteContainer, int tupleWidth, Supplier parent, Node activeNode) { + super(reteContainer, TupleMask.identity(tupleWidth), parent, activeNode); + } - public Collection get(Tuple signature) { - if (contains(signature)) { - return Collections.singleton(signature); - } else return null; - } + public Collection get(Tuple signature) { + if (contains(signature)) { + return Collections.singleton(signature); + } else + return null; + } - /** - * @param signature - * @return - */ - protected boolean contains(Tuple signature) { - return getTuples().contains(signature); - } + /** + * @param signature + * @return + */ + protected boolean contains(Tuple signature) { + return getTuples().contains(signature); + } - public Collection getSignatures() { - return getTuples(); - } + public Collection getSignatures() { + return getTuples(); + } - public Iterator iterator() { - return getTuples().iterator(); - } + public Iterator iterator() { + return getTuples().iterator(); + } - public void propagate(Direction direction, Tuple updateElement) { - propagate(direction, updateElement, updateElement, true); - } + public void propagate(Direction direction, Tuple updateElement) { + propagate(direction, updateElement, updateElement, true); + } } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/Indexer.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/Indexer.java index b21f4870..cfbb9a81 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/Indexer.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/Indexer.java @@ -18,40 +18,43 @@ import org.eclipse.incquery.runtime.rete.tuple.Tuple; import org.eclipse.incquery.runtime.rete.tuple.TupleMask; - /** - * A node that indexes incoming Tuples by their signatures as specified by a - * TupleMask. Notifies listeners about such update events through the IndexerListener. + * A node that indexes incoming Tuples by their signatures as specified by a TupleMask. Notifies listeners about such + * update events through the IndexerListener. + * + * Signature tuples are created by transforming the update tuples using the mask. Tuples stored with the same signature + * are grouped together. The group or a reduction thereof is retrievable. * - * Signature tuples are created by transforming the update tuples using the mask. - * Tuples stored with the same signature are grouped together. The group or a reduction thereof is retrievable. * @author Gabor Bergmann */ public interface Indexer extends Node { - /** - * @return the mask by which the contents are indexed. - */ - public TupleMask getMask(); - - /** - * @return the node whose contents are indexed. - */ - public Supplier getParent(); - - /** - * @return all stored tuples that conform to the specified signature, null if there are none such. - * CONTRACT: do not modify! - */ - public Collection get(Tuple signature); - - /** - * This indexer will be updated whenever a Rete update is sent to the active node (or an equivalent time slot allotted to it). - * The active node is typically the indexer itself, but it can be a different node such as its parent. - * @return the active node that operates this indexer - */ - public Node getActiveNode(); - - public void attachListener(IndexerListener listener); - public void detachListener(IndexerListener listener); + /** + * @return the mask by which the contents are indexed. + */ + public TupleMask getMask(); + + /** + * @return the node whose contents are indexed. + */ + public Supplier getParent(); + + /** + * @return all stored tuples that conform to the specified signature, null if there are none such. CONTRACT: do not + * modify! + */ + public Collection get(Tuple signature); + + /** + * This indexer will be updated whenever a Rete update is sent to the active node (or an equivalent time slot + * allotted to it). The active node is typically the indexer itself, but it can be a different node such as its + * parent. + * + * @return the active node that operates this indexer + */ + public Node getActiveNode(); + + public void attachListener(IndexerListener listener); + + public void detachListener(IndexerListener listener); } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/IndexerListener.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/IndexerListener.java index b1ea8607..c2ccee31 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/IndexerListener.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/IndexerListener.java @@ -16,20 +16,26 @@ import org.eclipse.incquery.runtime.rete.tuple.Tuple; /** - * A listener for update events concerning an Indexer. + * A listener for update events concerning an Indexer. + * * @author Bergmann Gábor - * + * */ public interface IndexerListener { - /** - * Notifies recipient that the indexer has just received an update. - * Contract: indexer already reflects the updated state. - * @param direction the direction of the update. - * @param updateElement the tuple that was updated. - * @param signature the signature of the tuple according to the indexer's mask. - * @param change whether this was the first inserted / last revoked update element with this particular signature. - */ - void notifyIndexerUpdate(Direction direction, Tuple updateElement, Tuple signature, boolean change); - - Node getOwner(); + /** + * Notifies recipient that the indexer has just received an update. Contract: indexer already reflects the updated + * state. + * + * @param direction + * the direction of the update. + * @param updateElement + * the tuple that was updated. + * @param signature + * the signature of the tuple according to the indexer's mask. + * @param change + * whether this was the first inserted / last revoked update element with this particular signature. + */ + void notifyIndexerUpdate(Direction direction, Tuple updateElement, Tuple signature, boolean change); + + Node getOwner(); } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/IndexerWithMemory.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/IndexerWithMemory.java index 95dfd6af..69ec9665 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/IndexerWithMemory.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/IndexerWithMemory.java @@ -24,63 +24,62 @@ /** * @author Bergmann Gábor - * + * */ public abstract class IndexerWithMemory extends StandardIndexer implements Receiver { - protected MaskedTupleMemory memory; + protected MaskedTupleMemory memory; - public MaskedTupleMemory getMemory() { - return memory; - } + public MaskedTupleMemory getMemory() { + return memory; + } - /** - * @param reteContainer - * @param mask - */ - public IndexerWithMemory(ReteContainer reteContainer, TupleMask mask) { - super(reteContainer, mask); - this.memory = new MaskedTupleMemory(mask); - reteContainer.registerClearable(memory); - } + /** + * @param reteContainer + * @param mask + */ + public IndexerWithMemory(ReteContainer reteContainer, TupleMask mask) { + super(reteContainer, mask); + this.memory = new MaskedTupleMemory(mask); + reteContainer.registerClearable(memory); + } - @Override + @Override public void update(Direction direction, Tuple updateElement) { - Tuple signature = mask.transform(updateElement); - boolean change = (direction == Direction.INSERT) ? memory.add( - updateElement, signature) : memory.remove(updateElement, - signature); - update(direction, updateElement,signature, change); - } + Tuple signature = mask.transform(updateElement); + boolean change = (direction == Direction.INSERT) ? memory.add(updateElement, signature) : memory.remove( + updateElement, signature); + update(direction, updateElement, signature, change); + } - /** - * Refined version of update - */ - protected abstract void update(Direction direction, Tuple updateElement, Tuple signature, boolean change); + /** + * Refined version of update + */ + protected abstract void update(Direction direction, Tuple updateElement, Tuple signature, boolean change); - @Override + @Override public void appendParent(Supplier supplier) { - if (parent == null) - parent = supplier; - else - throw new UnsupportedOperationException("Illegal RETE edge: " + this + " already has a parent (" + - parent + ") and cannot connect to additional parent (" + supplier + - "). "); - } + if (parent == null) + parent = supplier; + else + throw new UnsupportedOperationException("Illegal RETE edge: " + this + " already has a parent (" + parent + + ") and cannot connect to additional parent (" + supplier + "). "); + } - @Override + @Override public void removeParent(Supplier supplier) { - if (parent == supplier) - parent = null; - else - throw new IllegalArgumentException("Illegal RETE edge removal: the parent of " + this + " is not " + supplier); - } - - @Override - public Collection getParents() { - Vector v = new Vector(); - v.add(parent); - return v; - } - + if (parent == supplier) + parent = null; + else + throw new IllegalArgumentException("Illegal RETE edge removal: the parent of " + this + " is not " + + supplier); + } + + @Override + public Collection getParents() { + Vector v = new Vector(); + v.add(parent); + return v; + } + } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/IterableIndexer.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/IterableIndexer.java index 5cfc7c92..b8283850 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/IterableIndexer.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/IterableIndexer.java @@ -19,13 +19,12 @@ * An indexer that allows the iteration of all retrievable tuple groups (or reduced groups). * * @author Bergmann Gábor - * + * */ public interface IterableIndexer extends Indexer, Iterable { - /** - * A collection consisting of exactly those signatures whose tuple group is not empty - * CONTRACT: do not modify - */ - public Collection getSignatures(); + /** + * A collection consisting of exactly those signatures whose tuple group is not empty CONTRACT: do not modify + */ + public Collection getSignatures(); } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/JoinNode.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/JoinNode.java index 5ac70b7b..d16ff9c5 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/JoinNode.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/JoinNode.java @@ -18,86 +18,85 @@ import org.eclipse.incquery.runtime.rete.tuple.Tuple; import org.eclipse.incquery.runtime.rete.tuple.TupleMask; - /** * @author Gabor Bergmann * */ public class JoinNode extends DualInputNode { - /** - * @param reteContainer - * @param primarySlot - * @param secondarySlot - */ - public JoinNode(ReteContainer reteContainer, IterableIndexer primarySlot, - Indexer secondarySlot, TupleMask complementerSecondaryMask) { - super(reteContainer, primarySlot, secondarySlot, - complementerSecondaryMask); - // TODO Auto-generated constructor stub - } + /** + * @param reteContainer + * @param primarySlot + * @param secondarySlot + */ + public JoinNode(ReteContainer reteContainer, IterableIndexer primarySlot, Indexer secondarySlot, + TupleMask complementerSecondaryMask) { + super(reteContainer, primarySlot, secondarySlot, complementerSecondaryMask); + // TODO Auto-generated constructor stub + } + + @Override + public Tuple calibrate(Tuple primary, Tuple secondary) { + return unify(primary, secondary); + } + + // public static Tuple calibrate(Tuple primary, Tuple secondary, + // TupleMask complementerSecondaryMask) { + // return complementerSecondaryMask.combine(primary, secondary, + // Options.enableInheritance, true); + // } - @Override - public Tuple calibrate(Tuple primary, Tuple secondary) { - return unify(primary, secondary); - } + @Override + public void notifyUpdate(Side side, Direction direction, Tuple updateElement, Tuple signature, boolean change) { + Collection opposites = retrieveOpposites(side, signature); -// public static Tuple calibrate(Tuple primary, Tuple secondary, -// TupleMask complementerSecondaryMask) { -// return complementerSecondaryMask.combine(primary, secondary, -// Options.enableInheritance, true); -// } + if (opposites != null) { + for (Tuple opposite : opposites) { + propagateUpdate(direction, unify(side, updateElement, opposite)); + } + } - @Override - public void notifyUpdate(Side side, Direction direction, - Tuple updateElement, Tuple signature, boolean change) - { - Collection opposites = retrieveOpposites(side, signature); - - if (opposites != null) { - for (Tuple opposite : opposites) { - propagateUpdate(direction, unify(side, updateElement, opposite)); - } - } - - // compensate for coincidence of slots - if (coincidence) { - if (opposites != null) { - for (Tuple opposite : opposites) { - if (opposite.equals(updateElement)) continue; // INSERT: already joined with itself - propagateUpdate(direction, unify(opposite, updateElement)); - } - } - if (direction==Direction.REVOKE) // missed joining with itself - propagateUpdate(direction, unify(updateElement, updateElement)); -// -// switch(direction) { -// case INSERT: -// opposites = new ArrayList(opposites); -// opposites.remove(updateElement); -// break; -// case REVOKE: -// opposites = (opposites == null) ? new ArrayList() : new ArrayList(opposites); -// opposites.add(updateElement); -// break; -// } -// - } - } + // compensate for coincidence of slots + if (coincidence) { + if (opposites != null) { + for (Tuple opposite : opposites) { + if (opposite.equals(updateElement)) + continue; // INSERT: already joined with itself + propagateUpdate(direction, unify(opposite, updateElement)); + } + } + if (direction == Direction.REVOKE) // missed joining with itself + propagateUpdate(direction, unify(updateElement, updateElement)); + // + // switch(direction) { + // case INSERT: + // opposites = new ArrayList(opposites); + // opposites.remove(updateElement); + // break; + // case REVOKE: + // opposites = (opposites == null) ? new ArrayList() : new ArrayList(opposites); + // opposites.add(updateElement); + // break; + // } + // + } + } - @Override + @Override public void pullInto(Collection collector) { - reteContainer.flushUpdates(); + reteContainer.flushUpdates(); - for (Tuple signature : primarySlot.getSignatures()) { - Collection primaries = primarySlot.get(signature); // not null due to the contract of IterableIndex.getSignatures() - Collection opposites = secondarySlot.get(signature); - if (opposites != null) - for (Tuple ps: primaries) for (Tuple opposite : opposites) { - collector.add(unify(ps, opposite)); - } - } + for (Tuple signature : primarySlot.getSignatures()) { + Collection primaries = primarySlot.get(signature); // not null due to the contract of + // IterableIndex.getSignatures() + Collection opposites = secondarySlot.get(signature); + if (opposites != null) + for (Tuple ps : primaries) + for (Tuple opposite : opposites) { + collector.add(unify(ps, opposite)); + } + } - } + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/MemoryIdentityIndexer.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/MemoryIdentityIndexer.java index 0e9e8630..851da86c 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/MemoryIdentityIndexer.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/MemoryIdentityIndexer.java @@ -18,32 +18,38 @@ import org.eclipse.incquery.runtime.rete.network.Supplier; import org.eclipse.incquery.runtime.rete.tuple.Tuple; - /** - * Defines a trivial indexer that identically projects the contents of a memory-equipped node, and can therefore save space. - * Can only exist in connection with a memory, and must be operated by another node. Do not attach parents directly! + * Defines a trivial indexer that identically projects the contents of a memory-equipped node, and can therefore save + * space. Can only exist in connection with a memory, and must be operated by another node. Do not attach parents + * directly! + * * @author Bergmann Gábor */ public class MemoryIdentityIndexer extends IdentityIndexer { - Collection memory; - /** - * @param reteContainer - * @param tupleWidth the width of the tuples of memoryNode - * @param memory the memory whose contents are to be identity-indexed - * @param parent the parent node that owns the memory - */ - public MemoryIdentityIndexer(ReteContainer reteContainer, int tupleWidth, Collection memory, Supplier parent, Receiver activeNode) { - super(reteContainer, tupleWidth, parent, activeNode); - this.memory = memory; - } - - /** - * @return - */ - @Override - protected Collection getTuples() { - return memory; - } + Collection memory; + + /** + * @param reteContainer + * @param tupleWidth + * the width of the tuples of memoryNode + * @param memory + * the memory whose contents are to be identity-indexed + * @param parent + * the parent node that owns the memory + */ + public MemoryIdentityIndexer(ReteContainer reteContainer, int tupleWidth, Collection memory, + Supplier parent, Receiver activeNode) { + super(reteContainer, tupleWidth, parent, activeNode); + this.memory = memory; + } + + /** + * @return + */ + @Override + protected Collection getTuples() { + return memory; + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/MemoryNullIndexer.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/MemoryNullIndexer.java index d8803fd6..b04be893 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/MemoryNullIndexer.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/MemoryNullIndexer.java @@ -18,32 +18,38 @@ import org.eclipse.incquery.runtime.rete.network.Supplier; import org.eclipse.incquery.runtime.rete.tuple.Tuple; - /** - * Defines a trivial indexer that projects the contents of a memory-equipped node to the empty tuple, and can therefore save space. - * Can only exist in connection with a memory, and must be operated by another node. Do not attach parents directly! + * Defines a trivial indexer that projects the contents of a memory-equipped node to the empty tuple, and can therefore + * save space. Can only exist in connection with a memory, and must be operated by another node. Do not attach parents + * directly! + * * @author Bergmann Gábor */ public class MemoryNullIndexer extends NullIndexer { - Collection memory; - /** - * @param reteContainer - * @param tupleWidth the width of the tuples of memoryNode - * @param memory the memory whose contents are to be null-indexed - * @param parent the parent node that owns the memory - */ - public MemoryNullIndexer(ReteContainer reteContainer, int tupleWidth, Collection memory, Supplier parent, Receiver activeNode) { - super(reteContainer, tupleWidth, parent, activeNode); - this.memory = memory; - } - - /** - * @return - */ - @Override - protected Collection getTuples() { - return memory; - } + Collection memory; + + /** + * @param reteContainer + * @param tupleWidth + * the width of the tuples of memoryNode + * @param memory + * the memory whose contents are to be null-indexed + * @param parent + * the parent node that owns the memory + */ + public MemoryNullIndexer(ReteContainer reteContainer, int tupleWidth, Collection memory, Supplier parent, + Receiver activeNode) { + super(reteContainer, tupleWidth, parent, activeNode); + this.memory = memory; + } + + /** + * @return + */ + @Override + protected Collection getTuples() { + return memory; + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/NullIndexer.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/NullIndexer.java index cff606cc..c59cef4b 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/NullIndexer.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/NullIndexer.java @@ -24,50 +24,55 @@ import org.eclipse.incquery.runtime.rete.tuple.TupleMask; /** - * Defines an abstract trivial indexer that projects the contents of some stateful node to the empty tuple, and can therefore save space. - * Can only exist in connection with a stateful store, and must be operated by another node (the active node). Do not attach parents directly! + * Defines an abstract trivial indexer that projects the contents of some stateful node to the empty tuple, and can + * therefore save space. Can only exist in connection with a stateful store, and must be operated by another node (the + * active node). Do not attach parents directly! + * * @author Bergmann Gábor */ public abstract class NullIndexer extends SpecializedProjectionIndexer { - protected abstract Collection getTuples(); + protected abstract Collection getTuples(); - static Object[] empty = {}; - static Tuple nullSignature = new FlatTuple(empty); - static Collection nullSingleton = Collections.singleton(nullSignature); - static Collection emptySet = Collections.emptySet(); + static Object[] empty = {}; + static Tuple nullSignature = new FlatTuple(empty); + static Collection nullSingleton = Collections.singleton(nullSignature); + static Collection emptySet = Collections.emptySet(); - public NullIndexer(ReteContainer reteContainer, int tupleWidth, Supplier parent, Node activeNode) { - super(reteContainer, TupleMask.linear(0, tupleWidth), parent, activeNode); - } + public NullIndexer(ReteContainer reteContainer, int tupleWidth, Supplier parent, Node activeNode) { + super(reteContainer, TupleMask.linear(0, tupleWidth), parent, activeNode); + } - public Collection get(Tuple signature) { - if (nullSignature.equals(signature)) return isEmpty()? null :getTuples(); - else return null; - } + public Collection get(Tuple signature) { + if (nullSignature.equals(signature)) + return isEmpty() ? null : getTuples(); + else + return null; + } - public Collection getSignatures() { - return isEmpty() ? emptySet : nullSingleton; - } + public Collection getSignatures() { + return isEmpty() ? emptySet : nullSingleton; + } - /** - * @return - */ - protected boolean isEmpty() { - return getTuples().isEmpty(); - } - protected boolean isSingleElement() { - return getTuples().size() == 1; - } + /** + * @return + */ + protected boolean isEmpty() { + return getTuples().isEmpty(); + } - public Iterator iterator() { - return getTuples().iterator(); - } + protected boolean isSingleElement() { + return getTuples().size() == 1; + } - public void propagate(Direction direction, Tuple updateElement) { - boolean radical = (direction==Direction.REVOKE && isEmpty()) || (direction==Direction.INSERT && isSingleElement()); - propagate(direction, updateElement, nullSignature, radical); - } + public Iterator iterator() { + return getTuples().iterator(); + } + public void propagate(Direction direction, Tuple updateElement) { + boolean radical = (direction == Direction.REVOKE && isEmpty()) + || (direction == Direction.INSERT && isSingleElement()); + propagate(direction, updateElement, nullSignature, radical); + } } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/OnetimeIndexer.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/OnetimeIndexer.java index e12a362e..fe0444e9 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/OnetimeIndexer.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/OnetimeIndexer.java @@ -18,36 +18,32 @@ import org.eclipse.incquery.runtime.rete.tuple.Tuple; import org.eclipse.incquery.runtime.rete.tuple.TupleMask; - /** - * @author Gabor Bergmann Indexer whose lifetime last until the first get() DO - * NOT connect to nodes! + * @author Gabor Bergmann Indexer whose lifetime last until the first get() DO NOT connect to nodes! */ public class OnetimeIndexer extends GenericProjectionIndexer { - public OnetimeIndexer(ReteContainer reteContainer, TupleMask mask) { - super(reteContainer, mask); - } - - @Override - public Collection get(Tuple signature) { - if (org.eclipse.incquery.runtime.rete.util.Options.releaseOnetimeIndexers) { - reteContainer.unregisterClearable(memory); - reteContainer.unregisterNode(this); - } - return super.get(signature); - } - - @Override - public void appendParent(Supplier supplier) { - throw new UnsupportedOperationException( - "onetime indexer cannot have parents"); - } - - @Override - public void attachListener(IndexerListener listener) { - throw new UnsupportedOperationException( - "onetime indexer cannot have listeners"); - } + public OnetimeIndexer(ReteContainer reteContainer, TupleMask mask) { + super(reteContainer, mask); + } + + @Override + public Collection get(Tuple signature) { + if (org.eclipse.incquery.runtime.rete.util.Options.releaseOnetimeIndexers) { + reteContainer.unregisterClearable(memory); + reteContainer.unregisterNode(this); + } + return super.get(signature); + } + + @Override + public void appendParent(Supplier supplier) { + throw new UnsupportedOperationException("onetime indexer cannot have parents"); + } + + @Override + public void attachListener(IndexerListener listener) { + throw new UnsupportedOperationException("onetime indexer cannot have listeners"); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/OuterJoinNode.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/OuterJoinNode.java index c2212b14..459617b3 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/OuterJoinNode.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/OuterJoinNode.java @@ -22,84 +22,85 @@ * Performs a left outer join. * * @author Bergmann Gábor - * + * */ public class OuterJoinNode extends DualInputNode { - final Tuple defaults; + final Tuple defaults; - /** - * @param reteContainer - * @param primarySlot - * @param secondarySlot - * @param complementerSecondaryMask - * @param defaults the default line to use instead of missing elements if a left tuple has no match - * - */ - public OuterJoinNode(ReteContainer reteContainer, - IterableIndexer primarySlot, Indexer secondarySlot, - TupleMask complementerSecondaryMask, Tuple defaults) { - super(reteContainer, primarySlot, secondarySlot, - complementerSecondaryMask); - this.defaults = defaults; - } + /** + * @param reteContainer + * @param primarySlot + * @param secondarySlot + * @param complementerSecondaryMask + * @param defaults + * the default line to use instead of missing elements if a left tuple has no match + * + */ + public OuterJoinNode(ReteContainer reteContainer, IterableIndexer primarySlot, Indexer secondarySlot, + TupleMask complementerSecondaryMask, Tuple defaults) { + super(reteContainer, primarySlot, secondarySlot, complementerSecondaryMask); + this.defaults = defaults; + } - @Override - public Tuple calibrate(Tuple primary, Tuple secondary) { - return unify(primary, secondary); - } + @Override + public Tuple calibrate(Tuple primary, Tuple secondary) { + return unify(primary, secondary); + } - @Override - public void notifyUpdate(Side side, Direction direction, - Tuple updateElement, Tuple signature, boolean change) { - Collection opposites = retrieveOpposites(side, signature); - switch (side) { - case PRIMARY: - if (opposites != null) - for (Tuple opposite : opposites) { - propagateUpdate(direction, unify(updateElement, opposite)); - } - else - propagateUpdate(direction, unifyWithDefaults(updateElement)); - break; - case SECONDARY: - if (opposites != null) - for (Tuple opposite : opposites) { - propagateUpdate(direction, unify(opposite, updateElement)); - if (change) - propagateUpdate(direction.opposite(), unifyWithDefaults(opposite)); - } - break; - case BOTH: - for (Tuple opposite : opposites) { - propagateUpdate(direction, unify(updateElement, opposite)); - if (updateElement.equals(opposite)) continue; - propagateUpdate(direction, unify(opposite, updateElement)); - } - if (direction==Direction.REVOKE) // missed joining with itself - propagateUpdate(direction, unify(updateElement, updateElement)); - } - } + @Override + public void notifyUpdate(Side side, Direction direction, Tuple updateElement, Tuple signature, boolean change) { + Collection opposites = retrieveOpposites(side, signature); + switch (side) { + case PRIMARY: + if (opposites != null) + for (Tuple opposite : opposites) { + propagateUpdate(direction, unify(updateElement, opposite)); + } + else + propagateUpdate(direction, unifyWithDefaults(updateElement)); + break; + case SECONDARY: + if (opposites != null) + for (Tuple opposite : opposites) { + propagateUpdate(direction, unify(opposite, updateElement)); + if (change) + propagateUpdate(direction.opposite(), unifyWithDefaults(opposite)); + } + break; + case BOTH: + for (Tuple opposite : opposites) { + propagateUpdate(direction, unify(updateElement, opposite)); + if (updateElement.equals(opposite)) + continue; + propagateUpdate(direction, unify(opposite, updateElement)); + } + if (direction == Direction.REVOKE) // missed joining with itself + propagateUpdate(direction, unify(updateElement, updateElement)); + } + } - @Override + @Override public void pullInto(Collection collector) { - reteContainer.flushUpdates(); + reteContainer.flushUpdates(); - for (Tuple signature : primarySlot.getSignatures()) { - Collection primaries = primarySlot.get(signature); // not null due to the contract of IterableIndex.getSignatures() - Collection opposites = secondarySlot.get(signature); - if (opposites != null) - for (Tuple ps: primaries) for (Tuple opposite : opposites) { - collector.add(unify(ps, opposite)); - } - else - for (Tuple ps: primaries) { - collector.add(unifyWithDefaults(ps)); - } - } - } + for (Tuple signature : primarySlot.getSignatures()) { + Collection primaries = primarySlot.get(signature); // not null due to the contract of + // IterableIndex.getSignatures() + Collection opposites = secondarySlot.get(signature); + if (opposites != null) + for (Tuple ps : primaries) + for (Tuple opposite : opposites) { + collector.add(unify(ps, opposite)); + } + else + for (Tuple ps : primaries) { + collector.add(unifyWithDefaults(ps)); + } + } + } - private Tuple unifyWithDefaults(Tuple ps) { - return unify(ps, defaults); - } + private Tuple unifyWithDefaults(Tuple ps) { + return unify(ps, defaults); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/ProjectionIndexer.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/ProjectionIndexer.java index e736c63d..a8372638 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/ProjectionIndexer.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/ProjectionIndexer.java @@ -11,12 +11,12 @@ package org.eclipse.incquery.runtime.rete.index; - /** - * An iterable indexer that receives updates from a node, and groups received tuples intact, i.e. it does not reduce tuple groups. + * An iterable indexer that receives updates from a node, and groups received tuples intact, i.e. it does not reduce + * tuple groups. * * @author Bergmann Gábor - * + * */ public interface ProjectionIndexer extends IterableIndexer { diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/SpecializedProjectionIndexer.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/SpecializedProjectionIndexer.java index 3e6cee9c..3ceded9a 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/SpecializedProjectionIndexer.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/SpecializedProjectionIndexer.java @@ -20,21 +20,21 @@ * A specialized projection indexer that can be memory-less (relying on an external source of information). * * @author Bergmann Gábor - * + * */ public abstract class SpecializedProjectionIndexer extends StandardIndexer implements ProjectionIndexer { - - protected Node activeNode; - public SpecializedProjectionIndexer(ReteContainer reteContainer, TupleMask mask, Supplier parent, Node activeNode) { - super(reteContainer, mask); - this.parent = parent; - this.activeNode = activeNode; - } + protected Node activeNode; + + public SpecializedProjectionIndexer(ReteContainer reteContainer, TupleMask mask, Supplier parent, Node activeNode) { + super(reteContainer, mask); + this.parent = parent; + this.activeNode = activeNode; + } - @Override - public Node getActiveNode() { - return activeNode; - } + @Override + public Node getActiveNode() { + return activeNode; + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/StandardIndexer.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/StandardIndexer.java index 02229c19..0a95d107 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/StandardIndexer.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/StandardIndexer.java @@ -21,88 +21,89 @@ import org.eclipse.incquery.runtime.rete.tuple.Tuple; import org.eclipse.incquery.runtime.rete.tuple.TupleMask; - /** * An abstract standard implementation of the Indexer interface, providing common bookkeeping functionality. + * * @author Bergmann Gábor - * + * */ public abstract class StandardIndexer implements Indexer { - - protected ReteContainer reteContainer; - protected long nodeId; - protected Object tag; - protected Supplier parent; - protected List listeners; - protected TupleMask mask; - - public StandardIndexer(ReteContainer reteContainer, TupleMask mask) { - super(); - this.reteContainer = reteContainer; - this.nodeId = reteContainer.registerNode(this); - this.parent = null; - this.mask = mask; - this.listeners = new ArrayList(); - } - - protected void propagate(Direction direction, Tuple updateElement, Tuple signature, boolean change) { - for (IndexerListener listener : listeners) { - listener.notifyIndexerUpdate(direction, updateElement, signature, change); - } - } - - /** - * @return the mask - */ - public TupleMask getMask() { - return mask; - } - - public Supplier getParent() { - return parent; - } - - public void attachListener(IndexerListener listener) { - listeners.add(listener); - } - - public void detachListener(IndexerListener listener) { - listeners.remove(listener); - } - - public Collection getListeners() { - return listeners; - } - - public ReteContainer getContainer() { - return reteContainer; - } - - public long getNodeId() { - return nodeId; - } - - /** - * @return the tag - */ - public Object getTag() { - return tag; - } - - /** - * @param tag - * the tag to set - */ - public void setTag(Object tag) { - this.tag = tag; - } - - @Override - public String toString() { - if (tag != null) - return "[" + nodeId+ "]" + getClass().getSimpleName() + "("+ parent + "/"+ mask+")" + " [[" + tag.toString() + "]]"; - else - return "[" + nodeId+ "]" + getClass().getSimpleName() + "("+ parent + "/"+ mask+")"; - }; + + protected ReteContainer reteContainer; + protected long nodeId; + protected Object tag; + protected Supplier parent; + protected List listeners; + protected TupleMask mask; + + public StandardIndexer(ReteContainer reteContainer, TupleMask mask) { + super(); + this.reteContainer = reteContainer; + this.nodeId = reteContainer.registerNode(this); + this.parent = null; + this.mask = mask; + this.listeners = new ArrayList(); + } + + protected void propagate(Direction direction, Tuple updateElement, Tuple signature, boolean change) { + for (IndexerListener listener : listeners) { + listener.notifyIndexerUpdate(direction, updateElement, signature, change); + } + } + + /** + * @return the mask + */ + public TupleMask getMask() { + return mask; + } + + public Supplier getParent() { + return parent; + } + + public void attachListener(IndexerListener listener) { + listeners.add(listener); + } + + public void detachListener(IndexerListener listener) { + listeners.remove(listener); + } + + public Collection getListeners() { + return listeners; + } + + public ReteContainer getContainer() { + return reteContainer; + } + + public long getNodeId() { + return nodeId; + } + + /** + * @return the tag + */ + public Object getTag() { + return tag; + } + + /** + * @param tag + * the tag to set + */ + public void setTag(Object tag) { + this.tag = tag; + } + + @Override + public String toString() { + if (tag != null) + return "[" + nodeId + "]" + getClass().getSimpleName() + "(" + parent + "/" + mask + ")" + " [[" + + tag.toString() + "]]"; + else + return "[" + nodeId + "]" + getClass().getSimpleName() + "(" + parent + "/" + mask + ")"; + }; } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/TransitiveClosureNodeIndexer.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/TransitiveClosureNodeIndexer.java index 5499a21a..a2ce8204 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/TransitiveClosureNodeIndexer.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/index/TransitiveClosureNodeIndexer.java @@ -26,86 +26,85 @@ import org.eclipse.incquery.runtime.rete.tuple.TupleMask; public class TransitiveClosureNodeIndexer extends StandardIndexer implements IterableIndexer { - private TransitiveClosureNode tcNode; - private IncSCCAlg tcAlg; - private Collection emptySet; - - public TransitiveClosureNodeIndexer(TupleMask mask, IncSCCAlg tcAlg, TransitiveClosureNode tcNode) { - super(tcNode.getContainer(), mask); - this.tcAlg = tcAlg; - this.tcNode = tcNode; - this.emptySet = Collections.emptySet(); - } - - @Override - public Collection get(Tuple signature) { - if (signature.getSize() == mask.sourceWidth) { - if (mask.indices.length == 0) { - //mask ()/2 - return getSignatures(); - } - else if (mask.indices.length == 1) { - Set retSet = new HashSet(); - - //mask (0)/2 - if (mask.indices[0] == 0) { - Object source = signature.get(0); - for (Object target : tcAlg.getAllReachableTargets(source)) { - retSet.add(new FlatTuple(source, target)); - } - return retSet; - } - //mask (1)/2 - if (mask.indices[0] == 1) { - Object target = signature.get(1); - for (Object source : tcAlg.getAllReachableSources(target)) { - retSet.add(new FlatTuple(source, target)); - } - return retSet; - } - } - else { - //mask (0,1)/2 - if (mask.indices[0] == 0 && mask.indices[1] == 1) { - Object source = signature.get(0); - Object target = signature.get(1); - Tuple singleton = new FlatTuple(new FlatTuple(source, target)); - return (tcAlg.isReachable(source, target) ? Collections.singleton(singleton) : emptySet); - } - //mask (1,0)/2 - if (mask.indices[0] == 1 && mask.indices[1] == 0) { - Object source = signature.get(1); - Object target = signature.get(0); - Tuple singleton = new FlatTuple(new FlatTuple(source, target)); - return (tcAlg.isReachable(source, target) ? Collections.singleton(singleton) : emptySet); - } - } - } - return null; - } - - public Collection getSignatures() { - return asTupleCollection(tcAlg.getTcRelation()); - } + private TransitiveClosureNode tcNode; + private IncSCCAlg tcAlg; + private Collection emptySet; - public Iterator iterator() { - return asTupleCollection(tcAlg.getTcRelation()).iterator(); - } - - private Collection asTupleCollection(Collection> tuples) { - Set retSet = new HashSet(); - for (org.eclipse.incquery.runtime.base.itc.alg.misc.Tuple tuple : tuples) { - retSet.add(new FlatTuple(tuple.getSource(), tuple.getTarget())); - } - return retSet; - } - - public void propagate(Direction direction, Tuple updateElement, boolean change) { - propagate(direction, updateElement, new MaskedTuple(updateElement, mask), change); - } + public TransitiveClosureNodeIndexer(TupleMask mask, IncSCCAlg tcAlg, TransitiveClosureNode tcNode) { + super(tcNode.getContainer(), mask); + this.tcAlg = tcAlg; + this.tcNode = tcNode; + this.emptySet = Collections.emptySet(); + } - @Override - public Receiver getActiveNode() { - return tcNode; - } + @Override + public Collection get(Tuple signature) { + if (signature.getSize() == mask.sourceWidth) { + if (mask.indices.length == 0) { + // mask ()/2 + return getSignatures(); + } else if (mask.indices.length == 1) { + Set retSet = new HashSet(); + + // mask (0)/2 + if (mask.indices[0] == 0) { + Object source = signature.get(0); + for (Object target : tcAlg.getAllReachableTargets(source)) { + retSet.add(new FlatTuple(source, target)); + } + return retSet; + } + // mask (1)/2 + if (mask.indices[0] == 1) { + Object target = signature.get(1); + for (Object source : tcAlg.getAllReachableSources(target)) { + retSet.add(new FlatTuple(source, target)); + } + return retSet; + } + } else { + // mask (0,1)/2 + if (mask.indices[0] == 0 && mask.indices[1] == 1) { + Object source = signature.get(0); + Object target = signature.get(1); + Tuple singleton = new FlatTuple(new FlatTuple(source, target)); + return (tcAlg.isReachable(source, target) ? Collections.singleton(singleton) : emptySet); + } + // mask (1,0)/2 + if (mask.indices[0] == 1 && mask.indices[1] == 0) { + Object source = signature.get(1); + Object target = signature.get(0); + Tuple singleton = new FlatTuple(new FlatTuple(source, target)); + return (tcAlg.isReachable(source, target) ? Collections.singleton(singleton) : emptySet); + } + } + } + return null; + } + + public Collection getSignatures() { + return asTupleCollection(tcAlg.getTcRelation()); + } + + public Iterator iterator() { + return asTupleCollection(tcAlg.getTcRelation()).iterator(); + } + + private Collection asTupleCollection( + Collection> tuples) { + Set retSet = new HashSet(); + for (org.eclipse.incquery.runtime.base.itc.alg.misc.Tuple tuple : tuples) { + retSet.add(new FlatTuple(tuple.getSource(), tuple.getTarget())); + } + return retSet; + } + + public void propagate(Direction direction, Tuple updateElement, boolean change) { + propagate(direction, updateElement, new MaskedTuple(updateElement, mask), change); + } + + @Override + public Receiver getActiveNode() { + return tcNode; + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/matcher/IPatternMatcherContext.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/matcher/IPatternMatcherContext.java index 3812ff2a..466d0e6c 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/matcher/IPatternMatcherContext.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/matcher/IPatternMatcherContext.java @@ -9,89 +9,102 @@ * Gabor Bergmann - initial API and implementation *******************************************************************************/ - package org.eclipse.incquery.runtime.rete.matcher; import java.util.Collection; - /** - * Represents all knowledge of the outside world towards the pattern matcher, - * but without specific run-time or build-time information. + * Represents all knowledge of the outside world towards the pattern matcher, but without specific run-time or + * build-time information. * * @author Bergmann Gábor - * - * @param the type describing a pattern + * + * @param + * the type describing a pattern */ public interface IPatternMatcherContext { - - /** - * @return TERNARY if edges have their own identity, BINARY if they are only pairs of source and target - */ - EdgeInterpretation edgeInterpretation(); - public enum EdgeInterpretation { - TERNARY /*VPM*/, - BINARY /*EMF*/ - } - - - Object ternaryEdgeTargetType(Object typeObject); // TODO global supertypes? - Object ternaryEdgeSourceType(Object typeObject); // TODO global supertypes? - Object binaryEdgeTargetType(Object typeObject); // TODO global supertypes? - Object binaryEdgeSourceType(Object typeObject); // TODO global supertypes? - - - /** - * @return the direction in which sub/supertypes arequeryable - */ - GeneralizationQueryDirection allowedGeneralizationQueryDirection(); - public enum GeneralizationQueryDirection { - /** - * Supertypes can be queried. Notifications registered for a supertype will be delivered for all subtypes. - */ - SUPERTYPE_ONLY_SMART_NOTIFICATIONS /*EMF based on IncQuery-Base*/, - /** - * Supertypes can be queried. Notifications are delivered for the registered types. - */ - SUPERTYPE_ONLY /*EMF legacy*/, - /** - * Supertypes and subtypes can be queried. Notifications are delivered for the registered types. - */ - BOTH /*VPM*/ - } - - boolean isUnaryType(Object typeObject); - Collection enumerateDirectUnarySubtypes(Object typeObject); - Collection enumerateDirectUnarySupertypes(Object typeObject); - boolean isTernaryEdgeType(Object typeObject); - Collection enumerateDirectTernaryEdgeSubtypes(Object typeObject); - Collection enumerateDirectTernaryEdgeSupertypes(Object typeObject); - boolean isBinaryEdgeType(Object typeObject); - Collection enumerateDirectBinaryEdgeSubtypes(Object typeObject); - Collection enumerateDirectBinaryEdgeSupertypes(Object typeObject); - - Collection enumerateDirectSupertypes(Object typeObject); - Collection enumerateDirectSubtypes(Object typeObject); - -// boolean checkBelowContainer(Object container, Object contained); -// boolean checkInContainer(Object container, Object contained); - - void reportPatternDependency(PatternDescription pattern); - - //Logger getLogger(); - void logFatal(String message); - void logFatal(String message, Throwable cause); - void logError(String message); - void logError(String message, Throwable cause); - void logWarning(String message); - void logWarning(String message, Throwable cause); - void logDebug(String message); - - - String printPattern(PatternDescription pattern); - String printType(Object typeObject); - - - - + + /** + * @return TERNARY if edges have their own identity, BINARY if they are only pairs of source and target + */ + EdgeInterpretation edgeInterpretation(); + + public enum EdgeInterpretation { + TERNARY /* VPM */, BINARY /* EMF */ + } + + Object ternaryEdgeTargetType(Object typeObject); // TODO global supertypes? + + Object ternaryEdgeSourceType(Object typeObject); // TODO global supertypes? + + Object binaryEdgeTargetType(Object typeObject); // TODO global supertypes? + + Object binaryEdgeSourceType(Object typeObject); // TODO global supertypes? + + /** + * @return the direction in which sub/supertypes arequeryable + */ + GeneralizationQueryDirection allowedGeneralizationQueryDirection(); + + public enum GeneralizationQueryDirection { + /** + * Supertypes can be queried. Notifications registered for a supertype will be delivered for all subtypes. + */ + SUPERTYPE_ONLY_SMART_NOTIFICATIONS /* EMF based on IncQuery-Base */, + /** + * Supertypes can be queried. Notifications are delivered for the registered types. + */ + SUPERTYPE_ONLY /* EMF legacy */, + /** + * Supertypes and subtypes can be queried. Notifications are delivered for the registered types. + */ + BOTH /* VPM */ + } + + boolean isUnaryType(Object typeObject); + + Collection enumerateDirectUnarySubtypes(Object typeObject); + + Collection enumerateDirectUnarySupertypes(Object typeObject); + + boolean isTernaryEdgeType(Object typeObject); + + Collection enumerateDirectTernaryEdgeSubtypes(Object typeObject); + + Collection enumerateDirectTernaryEdgeSupertypes(Object typeObject); + + boolean isBinaryEdgeType(Object typeObject); + + Collection enumerateDirectBinaryEdgeSubtypes(Object typeObject); + + Collection enumerateDirectBinaryEdgeSupertypes(Object typeObject); + + Collection enumerateDirectSupertypes(Object typeObject); + + Collection enumerateDirectSubtypes(Object typeObject); + + // boolean checkBelowContainer(Object container, Object contained); + // boolean checkInContainer(Object container, Object contained); + + void reportPatternDependency(PatternDescription pattern); + + // Logger getLogger(); + void logFatal(String message); + + void logFatal(String message, Throwable cause); + + void logError(String message); + + void logError(String message, Throwable cause); + + void logWarning(String message); + + void logWarning(String message, Throwable cause); + + void logDebug(String message); + + String printPattern(PatternDescription pattern); + + String printType(Object typeObject); + } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/matcher/IPatternMatcherRuntimeContext.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/matcher/IPatternMatcherRuntimeContext.java index a409475b..13cc36da 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/matcher/IPatternMatcherRuntimeContext.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/matcher/IPatternMatcherRuntimeContext.java @@ -17,63 +17,73 @@ import org.eclipse.incquery.runtime.rete.boundary.IManipulationListener; import org.eclipse.incquery.runtime.rete.boundary.IPredicateTraceListener; - - /** * Represents all knowledge of the outside world, that is needed durin runtime operation, towards the pattern matcher. - * + * * @author Bergmann Gábor - * + * */ -public interface IPatternMatcherRuntimeContext extends - IPatternMatcherContext { - - // --------------------------------------------------------------------------------- - - - /** - * @pre: network, framework, boundary, disconnectables initialised - */ - IManipulationListener subscribePatternMatcherForUpdates(ReteEngine engine); - /** - * @pre: boundary, disconnectables initialised - */ - IPredicateTraceListener subscribePatternMatcherForTraceInfluences(ReteEngine engine); - - Object ternaryEdgeTarget(Object relation); - Object ternaryEdgeSource(Object relation); - - void enumerateAllUnaries(ModelElementCrawler crawler); - void enumerateAllTernaryEdges(ModelElementCrawler crawler); - void enumerateAllBinaryEdges(ModelElementPairCrawler crawler); // first=from, second=to - - void enumerateDirectUnaryInstances(Object typeObject, ModelElementCrawler crawler); - void enumerateDirectTernaryEdgeInstances(Object typeObject, ModelElementCrawler crawler); - void enumerateDirectBinaryEdgeInstances(Object typeObject, ModelElementPairCrawler crawler); // first=from, second=to - - void enumerateAllUnaryInstances(Object typeObject, ModelElementCrawler crawler); - void enumerateAllTernaryEdgeInstances(Object typeObject, ModelElementCrawler crawler); - void enumerateAllBinaryEdgeInstances(Object typeObject, ModelElementPairCrawler crawler); // first=from, second=to - - void enumerateAllUnaryContainments(ModelElementPairCrawler crawler); // first=container, second=contained - void enumerateAllInstantiations(ModelElementPairCrawler crawler); // first=type, second=instance - void enumerateAllGeneralizations(ModelElementPairCrawler crawler); // first=supertype, second=subtype - - void modelReadLock(); - void modelReadUnLock(); - - /** - * The given runnable will be executed, and all model traversals will be delayed until the execution is done. - * If there are any outstanding information to be read from the model, a single coalesced model traversal will initialize the caches and deliver the notifications. - * - * @param callable - */ - public abstract V coalesceTraversals(Callable callable) throws InvocationTargetException; - - interface ModelElementCrawler { - public void crawl(Object modelElement); - } - interface ModelElementPairCrawler { - public void crawl(Object first, Object second); - } +public interface IPatternMatcherRuntimeContext extends IPatternMatcherContext { + + // --------------------------------------------------------------------------------- + + /** + * @pre: network, framework, boundary, disconnectables initialised + */ + IManipulationListener subscribePatternMatcherForUpdates(ReteEngine engine); + + /** + * @pre: boundary, disconnectables initialised + */ + IPredicateTraceListener subscribePatternMatcherForTraceInfluences(ReteEngine engine); + + Object ternaryEdgeTarget(Object relation); + + Object ternaryEdgeSource(Object relation); + + void enumerateAllUnaries(ModelElementCrawler crawler); + + void enumerateAllTernaryEdges(ModelElementCrawler crawler); + + void enumerateAllBinaryEdges(ModelElementPairCrawler crawler); // first=from, second=to + + void enumerateDirectUnaryInstances(Object typeObject, ModelElementCrawler crawler); + + void enumerateDirectTernaryEdgeInstances(Object typeObject, ModelElementCrawler crawler); + + void enumerateDirectBinaryEdgeInstances(Object typeObject, ModelElementPairCrawler crawler); // first=from, + // second=to + + void enumerateAllUnaryInstances(Object typeObject, ModelElementCrawler crawler); + + void enumerateAllTernaryEdgeInstances(Object typeObject, ModelElementCrawler crawler); + + void enumerateAllBinaryEdgeInstances(Object typeObject, ModelElementPairCrawler crawler); // first=from, second=to + + void enumerateAllUnaryContainments(ModelElementPairCrawler crawler); // first=container, second=contained + + void enumerateAllInstantiations(ModelElementPairCrawler crawler); // first=type, second=instance + + void enumerateAllGeneralizations(ModelElementPairCrawler crawler); // first=supertype, second=subtype + + void modelReadLock(); + + void modelReadUnLock(); + + /** + * The given runnable will be executed, and all model traversals will be delayed until the execution is done. If + * there are any outstanding information to be read from the model, a single coalesced model traversal will + * initialize the caches and deliver the notifications. + * + * @param callable + */ + public abstract V coalesceTraversals(Callable callable) throws InvocationTargetException; + + interface ModelElementCrawler { + public void crawl(Object modelElement); + } + + interface ModelElementPairCrawler { + public void crawl(Object first, Object second); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/matcher/IPatternMatcherStringTypedContext.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/matcher/IPatternMatcherStringTypedContext.java index c118768b..90bb565d 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/matcher/IPatternMatcherStringTypedContext.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/matcher/IPatternMatcherStringTypedContext.java @@ -16,21 +16,22 @@ /** * * @author Bergmann Gábor - * + * */ public interface IPatternMatcherStringTypedContext extends - IPatternMatcherContext { + IPatternMatcherContext { + + // String retrieveUnaryTypeFQN(Object typeObject); + // String retrieveTernaryEdgeTypeFQN(Object typeObject); + // String retrieveBinaryEdgeTypeFQN(Object typeObject); - // String retrieveUnaryTypeFQN(Object typeObject); - // String retrieveTernaryEdgeTypeFQN(Object typeObject); - // String retrieveBinaryEdgeTypeFQN(Object typeObject); - - Object resolveConstant(String fullyQualifiedName) throws RetePatternBuildException; //Type? Instance? Entity? Relation? Who knows? + Object resolveConstant(String fullyQualifiedName) throws RetePatternBuildException; // Type? Instance? Entity? + // Relation? Who knows? - Object retrieveBinaryEdgeType(String fullyQualifiedName) throws RetePatternBuildException; + Object retrieveBinaryEdgeType(String fullyQualifiedName) throws RetePatternBuildException; - Object retrieveTernaryEdgeType(String fullyQualifiedName) throws RetePatternBuildException; + Object retrieveTernaryEdgeType(String fullyQualifiedName) throws RetePatternBuildException; - Object retrieveUnaryType(String fullyQualifiedName) throws RetePatternBuildException; + Object retrieveUnaryType(String fullyQualifiedName) throws RetePatternBuildException; } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/matcher/ReteEngine.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/matcher/ReteEngine.java index 9dd80127..cede3ca7 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/matcher/ReteEngine.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/matcher/ReteEngine.java @@ -33,437 +33,445 @@ import org.eclipse.incquery.runtime.rete.remote.Address; import org.eclipse.incquery.runtime.rete.tuple.TupleMask; - /** * @author Gabor Bergmann * */ public class ReteEngine { - protected Network reteNet; - protected final int reteThreads; - protected ReteBoundary boundary; - - protected IPatternMatcherRuntimeContext context; - - protected Collection disconnectables; - protected IManipulationListener manipulationListener; - protected IPredicateTraceListener traceListener; - // protected MachineListener machineListener; - - protected Map matchers; -// protected Map, RetePatternMatcher>> matchersScoped; // (pattern, scopemap) -> matcher - - protected IRetePatternBuilder, Address> builder; + protected Network reteNet; + protected final int reteThreads; + protected ReteBoundary boundary; + + protected IPatternMatcherRuntimeContext context; + + protected Collection disconnectables; + protected IManipulationListener manipulationListener; + protected IPredicateTraceListener traceListener; + // protected MachineListener machineListener; + + protected Map matchers; + // protected Map, RetePatternMatcher>> matchersScoped; // (pattern, scopemap) -> + // matcher + + protected IRetePatternBuilder, Address> builder; protected final boolean parallelExecutionEnabled; // TRUE if model manipulation can go on - // while RETE does its job. - -// protected BlockingQueue caughtExceptions; - - /** - * @param context the context of the pattern matcher, conveying all information from the outside world. - * @param reteThreads the number of threads to operate the RETE network with; - * 0 means single-threaded operation, - * 1 starts an asynchronous thread to operate the RETE net, - * >1 uses multiple RETE containers. - */ - public ReteEngine(IPatternMatcherRuntimeContext context, int reteThreads) { - super(); - this.context = context; - this.reteThreads = reteThreads; - this.parallelExecutionEnabled = reteThreads > 0; - // this.framework = new WeakReference(context.getFramework()); - - initEngine(); - - this.builder = null; - } - - /** - * initializes engine components - */ - synchronized private void initEngine() { - - this.disconnectables = new LinkedList(); -// this.caughtExceptions = new LinkedBlockingQueue(); - - this.reteNet = new Network(reteThreads, context); - this.boundary = new ReteBoundary(this); // prerequisite: network - - - this.matchers = new HashMap(); - /*this.matchersScoped = new HashMap,RetePatternMatcher>>();*/ - - - //prerequisite: network, framework, boundary, disconnectables - this.manipulationListener = context.subscribePatternMatcherForUpdates(this); - // prerequisite: boundary, disconnectables - this.traceListener = context.subscribePatternMatcherForTraceInfluences(this); - - } - - /** - * deconstructs engine components - */ - synchronized private void deconstructEngine() { - reteNet.kill(); - - for (Disconnectable disc : disconnectables) { - disc.disconnect(); - } - - this.matchers = null; - this.disconnectables = null; - - this.reteNet = null; - this.boundary = null; - - // this.machineListener = new MachineListener(this); // prerequisite: - // framework, disconnectables - this.manipulationListener = null; - this.traceListener = null; - - } - - /** - * Deconstructs the engine to get rid of it finally - */ - public void killEngine() { - deconstructEngine(); - // this.framework = null; - this.builder = null; - } - - /** - * Resets the engine to an after-initialization phase - * - */ - public void reset() { - deconstructEngine(); - - initEngine(); - - builder.refresh(); - } - - /** - * Accesses the patternmatcher for a given pattern, constructs one if - * a matcher is not available yet. - * - * @pre: builder is set. - * @param gtPattern - * the pattern to be matched. - * @return a patternmatcher object that can match occurences of the given - * pattern. - * @throws RetePatternBuildException - * if construction fails. - */ - public synchronized RetePatternMatcher accessMatcher(final PatternDescription gtPattern) throws RetePatternBuildException { - RetePatternMatcher matcher; - // String namespace = gtPattern.getNamespace().getName(); - // String name = gtPattern.getName(); - // String fqn = namespace + "." + name; - matcher = matchers.get(gtPattern); - if (matcher == null) { - context.modelReadLock(); - try { - if (parallelExecutionEnabled) reteNet.getStructuralChangeLock().lock(); - try { - try { - context.coalesceTraversals(new Callable() { - @Override - public Void call() throws RetePatternBuildException { - Address prodNode; - prodNode = boundary.accessProduction(gtPattern); - - RetePatternMatcher retePatternMatcher = new RetePatternMatcher(ReteEngine.this, prodNode); + + // while RETE does its job. + + // protected BlockingQueue caughtExceptions; + + /** + * @param context + * the context of the pattern matcher, conveying all information from the outside world. + * @param reteThreads + * the number of threads to operate the RETE network with; 0 means single-threaded operation, 1 starts an + * asynchronous thread to operate the RETE net, >1 uses multiple RETE containers. + */ + public ReteEngine(IPatternMatcherRuntimeContext context, int reteThreads) { + super(); + this.context = context; + this.reteThreads = reteThreads; + this.parallelExecutionEnabled = reteThreads > 0; + // this.framework = new WeakReference(context.getFramework()); + + initEngine(); + + this.builder = null; + } + + /** + * initializes engine components + */ + synchronized private void initEngine() { + + this.disconnectables = new LinkedList(); + // this.caughtExceptions = new LinkedBlockingQueue(); + + this.reteNet = new Network(reteThreads, context); + this.boundary = new ReteBoundary(this); // prerequisite: network + + this.matchers = new HashMap(); + /* this.matchersScoped = new HashMap,RetePatternMatcher>>(); */ + + // prerequisite: network, framework, boundary, disconnectables + this.manipulationListener = context.subscribePatternMatcherForUpdates(this); + // prerequisite: boundary, disconnectables + this.traceListener = context.subscribePatternMatcherForTraceInfluences(this); + + } + + /** + * deconstructs engine components + */ + synchronized private void deconstructEngine() { + reteNet.kill(); + + for (Disconnectable disc : disconnectables) { + disc.disconnect(); + } + + this.matchers = null; + this.disconnectables = null; + + this.reteNet = null; + this.boundary = null; + + // this.machineListener = new MachineListener(this); // prerequisite: + // framework, disconnectables + this.manipulationListener = null; + this.traceListener = null; + + } + + /** + * Deconstructs the engine to get rid of it finally + */ + public void killEngine() { + deconstructEngine(); + // this.framework = null; + this.builder = null; + } + + /** + * Resets the engine to an after-initialization phase + * + */ + public void reset() { + deconstructEngine(); + + initEngine(); + + builder.refresh(); + } + + /** + * Accesses the patternmatcher for a given pattern, constructs one if a matcher is not available yet. + * + * @pre: builder is set. + * @param gtPattern + * the pattern to be matched. + * @return a patternmatcher object that can match occurences of the given pattern. + * @throws RetePatternBuildException + * if construction fails. + */ + public synchronized RetePatternMatcher accessMatcher(final PatternDescription gtPattern) + throws RetePatternBuildException { + RetePatternMatcher matcher; + // String namespace = gtPattern.getNamespace().getName(); + // String name = gtPattern.getName(); + // String fqn = namespace + "." + name; + matcher = matchers.get(gtPattern); + if (matcher == null) { + context.modelReadLock(); + try { + if (parallelExecutionEnabled) + reteNet.getStructuralChangeLock().lock(); + try { + try { + context.coalesceTraversals(new Callable() { + @Override + public Void call() throws RetePatternBuildException { + Address prodNode; + prodNode = boundary.accessProduction(gtPattern); + + RetePatternMatcher retePatternMatcher = new RetePatternMatcher(ReteEngine.this, + prodNode); retePatternMatcher.setTag(gtPattern); matchers.put(gtPattern, retePatternMatcher); - return null; - } - }); - } catch (InvocationTargetException ex) { - final Throwable cause = ex.getCause(); - if (cause instanceof RetePatternBuildException) throw (RetePatternBuildException) cause; - if (cause instanceof RuntimeException) throw (RuntimeException) cause; - assert(false); - } - } finally { - if (parallelExecutionEnabled) reteNet.getStructuralChangeLock().unlock(); - settle(); - } - } finally { - context.modelReadUnLock(); - } - // reteNet.flushUpdates(); - matcher = matchers.get(gtPattern); - } - - return matcher; - } - - /** - * Constructs RETE pattern matchers for a collection of patterns, if they are not available yet. - * Model traversal during the whole construction period is coalesced (which may have an effect on performance, - * depending on the matcher context). - * - * @pre: builder is set. - * @param patterns the patterns to be matched. - * @throws RetePatternBuildException if construction fails. - */ - public synchronized void buildMatchersCoalesced(final Collection patterns) throws RetePatternBuildException { - context.modelReadLock(); - try { - if (parallelExecutionEnabled) reteNet.getStructuralChangeLock().lock(); - try { - try { - context.coalesceTraversals(new Callable() { - @Override - public Void call() throws RetePatternBuildException { - for (PatternDescription gtPattern : patterns) { - boundary.accessProduction(gtPattern); - } - return null; - } - }); - } catch (InvocationTargetException ex) { - final Throwable cause = ex.getCause(); - if (cause instanceof RetePatternBuildException) throw (RetePatternBuildException) cause; - if (cause instanceof RuntimeException) throw (RuntimeException) cause; - assert(false); - } - } finally { - if (parallelExecutionEnabled) reteNet.getStructuralChangeLock().unlock(); - } - settle(); - } finally { - context.modelReadUnLock(); - } - } - -// /** -// * Accesses the patternmatcher for a given pattern with additional scoping, constructs one if -// * a matcher is not available yet. -// * -// * @param gtPattern -// * the pattern to be matched. -// * @param additionalScopeMap -// * additional, optional scopes for the symbolic parameters -// * maps the position of the symbolic parameter to its additional scope (if any) -// * @pre: scope.parent is non-root, i.e. this is a nontrivial constraint -// * use the static method RetePatternMatcher.buildAdditionalScopeMap() to create from PatternCallSignature -// * @return a patternmatcher object that can match occurences of the given -// * pattern. -// * @throws PatternMatcherCompileTimeException -// * if construction fails. -// */ -// public synchronized RetePatternMatcher accessMatcherScoped(PatternDescription gtPattern, Map additionalScopeMap) -// throws PatternMatcherCompileTimeException { -// if (additionalScopeMap.isEmpty()) return accessMatcher(gtPattern); -// -// RetePatternMatcher matcher; -// -// Map, RetePatternMatcher> scopes = matchersScoped.get(gtPattern); -// if (scopes == null) { -// scopes = new HashMap, RetePatternMatcher>(); -// matchersScoped.put(gtPattern, scopes); -// } -// -// matcher = scopes.get(additionalScopeMap); -// if (matcher == null) { -// context.modelReadLock(); -// try { -// reteNet.getStructuralChangeLock().lock(); -// try { -// Address prodNode; -// prodNode = boundary.accessProductionScoped(gtPattern, additionalScopeMap); -// -// matcher = new RetePatternMatcher(this, prodNode); -// scopes.put(additionalScopeMap, matcher); -// } finally { -// reteNet.getStructuralChangeLock().unlock(); -// } -// } finally { -// context.modelReadUnLock(); -// } -// // reteNet.flushUpdates(); -// } -// -// return matcher; -// } - - /** - * Returns an indexer that groups the contents of this Production node by - * their projections to a given mask. Designed to be called by a - * RetePatternMatcher. - * - * @param production - * the production node to be indexed. - * @param mask - * the mask that defines the projection. - * @return the Indexer. - */ - synchronized Indexer accessProjection(Production production, - TupleMask mask) { - Library library = reteNet.getHeadContainer().getLibrary(); - Indexer result = library.peekProjectionIndexer(production, mask); - if (result == null) { - context.modelReadLock(); - try { - if (parallelExecutionEnabled) reteNet.getStructuralChangeLock().lock(); - try { - result = library.accessProjectionIndexerOnetime(production, mask); - } finally { - if (parallelExecutionEnabled) reteNet.getStructuralChangeLock().unlock(); - } - } finally { - context.modelReadUnLock(); - } - } - - return result; - } - - // /** - // * Retrieves the patternmatcher for a given pattern fqn, returns null if - // the matching network hasn't been constructed yet. - // * - // * @param fqn the fully qualified name of the pattern to be matched. - // * @return the previously constructed patternmatcher object that can match - // occurences of the given pattern, or null if it doesn't exist. - // */ - // public RetePatternMatcher getMatcher(String fqn) - // { - // RetePatternMatcher matcher = matchersByFqn.get(fqn); - // if (matcher == null) - // { - // Production prodNode = boundary.getProduction(fqn); - // - // matcher = new RetePatternMatcher(this, prodNode); - // matchersByFqn.put(fqn, matcher); - // } - // - // return matcher; - // } - - /** - * Waits until the pattern matcher is in a steady state and output can be - * retrieved. - */ - public void settle() { - reteNet.waitForReteTermination(); - } - - /** - * Waits until the pattern matcher is in a steady state and output can be - * retrieved. When steady state is reached, a retrieval action is executed - * before the steady state ceases. - * - * @param action - * the action to be run when reaching the steady-state. - */ - public void settle(Runnable action) { - reteNet.waitForReteTermination(action); - } - -// /** -// * @return the framework -// */ -// public IFramework getFramework() { -// return framework.get(); -// } - - /** - * @return the reteNet - */ - public Network getReteNet() { - return reteNet; - } - - /** - * @return the boundary - */ - public ReteBoundary getBoundary() { - return boundary; - } - - // /** - // * @return the pattern matcher builder - // */ - // public IRetePatternBuilder getBuilder() { - // return builder; - // } - - /** - * @param builder - * the pattern matcher builder to set - */ - public void setBuilder(IRetePatternBuilder, Address> builder) { - this.builder = builder; - } - - /** - * @return the manipulationListener - */ - public IManipulationListener getManipulationListener() { - return manipulationListener; - } - - /** - * @return the traceListener - */ - public IPredicateTraceListener geTraceListener() { - return traceListener; - } - - /** - * @param disc - * the new Disconnectable adapter. - */ - public void addDisconnectable(Disconnectable disc) { - disconnectables.add(disc); - } - - /** - * @return the parallelExecutionEnabled - */ - public boolean isParallelExecutionEnabled() { - return parallelExecutionEnabled; - } - - - /** - * @return the context - */ - public IPatternMatcherRuntimeContext getContext() { - return context; - } - - public IRetePatternBuilder, Address> getBuilder() { - return builder; - } - -// /** -// * For internal use only: logs exceptions occurring during term evaluation inside the RETE net. -// * @param e -// */ -// public void logEvaluatorException(Throwable e) { -// try { -// caughtExceptions.put(e); -// } catch (InterruptedException e1) { -// logEvaluatorException(e); -// } -// } -// /** -// * Polls the exceptions caught and logged during term evaluation by this RETE engine. -// * Recommended usage: iterate polling until null is returned. -// * -// * @return the next caught exception, or null if there are no more. -// */ -// public Throwable getNextLoggedEvaluatorException() { -// return caughtExceptions.poll(); -// } - + return null; + } + }); + } catch (InvocationTargetException ex) { + final Throwable cause = ex.getCause(); + if (cause instanceof RetePatternBuildException) + throw (RetePatternBuildException) cause; + if (cause instanceof RuntimeException) + throw (RuntimeException) cause; + assert (false); + } + } finally { + if (parallelExecutionEnabled) + reteNet.getStructuralChangeLock().unlock(); + settle(); + } + } finally { + context.modelReadUnLock(); + } + // reteNet.flushUpdates(); + matcher = matchers.get(gtPattern); + } + + return matcher; + } + + /** + * Constructs RETE pattern matchers for a collection of patterns, if they are not available yet. Model traversal + * during the whole construction period is coalesced (which may have an effect on performance, depending on the + * matcher context). + * + * @pre: builder is set. + * @param patterns + * the patterns to be matched. + * @throws RetePatternBuildException + * if construction fails. + */ + public synchronized void buildMatchersCoalesced(final Collection patterns) + throws RetePatternBuildException { + context.modelReadLock(); + try { + if (parallelExecutionEnabled) + reteNet.getStructuralChangeLock().lock(); + try { + try { + context.coalesceTraversals(new Callable() { + @Override + public Void call() throws RetePatternBuildException { + for (PatternDescription gtPattern : patterns) { + boundary.accessProduction(gtPattern); + } + return null; + } + }); + } catch (InvocationTargetException ex) { + final Throwable cause = ex.getCause(); + if (cause instanceof RetePatternBuildException) + throw (RetePatternBuildException) cause; + if (cause instanceof RuntimeException) + throw (RuntimeException) cause; + assert (false); + } + } finally { + if (parallelExecutionEnabled) + reteNet.getStructuralChangeLock().unlock(); + } + settle(); + } finally { + context.modelReadUnLock(); + } + } + + // /** + // * Accesses the patternmatcher for a given pattern with additional scoping, constructs one if + // * a matcher is not available yet. + // * + // * @param gtPattern + // * the pattern to be matched. + // * @param additionalScopeMap + // * additional, optional scopes for the symbolic parameters + // * maps the position of the symbolic parameter to its additional scope (if any) + // * @pre: scope.parent is non-root, i.e. this is a nontrivial constraint + // * use the static method RetePatternMatcher.buildAdditionalScopeMap() to create from PatternCallSignature + // * @return a patternmatcher object that can match occurences of the given + // * pattern. + // * @throws PatternMatcherCompileTimeException + // * if construction fails. + // */ + // public synchronized RetePatternMatcher accessMatcherScoped(PatternDescription gtPattern, Map + // additionalScopeMap) + // throws PatternMatcherCompileTimeException { + // if (additionalScopeMap.isEmpty()) return accessMatcher(gtPattern); + // + // RetePatternMatcher matcher; + // + // Map, RetePatternMatcher> scopes = matchersScoped.get(gtPattern); + // if (scopes == null) { + // scopes = new HashMap, RetePatternMatcher>(); + // matchersScoped.put(gtPattern, scopes); + // } + // + // matcher = scopes.get(additionalScopeMap); + // if (matcher == null) { + // context.modelReadLock(); + // try { + // reteNet.getStructuralChangeLock().lock(); + // try { + // Address prodNode; + // prodNode = boundary.accessProductionScoped(gtPattern, additionalScopeMap); + // + // matcher = new RetePatternMatcher(this, prodNode); + // scopes.put(additionalScopeMap, matcher); + // } finally { + // reteNet.getStructuralChangeLock().unlock(); + // } + // } finally { + // context.modelReadUnLock(); + // } + // // reteNet.flushUpdates(); + // } + // + // return matcher; + // } + + /** + * Returns an indexer that groups the contents of this Production node by their projections to a given mask. + * Designed to be called by a RetePatternMatcher. + * + * @param production + * the production node to be indexed. + * @param mask + * the mask that defines the projection. + * @return the Indexer. + */ + synchronized Indexer accessProjection(Production production, TupleMask mask) { + Library library = reteNet.getHeadContainer().getLibrary(); + Indexer result = library.peekProjectionIndexer(production, mask); + if (result == null) { + context.modelReadLock(); + try { + if (parallelExecutionEnabled) + reteNet.getStructuralChangeLock().lock(); + try { + result = library.accessProjectionIndexerOnetime(production, mask); + } finally { + if (parallelExecutionEnabled) + reteNet.getStructuralChangeLock().unlock(); + } + } finally { + context.modelReadUnLock(); + } + } + + return result; + } + + // /** + // * Retrieves the patternmatcher for a given pattern fqn, returns null if + // the matching network hasn't been constructed yet. + // * + // * @param fqn the fully qualified name of the pattern to be matched. + // * @return the previously constructed patternmatcher object that can match + // occurences of the given pattern, or null if it doesn't exist. + // */ + // public RetePatternMatcher getMatcher(String fqn) + // { + // RetePatternMatcher matcher = matchersByFqn.get(fqn); + // if (matcher == null) + // { + // Production prodNode = boundary.getProduction(fqn); + // + // matcher = new RetePatternMatcher(this, prodNode); + // matchersByFqn.put(fqn, matcher); + // } + // + // return matcher; + // } + + /** + * Waits until the pattern matcher is in a steady state and output can be retrieved. + */ + public void settle() { + reteNet.waitForReteTermination(); + } + + /** + * Waits until the pattern matcher is in a steady state and output can be retrieved. When steady state is reached, a + * retrieval action is executed before the steady state ceases. + * + * @param action + * the action to be run when reaching the steady-state. + */ + public void settle(Runnable action) { + reteNet.waitForReteTermination(action); + } + + // /** + // * @return the framework + // */ + // public IFramework getFramework() { + // return framework.get(); + // } + + /** + * @return the reteNet + */ + public Network getReteNet() { + return reteNet; + } + + /** + * @return the boundary + */ + public ReteBoundary getBoundary() { + return boundary; + } + + // /** + // * @return the pattern matcher builder + // */ + // public IRetePatternBuilder getBuilder() { + // return builder; + // } + + /** + * @param builder + * the pattern matcher builder to set + */ + public void setBuilder( + IRetePatternBuilder, Address> builder) { + this.builder = builder; + } + + /** + * @return the manipulationListener + */ + public IManipulationListener getManipulationListener() { + return manipulationListener; + } + + /** + * @return the traceListener + */ + public IPredicateTraceListener geTraceListener() { + return traceListener; + } + + /** + * @param disc + * the new Disconnectable adapter. + */ + public void addDisconnectable(Disconnectable disc) { + disconnectables.add(disc); + } + + /** + * @return the parallelExecutionEnabled + */ + public boolean isParallelExecutionEnabled() { + return parallelExecutionEnabled; + } + + /** + * @return the context + */ + public IPatternMatcherRuntimeContext getContext() { + return context; + } + + public IRetePatternBuilder, Address> getBuilder() { + return builder; + } + + // /** + // * For internal use only: logs exceptions occurring during term evaluation inside the RETE net. + // * @param e + // */ + // public void logEvaluatorException(Throwable e) { + // try { + // caughtExceptions.put(e); + // } catch (InterruptedException e1) { + // logEvaluatorException(e); + // } + // } + // /** + // * Polls the exceptions caught and logged during term evaluation by this RETE engine. + // * Recommended usage: iterate polling until null is returned. + // * + // * @return the next caught exception, or null if there are no more. + // */ + // public Throwable getNextLoggedEvaluatorException() { + // return caughtExceptions.poll(); + // } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/matcher/RetePatternMatcher.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/matcher/RetePatternMatcher.java index 2aeda3e7..3e75897d 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/matcher/RetePatternMatcher.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/matcher/RetePatternMatcher.java @@ -26,292 +26,289 @@ import org.eclipse.incquery.runtime.rete.tuple.Tuple; import org.eclipse.incquery.runtime.rete.tuple.TupleMask; - - /** * @author Gabor Bergmann * */ public class RetePatternMatcher extends TransformerNode { - protected ReteEngine engine; - protected ReteBoundary boundary; - protected Production productionNode; - protected HashMap posMapping; - protected Map taggedChildren = new HashMap(); - protected boolean connected = false; // is rete-wise connected to the - // production node? - - - /** - * @param productionNode - * a production node that matches this pattern without any - * parameter bindings - * @pre: Production must be local to the head - * container - */ - public RetePatternMatcher(ReteEngine engine, - Address productionNode) { - super(engine.getReteNet().getHeadContainer()); - this.engine = engine; - this.boundary = engine.getBoundary(); - if (!engine.getReteNet().getHeadContainer().isLocal(productionNode)) - throw new IllegalArgumentException( - "@pre: Production must be local to the head container"); - this.productionNode = engine.getReteNet().getHeadContainer() - .resolveLocal(productionNode); - this.posMapping = this.productionNode.getPosMapping(); - } - - // /** - // * @return the productionNode - // */ - // public Production getProductionNode() { - // return productionNode; - // } - - public Tuple matchOneRandomly(Object[] inputMapping, boolean[] fixed) { - ArrayList allMatches = matchAll(inputMapping, fixed); - if (allMatches == null || allMatches.isEmpty()) return null; - else return allMatches.get((int)(Math.random() * allMatches.size())); - } - public ArrayList matchAll(Object[] inputMapping, boolean[] fixed) { - // retrieving the projection - TupleMask mask = new TupleMask(fixed); - Tuple inputSignature = mask.transform(new FlatTuple(inputMapping)); - - AllMatchFetcher fetcher = new AllMatchFetcher(engine.accessProjection( - productionNode, mask), boundary.wrapTuple(inputSignature)); - engine.reteNet.waitForReteTermination(fetcher); - ArrayList unscopedMatches = fetcher.getMatches(); - - // checking scopes - if (unscopedMatches == null) return new ArrayList(); - else return unscopedMatches; - - } - public Tuple matchOne(Object[] inputMapping, boolean[] fixed) { - // retrieving the projection - TupleMask mask = new TupleMask(fixed); - Tuple inputSignature = mask.transform(new FlatTuple(inputMapping)); - - SingleMatchFetcher fetcher = new SingleMatchFetcher(engine.accessProjection( - productionNode, mask), boundary.wrapTuple(inputSignature)); - engine.reteNet.waitForReteTermination(fetcher); - return fetcher.getMatch(); - } - - /** - * Counts the number of occurrences of the pattern that match inputMapping - * on positions where fixed is true. - * - * @return the number of occurrences - */ - public int count(Object[] inputMapping, boolean[] fixed) { - TupleMask mask = new TupleMask(fixed); - Tuple inputSignature = mask.transform(new FlatTuple(inputMapping)); - - CountFetcher fetcher = new CountFetcher(engine.accessProjection( - productionNode, mask), boundary.wrapTuple(inputSignature)); - engine.reteNet.waitForReteTermination(fetcher); - - return fetcher.getCount(); - } - - /** - * Connects a new external receiver that will receive update notifications - * from now on. The receiver will practically connect to the production - * node, the added value is unwrapping the updates for external use. - * - * @param synchronize - * if true, the contents of the production node will be inserted - * into the receiver after the connection is established. - */ - public synchronized void connect(Receiver receiver, boolean synchronize) { - if (!connected) { // connect to the production node as a RETE-child - reteContainer.connect(productionNode, this); - connected = true; - } - if (synchronize) - reteContainer.connectAndSynchronize(this, receiver); - else - reteContainer.connect(this, receiver); - } - - /** - * Connects a new external receiver that will receive update notifications - * from now on. The receiver will practically connect to the production - * node, the added value is unwrapping the updates for external use. - * - * The external receiver will be disconnectable later based on its tag. - * - * @param tag an identifier to recognize the child node by. - * - * @param synchronize - * if true, the contents of the production node will be inserted - * into the receiver after the connection is established. - * - */ - public synchronized void connect(Receiver receiver, Object tag, boolean synchronize) { - taggedChildren.put(tag, receiver); - connect(receiver, synchronize); - } - - /** - * Disconnects a child node. - */ - public synchronized void disconnect(Receiver receiver) { - reteContainer.disconnect(this, receiver); - } - - /** - * Disconnects the child node that was connected by specifying the given tag. - * - * @return if a child node was found registered with this tag. - */ - public synchronized boolean disconnectByTag(Object tag) { - final Receiver receiver = taggedChildren.remove(tag); - final boolean found = receiver != null; - if (found) disconnect(receiver); - return found; - } - - /** - * @return the posMapping - */ - public HashMap getPosMapping() { - return posMapping; - } - - @Override - protected Tuple transform(Tuple input) { - return boundary.unwrapTuple(input); - } - - abstract class AbstractMatchFetcher implements Runnable { - Indexer indexer; - Tuple signature; - - public AbstractMatchFetcher(Indexer indexer, Tuple signature) { - super(); - this.indexer = indexer; - this.signature = signature; - } - - public void run() { - fetch(indexer.get(signature)); - } - - protected abstract void fetch(Collection matches); - - } - - class AllMatchFetcher extends AbstractMatchFetcher { - - public AllMatchFetcher(Indexer indexer, Tuple signature) { - super(indexer, signature); - } - - ArrayList matches = null; - - public ArrayList getMatches() { - return matches; - } - - - @Override - protected void fetch(Collection matches) { - if (matches==null) this.matches = null; - else { - this.matches = new ArrayList(matches.size()); - int i=0; - for (Tuple t : matches) - this.matches.add(i++, boundary.unwrapTuple(t)); - } - - } - - } - - class SingleMatchFetcher extends AbstractMatchFetcher { - - public SingleMatchFetcher(Indexer indexer, Tuple signature) { - super(indexer, signature); - } - - Tuple match = null; - - public Tuple getMatch() { - return match; - } - - @Override - protected void fetch(Collection matches) { - if (matches != null && !matches.isEmpty()) - match = boundary.unwrapTuple(matches.iterator().next()); - } - -// public void run() { -// Collection unscopedMatches = indexer.get(signature); -// -// // checking scopes -// if (unscopedMatches != null) { -// for (Tuple um : /* productionNode */unscopedMatches) { -// match = boundary.unwrapTuple(um); -// return; -// -//// Tuple ps = boundary.unwrapTuple(um); -//// boolean ok = true; -//// if (!ignoreScope) for (int k = 0; (k < ps.getSize()) && ok; k++) { -//// if (pcs[k].getParameterMode() == ParameterMode.INPUT) { -//// // ok = ok && (inputMapping[k]==ps.elements[k]); -//// // should now be true -//// } else // ParameterMode.OUTPUT -//// { -//// IEntity scopeParent = (IEntity) pcs[k].getParameterScope().getParent(); -//// Integer containmentMode = pcs[k].getParameterScope().getContainmentMode(); -//// if (containmentMode == Scope.BELOW) -//// ok = ok && ((IModelElement) ps.get(k)).isBelowNamespace(scopeParent); -//// else -//// /* case Scope.IN: */ -//// ok = ok && scopeParent.equals(((IModelElement) ps.get(k)).getNamespace()); -//// // note: getNamespace returns null instead of the -//// // (imaginary) modelspace root entity for top level -//// // elements; -//// // this is not a problem here as Scope.IN implies -//// // scopeParent != root. -//// -//// } -//// } -//// -//// if (ok) { -//// reteMatching = new ReteMatching(ps, posMapping); -//// return; -//// } -// } -// } -// -// } - - } - - class CountFetcher extends AbstractMatchFetcher { - - public CountFetcher(Indexer indexer, Tuple signature) { - super(indexer, signature); - } - - int count = 0; - - public int getCount() { - return count; - } - - @Override - protected void fetch(Collection matches) { - count = matches == null ? 0 : matches.size(); - } - - } - + protected ReteEngine engine; + protected ReteBoundary boundary; + protected Production productionNode; + protected HashMap posMapping; + protected Map taggedChildren = new HashMap(); + protected boolean connected = false; // is rete-wise connected to the + // production node? + + /** + * @param productionNode + * a production node that matches this pattern without any parameter bindings + * @pre: Production must be local to the head container + */ + public RetePatternMatcher(ReteEngine engine, Address productionNode) { + super(engine.getReteNet().getHeadContainer()); + this.engine = engine; + this.boundary = engine.getBoundary(); + if (!engine.getReteNet().getHeadContainer().isLocal(productionNode)) + throw new IllegalArgumentException("@pre: Production must be local to the head container"); + this.productionNode = engine.getReteNet().getHeadContainer().resolveLocal(productionNode); + this.posMapping = this.productionNode.getPosMapping(); + } + + // /** + // * @return the productionNode + // */ + // public Production getProductionNode() { + // return productionNode; + // } + + public Tuple matchOneRandomly(Object[] inputMapping, boolean[] fixed) { + ArrayList allMatches = matchAll(inputMapping, fixed); + if (allMatches == null || allMatches.isEmpty()) + return null; + else + return allMatches.get((int) (Math.random() * allMatches.size())); + } + + public ArrayList matchAll(Object[] inputMapping, boolean[] fixed) { + // retrieving the projection + TupleMask mask = new TupleMask(fixed); + Tuple inputSignature = mask.transform(new FlatTuple(inputMapping)); + + AllMatchFetcher fetcher = new AllMatchFetcher(engine.accessProjection(productionNode, mask), + boundary.wrapTuple(inputSignature)); + engine.reteNet.waitForReteTermination(fetcher); + ArrayList unscopedMatches = fetcher.getMatches(); + + // checking scopes + if (unscopedMatches == null) + return new ArrayList(); + else + return unscopedMatches; + + } + + public Tuple matchOne(Object[] inputMapping, boolean[] fixed) { + // retrieving the projection + TupleMask mask = new TupleMask(fixed); + Tuple inputSignature = mask.transform(new FlatTuple(inputMapping)); + + SingleMatchFetcher fetcher = new SingleMatchFetcher(engine.accessProjection(productionNode, mask), + boundary.wrapTuple(inputSignature)); + engine.reteNet.waitForReteTermination(fetcher); + return fetcher.getMatch(); + } + + /** + * Counts the number of occurrences of the pattern that match inputMapping on positions where fixed is true. + * + * @return the number of occurrences + */ + public int count(Object[] inputMapping, boolean[] fixed) { + TupleMask mask = new TupleMask(fixed); + Tuple inputSignature = mask.transform(new FlatTuple(inputMapping)); + + CountFetcher fetcher = new CountFetcher(engine.accessProjection(productionNode, mask), + boundary.wrapTuple(inputSignature)); + engine.reteNet.waitForReteTermination(fetcher); + + return fetcher.getCount(); + } + + /** + * Connects a new external receiver that will receive update notifications from now on. The receiver will + * practically connect to the production node, the added value is unwrapping the updates for external use. + * + * @param synchronize + * if true, the contents of the production node will be inserted into the receiver after the connection + * is established. + */ + public synchronized void connect(Receiver receiver, boolean synchronize) { + if (!connected) { // connect to the production node as a RETE-child + reteContainer.connect(productionNode, this); + connected = true; + } + if (synchronize) + reteContainer.connectAndSynchronize(this, receiver); + else + reteContainer.connect(this, receiver); + } + + /** + * Connects a new external receiver that will receive update notifications from now on. The receiver will + * practically connect to the production node, the added value is unwrapping the updates for external use. + * + * The external receiver will be disconnectable later based on its tag. + * + * @param tag + * an identifier to recognize the child node by. + * + * @param synchronize + * if true, the contents of the production node will be inserted into the receiver after the connection + * is established. + * + */ + public synchronized void connect(Receiver receiver, Object tag, boolean synchronize) { + taggedChildren.put(tag, receiver); + connect(receiver, synchronize); + } + + /** + * Disconnects a child node. + */ + public synchronized void disconnect(Receiver receiver) { + reteContainer.disconnect(this, receiver); + } + + /** + * Disconnects the child node that was connected by specifying the given tag. + * + * @return if a child node was found registered with this tag. + */ + public synchronized boolean disconnectByTag(Object tag) { + final Receiver receiver = taggedChildren.remove(tag); + final boolean found = receiver != null; + if (found) + disconnect(receiver); + return found; + } + + /** + * @return the posMapping + */ + public HashMap getPosMapping() { + return posMapping; + } + + @Override + protected Tuple transform(Tuple input) { + return boundary.unwrapTuple(input); + } + + abstract class AbstractMatchFetcher implements Runnable { + Indexer indexer; + Tuple signature; + + public AbstractMatchFetcher(Indexer indexer, Tuple signature) { + super(); + this.indexer = indexer; + this.signature = signature; + } + + public void run() { + fetch(indexer.get(signature)); + } + + protected abstract void fetch(Collection matches); + + } + + class AllMatchFetcher extends AbstractMatchFetcher { + + public AllMatchFetcher(Indexer indexer, Tuple signature) { + super(indexer, signature); + } + + ArrayList matches = null; + + public ArrayList getMatches() { + return matches; + } + + @Override + protected void fetch(Collection matches) { + if (matches == null) + this.matches = null; + else { + this.matches = new ArrayList(matches.size()); + int i = 0; + for (Tuple t : matches) + this.matches.add(i++, boundary.unwrapTuple(t)); + } + + } + + } + + class SingleMatchFetcher extends AbstractMatchFetcher { + + public SingleMatchFetcher(Indexer indexer, Tuple signature) { + super(indexer, signature); + } + + Tuple match = null; + + public Tuple getMatch() { + return match; + } + + @Override + protected void fetch(Collection matches) { + if (matches != null && !matches.isEmpty()) + match = boundary.unwrapTuple(matches.iterator().next()); + } + + // public void run() { + // Collection unscopedMatches = indexer.get(signature); + // + // // checking scopes + // if (unscopedMatches != null) { + // for (Tuple um : /* productionNode */unscopedMatches) { + // match = boundary.unwrapTuple(um); + // return; + // + // // Tuple ps = boundary.unwrapTuple(um); + // // boolean ok = true; + // // if (!ignoreScope) for (int k = 0; (k < ps.getSize()) && ok; k++) { + // // if (pcs[k].getParameterMode() == ParameterMode.INPUT) { + // // // ok = ok && (inputMapping[k]==ps.elements[k]); + // // // should now be true + // // } else // ParameterMode.OUTPUT + // // { + // // IEntity scopeParent = (IEntity) pcs[k].getParameterScope().getParent(); + // // Integer containmentMode = pcs[k].getParameterScope().getContainmentMode(); + // // if (containmentMode == Scope.BELOW) + // // ok = ok && ((IModelElement) ps.get(k)).isBelowNamespace(scopeParent); + // // else + // // /* case Scope.IN: */ + // // ok = ok && scopeParent.equals(((IModelElement) ps.get(k)).getNamespace()); + // // // note: getNamespace returns null instead of the + // // // (imaginary) modelspace root entity for top level + // // // elements; + // // // this is not a problem here as Scope.IN implies + // // // scopeParent != root. + // // + // // } + // // } + // // + // // if (ok) { + // // reteMatching = new ReteMatching(ps, posMapping); + // // return; + // // } + // } + // } + // + // } + + } + + class CountFetcher extends AbstractMatchFetcher { + + public CountFetcher(Indexer indexer, Tuple signature) { + super(indexer, signature); + } + + int count = 0; + + public int getCount() { + return count; + } + + @Override + protected void fetch(Collection matches) { + count = matches == null ? 0 : matches.size(); + } + + } + } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/misc/Bag.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/misc/Bag.java index 70e40a66..7d379d38 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/misc/Bag.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/misc/Bag.java @@ -18,29 +18,27 @@ import org.eclipse.incquery.runtime.rete.network.ReteContainer; import org.eclipse.incquery.runtime.rete.tuple.Tuple; - /** * @author Gabor Bergmann * - * A bag is a container that tuples can be dumped into. Does NOT - * propagate updates! Optimized for small contents size OR positive - * updates only. + * A bag is a container that tuples can be dumped into. Does NOT propagate updates! Optimized for small contents + * size OR positive updates only. */ public class Bag extends SimpleReceiver { - public Collection contents; + public Collection contents; - public Bag(ReteContainer reteContainer) { - super(reteContainer); - contents = new LinkedList(); - } + public Bag(ReteContainer reteContainer) { + super(reteContainer); + contents = new LinkedList(); + } - @Override + @Override public void update(Direction direction, Tuple updateElement) { - if (direction == Direction.INSERT) - contents.add(updateElement); - else - contents.remove(updateElement); - } + if (direction == Direction.INSERT) + contents.add(updateElement); + else + contents.remove(updateElement); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/misc/ConstantNode.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/misc/ConstantNode.java index bfad65eb..d71cc66d 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/misc/ConstantNode.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/misc/ConstantNode.java @@ -17,7 +17,6 @@ import org.eclipse.incquery.runtime.rete.network.StandardNode; import org.eclipse.incquery.runtime.rete.tuple.Tuple; - /** * Node that always contains a single constant Tuple * @@ -25,15 +24,15 @@ */ public class ConstantNode extends StandardNode { - protected Tuple constant; + protected Tuple constant; - public ConstantNode(ReteContainer reteContainer, Tuple constant) { - super(reteContainer); - this.constant = constant; - } + public ConstantNode(ReteContainer reteContainer, Tuple constant) { + super(reteContainer); + this.constant = constant; + } - public void pullInto(Collection collector) { - collector.add(constant); - } + public void pullInto(Collection collector) { + collector.add(constant); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/misc/DefaultDeltaMonitor.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/misc/DefaultDeltaMonitor.java index 98e15aab..baaf3d59 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/misc/DefaultDeltaMonitor.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/misc/DefaultDeltaMonitor.java @@ -17,29 +17,29 @@ /** * Default configuration for DeltaMonitor. + * * @author Bergmann Gábor - * + * */ public class DefaultDeltaMonitor extends DeltaMonitor { - /** - * @param reteContainer - */ - public DefaultDeltaMonitor(ReteContainer reteContainer) { - super(reteContainer); - } - - /** - * @param network - */ - public DefaultDeltaMonitor(Network network) { - super(network.getHeadContainer()); - } + /** + * @param reteContainer + */ + public DefaultDeltaMonitor(ReteContainer reteContainer) { + super(reteContainer); + } + /** + * @param network + */ + public DefaultDeltaMonitor(Network network) { + super(network.getHeadContainer()); + } - @Override - public Tuple statelessConvert(Tuple tuple) { - return tuple; - } + @Override + public Tuple statelessConvert(Tuple tuple) { + return tuple; + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/misc/DeltaMonitor.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/misc/DeltaMonitor.java index 1a0d74e4..3b59507e 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/misc/DeltaMonitor.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/misc/DeltaMonitor.java @@ -19,96 +19,94 @@ import org.eclipse.incquery.runtime.rete.tuple.Clearable; import org.eclipse.incquery.runtime.rete.tuple.Tuple; - /** - * A monitoring object that connects to the rete network as a receiver to - * reflect changes since an arbitrary state acknowledged by the client. Match tuples - * are represented by a type MatchType. + * A monitoring object that connects to the rete network as a receiver to reflect changes since an arbitrary state + * acknowledged by the client. Match tuples are represented by a type MatchType. * - *

    Usage. If a new matching is found, it appears in the matchFoundEvents collection, - * and disappears when that particular matching cannot be found anymore. If the - * event of finding a match has been processed by the client, it can be removed - * manually. In this case, when a previously found matching is lost, the Tuple - * will appear in the matchLostEvents collection, and disappear upon finding the - * same matching again. "Matching lost" events can also be acknowledged by - * removing a Tuple from the collection. If the matching is found once again, it - * will return to matchFoundEvents. + *

    + * Usage. If a new matching is found, it appears in the matchFoundEvents collection, and disappears when that + * particular matching cannot be found anymore. If the event of finding a match has been processed by the client, it can + * be removed manually. In this case, when a previously found matching is lost, the Tuple will appear in the + * matchLostEvents collection, and disappear upon finding the same matching again. "Matching lost" events can also be + * acknowledged by removing a Tuple from the collection. If the matching is found once again, it will return to + * matchFoundEvents. * - *

    Technical notes. Does NOT propagate updates! + *

    + * Technical notes. Does NOT propagate updates! * - * By overriding statelessConvert(), results can be stored to a MatchType. - * MatchType must provide equals() and hashCode() reflecting its contents. - * The default implementation (DefaultDeltaMonitor) uses Tuple as MatchType. + * By overriding statelessConvert(), results can be stored to a MatchType. MatchType must provide equals() and + * hashCode() reflecting its contents. The default implementation (DefaultDeltaMonitor) uses Tuple as MatchType. * - * By overriding statelessFilter(), some tuples can be filtered. + * By overriding statelessFilter(), some tuples can be filtered. * * @author Gabor Bergmann * */ public abstract class DeltaMonitor extends SimpleReceiver implements Clearable { - /** - * matches that are newly found - */ - public Collection matchFoundEvents; - /** - * matches that are newly lost - */ - public Collection matchLostEvents; + /** + * matches that are newly found + */ + public Collection matchFoundEvents; + /** + * matches that are newly lost + */ + public Collection matchLostEvents; + + /** + * @param reteContainer + */ + public DeltaMonitor(ReteContainer reteContainer) { + super(reteContainer); + matchFoundEvents = new LinkedHashSet(); + matchLostEvents = new LinkedHashSet(); + reteContainer.registerClearable(this); + } + + // /** + // * Build a delta monitor into the head container of the network. + // * + // * @param network + // */ + // public DeltaMonitor(Network network) { + // this(network.getHeadContainer()); + // } - /** - * @param reteContainer - */ - public DeltaMonitor(ReteContainer reteContainer) { - super(reteContainer); - matchFoundEvents = new LinkedHashSet(); - matchLostEvents = new LinkedHashSet(); - reteContainer.registerClearable(this); - } - -// /** -// * Build a delta monitor into the head container of the network. -// * -// * @param network -// */ -// public DeltaMonitor(Network network) { -// this(network.getHeadContainer()); -// } - - /** - * Override this method to provide a lightweight, stateless filter on the tuples - * @param tuple the occurrence that is to be filtered - * @return true if this tuple should be monitored, false if ignored - */ - public boolean statelessFilter(Tuple tuple) { - return true; - } - - public abstract MatchType statelessConvert(Tuple tuple); + /** + * Override this method to provide a lightweight, stateless filter on the tuples + * + * @param tuple + * the occurrence that is to be filtered + * @return true if this tuple should be monitored, false if ignored + */ + public boolean statelessFilter(Tuple tuple) { + return true; + } + public abstract MatchType statelessConvert(Tuple tuple); - @Override + @Override public void update(Direction direction, Tuple updateElement) { - if (statelessFilter(updateElement)) { - MatchType match = statelessConvert(updateElement); - if (direction == Direction.INSERT) { - if (!matchLostEvents.remove(match)) // either had before but - // lost - matchFoundEvents.add(match); // or brand-new - } else // revoke - { - if (!matchFoundEvents.remove(match)) // either never found - // in the first - // place - matchLostEvents.add(match); // or newly lost - } - } - } + if (statelessFilter(updateElement)) { + MatchType match = statelessConvert(updateElement); + if (direction == Direction.INSERT) { + if (!matchLostEvents.remove(match)) // either had before but + // lost + matchFoundEvents.add(match); // or brand-new + } else // revoke + { + if (!matchFoundEvents.remove(match)) // either never found + // in the first + // place + matchLostEvents.add(match); // or newly lost + } + } + } - @Override + @Override public void clear() { - matchFoundEvents.clear(); - matchLostEvents.clear(); - } + matchFoundEvents.clear(); + matchLostEvents.clear(); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/misc/SimpleReceiver.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/misc/SimpleReceiver.java index f1065562..f3b43601 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/misc/SimpleReceiver.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/misc/SimpleReceiver.java @@ -20,52 +20,54 @@ /** * @author Bergmann Gabor - * + * */ public abstract class SimpleReceiver extends BaseNode implements Receiver { - protected Supplier parent = null; + protected Supplier parent = null; - /** - * @param reteContainer - */ - public SimpleReceiver(ReteContainer reteContainer) { - super(reteContainer); - } + /** + * @param reteContainer + */ + public SimpleReceiver(ReteContainer reteContainer) { + super(reteContainer); + } - @Override - public void appendParent(Supplier supplier) { - if (parent == null) - parent = supplier; - else - throw new UnsupportedOperationException("Illegal RETE edge: " + this + " already has a parent (" + - parent + ") and cannot connect to additional parent (" + supplier + - ") as it is not a Uniqueness Enforcer Node. "); - } + @Override + public void appendParent(Supplier supplier) { + if (parent == null) + parent = supplier; + else + throw new UnsupportedOperationException("Illegal RETE edge: " + this + " already has a parent (" + parent + + ") and cannot connect to additional parent (" + supplier + + ") as it is not a Uniqueness Enforcer Node. "); + } - @Override - public void removeParent(Supplier supplier) { - if (parent == supplier) - parent = null; - else - throw new IllegalArgumentException("Illegal RETE edge removal: the parent of " + this + " is not " + supplier); - } + @Override + public void removeParent(Supplier supplier) { + if (parent == supplier) + parent = null; + else + throw new IllegalArgumentException("Illegal RETE edge removal: the parent of " + this + " is not " + + supplier); + } - @Override - public Collection getParents() { - if (parent == null) - return Collections.emptySet(); - else - return Collections.singleton(parent); - } + @Override + public Collection getParents() { + if (parent == null) + return Collections.emptySet(); + else + return Collections.singleton(parent); + } - /** - * Disconnects this node from the network. Can be called publicly. - * @pre: child nodes, if any, must already be disconnected. - */ - public void disconnectFromNetwork() { - if (parent != null) - reteContainer.disconnect(parent, this); - } + /** + * Disconnects this node from the network. Can be called publicly. + * + * @pre: child nodes, if any, must already be disconnected. + */ + public void disconnectFromNetwork() { + if (parent != null) + reteContainer.disconnect(parent, this); + } } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/BaseNode.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/BaseNode.java index 4ee23587..e958bd63 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/BaseNode.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/BaseNode.java @@ -12,52 +12,52 @@ /** * Base implementation for a Rete node. + * * @author Bergmann Gabor - * + * */ public abstract class BaseNode implements Node { - protected ReteContainer reteContainer; - protected long nodeId; - protected Object tag; - - /** - * @param reteContainer the container to create this node in - */ - public BaseNode(ReteContainer reteContainer) { - super(); - this.reteContainer = reteContainer; - this.nodeId = reteContainer.registerNode(this); - } - - @Override - public String toString() { - if (tag != null) - return "[" + nodeId+ "]" + getClass().getSimpleName() + "[[" + tag.toString() + "]]"; - else - return "[" + nodeId+ "]" + getClass().getSimpleName(); - } - - @Override + protected ReteContainer reteContainer; + protected long nodeId; + protected Object tag; + + /** + * @param reteContainer + * the container to create this node in + */ + public BaseNode(ReteContainer reteContainer) { + super(); + this.reteContainer = reteContainer; + this.nodeId = reteContainer.registerNode(this); + } + + @Override + public String toString() { + if (tag != null) + return "[" + nodeId + "]" + getClass().getSimpleName() + "[[" + tag.toString() + "]]"; + else + return "[" + nodeId + "]" + getClass().getSimpleName(); + } + + @Override public ReteContainer getContainer() { - return reteContainer; - } + return reteContainer; + } - @Override + @Override public long getNodeId() { - return nodeId; - } - + return nodeId; + } - @Override + @Override public Object getTag() { - return tag; - } - + return tag; + } - @Override + @Override public void setTag(Object tag) { - this.tag = tag; - } + this.tag = tag; + } } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Direction.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Direction.java index 5b49438f..00163ca3 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Direction.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Direction.java @@ -12,23 +12,22 @@ package org.eclipse.incquery.runtime.rete.network; /** - * Indicates whether a propagated update event signals the insertion or deletion - * of an element + * Indicates whether a propagated update event signals the insertion or deletion of an element * * @author Gabor Bergmann * */ public enum Direction { - INSERT, REVOKE; + INSERT, REVOKE; - public Direction opposite() { - switch (this) { - case INSERT: - return REVOKE; - case REVOKE: - return INSERT; - default: - return INSERT; - } - } + public Direction opposite() { + switch (this) { + case INSERT: + return REVOKE; + case REVOKE: + return INSERT; + default: + return INSERT; + } + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Library.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Library.java index a5665be2..6bc42111 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Library.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Library.java @@ -40,440 +40,422 @@ import org.eclipse.incquery.runtime.rete.tuple.TupleMask; import org.eclipse.incquery.runtime.rete.util.Options; - /** - * Stores the internal parts of a rete network. Nodes are stored according to - * type and parameters. + * Stores the internal parts of a rete network. Nodes are stored according to type and parameters. * * @author Gabor Bergmann */ public class Library { - // boolean activeStorage = true; - - ReteContainer reteContainer; - - Map projectionIndexers; // Tuple - Map countNodes; // Tuple - Map joinNodes; // Tuple - Map existenceNodes; // Tuple - Map ineqFilters; // Tuple - Map eqFilters; // Tuple - Map valueBinderFilters; // Tuple - Map trimmers; // Tuple - Map transparentNodes; // Tuple - Map constantNodes; // Tuple constants - Map tcNodes; - - Map remoteReceivers; - Map, RemoteSupplier> remoteSuppliers; - - /** - * @param reteContainer - * the ReteNet whose interior is to be mapped. - */ - public Library(ReteContainer reteContainer) { - super(); - this.reteContainer = reteContainer; - - projectionIndexers = new HashMap(); - joinNodes = new HashMap(); - existenceNodes = new HashMap(); - ineqFilters = new HashMap(); - eqFilters = new HashMap(); - valueBinderFilters = new HashMap(); - trimmers = new HashMap(); - transparentNodes = new HashMap(); - constantNodes = new HashMap(); - countNodes = new HashMap(); - tcNodes = new HashMap(); - - remoteReceivers = new HashMap(); - remoteSuppliers = new HashMap, RemoteSupplier>(); - } - - synchronized RemoteReceiver accessRemoteReceiver( - Address address) { - if (!reteContainer.isLocal(address)) - return address.getContainer().getLibrary().accessRemoteReceiver( - address); - Supplier localSupplier = reteContainer.resolveLocal(address); - RemoteReceiver result = remoteReceivers.get(localSupplier); - if (result == null) { - result = new RemoteReceiver(reteContainer); - reteContainer.connect(localSupplier, result); // stateless node, no - // synch required - - if (Options.nodeSharingOption != Options.NodeSharingOption.NEVER) - remoteReceivers.put(localSupplier, result); - } - return result; - } - - /** - * @pre: address is NOT local - */ - synchronized RemoteSupplier accessRemoteSupplier( - Address address) { - RemoteSupplier result = remoteSuppliers.get(address); - if (result == null) { - result = new RemoteSupplier(reteContainer, address.getContainer() - .getLibrary().accessRemoteReceiver(address)); - // network.connectAndSynchronize(supplier, result); - - if (Options.nodeSharingOption != Options.NodeSharingOption.NEVER) - remoteSuppliers.put(address, result); - } - return result; - } - - /** - * The powerful method for accessing any (supplier) Address as a local - * supplier. - */ - public Supplier asSupplier(Address address) { - if (!reteContainer.isLocal(address)) - return accessRemoteSupplier(address); - else - return reteContainer.resolveLocal(address); - } - - public Address accessProjectionIndexer( - Address supplierAddress, TupleMask mask) - { - Supplier supplier = asSupplier(supplierAddress); - return reteContainer.makeAddress(accessProjectionIndexer(supplier, mask)); - } - public Address accessCountNode( - Address supplierAddress, TupleMask mask) - { - Supplier supplier = asSupplier(supplierAddress); - return reteContainer.makeAddress(accessCountNode(supplier, mask)); - } - public Address accessCountOuterIndexer( - Address supplierAddress, TupleMask mask) - { - Supplier supplier = asSupplier(supplierAddress); - return reteContainer.makeAddress(accessCountNode(supplier, mask).getAggregatorOuterIndexer()); - } - public Address accessCountOuterIdentityIndexer( - Address supplierAddress, TupleMask mask, - int resultPositionInSignature) - { - Supplier supplier = asSupplier(supplierAddress); - return reteContainer.makeAddress( - accessCountNode(supplier, mask).getAggregatorOuterIdentityIndexer(resultPositionInSignature)); - } - - // local version - public synchronized ProjectionIndexer accessProjectionIndexer(Supplier supplier, - TupleMask mask) { - Object[] paramsArray = { supplier.getNodeId(), mask }; - Tuple params = new FlatTuple(paramsArray); - ProjectionIndexer result = projectionIndexers.get(params); - if (result == null) { - result = supplier.constructIndex(mask); - if (Options.nodeSharingOption != Options.NodeSharingOption.NEVER) - projectionIndexers.put(params, result); - } - return result; - } - // local version - public synchronized CountNode accessCountNode(Supplier supplier, TupleMask mask) { - Object[] paramsArray = { supplier.getNodeId(), mask }; - Tuple params = new FlatTuple(paramsArray); - CountNode result = countNodes.get(params); - if (result == null) { - result = new CountNode(reteContainer, accessProjectionIndexer(supplier, mask)); - - if (Options.nodeSharingOption != Options.NodeSharingOption.NEVER) - countNodes.put(params, result); - } - return result; - } - - // local version - public synchronized ProjectionIndexer accessProjectionIndexerOnetime(Supplier supplier, - TupleMask mask) { - if (Options.nodeSharingOption != Options.NodeSharingOption.NEVER) - return accessProjectionIndexer(supplier, mask); - - reteContainer.flushUpdates(); - OnetimeIndexer result = new OnetimeIndexer(reteContainer, mask); - reteContainer.sendConstructionUpdates(result, Direction.INSERT, - reteContainer.pullContents(supplier)); - reteContainer.flushUpdates(); - - return result; - } - - // local, read-only version - public synchronized ProjectionIndexer peekProjectionIndexer(Supplier supplier, TupleMask mask) { - Object[] paramsArray = { supplier.getNodeId(), mask }; - Tuple params = new FlatTuple(paramsArray); - return projectionIndexers.get(params); - } - - /** - * @pre: both projectionIndexers must be local to this container. - */ - public synchronized Address accessJoinNode( - Address primaryIndexer, - Address secondaryIndexer, - TupleMask complementer) - { - Slots slots = avoidActiveNodeConflict( - reteContainer.resolveLocal(primaryIndexer), reteContainer.resolveLocal(secondaryIndexer)); - IterableIndexer primarySlot = slots.primary; - Indexer secondarySlot = slots.secondary; - - Object[] paramsArray = { primarySlot.getNodeId(), - secondarySlot.getNodeId(), complementer }; - Tuple params = new FlatTuple(paramsArray); - JoinNode result = joinNodes.get(params); - if (result == null) { - result = new JoinNode(reteContainer, primarySlot, secondarySlot, - complementer); - // network.connectAndSynchronize(supplier, result); - - if (Options.nodeSharingOption == Options.NodeSharingOption.ALL) - joinNodes.put(params, result); - } - return reteContainer.makeAddress(result); - } - - /** - * If two indexers share their active node, joining them via DualInputNode is error-prone. - * Exception: coincidence of the two indexers is supported. - * @return a replacement for the secondary Indexers, if needed - */ - private Slots avoidActiveNodeConflict( - final IterableIndexer primarySlot, - final Indexer secondarySlot) { - Slots result = new Slots(){{primary = primarySlot; secondary = secondarySlot;}}; - if (activeNodeConflict(primarySlot, secondarySlot)) - if (secondarySlot instanceof IterableIndexer) - result.secondary = accessActiveIndexer((IterableIndexer)secondarySlot); - else - result.primary = accessActiveIndexer(primarySlot); - return result; - } - private static class Slots { - IterableIndexer primary; - Indexer secondary; - } - - /** - * Returns a copy of the given indexer that is an active node by itself (created if does not exist). - * (Convention: attached with same mask to a transparent node that is attached to parent node.) - * Node is created if it does not exist yet. - * @return an identical but active indexer - */ - private ProjectionIndexer accessActiveIndexer(IterableIndexer indexer) { - TransparentNode transparent = accessTransparentNodeInternal(indexer.getParent()); - return accessProjectionIndexer(transparent, indexer.getMask()); - } - -// /** -// * Read-only-check for a copy of the given indexer that is an active node by itself. -// * (Expected convention: attached with same mask to a transparent node that is attached to parent node.) -// * @return an identical but active indexer, if such exists, null otherwise -// */ -// private ProjectionIndexer peekActiveIndexer(Indexer indexer) { -// TransparentNode transparent = transparentNodes.get(indexer.getParent()); -// if (transparent != null) { -// return peekProjectionIndexer(transparent, indexer.getMask()); -// } -// return null; -// } - - /** - * If two indexers share their active node, joining them via DualInputNode is error-prone. - * Exception: coincidence of the two indexers is supported. - * @return true if there is a conflict of active nodes. - */ - private boolean activeNodeConflict(Indexer primarySlot, Indexer secondarySlot) { - return !primarySlot.equals(secondarySlot) && - primarySlot.getActiveNode().equals(secondarySlot.getActiveNode()); - } - - /** - * @pre: both projectionIndexers must be local to this container. - */ - public synchronized Address accessExistenceNode( - Address primaryIndexer, - Address secondaryIndexer, - boolean negative) - { - Slots slots = avoidActiveNodeConflict( - reteContainer.resolveLocal(primaryIndexer), reteContainer.resolveLocal(secondaryIndexer)); - IterableIndexer primarySlot = slots.primary; - Indexer secondarySlot = slots.secondary; - - Object[] paramsArray = { primarySlot.getNodeId(), - secondarySlot.getNodeId(), negative }; - Tuple params = new FlatTuple(paramsArray); - ExistenceNode result = existenceNodes.get(params); - if (result == null) { - result = new ExistenceNode(reteContainer, primarySlot, - secondarySlot, negative); - // network.connectAndSynchronize(supplier, result); - - if (Options.nodeSharingOption == Options.NodeSharingOption.ALL) - existenceNodes.put(params, result); - } - return reteContainer.makeAddress(result); - } - - public synchronized Address accessInequalityFilterNode( - Address supplierAddress, int subject, - TupleMask inequalityMask) { - Supplier supplier = asSupplier(supplierAddress); - Object[] paramsArray = { supplier.getNodeId(), subject, inequalityMask }; - Tuple params = new FlatTuple(paramsArray); - InequalityFilterNode result = ineqFilters.get(params); - if (result == null) { - result = new InequalityFilterNode(reteContainer, subject, - inequalityMask); - reteContainer.connect(supplier, result); // stateless node, no synch - // required - - if (Options.nodeSharingOption == Options.NodeSharingOption.ALL) - ineqFilters.put(params, result); - } - return reteContainer.makeAddress(result); - } - - public synchronized Address accessValueBinderFilterNode( - Address supplierAddress, int bindingIndex, - Object bindingValue) { - Supplier supplier = asSupplier(supplierAddress); - Object[] paramsArray = { supplier.getNodeId(), bindingIndex, bindingValue }; - Tuple params = new FlatTuple(paramsArray); - ValueBinderFilterNode result = valueBinderFilters.get(params); - if (result == null) { - result = new ValueBinderFilterNode(reteContainer, bindingIndex, - bindingValue); - reteContainer.connect(supplier, result); // stateless node, no synch - // required - - if (Options.nodeSharingOption == Options.NodeSharingOption.ALL) - valueBinderFilters.put(params, result); - } - return reteContainer.makeAddress(result); - } - - public synchronized Address accessEqualityFilterNode( - Address supplierAddress, int[] indices) { - Supplier supplier = asSupplier(supplierAddress); - Object[] paramsArray = { supplier.getNodeId(), new FlatTuple(indices) }; - Tuple params = new FlatTuple(paramsArray); - EqualityFilterNode result = eqFilters.get(params); - if (result == null) { - result = new EqualityFilterNode(reteContainer, indices); - reteContainer.connect(supplier, result); // stateless node, no synch - // required - - if (Options.nodeSharingOption == Options.NodeSharingOption.ALL) - eqFilters.put(params, result); - } - return reteContainer.makeAddress(result); - } - - public synchronized Address accessTrimmerNode( - Address supplierAddress, TupleMask mask) { - Supplier supplier = asSupplier(supplierAddress); - Object[] paramsArray = { supplier.getNodeId(), mask }; - Tuple params = new FlatTuple(paramsArray); - TrimmerNode result = trimmers.get(params); - if (result == null) { - result = new TrimmerNode(reteContainer, mask); - reteContainer.connect(supplier, result); // stateless node, no synch - // required - - if (Options.nodeSharingOption == Options.NodeSharingOption.ALL) - trimmers.put(params, result); - } - return reteContainer.makeAddress(result); - } - - public synchronized Address accessTransparentNode( - Address supplierAddress) { - Supplier supplier = asSupplier(supplierAddress); - TransparentNode result = accessTransparentNodeInternal(supplier); - return reteContainer.makeAddress(result); - } - private TransparentNode accessTransparentNodeInternal(Supplier supplier) { - Supplier params = supplier; - TransparentNode result = transparentNodes.get(params); - if (result == null) { - result = new TransparentNode(reteContainer); - reteContainer.connect(supplier, result); // stateless node, no synch - // required - - if (Options.nodeSharingOption == Options.NodeSharingOption.ALL) - transparentNodes.put(params, result); - } - return result; - } - - public synchronized Address accessConstantNode(Tuple constants) { - // Object[] paramsArray = {supplier.getNodeId(), mask}; - Tuple params = constants;// new FlatTuple(paramsArray); - ConstantNode result = constantNodes.get(params); - if (result == null) { - result = new ConstantNode(reteContainer, constants); - // network.connectAndSynchronize(supplier, result) - - if (Options.nodeSharingOption == Options.NodeSharingOption.ALL) - constantNodes.put(params, result); - } - return reteContainer.makeAddress(result); - } - -// public synchronized void registerSpecializedProjectionIndexer(Node node, ProjectionIndexer indexer) { -// if (Options.nodeSharingOption != Options.NodeSharingOption.NEVER) { -// Object[] paramsArray = { node.getNodeId(), indexer.getMask() }; -// Tuple params = new FlatTuple(paramsArray); -// projectionIndexers.put(params, indexer); -// } -// } - - public synchronized Address newUniquenessEnforcerNode(int tupleWidth, Object tag) { - UniquenessEnforcerNode node = new UniquenessEnforcerNode(reteContainer, tupleWidth); - node.setTag(tag); - Address address = reteContainer.makeAddress(node); - return address; - } - - public synchronized Address newProductionNode(HashMap posMapping, Object tag) { - DefaultProductionNode node = new DefaultProductionNode(reteContainer, posMapping); - node.setTag(tag); - Address address = reteContainer.makeAddress(node); - return address; - } - - public synchronized Address accessTransitiveClosureNode(Address supplierAddress) { - Supplier supplier = asSupplier(supplierAddress); - Object[] paramsArray = { supplier.getNodeId() }; - Tuple params = new FlatTuple(paramsArray); - TransitiveClosureNode result = tcNodes.get(params); - if (result == null) { - Collection tuples = new ArrayList(); - supplier.pullInto(tuples); - result = new TransitiveClosureNode(reteContainer, tuples); - //reteContainer.connectAndSynchronize(supplier, result); - reteContainer.connect(supplier, result); - - if (Options.nodeSharingOption == Options.NodeSharingOption.ALL) - tcNodes.put(params, result); - } - return reteContainer.makeAddress(result); - } + // boolean activeStorage = true; + + ReteContainer reteContainer; + + Map projectionIndexers; // Tuple + Map countNodes; // Tuple + Map joinNodes; // Tuple + Map existenceNodes; // Tuple + Map ineqFilters; // Tuple + Map eqFilters; // Tuple + Map valueBinderFilters; // Tuple + Map trimmers; // Tuple + Map transparentNodes; // Tuple + Map constantNodes; // Tuple constants + Map tcNodes; + + Map remoteReceivers; + Map, RemoteSupplier> remoteSuppliers; + + /** + * @param reteContainer + * the ReteNet whose interior is to be mapped. + */ + public Library(ReteContainer reteContainer) { + super(); + this.reteContainer = reteContainer; + + projectionIndexers = new HashMap(); + joinNodes = new HashMap(); + existenceNodes = new HashMap(); + ineqFilters = new HashMap(); + eqFilters = new HashMap(); + valueBinderFilters = new HashMap(); + trimmers = new HashMap(); + transparentNodes = new HashMap(); + constantNodes = new HashMap(); + countNodes = new HashMap(); + tcNodes = new HashMap(); + + remoteReceivers = new HashMap(); + remoteSuppliers = new HashMap, RemoteSupplier>(); + } + + synchronized RemoteReceiver accessRemoteReceiver(Address address) { + if (!reteContainer.isLocal(address)) + return address.getContainer().getLibrary().accessRemoteReceiver(address); + Supplier localSupplier = reteContainer.resolveLocal(address); + RemoteReceiver result = remoteReceivers.get(localSupplier); + if (result == null) { + result = new RemoteReceiver(reteContainer); + reteContainer.connect(localSupplier, result); // stateless node, no + // synch required + + if (Options.nodeSharingOption != Options.NodeSharingOption.NEVER) + remoteReceivers.put(localSupplier, result); + } + return result; + } + + /** + * @pre: address is NOT local + */ + synchronized RemoteSupplier accessRemoteSupplier(Address address) { + RemoteSupplier result = remoteSuppliers.get(address); + if (result == null) { + result = new RemoteSupplier(reteContainer, address.getContainer().getLibrary() + .accessRemoteReceiver(address)); + // network.connectAndSynchronize(supplier, result); + + if (Options.nodeSharingOption != Options.NodeSharingOption.NEVER) + remoteSuppliers.put(address, result); + } + return result; + } + + /** + * The powerful method for accessing any (supplier) Address as a local supplier. + */ + public Supplier asSupplier(Address address) { + if (!reteContainer.isLocal(address)) + return accessRemoteSupplier(address); + else + return reteContainer.resolveLocal(address); + } + + public Address accessProjectionIndexer(Address supplierAddress, + TupleMask mask) { + Supplier supplier = asSupplier(supplierAddress); + return reteContainer.makeAddress(accessProjectionIndexer(supplier, mask)); + } + + public Address accessCountNode(Address supplierAddress, TupleMask mask) { + Supplier supplier = asSupplier(supplierAddress); + return reteContainer.makeAddress(accessCountNode(supplier, mask)); + } + + public Address accessCountOuterIndexer(Address supplierAddress, + TupleMask mask) { + Supplier supplier = asSupplier(supplierAddress); + return reteContainer.makeAddress(accessCountNode(supplier, mask).getAggregatorOuterIndexer()); + } + + public Address accessCountOuterIdentityIndexer(Address supplierAddress, + TupleMask mask, int resultPositionInSignature) { + Supplier supplier = asSupplier(supplierAddress); + return reteContainer.makeAddress(accessCountNode(supplier, mask).getAggregatorOuterIdentityIndexer( + resultPositionInSignature)); + } + + // local version + public synchronized ProjectionIndexer accessProjectionIndexer(Supplier supplier, TupleMask mask) { + Object[] paramsArray = { supplier.getNodeId(), mask }; + Tuple params = new FlatTuple(paramsArray); + ProjectionIndexer result = projectionIndexers.get(params); + if (result == null) { + result = supplier.constructIndex(mask); + if (Options.nodeSharingOption != Options.NodeSharingOption.NEVER) + projectionIndexers.put(params, result); + } + return result; + } + + // local version + public synchronized CountNode accessCountNode(Supplier supplier, TupleMask mask) { + Object[] paramsArray = { supplier.getNodeId(), mask }; + Tuple params = new FlatTuple(paramsArray); + CountNode result = countNodes.get(params); + if (result == null) { + result = new CountNode(reteContainer, accessProjectionIndexer(supplier, mask)); + + if (Options.nodeSharingOption != Options.NodeSharingOption.NEVER) + countNodes.put(params, result); + } + return result; + } + + // local version + public synchronized ProjectionIndexer accessProjectionIndexerOnetime(Supplier supplier, TupleMask mask) { + if (Options.nodeSharingOption != Options.NodeSharingOption.NEVER) + return accessProjectionIndexer(supplier, mask); + + reteContainer.flushUpdates(); + OnetimeIndexer result = new OnetimeIndexer(reteContainer, mask); + reteContainer.sendConstructionUpdates(result, Direction.INSERT, reteContainer.pullContents(supplier)); + reteContainer.flushUpdates(); + + return result; + } + + // local, read-only version + public synchronized ProjectionIndexer peekProjectionIndexer(Supplier supplier, TupleMask mask) { + Object[] paramsArray = { supplier.getNodeId(), mask }; + Tuple params = new FlatTuple(paramsArray); + return projectionIndexers.get(params); + } + + /** + * @pre: both projectionIndexers must be local to this container. + */ + public synchronized Address accessJoinNode(Address primaryIndexer, + Address secondaryIndexer, TupleMask complementer) { + Slots slots = avoidActiveNodeConflict(reteContainer.resolveLocal(primaryIndexer), + reteContainer.resolveLocal(secondaryIndexer)); + IterableIndexer primarySlot = slots.primary; + Indexer secondarySlot = slots.secondary; + + Object[] paramsArray = { primarySlot.getNodeId(), secondarySlot.getNodeId(), complementer }; + Tuple params = new FlatTuple(paramsArray); + JoinNode result = joinNodes.get(params); + if (result == null) { + result = new JoinNode(reteContainer, primarySlot, secondarySlot, complementer); + // network.connectAndSynchronize(supplier, result); + + if (Options.nodeSharingOption == Options.NodeSharingOption.ALL) + joinNodes.put(params, result); + } + return reteContainer.makeAddress(result); + } + + /** + * If two indexers share their active node, joining them via DualInputNode is error-prone. Exception: coincidence of + * the two indexers is supported. + * + * @return a replacement for the secondary Indexers, if needed + */ + private Slots avoidActiveNodeConflict(final IterableIndexer primarySlot, final Indexer secondarySlot) { + Slots result = new Slots() { + { + primary = primarySlot; + secondary = secondarySlot; + } + }; + if (activeNodeConflict(primarySlot, secondarySlot)) + if (secondarySlot instanceof IterableIndexer) + result.secondary = accessActiveIndexer((IterableIndexer) secondarySlot); + else + result.primary = accessActiveIndexer(primarySlot); + return result; + } + + private static class Slots { + IterableIndexer primary; + Indexer secondary; + } + + /** + * Returns a copy of the given indexer that is an active node by itself (created if does not exist). (Convention: + * attached with same mask to a transparent node that is attached to parent node.) Node is created if it does not + * exist yet. + * + * @return an identical but active indexer + */ + private ProjectionIndexer accessActiveIndexer(IterableIndexer indexer) { + TransparentNode transparent = accessTransparentNodeInternal(indexer.getParent()); + return accessProjectionIndexer(transparent, indexer.getMask()); + } + + // /** + // * Read-only-check for a copy of the given indexer that is an active node by itself. + // * (Expected convention: attached with same mask to a transparent node that is attached to parent node.) + // * @return an identical but active indexer, if such exists, null otherwise + // */ + // private ProjectionIndexer peekActiveIndexer(Indexer indexer) { + // TransparentNode transparent = transparentNodes.get(indexer.getParent()); + // if (transparent != null) { + // return peekProjectionIndexer(transparent, indexer.getMask()); + // } + // return null; + // } + + /** + * If two indexers share their active node, joining them via DualInputNode is error-prone. Exception: coincidence of + * the two indexers is supported. + * + * @return true if there is a conflict of active nodes. + */ + private boolean activeNodeConflict(Indexer primarySlot, Indexer secondarySlot) { + return !primarySlot.equals(secondarySlot) && primarySlot.getActiveNode().equals(secondarySlot.getActiveNode()); + } + + /** + * @pre: both projectionIndexers must be local to this container. + */ + public synchronized Address accessExistenceNode(Address primaryIndexer, + Address secondaryIndexer, boolean negative) { + Slots slots = avoidActiveNodeConflict(reteContainer.resolveLocal(primaryIndexer), + reteContainer.resolveLocal(secondaryIndexer)); + IterableIndexer primarySlot = slots.primary; + Indexer secondarySlot = slots.secondary; + + Object[] paramsArray = { primarySlot.getNodeId(), secondarySlot.getNodeId(), negative }; + Tuple params = new FlatTuple(paramsArray); + ExistenceNode result = existenceNodes.get(params); + if (result == null) { + result = new ExistenceNode(reteContainer, primarySlot, secondarySlot, negative); + // network.connectAndSynchronize(supplier, result); + + if (Options.nodeSharingOption == Options.NodeSharingOption.ALL) + existenceNodes.put(params, result); + } + return reteContainer.makeAddress(result); + } + + public synchronized Address accessInequalityFilterNode( + Address supplierAddress, int subject, TupleMask inequalityMask) { + Supplier supplier = asSupplier(supplierAddress); + Object[] paramsArray = { supplier.getNodeId(), subject, inequalityMask }; + Tuple params = new FlatTuple(paramsArray); + InequalityFilterNode result = ineqFilters.get(params); + if (result == null) { + result = new InequalityFilterNode(reteContainer, subject, inequalityMask); + reteContainer.connect(supplier, result); // stateless node, no synch + // required + + if (Options.nodeSharingOption == Options.NodeSharingOption.ALL) + ineqFilters.put(params, result); + } + return reteContainer.makeAddress(result); + } + + public synchronized Address accessValueBinderFilterNode( + Address supplierAddress, int bindingIndex, Object bindingValue) { + Supplier supplier = asSupplier(supplierAddress); + Object[] paramsArray = { supplier.getNodeId(), bindingIndex, bindingValue }; + Tuple params = new FlatTuple(paramsArray); + ValueBinderFilterNode result = valueBinderFilters.get(params); + if (result == null) { + result = new ValueBinderFilterNode(reteContainer, bindingIndex, bindingValue); + reteContainer.connect(supplier, result); // stateless node, no synch + // required + + if (Options.nodeSharingOption == Options.NodeSharingOption.ALL) + valueBinderFilters.put(params, result); + } + return reteContainer.makeAddress(result); + } + + public synchronized Address accessEqualityFilterNode( + Address supplierAddress, int[] indices) { + Supplier supplier = asSupplier(supplierAddress); + Object[] paramsArray = { supplier.getNodeId(), new FlatTuple(indices) }; + Tuple params = new FlatTuple(paramsArray); + EqualityFilterNode result = eqFilters.get(params); + if (result == null) { + result = new EqualityFilterNode(reteContainer, indices); + reteContainer.connect(supplier, result); // stateless node, no synch + // required + + if (Options.nodeSharingOption == Options.NodeSharingOption.ALL) + eqFilters.put(params, result); + } + return reteContainer.makeAddress(result); + } + + public synchronized Address accessTrimmerNode(Address supplierAddress, + TupleMask mask) { + Supplier supplier = asSupplier(supplierAddress); + Object[] paramsArray = { supplier.getNodeId(), mask }; + Tuple params = new FlatTuple(paramsArray); + TrimmerNode result = trimmers.get(params); + if (result == null) { + result = new TrimmerNode(reteContainer, mask); + reteContainer.connect(supplier, result); // stateless node, no synch + // required + + if (Options.nodeSharingOption == Options.NodeSharingOption.ALL) + trimmers.put(params, result); + } + return reteContainer.makeAddress(result); + } + + public synchronized Address accessTransparentNode(Address supplierAddress) { + Supplier supplier = asSupplier(supplierAddress); + TransparentNode result = accessTransparentNodeInternal(supplier); + return reteContainer.makeAddress(result); + } + + private TransparentNode accessTransparentNodeInternal(Supplier supplier) { + Supplier params = supplier; + TransparentNode result = transparentNodes.get(params); + if (result == null) { + result = new TransparentNode(reteContainer); + reteContainer.connect(supplier, result); // stateless node, no synch + // required + + if (Options.nodeSharingOption == Options.NodeSharingOption.ALL) + transparentNodes.put(params, result); + } + return result; + } + + public synchronized Address accessConstantNode(Tuple constants) { + // Object[] paramsArray = {supplier.getNodeId(), mask}; + Tuple params = constants;// new FlatTuple(paramsArray); + ConstantNode result = constantNodes.get(params); + if (result == null) { + result = new ConstantNode(reteContainer, constants); + // network.connectAndSynchronize(supplier, result) + + if (Options.nodeSharingOption == Options.NodeSharingOption.ALL) + constantNodes.put(params, result); + } + return reteContainer.makeAddress(result); + } + + // public synchronized void registerSpecializedProjectionIndexer(Node node, ProjectionIndexer indexer) { + // if (Options.nodeSharingOption != Options.NodeSharingOption.NEVER) { + // Object[] paramsArray = { node.getNodeId(), indexer.getMask() }; + // Tuple params = new FlatTuple(paramsArray); + // projectionIndexers.put(params, indexer); + // } + // } + + public synchronized Address newUniquenessEnforcerNode(int tupleWidth, Object tag) { + UniquenessEnforcerNode node = new UniquenessEnforcerNode(reteContainer, tupleWidth); + node.setTag(tag); + Address address = reteContainer.makeAddress(node); + return address; + } + + public synchronized Address newProductionNode(HashMap posMapping, Object tag) { + DefaultProductionNode node = new DefaultProductionNode(reteContainer, posMapping); + node.setTag(tag); + Address address = reteContainer.makeAddress(node); + return address; + } + + public synchronized Address accessTransitiveClosureNode( + Address supplierAddress) { + Supplier supplier = asSupplier(supplierAddress); + Object[] paramsArray = { supplier.getNodeId() }; + Tuple params = new FlatTuple(paramsArray); + TransitiveClosureNode result = tcNodes.get(params); + if (result == null) { + Collection tuples = new ArrayList(); + supplier.pullInto(tuples); + result = new TransitiveClosureNode(reteContainer, tuples); + // reteContainer.connectAndSynchronize(supplier, result); + reteContainer.connect(supplier, result); + + if (Options.nodeSharingOption == Options.NodeSharingOption.ALL) + tcNodes.put(params, result); + } + return reteContainer.makeAddress(result); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Network.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Network.java index ccb26ea3..d765871f 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Network.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Network.java @@ -25,356 +25,330 @@ import org.eclipse.incquery.runtime.rete.tuple.Tuple; import org.eclipse.incquery.runtime.rete.util.Options; - /** * @author Gabor Bergmann * */ public class Network { - int threads; - - protected ArrayList containers; - ReteContainer headContainer; - private int firstContainer = 0; - private int nextContainer = 0; - - // the following fields exist only if threads > 0 - protected Map globalTerminationCriteria = null; - protected Map reportedClocks = null; - protected Lock updateLock = null; // grab during normal update operations - protected Lock structuralChangeLock = null; // grab if the network structure is to - // be changed - - protected IPatternMatcherRuntimeContext context; - - - /** - * @param threads the number of threads to operate the network with; - * 0 means single-threaded operation, - * 1 starts an asynchronous thread to operate the RETE net, - * >1 uses multiple RETE containers. - */ - public Network(int threads, IPatternMatcherRuntimeContext context) { - super(); - this.threads = threads; - this.context = context; - - containers = new ArrayList(); - firstContainer = (threads > 1) ? Options.firstFreeContainer : 0; // NOPMD - nextContainer = firstContainer; - - if (threads > 0) { - globalTerminationCriteria = new HashMap(); - reportedClocks = new HashMap(); - ReadWriteLock rwl = new ReentrantReadWriteLock(); - updateLock = rwl.readLock(); - structuralChangeLock = rwl.writeLock(); - for (int i = 0; i < threads; ++i) containers.add(new ReteContainer(this, true)); - } else - containers.add(new ReteContainer(this, false)); - - headContainer = containers.get(0); - } - - /** - * Kills this Network along with all containers and message consumption - * cycles. - */ - public void kill() { - for (ReteContainer container : containers) { - container.kill(); - } - containers.clear(); - } - - /** - * Returns the head container, that is guaranteed to reside in the same JVM - * as the Network object. - * - * @return - */ - public ReteContainer getHeadContainer() { - return headContainer; - } - - /** - * Returns the next container in round-robin fashion. Configurable not to - * yield head container. - */ - public ReteContainer getNextContainer() { - if (nextContainer >= containers.size()) - nextContainer = firstContainer; - return containers.get(nextContainer++); - } - - /** - * Internal message delivery method. - * @pre threads > 0 - */ - private void sendUpdate(Address receiver, - Direction direction, Tuple updateElement) { - ReteContainer affectedContainer = receiver.getContainer(); - synchronized (globalTerminationCriteria) { - long newCriterion = affectedContainer.sendUpdateToLocalAddress( - receiver, direction, updateElement); - terminationCriterion(affectedContainer, newCriterion); - } - } - - /** - * Internal message delivery method for single-threaded operation - * @pre threads == 0 - */ - private void sendUpdateSingleThreaded(Address receiver, - Direction direction, Tuple updateElement) { - ReteContainer affectedContainer = receiver.getContainer(); - affectedContainer.sendUpdateToLocalAddressSingleThreaded(receiver, direction, updateElement); - } - - /** - * Internal message delivery method. - * @pre threads > 0 - */ - private void sendUpdates(Address receiver, - Direction direction, Collection updateElements) { - if (updateElements.isEmpty()) - return; - ReteContainer affectedContainer = receiver.getContainer(); - synchronized (globalTerminationCriteria) { - long newCriterion = affectedContainer.sendUpdatesToLocalAddress( - receiver, direction, updateElements); - terminationCriterion(affectedContainer, newCriterion); - } - } - - /** - * Sends an update message to the receiver node, indicating a newly found or - * lost partial matching. The node may reside in any of the containers - * associated with this network. To be called from a user thread during - * normal operation, NOT during construction. - * - * @return the value of the target container's clock at the time when the - * message was accepted into its message queue - */ - public void sendExternalUpdate(Address receiver, - Direction direction, Tuple updateElement) { - if (threads > 0) - { - try { - updateLock.lock(); - sendUpdate(receiver, direction, updateElement); - } finally { - updateLock.unlock(); - } - } - else { - sendUpdateSingleThreaded(receiver, direction, updateElement); - //getHeadContainer(). - } - } - - /** - * Sends an update message to the receiver node, indicating a newly found or - * lost partial matching. The node may reside in any of the containers - * associated with this network. To be called from a user thread during - * construction. - * - * @pre: structuralChangeLock MUST be grabbed by the sequence - * (but not necessarily this thread, as the sequence may span through network - * calls, that's why it's not enforced here ) - * - * @return the value of the target container's clock at the time when the - * message was accepted into its message queue - */ - public void sendConstructionUpdate(Address receiver, - Direction direction, Tuple updateElement) { - // structuralChangeLock.lock(); - if (threads > 0) - sendUpdate(receiver, direction, updateElement); - else - receiver.getContainer().sendUpdateToLocalAddressSingleThreaded(receiver, direction, updateElement); - // structuralChangeLock.unlock(); - } - - /** - * Sends multiple update messages atomically to the receiver node, - * indicating a newly found or lost partial matching. The node may reside in - * any of the containers associated with this network. To be called from a - * user thread during construction. - * - * @pre: structuralChangeLock MUST be grabbed by the sequence - * (but not necessarily this thread, as the sequence may span through network - * calls, that's why it's not enforced here ) - * - * @return the value of the target container's clock at the time when the - * message was accepted into its message queue - */ - public void sendConstructionUpdates(Address receiver, - Direction direction, Collection updateElements) { - // structuralChangeLock.lock(); - if (threads > 0) - sendUpdates(receiver, direction, updateElements); - else - receiver.getContainer().sendUpdatesToLocalAddressSingleThreaded(receiver, direction, updateElements); - // structuralChangeLock.unlock(); - } - - /** - * Establishes connection between a supplier and a receiver node, regardless - * which container they are in. Not to be called remotely, because this - * method enforces the structural lock. - * - * @param supplier - * @param receiver - * @param synchronise - * indicates whether the receiver should be synchronised to the - * current contents of the supplier - */ - public void connectRemoteNodes(Address supplier, - Address receiver, boolean synchronise) { - try { - if (threads > 0) structuralChangeLock.lock(); - receiver.getContainer().connectRemoteNodes(supplier, receiver, synchronise); - } finally { - if (threads > 0) structuralChangeLock.unlock(); - } - } - - /** - * Severs connection between a supplier and a receiver node, regardless - * which container they are in. Not to be called remotely, because this - * method enforces the structural lock. - * - * @param supplier - * @param receiver - * @param desynchronise - * indicates whether the current contents of the supplier should - * be subtracted from the receiver - */ - public void disconnectRemoteNodes(Address supplier, - Address receiver, boolean desynchronise) { - try { - if (threads > 0) structuralChangeLock.lock(); - receiver.getContainer().disconnectRemoteNodes(supplier, receiver, desynchronise); - } finally { - if (threads > 0) structuralChangeLock.unlock(); - } - } - - /** - * Containers use this method to report whenever they run out of messages in - * their queue. - * - * To be called from the thread of the reporting container. - * - * @pre threads > 0. - * @param reportingContainer - * the container reporting the emptiness of its message queue. - * @param clock - * the value of the container's clock when reporting. - * @param localTerminationCriteria - * the latest clock values this container has received from other - * containers since the last time it reported termination. - */ - void reportLocalUpdateTermination(ReteContainer reportingContainer, - long clock, Map localTerminationCriteria) { - synchronized (globalTerminationCriteria) { - for (Entry criterion : - localTerminationCriteria.entrySet()) { - terminationCriterion(criterion.getKey(), criterion.getValue()); - } - - reportedClocks.put(reportingContainer, clock); - Long criterion = globalTerminationCriteria.get(reportingContainer); - if (criterion != null && criterion < clock) - globalTerminationCriteria.remove(reportingContainer); - - if (globalTerminationCriteria.isEmpty()) - globalTerminationCriteria.notifyAll(); - } - } - - /** - * @pre threads > 0 - */ - private void terminationCriterion(ReteContainer affectedContainer, - long newCriterion) { - synchronized (globalTerminationCriteria) { - Long oldCriterion = globalTerminationCriteria - .get(affectedContainer); - Long oldClock = reportedClocks.get(affectedContainer); - long relevantClock = oldClock == null ? 0 : oldClock; - if ((relevantClock <= newCriterion) - && (oldCriterion == null || oldCriterion < newCriterion)) { - globalTerminationCriteria.put(affectedContainer, newCriterion); - } - } - } - - /** - * Waits until all rete update operations are settled in all containers. - * Returns immediately, if no updates are pending. - * - * To be called from any user thread. - */ - public void waitForReteTermination() { - if (threads > 0) - { - synchronized (globalTerminationCriteria) { - while (!globalTerminationCriteria.isEmpty()) { - try { - globalTerminationCriteria.wait(); - } catch (InterruptedException e) { - - } - } - } - } - else headContainer.messageConsumptionSingleThreaded(); - } - - /** - * Waits to execute action until all rete update operations are settled in - * all containers. Runs action and returns immediately, if no updates are - * pending. The given action is guaranteed to be run when the terminated - * state still persists. - * - * @param action - * the action to be run when reaching the steady-state. - * - * To be called from any user thread. - */ - public void waitForReteTermination(Runnable action) { - if (threads > 0) - { - synchronized (globalTerminationCriteria) { - while (!globalTerminationCriteria.isEmpty()) { - try { - globalTerminationCriteria.wait(); - } catch (InterruptedException e) { - - } - } - action.run(); - } - } - else { - headContainer.messageConsumptionSingleThreaded(); - action.run(); - } - - } - - /** - * @return the structuralChangeLock - */ - public Lock getStructuralChangeLock() { - return structuralChangeLock; - } - - public IPatternMatcherRuntimeContext getContext() { - return context; - } - + int threads; + + protected ArrayList containers; + ReteContainer headContainer; + private int firstContainer = 0; + private int nextContainer = 0; + + // the following fields exist only if threads > 0 + protected Map globalTerminationCriteria = null; + protected Map reportedClocks = null; + protected Lock updateLock = null; // grab during normal update operations + protected Lock structuralChangeLock = null; // grab if the network structure is to + // be changed + + protected IPatternMatcherRuntimeContext context; + + /** + * @param threads + * the number of threads to operate the network with; 0 means single-threaded operation, 1 starts an + * asynchronous thread to operate the RETE net, >1 uses multiple RETE containers. + */ + public Network(int threads, IPatternMatcherRuntimeContext context) { + super(); + this.threads = threads; + this.context = context; + + containers = new ArrayList(); + firstContainer = (threads > 1) ? Options.firstFreeContainer : 0; // NOPMD + nextContainer = firstContainer; + + if (threads > 0) { + globalTerminationCriteria = new HashMap(); + reportedClocks = new HashMap(); + ReadWriteLock rwl = new ReentrantReadWriteLock(); + updateLock = rwl.readLock(); + structuralChangeLock = rwl.writeLock(); + for (int i = 0; i < threads; ++i) + containers.add(new ReteContainer(this, true)); + } else + containers.add(new ReteContainer(this, false)); + + headContainer = containers.get(0); + } + + /** + * Kills this Network along with all containers and message consumption cycles. + */ + public void kill() { + for (ReteContainer container : containers) { + container.kill(); + } + containers.clear(); + } + + /** + * Returns the head container, that is guaranteed to reside in the same JVM as the Network object. + * + * @return + */ + public ReteContainer getHeadContainer() { + return headContainer; + } + + /** + * Returns the next container in round-robin fashion. Configurable not to yield head container. + */ + public ReteContainer getNextContainer() { + if (nextContainer >= containers.size()) + nextContainer = firstContainer; + return containers.get(nextContainer++); + } + + /** + * Internal message delivery method. + * + * @pre threads > 0 + */ + private void sendUpdate(Address receiver, Direction direction, Tuple updateElement) { + ReteContainer affectedContainer = receiver.getContainer(); + synchronized (globalTerminationCriteria) { + long newCriterion = affectedContainer.sendUpdateToLocalAddress(receiver, direction, updateElement); + terminationCriterion(affectedContainer, newCriterion); + } + } + + /** + * Internal message delivery method for single-threaded operation + * + * @pre threads == 0 + */ + private void sendUpdateSingleThreaded(Address receiver, Direction direction, Tuple updateElement) { + ReteContainer affectedContainer = receiver.getContainer(); + affectedContainer.sendUpdateToLocalAddressSingleThreaded(receiver, direction, updateElement); + } + + /** + * Internal message delivery method. + * + * @pre threads > 0 + */ + private void sendUpdates(Address receiver, Direction direction, Collection updateElements) { + if (updateElements.isEmpty()) + return; + ReteContainer affectedContainer = receiver.getContainer(); + synchronized (globalTerminationCriteria) { + long newCriterion = affectedContainer.sendUpdatesToLocalAddress(receiver, direction, updateElements); + terminationCriterion(affectedContainer, newCriterion); + } + } + + /** + * Sends an update message to the receiver node, indicating a newly found or lost partial matching. The node may + * reside in any of the containers associated with this network. To be called from a user thread during normal + * operation, NOT during construction. + * + * @return the value of the target container's clock at the time when the message was accepted into its message + * queue + */ + public void sendExternalUpdate(Address receiver, Direction direction, Tuple updateElement) { + if (threads > 0) { + try { + updateLock.lock(); + sendUpdate(receiver, direction, updateElement); + } finally { + updateLock.unlock(); + } + } else { + sendUpdateSingleThreaded(receiver, direction, updateElement); + // getHeadContainer(). + } + } + + /** + * Sends an update message to the receiver node, indicating a newly found or lost partial matching. The node may + * reside in any of the containers associated with this network. To be called from a user thread during + * construction. + * + * @pre: structuralChangeLock MUST be grabbed by the sequence (but not necessarily this thread, as the sequence may + * span through network calls, that's why it's not enforced here ) + * + * @return the value of the target container's clock at the time when the message was accepted into its message + * queue + */ + public void sendConstructionUpdate(Address receiver, Direction direction, Tuple updateElement) { + // structuralChangeLock.lock(); + if (threads > 0) + sendUpdate(receiver, direction, updateElement); + else + receiver.getContainer().sendUpdateToLocalAddressSingleThreaded(receiver, direction, updateElement); + // structuralChangeLock.unlock(); + } + + /** + * Sends multiple update messages atomically to the receiver node, indicating a newly found or lost partial + * matching. The node may reside in any of the containers associated with this network. To be called from a user + * thread during construction. + * + * @pre: structuralChangeLock MUST be grabbed by the sequence (but not necessarily this thread, as the sequence may + * span through network calls, that's why it's not enforced here ) + * + * @return the value of the target container's clock at the time when the message was accepted into its message + * queue + */ + public void sendConstructionUpdates(Address receiver, Direction direction, + Collection updateElements) { + // structuralChangeLock.lock(); + if (threads > 0) + sendUpdates(receiver, direction, updateElements); + else + receiver.getContainer().sendUpdatesToLocalAddressSingleThreaded(receiver, direction, updateElements); + // structuralChangeLock.unlock(); + } + + /** + * Establishes connection between a supplier and a receiver node, regardless which container they are in. Not to be + * called remotely, because this method enforces the structural lock. + * + * @param supplier + * @param receiver + * @param synchronise + * indicates whether the receiver should be synchronised to the current contents of the supplier + */ + public void connectRemoteNodes(Address supplier, Address receiver, + boolean synchronise) { + try { + if (threads > 0) + structuralChangeLock.lock(); + receiver.getContainer().connectRemoteNodes(supplier, receiver, synchronise); + } finally { + if (threads > 0) + structuralChangeLock.unlock(); + } + } + + /** + * Severs connection between a supplier and a receiver node, regardless which container they are in. Not to be + * called remotely, because this method enforces the structural lock. + * + * @param supplier + * @param receiver + * @param desynchronise + * indicates whether the current contents of the supplier should be subtracted from the receiver + */ + public void disconnectRemoteNodes(Address supplier, Address receiver, + boolean desynchronise) { + try { + if (threads > 0) + structuralChangeLock.lock(); + receiver.getContainer().disconnectRemoteNodes(supplier, receiver, desynchronise); + } finally { + if (threads > 0) + structuralChangeLock.unlock(); + } + } + + /** + * Containers use this method to report whenever they run out of messages in their queue. + * + * To be called from the thread of the reporting container. + * + * @pre threads > 0. + * @param reportingContainer + * the container reporting the emptiness of its message queue. + * @param clock + * the value of the container's clock when reporting. + * @param localTerminationCriteria + * the latest clock values this container has received from other containers since the last time it + * reported termination. + */ + void reportLocalUpdateTermination(ReteContainer reportingContainer, long clock, + Map localTerminationCriteria) { + synchronized (globalTerminationCriteria) { + for (Entry criterion : localTerminationCriteria.entrySet()) { + terminationCriterion(criterion.getKey(), criterion.getValue()); + } + + reportedClocks.put(reportingContainer, clock); + Long criterion = globalTerminationCriteria.get(reportingContainer); + if (criterion != null && criterion < clock) + globalTerminationCriteria.remove(reportingContainer); + + if (globalTerminationCriteria.isEmpty()) + globalTerminationCriteria.notifyAll(); + } + } + + /** + * @pre threads > 0 + */ + private void terminationCriterion(ReteContainer affectedContainer, long newCriterion) { + synchronized (globalTerminationCriteria) { + Long oldCriterion = globalTerminationCriteria.get(affectedContainer); + Long oldClock = reportedClocks.get(affectedContainer); + long relevantClock = oldClock == null ? 0 : oldClock; + if ((relevantClock <= newCriterion) && (oldCriterion == null || oldCriterion < newCriterion)) { + globalTerminationCriteria.put(affectedContainer, newCriterion); + } + } + } + + /** + * Waits until all rete update operations are settled in all containers. Returns immediately, if no updates are + * pending. + * + * To be called from any user thread. + */ + public void waitForReteTermination() { + if (threads > 0) { + synchronized (globalTerminationCriteria) { + while (!globalTerminationCriteria.isEmpty()) { + try { + globalTerminationCriteria.wait(); + } catch (InterruptedException e) { + + } + } + } + } else + headContainer.messageConsumptionSingleThreaded(); + } + + /** + * Waits to execute action until all rete update operations are settled in all containers. Runs action and returns + * immediately, if no updates are pending. The given action is guaranteed to be run when the terminated state still + * persists. + * + * @param action + * the action to be run when reaching the steady-state. + * + * To be called from any user thread. + */ + public void waitForReteTermination(Runnable action) { + if (threads > 0) { + synchronized (globalTerminationCriteria) { + while (!globalTerminationCriteria.isEmpty()) { + try { + globalTerminationCriteria.wait(); + } catch (InterruptedException e) { + + } + } + action.run(); + } + } else { + headContainer.messageConsumptionSingleThreaded(); + action.run(); + } + + } + + /** + * @return the structuralChangeLock + */ + public Lock getStructuralChangeLock() { + return structuralChangeLock; + } + + public IPatternMatcherRuntimeContext getContext() { + return context; + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Node.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Node.java index 28e0f07c..02708276 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Node.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Node.java @@ -12,38 +12,37 @@ package org.eclipse.incquery.runtime.rete.network; /** - * A node of a rete network, should be uniquely identified by network and - * nodeId. NodeId can be requested by registering at the Network on - * construction. + * A node of a rete network, should be uniquely identified by network and nodeId. NodeId can be requested by registering + * at the Network on construction. * * @author Gabor Bergmann */ public interface Node { - /** - * @return the network this node belongs to. - */ - ReteContainer getContainer(); + /** + * @return the network this node belongs to. + */ + ReteContainer getContainer(); - /** - * @return the identifier unique to this node within the network. - */ - long getNodeId(); + /** + * @return the identifier unique to this node within the network. + */ + long getNodeId(); - /** - * Assigns a descriptive tag to the node - */ - void setTag(Object tag); + /** + * Assigns a descriptive tag to the node + */ + void setTag(Object tag); - /** - * @return the tag of the node - */ - Object getTag(); - -// /** -// * The semantics of the tuples contained in this node. -// * @return a tuple of correct size representing the semantics of each position. -// * @post not null -// */ -// Tuple getSemantics(); + /** + * @return the tag of the node + */ + Object getTag(); + + // /** + // * The semantics of the tuples contained in this node. + // * @return a tuple of correct size representing the semantics of each position. + // * @post not null + // */ + // Tuple getSemantics(); } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Production.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Production.java index 246ab500..537fdc25 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Production.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Production.java @@ -15,7 +15,6 @@ import org.eclipse.incquery.runtime.rete.tuple.Tuple; - /** * Interface intended for nodes containing complete matches. * @@ -23,27 +22,26 @@ */ public interface Production extends Tunnel, Iterable { - /** - * @return the position mapping of this particular pattern that maps members - * of the tuple type to their positions - */ - HashMap getPosMapping(); + /** + * @return the position mapping of this particular pattern that maps members of the tuple type to their positions + */ + HashMap getPosMapping(); - // /** - // * Removes all parents of the production node, - // * making it once independent from the pattern recognition subnet, - // * so that a new pattern definition can be applied. - // */ - // void tearOff(); - // - // /** - // * Sets the dirty flag. - // */ - // void setDirty(boolean dirty); - // - // /** - // * Returns the value of the dirty flag. - // * If true, pattern matcher needs to be reconstructed. - // */ - // boolean isDirty(); + // /** + // * Removes all parents of the production node, + // * making it once independent from the pattern recognition subnet, + // * so that a new pattern definition can be applied. + // */ + // void tearOff(); + // + // /** + // * Sets the dirty flag. + // */ + // void setDirty(boolean dirty); + // + // /** + // * Returns the value of the dirty flag. + // * If true, pattern matcher needs to be reconstructed. + // */ + // boolean isDirty(); } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Receiver.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Receiver.java index 9a421754..e8560916 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Receiver.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Receiver.java @@ -16,32 +16,30 @@ import org.eclipse.incquery.runtime.rete.tuple.Tuple; /** - * ALL METHODS: FOR INTERNAL USE ONLY; ONLY INVOKE FROM - * {@link ReteContainer} - * + * ALL METHODS: FOR INTERNAL USE ONLY; ONLY INVOKE FROM {@link ReteContainer} + * * @author Gabor Bergmann */ public interface Receiver extends Node { - /** - * updates the receiver with a newly found or lost partial matching - */ - public void update(Direction direction, Tuple updateElement); - - /** - * appends a parent that will continously send insert and revoke updates to - * this supplier - */ - void appendParent(Supplier supplier); - - /** - * removes a parent - */ - void removeParent(Supplier supplier); - - /** - * access active parent - */ - Collection getParents(); + /** + * updates the receiver with a newly found or lost partial matching + */ + public void update(Direction direction, Tuple updateElement); + + /** + * appends a parent that will continously send insert and revoke updates to this supplier + */ + void appendParent(Supplier supplier); + + /** + * removes a parent + */ + void removeParent(Supplier supplier); + + /** + * access active parent + */ + Collection getParents(); } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/ReteContainer.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/ReteContainer.java index 79fae354..b7ceaf8c 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/ReteContainer.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/ReteContainer.java @@ -23,7 +23,6 @@ import org.eclipse.incquery.runtime.rete.tuple.Clearable; import org.eclipse.incquery.runtime.rete.tuple.Tuple; - /** * @author Gabor Bergmann * @@ -31,596 +30,565 @@ */ public final class ReteContainer { - protected Thread consumerThread = null; - protected boolean killed = false; - - protected Network network; - - protected LinkedList clearables; - protected Map nodesById; - protected long nextId = 0; - protected Library library; - - protected Deque internalMessageQueue = new ArrayDeque(); - protected /*volatile*/ Deque externalMessageQueue = new ArrayDeque(); - protected Object externalMessageLock = new Object(); - protected Long clock = 1L; // even: steady state, odd: active queue; access - // ONLY with messageQueue locked! - protected Map terminationCriteria = null; - - /** - * @param threaded false if operating in a single-threaded environment - */ - public ReteContainer(Network network, boolean threaded) { - super(); - this.network = network; - nodesById = new HashMap(); - clearables = new LinkedList(); - library = new Library(this); - - if (threaded) - { - terminationCriteria = new HashMap(); - consumerThread = new Thread("Rete thread of " + ReteContainer.super.toString()) { - @Override - public void run() { - messageConsumptionCycle(); - }; - }; - consumerThread.start(); - } - } - - /** - * Stops this container. To be called by Network.kill() - */ - public void kill() { - killed = true; - if (consumerThread!=null) consumerThread.interrupt(); - } - - /** - * Establishes connection between a supplier and a receiver node, regardless - * which container they are in. Assumption is that this container is the - * home of the receiver, but it is not strictly necessary. - * - * @param synchronise - * indicates whether the receiver should be synchronised to the - * current contents of the supplier - */ - public void connectRemoteNodes(Address supplier, - Address receiver, boolean synchronise) { - if (!isLocal(receiver)) - receiver.getContainer().connectRemoteNodes(supplier, receiver, - synchronise); - else { - Receiver child = resolveLocal(receiver); - connectRemoteSupplier(supplier, child, synchronise); - } - } - - /** - * Severs connection between a supplier and a receiver node, regardless - * which container they are in. Assumption is that this container is the - * home of the receiver, but it is not strictly necessary. - * - * @param desynchronise - * indicates whether the current contents of the supplier should - * be subtracted from the receiver - */ - public void disconnectRemoteNodes(Address supplier, - Address receiver, boolean desynchronise) { - if (!isLocal(receiver)) - receiver.getContainer().disconnectRemoteNodes(supplier, receiver, - desynchronise); - else { - Receiver child = resolveLocal(receiver); - disconnectRemoteSupplier(supplier, child, desynchronise); - } - } - - /** - * Establishes connection between a remote supplier and a local receiver - * node. - * - * @param synchronise - * indicates whether the receiver should be synchronised to the - * current contents of the supplier - */ - public void connectRemoteSupplier(Address supplier, - Receiver receiver, boolean synchronise) { - Supplier parent = library.asSupplier(supplier); - if (synchronise) - connectAndSynchronize(parent, receiver); - else - connect(parent, receiver); - } - - /** - * Severs connection between a remote supplier and a local receiver node. - * - * @param desynchronise - * indicates whether the current contents of the supplier should - * be subtracted from the receiver - */ - public void disconnectRemoteSupplier(Address supplier, - Receiver receiver, boolean desynchronise) { - Supplier parent = library.asSupplier(supplier); - if (desynchronise) - disconnectAndDesynchronize(parent, receiver); - else - disconnect(parent, receiver); - } - - /** - * Connects a receiver to a supplier - */ - public void connect(Supplier supplier, Receiver receiver) { - supplier.appendChild(receiver); - receiver.appendParent(supplier); - } - - /** - * Disconnects a receiver from a supplier - */ - public void disconnect(Supplier supplier, Receiver receiver) { - supplier.removeChild(receiver); - receiver.removeParent(supplier); - } - - /** - * Connects a receiver to a remote supplier, and synchronises it to the - * current contents of the supplier - */ - public void connectAndSynchronize(Supplier supplier, Receiver receiver) { - flushUpdates(); // first, all pending updates should be flushed into the - // supplier BEFORE connecting - supplier.appendChild(receiver); - receiver.appendParent(supplier); - - Collection pulled = pullContents(supplier); - sendConstructionUpdates(receiver, Direction.INSERT, pulled); - - flushUpdates(); // deliver the positive updates - } - - /** - * Disconnects a receiver from a supplier - */ - public void disconnectAndDesynchronize(Supplier supplier, Receiver receiver) { - flushUpdates(); // first, all pending updates should be flushed into the - // supplier BEFORE disconnecting - - supplier.removeChild(receiver); - receiver.removeParent(supplier); - - Collection pulled = pullContents(supplier); - sendConstructionUpdates(receiver, Direction.REVOKE, pulled); - - flushUpdates(); // deliver the negative updates - } - - /** - * Sends an update message to the receiver node, indicating a newly found or - * lost partial matching. They are inserted into the queue atomically. - * Delivery is either synchronous or asynchronous. Designed to be called - * during network construction. - */ - public void sendConstructionUpdate(Receiver receiver, Direction direction, Tuple updateElement) { - if (consumerThread == null) sendUpdateInternal(receiver, direction, updateElement); - else network.sendConstructionUpdate(makeAddress(receiver), direction, updateElement); - } - - /** - * Sends several update messages atomically to the receiver node, indicating - * a newly found or lost partial matching. They are inserted into the queue - * atomically. Delivery is either synchronous or asynchronous. Designed to - * be called during network construction. - */ - public void sendConstructionUpdates(Receiver receiver, Direction direction, Collection updateElements) - { - if (consumerThread == null) - for (Tuple updateElement : updateElements) - sendUpdateInternal(receiver, direction, updateElement); - else network.sendConstructionUpdates(makeAddress(receiver), direction, updateElements); - } - - /** - * Sends an update message to the receiver node, indicating a newly found or - * lost partial matching. NOT to be called from user threads. - */ - public void sendUpdateInternal(Receiver receiver, Direction direction, - Tuple updateElement) { - // sendUpdateExternal(receiver, direction, updateElement); - // if (org.eclipse.incquery.runtime.rete.util.Options.synchronous) receiver.update(direction, - // updateElement); - // else { - UpdateMessage message = new UpdateMessage(receiver, direction, - updateElement); - internalMessageQueue.add(message); - // synchronized(externalMessageQueue) - // { - // externalMessageQueue.add(message); - // // no notifyAll() needed, since we are in the message consumption - // thread - // } - // } - - } - - /** - * Sends an update message to the receiver node, indicating a newly found or - * lost partial matching. The receiver is indicated by the Address. Designed - * to be called by the Network, DO NOT use in any other way. @pre: - * address.container == this, e.g. address MUST be local - * - * @return the value of the container's clock at the time when the message - * was accepted into the local message queue - */ - long sendUpdateToLocalAddress(Address address, - Direction direction, Tuple updateElement) { - long timestamp; - Receiver receiver = resolveLocal(address); - UpdateMessage message = new UpdateMessage(receiver, direction, - updateElement); - synchronized (externalMessageLock) { - externalMessageQueue.add(message); - // messageQueue.add(new UpdateMessage(resolveLocal(address), - // direction, updateElement)); - // this.sendUpdateInternal(resolveLocal(address), direction, - // updateElement); - timestamp = clock; - externalMessageLock.notifyAll(); - } - - return timestamp; - - } - - - /** - * Sends multiple update messages atomically to the receiver node, - * indicating a newly found or lost partial matching. The receiver is - * indicated by the Address. Designed to be called by the Network, DO NOT - * use in any other way. @pre: address.container == this, e.g. address MUST - * be local @pre: updateElements is nonempty! - * - * @return the value of the container's clock at the time when the message - * was accepted into the local message queue - */ - long sendUpdatesToLocalAddress(Address address, - Direction direction, Collection updateElements) { - - long timestamp; - Receiver receiver = resolveLocal(address); - // UpdateMessage message = new UpdateMessage(receiver, direction, - // updateElement); - synchronized (externalMessageLock) { - for (Tuple ps : updateElements) - externalMessageQueue.add(new UpdateMessage(receiver, direction, - ps)); - // messageQueue.add(new UpdateMessage(resolveLocal(address), - // direction, updateElement)); - // this.sendUpdateInternal(resolveLocal(address), direction, - // updateElement); - timestamp = clock; - externalMessageLock.notifyAll(); - } - - return timestamp; - } - - /** - * Sends an update message to the receiver node, indicating a newly found or - * lost partial matching. The receiver is indicated by the Address. Designed - * to be called by the Network in single-threaded operation, DO NOT use in any other way. - */ - void sendUpdateToLocalAddressSingleThreaded(Address address, - Direction direction, Tuple updateElement) { - Receiver receiver = resolveLocal(address); - UpdateMessage message = new UpdateMessage(receiver, direction, - updateElement); - internalMessageQueue.add(message); - } - - /** - * Sends multiple update messages to the receiver node, indicating a newly - * found or lost partial matching. The receiver is indicated by the Address. - * Designed to be called by the Network in single-threaded operation, DO NOT - * use in any other way. - * - * @pre: address.container == this, e.g. address MUST be local - */ - void sendUpdatesToLocalAddressSingleThreaded(Address address, - Direction direction, Collection updateElements) - { - Receiver receiver = resolveLocal(address); - for (Tuple ps : updateElements) - internalMessageQueue.add(new UpdateMessage(receiver, direction, ps)); - } - - /** - * Sends an update message to a node in a different container. The receiver - * is indicated by the Address. Designed to be called by RemoteReceivers, DO - * NOT use in any other way. - * - * @return the value of the container's clock at the time when the message - * was accepted into the local message queue - */ - public void sendUpdateToRemoteAddress(Address address, - Direction direction, Tuple updateElement) { - ReteContainer otherContainer = address.getContainer(); - long otherClock = otherContainer.sendUpdateToLocalAddress(address, - direction, updateElement); - // Long criterion = terminationCriteria.get(otherContainer); - // if (criterion==null || otherClock > criterion) - terminationCriteria.put(otherContainer, otherClock); - } - - /** - * Finalises all update sequences and returns. To be called from user - * threads (e.g. network construction). - */ - public void flushUpdates() { - network.waitForReteTermination(); - // synchronized (messageQueue) - // { - // while (!messageQueue.isEmpty()) - // { - // try { - // UpdateMessage message = messageQueue.take(); - // message.receiver.update(message.direction, message.updateElement); - // } catch (InterruptedException e) {} - // } - // } - } - - /** - * Retrieves a safe copy of the contents of a supplier. - */ - public Collection pullContents(Supplier supplier) { - flushUpdates(); - Collection collector = new LinkedList(); - supplier.pullInto(collector); - return collector; - } - - /** - * Retrieves the contents of a SingleInputNode's parentage. - */ - public Collection pullPropagatedContents(SingleInputNode supplier) { - flushUpdates(); - Collection collector = new LinkedList(); - supplier.propagatePullInto(collector); - return collector; - } - - /** - * Retrieves the contents of a supplier for a remote caller. Assumption is - * that this container is the home of the supplier, but it is not strictly - * necessary. - * - * @param supplier - * the address of the supplier to be pulled. - */ - public Collection remotePull(Address supplier) { - if (!isLocal(supplier)) - return supplier.getContainer().remotePull(supplier); - return pullContents(resolveLocal(supplier)); - } - - /** - * Proxies for the getPosMapping() of Production nodes. - * Retrieves the posmapping of a remote or local Production to a remote or local caller. - */ - public HashMap remotePosMapping(Address production) { - if (!isLocal(production)) - return production.getContainer().remotePosMapping(production); - return resolveLocal(production).getPosMapping(); - } - - /** - * Continually consumes update messages. Should be run on a dedicated thread. - */ - void messageConsumptionCycle() { - while (!killed) // deliver messages on and on and on.... - { - long incrementedClock = 0; - UpdateMessage message = null; - - if (!internalMessageQueue.isEmpty()) // take internal messages first - message = internalMessageQueue.removeFirst(); - else - // no internal message, take an incoming message - synchronized (externalMessageLock) { // no sleeping allowed, - // because external - // queue is locked for - // precise clocking of - // termination point! - if (!externalMessageQueue.isEmpty()) { // if external queue - // is non-empty, - // retrieve the next - // message instantly - { - message = takeExternalMessage(); - } - } else { // if external queue is found empty (and this is - // the first time in a row) - incrementedClock = ++clock; // local termination point - // synchronized(clock){incrementedClock = ++clock;} - } - } - - if (message == null) // both queues were empty - { - localUpdateTermination(incrementedClock); // report local - // termination point - while (message == null) // wait for a message while external - // queue is still empty - { - synchronized (externalMessageLock) { - while (externalMessageQueue.isEmpty()) { - try { - externalMessageLock.wait(); - } catch (InterruptedException e) { - if (killed) - return; - } - } - message = takeExternalMessage(); - } - - } - } - - // now we have a message to deliver - message.receiver.update(message.direction, message.updateElement); - } - } - - /** - * Iteratively consumes update messages until there are none left. - * Requires single-threaded behaviour. - */ - void messageConsumptionSingleThreaded() { - while (!internalMessageQueue.isEmpty()) // deliver messages on and on and on.... - { - UpdateMessage message = internalMessageQueue.removeFirst(); - message.receiver.update(message.direction, message.updateElement); - } - } - - private void localUpdateTermination(long incrementedClock) { - network.reportLocalUpdateTermination(this, incrementedClock, - terminationCriteria); - terminationCriteria.clear(); - - // synchronized(clock){++clock;} // +1 incrementing for parity and easy - // comparison - } - - // @pre: externalMessageQueue synchronized && nonempty - private UpdateMessage takeExternalMessage() { - UpdateMessage message = externalMessageQueue.removeFirst(); - if (!externalMessageQueue.isEmpty()) { // copy the whole queue over - // for speedup - Deque temp = externalMessageQueue; - externalMessageQueue = internalMessageQueue; - internalMessageQueue = temp; - } - return message; - } - - /** - * Provides an external address for the selected node. - * @pre node belongs to this container. - */ - public Address makeAddress(N node) { - return new Address(node); - } - - /** - * Checks whether a certain address points to a node at this container. - */ - public boolean isLocal(Address address) { - return address.getContainer() == this; - } - - /** - * Returns an addressed node at this container. @pre: address.container == - * this, e.g. address MUST be local, no checks are performed. - */ - @SuppressWarnings("unchecked") - public N resolveLocal(Address address) { - N cached = address.getNodeCache(); - if (cached != null) - return cached; - else { - N node = (N) nodesById.get(address.getNodeId()); - address.setNodeCache(node); - return node; - } - } - - /** - * Registers a node into the rete network (should be called by constructor). - * Every node MUST be registered by its constructor. - * - * @return the unique nodeId issued to the node. - */ - public long registerNode(Node n) { - long id = nextId++; - nodesById.put(id, n); - return id; - } - - /** - * Unregisters a node from the rete network. Do NOT call if node is still - * connected to other Nodes, or Adressed or otherwise referenced. - */ - public void unregisterNode(Node n) { - nodesById.remove(n.getNodeId()); - } - - /** - * Registers a pattern memory into the rete network. Every memory MUST be - * registered by its owner node. - */ - public void registerClearable(Clearable c) { - clearables.addFirst(c); - } - - /** - * Unregisters a pattern memory from the rete network. - */ - public void unregisterClearable(Clearable c) { - clearables.remove(c); - } - - /** - * Clears all memory contents in the network. Reverts to initial state. - */ - public void clearAll() { - for (Clearable c : clearables) { - c.clear(); - } - } - - /** - * @return the library - */ - public Library getLibrary() { - return library; - } - - public Network getNetwork() { - return network; - } - - /* (non-Javadoc) - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - String separator = System.getProperty("line.separator"); - sb.append(super.toString() + "[[[" + separator); - java.util.List keys = new java.util.ArrayList(nodesById.keySet()); - java.util.Collections.sort(keys); - for (Long key: keys){ - sb.append(key + " -> " + nodesById.get(key) + separator); - } - sb.append("]]] of " + network); - return sb.toString(); - } - - /** - * Access all the Rete nodes inside this container. - * @return the collection of {@link Node} instances - */ - public Collection getAllNodes() { - return nodesById.values(); - } - + protected Thread consumerThread = null; + protected boolean killed = false; + + protected Network network; + + protected LinkedList clearables; + protected Map nodesById; + protected long nextId = 0; + protected Library library; + + protected Deque internalMessageQueue = new ArrayDeque(); + protected/* volatile */Deque externalMessageQueue = new ArrayDeque(); + protected Object externalMessageLock = new Object(); + protected Long clock = 1L; // even: steady state, odd: active queue; access + // ONLY with messageQueue locked! + protected Map terminationCriteria = null; + + /** + * @param threaded + * false if operating in a single-threaded environment + */ + public ReteContainer(Network network, boolean threaded) { + super(); + this.network = network; + nodesById = new HashMap(); + clearables = new LinkedList(); + library = new Library(this); + + if (threaded) { + terminationCriteria = new HashMap(); + consumerThread = new Thread("Rete thread of " + ReteContainer.super.toString()) { + @Override + public void run() { + messageConsumptionCycle(); + }; + }; + consumerThread.start(); + } + } + + /** + * Stops this container. To be called by Network.kill() + */ + public void kill() { + killed = true; + if (consumerThread != null) + consumerThread.interrupt(); + } + + /** + * Establishes connection between a supplier and a receiver node, regardless which container they are in. Assumption + * is that this container is the home of the receiver, but it is not strictly necessary. + * + * @param synchronise + * indicates whether the receiver should be synchronised to the current contents of the supplier + */ + public void connectRemoteNodes(Address supplier, Address receiver, + boolean synchronise) { + if (!isLocal(receiver)) + receiver.getContainer().connectRemoteNodes(supplier, receiver, synchronise); + else { + Receiver child = resolveLocal(receiver); + connectRemoteSupplier(supplier, child, synchronise); + } + } + + /** + * Severs connection between a supplier and a receiver node, regardless which container they are in. Assumption is + * that this container is the home of the receiver, but it is not strictly necessary. + * + * @param desynchronise + * indicates whether the current contents of the supplier should be subtracted from the receiver + */ + public void disconnectRemoteNodes(Address supplier, Address receiver, + boolean desynchronise) { + if (!isLocal(receiver)) + receiver.getContainer().disconnectRemoteNodes(supplier, receiver, desynchronise); + else { + Receiver child = resolveLocal(receiver); + disconnectRemoteSupplier(supplier, child, desynchronise); + } + } + + /** + * Establishes connection between a remote supplier and a local receiver node. + * + * @param synchronise + * indicates whether the receiver should be synchronised to the current contents of the supplier + */ + public void connectRemoteSupplier(Address supplier, Receiver receiver, boolean synchronise) { + Supplier parent = library.asSupplier(supplier); + if (synchronise) + connectAndSynchronize(parent, receiver); + else + connect(parent, receiver); + } + + /** + * Severs connection between a remote supplier and a local receiver node. + * + * @param desynchronise + * indicates whether the current contents of the supplier should be subtracted from the receiver + */ + public void disconnectRemoteSupplier(Address supplier, Receiver receiver, boolean desynchronise) { + Supplier parent = library.asSupplier(supplier); + if (desynchronise) + disconnectAndDesynchronize(parent, receiver); + else + disconnect(parent, receiver); + } + + /** + * Connects a receiver to a supplier + */ + public void connect(Supplier supplier, Receiver receiver) { + supplier.appendChild(receiver); + receiver.appendParent(supplier); + } + + /** + * Disconnects a receiver from a supplier + */ + public void disconnect(Supplier supplier, Receiver receiver) { + supplier.removeChild(receiver); + receiver.removeParent(supplier); + } + + /** + * Connects a receiver to a remote supplier, and synchronises it to the current contents of the supplier + */ + public void connectAndSynchronize(Supplier supplier, Receiver receiver) { + flushUpdates(); // first, all pending updates should be flushed into the + // supplier BEFORE connecting + supplier.appendChild(receiver); + receiver.appendParent(supplier); + + Collection pulled = pullContents(supplier); + sendConstructionUpdates(receiver, Direction.INSERT, pulled); + + flushUpdates(); // deliver the positive updates + } + + /** + * Disconnects a receiver from a supplier + */ + public void disconnectAndDesynchronize(Supplier supplier, Receiver receiver) { + flushUpdates(); // first, all pending updates should be flushed into the + // supplier BEFORE disconnecting + + supplier.removeChild(receiver); + receiver.removeParent(supplier); + + Collection pulled = pullContents(supplier); + sendConstructionUpdates(receiver, Direction.REVOKE, pulled); + + flushUpdates(); // deliver the negative updates + } + + /** + * Sends an update message to the receiver node, indicating a newly found or lost partial matching. They are + * inserted into the queue atomically. Delivery is either synchronous or asynchronous. Designed to be called during + * network construction. + */ + public void sendConstructionUpdate(Receiver receiver, Direction direction, Tuple updateElement) { + if (consumerThread == null) + sendUpdateInternal(receiver, direction, updateElement); + else + network.sendConstructionUpdate(makeAddress(receiver), direction, updateElement); + } + + /** + * Sends several update messages atomically to the receiver node, indicating a newly found or lost partial matching. + * They are inserted into the queue atomically. Delivery is either synchronous or asynchronous. Designed to be + * called during network construction. + */ + public void sendConstructionUpdates(Receiver receiver, Direction direction, Collection updateElements) { + if (consumerThread == null) + for (Tuple updateElement : updateElements) + sendUpdateInternal(receiver, direction, updateElement); + else + network.sendConstructionUpdates(makeAddress(receiver), direction, updateElements); + } + + /** + * Sends an update message to the receiver node, indicating a newly found or lost partial matching. NOT to be called + * from user threads. + */ + public void sendUpdateInternal(Receiver receiver, Direction direction, Tuple updateElement) { + // sendUpdateExternal(receiver, direction, updateElement); + // if (org.eclipse.incquery.runtime.rete.util.Options.synchronous) receiver.update(direction, + // updateElement); + // else { + UpdateMessage message = new UpdateMessage(receiver, direction, updateElement); + internalMessageQueue.add(message); + // synchronized(externalMessageQueue) + // { + // externalMessageQueue.add(message); + // // no notifyAll() needed, since we are in the message consumption + // thread + // } + // } + + } + + /** + * Sends an update message to the receiver node, indicating a newly found or lost partial matching. The receiver is + * indicated by the Address. Designed to be called by the Network, DO NOT use in any other way. @pre: + * address.container == this, e.g. address MUST be local + * + * @return the value of the container's clock at the time when the message was accepted into the local message queue + */ + long sendUpdateToLocalAddress(Address address, Direction direction, Tuple updateElement) { + long timestamp; + Receiver receiver = resolveLocal(address); + UpdateMessage message = new UpdateMessage(receiver, direction, updateElement); + synchronized (externalMessageLock) { + externalMessageQueue.add(message); + // messageQueue.add(new UpdateMessage(resolveLocal(address), + // direction, updateElement)); + // this.sendUpdateInternal(resolveLocal(address), direction, + // updateElement); + timestamp = clock; + externalMessageLock.notifyAll(); + } + + return timestamp; + + } + + /** + * Sends multiple update messages atomically to the receiver node, indicating a newly found or lost partial + * matching. The receiver is indicated by the Address. Designed to be called by the Network, DO NOT use in any other + * way. @pre: address.container == this, e.g. address MUST be local @pre: updateElements is nonempty! + * + * @return the value of the container's clock at the time when the message was accepted into the local message queue + */ + long sendUpdatesToLocalAddress(Address address, Direction direction, + Collection updateElements) { + + long timestamp; + Receiver receiver = resolveLocal(address); + // UpdateMessage message = new UpdateMessage(receiver, direction, + // updateElement); + synchronized (externalMessageLock) { + for (Tuple ps : updateElements) + externalMessageQueue.add(new UpdateMessage(receiver, direction, ps)); + // messageQueue.add(new UpdateMessage(resolveLocal(address), + // direction, updateElement)); + // this.sendUpdateInternal(resolveLocal(address), direction, + // updateElement); + timestamp = clock; + externalMessageLock.notifyAll(); + } + + return timestamp; + } + + /** + * Sends an update message to the receiver node, indicating a newly found or lost partial matching. The receiver is + * indicated by the Address. Designed to be called by the Network in single-threaded operation, DO NOT use in any + * other way. + */ + void sendUpdateToLocalAddressSingleThreaded(Address address, Direction direction, + Tuple updateElement) { + Receiver receiver = resolveLocal(address); + UpdateMessage message = new UpdateMessage(receiver, direction, updateElement); + internalMessageQueue.add(message); + } + + /** + * Sends multiple update messages to the receiver node, indicating a newly found or lost partial matching. The + * receiver is indicated by the Address. Designed to be called by the Network in single-threaded operation, DO NOT + * use in any other way. + * + * @pre: address.container == this, e.g. address MUST be local + */ + void sendUpdatesToLocalAddressSingleThreaded(Address address, Direction direction, + Collection updateElements) { + Receiver receiver = resolveLocal(address); + for (Tuple ps : updateElements) + internalMessageQueue.add(new UpdateMessage(receiver, direction, ps)); + } + + /** + * Sends an update message to a node in a different container. The receiver is indicated by the Address. Designed to + * be called by RemoteReceivers, DO NOT use in any other way. + * + * @return the value of the container's clock at the time when the message was accepted into the local message queue + */ + public void sendUpdateToRemoteAddress(Address address, Direction direction, Tuple updateElement) { + ReteContainer otherContainer = address.getContainer(); + long otherClock = otherContainer.sendUpdateToLocalAddress(address, direction, updateElement); + // Long criterion = terminationCriteria.get(otherContainer); + // if (criterion==null || otherClock > criterion) + terminationCriteria.put(otherContainer, otherClock); + } + + /** + * Finalises all update sequences and returns. To be called from user threads (e.g. network construction). + */ + public void flushUpdates() { + network.waitForReteTermination(); + // synchronized (messageQueue) + // { + // while (!messageQueue.isEmpty()) + // { + // try { + // UpdateMessage message = messageQueue.take(); + // message.receiver.update(message.direction, message.updateElement); + // } catch (InterruptedException e) {} + // } + // } + } + + /** + * Retrieves a safe copy of the contents of a supplier. + */ + public Collection pullContents(Supplier supplier) { + flushUpdates(); + Collection collector = new LinkedList(); + supplier.pullInto(collector); + return collector; + } + + /** + * Retrieves the contents of a SingleInputNode's parentage. + */ + public Collection pullPropagatedContents(SingleInputNode supplier) { + flushUpdates(); + Collection collector = new LinkedList(); + supplier.propagatePullInto(collector); + return collector; + } + + /** + * Retrieves the contents of a supplier for a remote caller. Assumption is that this container is the home of the + * supplier, but it is not strictly necessary. + * + * @param supplier + * the address of the supplier to be pulled. + */ + public Collection remotePull(Address supplier) { + if (!isLocal(supplier)) + return supplier.getContainer().remotePull(supplier); + return pullContents(resolveLocal(supplier)); + } + + /** + * Proxies for the getPosMapping() of Production nodes. Retrieves the posmapping of a remote or local Production to + * a remote or local caller. + */ + public HashMap remotePosMapping(Address production) { + if (!isLocal(production)) + return production.getContainer().remotePosMapping(production); + return resolveLocal(production).getPosMapping(); + } + + /** + * Continually consumes update messages. Should be run on a dedicated thread. + */ + void messageConsumptionCycle() { + while (!killed) // deliver messages on and on and on.... + { + long incrementedClock = 0; + UpdateMessage message = null; + + if (!internalMessageQueue.isEmpty()) // take internal messages first + message = internalMessageQueue.removeFirst(); + else + // no internal message, take an incoming message + synchronized (externalMessageLock) { // no sleeping allowed, + // because external + // queue is locked for + // precise clocking of + // termination point! + if (!externalMessageQueue.isEmpty()) { // if external queue + // is non-empty, + // retrieve the next + // message instantly + { + message = takeExternalMessage(); + } + } else { // if external queue is found empty (and this is + // the first time in a row) + incrementedClock = ++clock; // local termination point + // synchronized(clock){incrementedClock = ++clock;} + } + } + + if (message == null) // both queues were empty + { + localUpdateTermination(incrementedClock); // report local + // termination point + while (message == null) // wait for a message while external + // queue is still empty + { + synchronized (externalMessageLock) { + while (externalMessageQueue.isEmpty()) { + try { + externalMessageLock.wait(); + } catch (InterruptedException e) { + if (killed) + return; + } + } + message = takeExternalMessage(); + } + + } + } + + // now we have a message to deliver + message.receiver.update(message.direction, message.updateElement); + } + } + + /** + * Iteratively consumes update messages until there are none left. Requires single-threaded behaviour. + */ + void messageConsumptionSingleThreaded() { + while (!internalMessageQueue.isEmpty()) // deliver messages on and on and on.... + { + UpdateMessage message = internalMessageQueue.removeFirst(); + message.receiver.update(message.direction, message.updateElement); + } + } + + private void localUpdateTermination(long incrementedClock) { + network.reportLocalUpdateTermination(this, incrementedClock, terminationCriteria); + terminationCriteria.clear(); + + // synchronized(clock){++clock;} // +1 incrementing for parity and easy + // comparison + } + + // @pre: externalMessageQueue synchronized && nonempty + private UpdateMessage takeExternalMessage() { + UpdateMessage message = externalMessageQueue.removeFirst(); + if (!externalMessageQueue.isEmpty()) { // copy the whole queue over + // for speedup + Deque temp = externalMessageQueue; + externalMessageQueue = internalMessageQueue; + internalMessageQueue = temp; + } + return message; + } + + /** + * Provides an external address for the selected node. + * + * @pre node belongs to this container. + */ + public Address makeAddress(N node) { + return new Address(node); + } + + /** + * Checks whether a certain address points to a node at this container. + */ + public boolean isLocal(Address address) { + return address.getContainer() == this; + } + + /** + * Returns an addressed node at this container. @pre: address.container == this, e.g. address MUST be local, no + * checks are performed. + */ + @SuppressWarnings("unchecked") + public N resolveLocal(Address address) { + N cached = address.getNodeCache(); + if (cached != null) + return cached; + else { + N node = (N) nodesById.get(address.getNodeId()); + address.setNodeCache(node); + return node; + } + } + + /** + * Registers a node into the rete network (should be called by constructor). Every node MUST be registered by its + * constructor. + * + * @return the unique nodeId issued to the node. + */ + public long registerNode(Node n) { + long id = nextId++; + nodesById.put(id, n); + return id; + } + + /** + * Unregisters a node from the rete network. Do NOT call if node is still connected to other Nodes, or Adressed or + * otherwise referenced. + */ + public void unregisterNode(Node n) { + nodesById.remove(n.getNodeId()); + } + + /** + * Registers a pattern memory into the rete network. Every memory MUST be registered by its owner node. + */ + public void registerClearable(Clearable c) { + clearables.addFirst(c); + } + + /** + * Unregisters a pattern memory from the rete network. + */ + public void unregisterClearable(Clearable c) { + clearables.remove(c); + } + + /** + * Clears all memory contents in the network. Reverts to initial state. + */ + public void clearAll() { + for (Clearable c : clearables) { + c.clear(); + } + } + + /** + * @return the library + */ + public Library getLibrary() { + return library; + } + + public Network getNetwork() { + return network; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + String separator = System.getProperty("line.separator"); + sb.append(super.toString() + "[[[" + separator); + java.util.List keys = new java.util.ArrayList(nodesById.keySet()); + java.util.Collections.sort(keys); + for (Long key : keys) { + sb.append(key + " -> " + nodesById.get(key) + separator); + } + sb.append("]]] of " + network); + return sb.toString(); + } + + /** + * Access all the Rete nodes inside this container. + * + * @return the collection of {@link Node} instances + */ + public Collection getAllNodes() { + return nodesById.values(); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/StandardNode.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/StandardNode.java index 2e7160d1..11d45b4e 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/StandardNode.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/StandardNode.java @@ -20,44 +20,44 @@ import org.eclipse.incquery.runtime.rete.tuple.Tuple; import org.eclipse.incquery.runtime.rete.tuple.TupleMask; - /** * Base implementation for a supplier node. + * * @author Gabor Bergmann * */ public abstract class StandardNode extends BaseNode implements Supplier { - protected List children = new LinkedList(); + protected List children = new LinkedList(); - public StandardNode(ReteContainer reteContainer) { - super(reteContainer); - } + public StandardNode(ReteContainer reteContainer) { + super(reteContainer); + } - protected void propagateUpdate(Direction direction, Tuple updateElement) { - for (Receiver r : children) - reteContainer.sendUpdateInternal(r, direction, updateElement); - } + protected void propagateUpdate(Direction direction, Tuple updateElement) { + for (Receiver r : children) + reteContainer.sendUpdateInternal(r, direction, updateElement); + } - @Override + @Override public void appendChild(Receiver receiver) { - children.add(receiver); - } + children.add(receiver); + } - @Override + @Override public void removeChild(Receiver receiver) { - children.remove(receiver); - } - - @Override - public Collection getReceivers() { - return children; - } - - @Override - public ProjectionIndexer constructIndex(TupleMask mask) { - final GenericProjectionIndexer indexer = new GenericProjectionIndexer(reteContainer, mask); - reteContainer.connectAndSynchronize(this, indexer); - return indexer; - } + children.remove(receiver); + } + + @Override + public Collection getReceivers() { + return children; + } + + @Override + public ProjectionIndexer constructIndex(TupleMask mask) { + final GenericProjectionIndexer indexer = new GenericProjectionIndexer(reteContainer, mask); + reteContainer.connectAndSynchronize(this, indexer); + return indexer; + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Supplier.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Supplier.java index 8210dd5c..0e3f1492 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Supplier.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Supplier.java @@ -17,41 +17,37 @@ import org.eclipse.incquery.runtime.rete.tuple.Tuple; import org.eclipse.incquery.runtime.rete.tuple.TupleMask; - /** * @author Gabor Bergmann * - * A supplier is an object that can propagate insert or revoke events - * towards receivers. + * A supplier is an object that can propagate insert or revoke events towards receivers. */ public interface Supplier extends Node { - /** - * pulls the contents of this object in this particular moment into a target - * collection - */ - public void pullInto(Collection collector); - - /** - * appends a receiver that will continously receive insert and revoke - * updates from this supplier - */ - void appendChild(Receiver receiver); - - /** - * removes a receiver - */ - void removeChild(Receiver receiver); - - /** - * Instantiates (or reuses, depending on implementation) an index according to the given mask. - * Intended for internal use; clients should invoke through Library.accesProjectionIndexer() instead to enable reusing. - */ - ProjectionIndexer constructIndex(TupleMask mask); - - /** - * lists receivers - */ - Collection getReceivers(); + /** + * pulls the contents of this object in this particular moment into a target collection + */ + public void pullInto(Collection collector); + + /** + * appends a receiver that will continously receive insert and revoke updates from this supplier + */ + void appendChild(Receiver receiver); + + /** + * removes a receiver + */ + void removeChild(Receiver receiver); + + /** + * Instantiates (or reuses, depending on implementation) an index according to the given mask. Intended for internal + * use; clients should invoke through Library.accesProjectionIndexer() instead to enable reusing. + */ + ProjectionIndexer constructIndex(TupleMask mask); + + /** + * lists receivers + */ + Collection getReceivers(); } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Tunnel.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Tunnel.java index ade76822..8a5b1634 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Tunnel.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/Tunnel.java @@ -14,8 +14,7 @@ /** * @author Gabor Bergmann * - * A Tunnel is an interface into which elments can be instered and from - * which productions can be extracted. + * A Tunnel is an interface into which elments can be instered and from which productions can be extracted. */ public interface Tunnel extends Supplier, Receiver { diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/UpdateMessage.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/UpdateMessage.java index cbfb6564..bdfef669 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/UpdateMessage.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/network/UpdateMessage.java @@ -14,23 +14,24 @@ import org.eclipse.incquery.runtime.rete.tuple.Tuple; class UpdateMessage { - public Receiver receiver; - public Direction direction; - public Tuple updateElement; + public Receiver receiver; + public Direction direction; + public Tuple updateElement; - public UpdateMessage(Receiver receiver, Direction direction, - Tuple updateElement) { - this.receiver = receiver; - this.direction = direction; - this.updateElement = updateElement; - } - - /* (non-Javadoc) - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return "M." + direction + ": " + updateElement + " -> " + receiver; - } + public UpdateMessage(Receiver receiver, Direction direction, Tuple updateElement) { + this.receiver = receiver; + this.direction = direction; + this.updateElement = updateElement; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "M." + direction + ": " + updateElement + " -> " + receiver; + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/remote/Address.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/remote/Address.java index 9e7c71e9..1f1e3407 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/remote/Address.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/remote/Address.java @@ -21,130 +21,136 @@ * */ public class Address { - ReteContainer container; - Long nodeId; - /** - * Feel free to leave null e.g. if node is in a separate JVM. - */ - T nodeCache; - - /** - * Address of local node (use only for containers in the same VM!) - */ - public static Address of(N node) { - return new Address(node); - } - - /** - * General constructor. - * @param container - * @param nodeId - */ - public Address(ReteContainer container, Long nodeId) { - super(); - this.container = container; - this.nodeId = nodeId; - } - /** - * Local-only constructor. (use only for containers in the same VM!) - * @param T the node to address - */ - public Address(T node) { - super(); - this.nodeCache = node; - this.container = node.getContainer(); - this.nodeId = node.getNodeId(); - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result - + ((container == null) ? 0 : container.hashCode()); - result = prime * result + ((nodeId == null) ? 0 : nodeId.hashCode()); - return result; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (!(obj instanceof Address)) - return false; - final Address other = (Address) obj; - if (container == null) { - if (other.container != null) - return false; - } else if (!container.equals(other.container)) - return false; - if (nodeId == null) { - if (other.nodeId != null) - return false; - } else if (!nodeId.equals(other.nodeId)) - return false; - return true; - } - - /** - * @return the container - */ - public ReteContainer getContainer() { - return container; - } - - /** - * @param container - * the container to set - */ - public void setContainer(ReteContainer container) { - this.container = container; - } - - /** - * @return the nodeId - */ - public Long getNodeId() { - return nodeId; - } - - /** - * @param nodeId - * the nodeId to set - */ - public void setNodeId(Long nodeId) { - this.nodeId = nodeId; - } - - public T getNodeCache() { - return nodeCache; - } - - public void setNodeCache(T nodeCache) { - this.nodeCache = nodeCache; - } - - /* (non-Javadoc) - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - if (nodeCache==null) - return "A("+nodeId+" @ "+container+")"; - else return "A("+nodeCache+")"; - - } + ReteContainer container; + Long nodeId; + /** + * Feel free to leave null e.g. if node is in a separate JVM. + */ + T nodeCache; + + /** + * Address of local node (use only for containers in the same VM!) + */ + public static Address of(N node) { + return new Address(node); + } + + /** + * General constructor. + * + * @param container + * @param nodeId + */ + public Address(ReteContainer container, Long nodeId) { + super(); + this.container = container; + this.nodeId = nodeId; + } + + /** + * Local-only constructor. (use only for containers in the same VM!) + * + * @param T + * the node to address + */ + public Address(T node) { + super(); + this.nodeCache = node; + this.container = node.getContainer(); + this.nodeId = node.getNodeId(); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((container == null) ? 0 : container.hashCode()); + result = prime * result + ((nodeId == null) ? 0 : nodeId.hashCode()); + return result; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (!(obj instanceof Address)) + return false; + final Address other = (Address) obj; + if (container == null) { + if (other.container != null) + return false; + } else if (!container.equals(other.container)) + return false; + if (nodeId == null) { + if (other.nodeId != null) + return false; + } else if (!nodeId.equals(other.nodeId)) + return false; + return true; + } + + /** + * @return the container + */ + public ReteContainer getContainer() { + return container; + } + + /** + * @param container + * the container to set + */ + public void setContainer(ReteContainer container) { + this.container = container; + } + + /** + * @return the nodeId + */ + public Long getNodeId() { + return nodeId; + } + + /** + * @param nodeId + * the nodeId to set + */ + public void setNodeId(Long nodeId) { + this.nodeId = nodeId; + } + + public T getNodeCache() { + return nodeCache; + } + + public void setNodeCache(T nodeCache) { + this.nodeCache = nodeCache; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + if (nodeCache == null) + return "A(" + nodeId + " @ " + container + ")"; + else + return "A(" + nodeCache + ")"; + + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/remote/RemoteReceiver.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/remote/RemoteReceiver.java index 5e466170..e6733d53 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/remote/RemoteReceiver.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/remote/RemoteReceiver.java @@ -21,39 +21,36 @@ import org.eclipse.incquery.runtime.rete.single.SingleInputNode; import org.eclipse.incquery.runtime.rete.tuple.Tuple; - /** - * This node delivers updates to a remote recipient; no updates are propagated - * further in this network. + * This node delivers updates to a remote recipient; no updates are propagated further in this network. * * @author Gabor Bergmann * */ public class RemoteReceiver extends SingleInputNode { - List> targets; + List> targets; - public RemoteReceiver(ReteContainer reteContainer) { - super(reteContainer); - targets = new ArrayList>(); - } + public RemoteReceiver(ReteContainer reteContainer) { + super(reteContainer); + targets = new ArrayList>(); + } - public void addTarget(Address target) { - targets.add(target); - } + public void addTarget(Address target) { + targets.add(target); + } - public void pullInto(Collection collector) { - propagatePullInto(collector); - } + public void pullInto(Collection collector) { + propagatePullInto(collector); + } - public Collection remotePull() { - return reteContainer.pullContents(this); - } + public Collection remotePull() { + return reteContainer.pullContents(this); + } - public void update(Direction direction, Tuple updateElement) { - for (Address ad : targets) - reteContainer.sendUpdateToRemoteAddress(ad, direction, - updateElement); - } + public void update(Direction direction, Tuple updateElement) { + for (Address ad : targets) + reteContainer.sendUpdateToRemoteAddress(ad, direction, updateElement); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/remote/RemoteSupplier.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/remote/RemoteSupplier.java index f1960b9c..e94d6e52 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/remote/RemoteSupplier.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/remote/RemoteSupplier.java @@ -18,36 +18,33 @@ import org.eclipse.incquery.runtime.rete.single.SingleInputNode; import org.eclipse.incquery.runtime.rete.tuple.Tuple; - /** - * This node receives updates from a remote supplier; no local updates are - * expected. + * This node receives updates from a remote supplier; no local updates are expected. * * @author Gabor Bergmann * */ public class RemoteSupplier extends SingleInputNode { - RemoteReceiver counterpart; - - /** - * @param reteContainer - * @param remoteAddress - */ - public RemoteSupplier(ReteContainer reteContainer, - RemoteReceiver counterpart) { - super(reteContainer); - this.counterpart = counterpart; - counterpart.addTarget(reteContainer.makeAddress(this)); - } - - public void pullInto(Collection collector) { - Collection pulled = counterpart.remotePull(); - collector.addAll(pulled); - } - - public void update(Direction direction, Tuple updateElement) { - propagateUpdate(direction, updateElement); - } + RemoteReceiver counterpart; + + /** + * @param reteContainer + * @param remoteAddress + */ + public RemoteSupplier(ReteContainer reteContainer, RemoteReceiver counterpart) { + super(reteContainer); + this.counterpart = counterpart; + counterpart.addTarget(reteContainer.makeAddress(this)); + } + + public void pullInto(Collection collector) { + Collection pulled = counterpart.remotePull(); + collector.addAll(pulled); + } + + public void update(Direction direction, Tuple updateElement) { + propagateUpdate(direction, updateElement); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/DefaultProductionNode.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/DefaultProductionNode.java index d01ed483..1cd17d65 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/DefaultProductionNode.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/DefaultProductionNode.java @@ -18,39 +18,35 @@ import org.eclipse.incquery.runtime.rete.network.ReteContainer; import org.eclipse.incquery.runtime.rete.tuple.Tuple; - /** - * Default implementation of the Production node, based on - * UniquenessEnforcerNode + * Default implementation of the Production node, based on UniquenessEnforcerNode * * @author Gabor Bergmann */ -public class DefaultProductionNode extends UniquenessEnforcerNode implements - Production { - - protected HashMap posMapping; - - // protected HashMap projections; - - /** - * @param reteContainer - * @param posMapping - */ - public DefaultProductionNode(ReteContainer reteContainer, - HashMap posMapping) { - super(reteContainer, posMapping.size()); - this.posMapping = posMapping; - // this.projections= new HashMap(); - } - - /** - * @return the posMapping - */ - public HashMap getPosMapping() { - return posMapping; - } - - public Iterator iterator() { - return memory.iterator(); - } +public class DefaultProductionNode extends UniquenessEnforcerNode implements Production { + + protected HashMap posMapping; + + // protected HashMap projections; + + /** + * @param reteContainer + * @param posMapping + */ + public DefaultProductionNode(ReteContainer reteContainer, HashMap posMapping) { + super(reteContainer, posMapping.size()); + this.posMapping = posMapping; + // this.projections= new HashMap(); + } + + /** + * @return the posMapping + */ + public HashMap getPosMapping() { + return posMapping; + } + + public Iterator iterator() { + return memory.iterator(); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/EqualityFilterNode.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/EqualityFilterNode.java index 925e24cf..866fa194 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/EqualityFilterNode.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/EqualityFilterNode.java @@ -16,28 +16,28 @@ public class EqualityFilterNode extends FilterNode { - int[] indices; - int first; + int[] indices; + int first; - /** - * @param reteContainer - * @param indices - * indices of the Tuple that should hold equal values - */ - public EqualityFilterNode(ReteContainer reteContainer, int[] indices) { - super(reteContainer); - this.indices = indices; - first = indices[0]; - } + /** + * @param reteContainer + * @param indices + * indices of the Tuple that should hold equal values + */ + public EqualityFilterNode(ReteContainer reteContainer, int[] indices) { + super(reteContainer); + this.indices = indices; + first = indices[0]; + } - @Override - public boolean check(Tuple ps) { - Object firstElement = ps.get(first); - for (int i = 1 /* first is omitted */; i < indices.length; i++) { - if (!ps.get(indices[i]).equals(firstElement)) - return false; - } - return true; - } + @Override + public boolean check(Tuple ps) { + Object firstElement = ps.get(first); + for (int i = 1 /* first is omitted */; i < indices.length; i++) { + if (!ps.get(indices[i]).equals(firstElement)) + return false; + } + return true; + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/FilterNode.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/FilterNode.java index 5f86b076..6be3d492 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/FilterNode.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/FilterNode.java @@ -17,10 +17,9 @@ import org.eclipse.incquery.runtime.rete.network.ReteContainer; import org.eclipse.incquery.runtime.rete.tuple.Tuple; - /** - * This node implements a simple filter. A stateless abstract check() predicate - * determines whether a matching is allowed to pass. + * This node implements a simple filter. A stateless abstract check() predicate determines whether a matching is allowed + * to pass. * * * @@ -29,32 +28,31 @@ */ public abstract class FilterNode extends SingleInputNode { - public FilterNode(ReteContainer reteContainer) { - super(reteContainer); - } - - /** - * Abstract filtering predicate. Expected to be stateless. - * - * @param ps - * the matching to be checked. - * @return true if and only if the parameter matching is allowed to pass - * through this node. - */ - public abstract boolean check(Tuple ps); - - @Override + public FilterNode(ReteContainer reteContainer) { + super(reteContainer); + } + + /** + * Abstract filtering predicate. Expected to be stateless. + * + * @param ps + * the matching to be checked. + * @return true if and only if the parameter matching is allowed to pass through this node. + */ + public abstract boolean check(Tuple ps); + + @Override public void pullInto(Collection collector) { - for (Tuple ps : reteContainer.pullPropagatedContents(this)) { - if (check(ps)) - collector.add(ps); - } - } + for (Tuple ps : reteContainer.pullPropagatedContents(this)) { + if (check(ps)) + collector.add(ps); + } + } - @Override + @Override public void update(Direction direction, Tuple updateElement) { - if (check(updateElement)) - propagateUpdate(direction, updateElement); - } + if (check(updateElement)) + propagateUpdate(direction, updateElement); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/InequalityFilterNode.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/InequalityFilterNode.java index 7ceb3e56..322c2e77 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/InequalityFilterNode.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/InequalityFilterNode.java @@ -16,9 +16,8 @@ import org.eclipse.incquery.runtime.rete.tuple.TupleMask; /** - * This node filters patterns according to equalities and inequalities of - * elements. The 'subject' element is asserted to be different from the elements - * given by the inequalityMask. + * This node filters patterns according to equalities and inequalities of elements. The 'subject' element is asserted to + * be different from the elements given by the inequalityMask. * * * @author Gabor Bergmann @@ -26,32 +25,30 @@ */ public class InequalityFilterNode extends FilterNode { - int subjectIndex; - TupleMask inequalityMask; + int subjectIndex; + TupleMask inequalityMask; - /** - * @param reteContainer - * @param subjectIndex - * the index of the element that should be compared. - * @param inequalityMask - * the indices of elements that should be different from the - * subjectIndex. - */ - public InequalityFilterNode(ReteContainer reteContainer, int subject, - TupleMask inequalityMask) { - super(reteContainer); - this.subjectIndex = subject; - this.inequalityMask = inequalityMask; - } + /** + * @param reteContainer + * @param subjectIndex + * the index of the element that should be compared. + * @param inequalityMask + * the indices of elements that should be different from the subjectIndex. + */ + public InequalityFilterNode(ReteContainer reteContainer, int subject, TupleMask inequalityMask) { + super(reteContainer); + this.subjectIndex = subject; + this.inequalityMask = inequalityMask; + } - @Override - public boolean check(Tuple ps) { - Object subject = ps.get(subjectIndex); - for (int ineq : inequalityMask.indices) { - if (subject.equals(ps.get(ineq))) - return false; - } - return true; - } + @Override + public boolean check(Tuple ps) { + Object subject = ps.get(subjectIndex); + for (int ineq : inequalityMask.indices) { + if (subject.equals(ps.get(ineq))) + return false; + } + return true; + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/SingleInputNode.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/SingleInputNode.java index a87c7392..487d98df 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/SingleInputNode.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/SingleInputNode.java @@ -20,51 +20,52 @@ import org.eclipse.incquery.runtime.rete.network.Tunnel; import org.eclipse.incquery.runtime.rete.tuple.Tuple; - /** * @author Gabor Bergmann * */ public abstract class SingleInputNode extends StandardNode implements Tunnel { - protected Supplier parent; + protected Supplier parent; - public SingleInputNode(ReteContainer reteContainer) { - super(reteContainer); - parent = null; - } + public SingleInputNode(ReteContainer reteContainer) { + super(reteContainer); + parent = null; + } - @Override + @Override public void appendParent(Supplier supplier) { - if (parent == null) - parent = supplier; - else - throw new UnsupportedOperationException("Illegal RETE edge: " + this + " already has a parent (" + - parent + ") and cannot connect to additional parent (" + supplier + - ") as it is not a Uniqueness Enforcer Node. "); - } + if (parent == null) + parent = supplier; + else + throw new UnsupportedOperationException("Illegal RETE edge: " + this + " already has a parent (" + parent + + ") and cannot connect to additional parent (" + supplier + + ") as it is not a Uniqueness Enforcer Node. "); + } - @Override + @Override public void removeParent(Supplier supplier) { - if (parent == supplier) - parent = null; - else - throw new IllegalArgumentException("Illegal RETE edge removal: the parent of " + this + " is not " + supplier); - } + if (parent == supplier) + parent = null; + else + throw new IllegalArgumentException("Illegal RETE edge removal: the parent of " + this + " is not " + + supplier); + } + + /** + * To be called by derived classes and ReteContainer. + */ + public void propagatePullInto(Collection collector) { + if (parent != null) + parent.pullInto(collector); + } - /** - * To be called by derived classes and ReteContainer. - */ - public void propagatePullInto(Collection collector) { - if (parent != null) parent.pullInto(collector); - } - - @Override - public Collection getParents() { - if (parent == null) - return Collections.emptySet(); - else - return Collections.singleton(parent); - } + @Override + public Collection getParents() { + if (parent == null) + return Collections.emptySet(); + else + return Collections.singleton(parent); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/TransformerNode.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/TransformerNode.java index 64490c20..3e7136d2 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/TransformerNode.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/TransformerNode.java @@ -17,23 +17,22 @@ import org.eclipse.incquery.runtime.rete.network.ReteContainer; import org.eclipse.incquery.runtime.rete.tuple.Tuple; - public abstract class TransformerNode extends SingleInputNode { - public TransformerNode(ReteContainer reteContainer) { - super(reteContainer); - } + public TransformerNode(ReteContainer reteContainer) { + super(reteContainer); + } - protected abstract Tuple transform(Tuple input); + protected abstract Tuple transform(Tuple input); - public void pullInto(Collection collector) { - for (Tuple ps : reteContainer.pullPropagatedContents(this)) { - collector.add(transform(ps)); - } - } + public void pullInto(Collection collector) { + for (Tuple ps : reteContainer.pullPropagatedContents(this)) { + collector.add(transform(ps)); + } + } - public void update(Direction direction, Tuple updateElement) { - propagateUpdate(direction, transform(updateElement)); - } + public void update(Direction direction, Tuple updateElement) { + propagateUpdate(direction, transform(updateElement)); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/TransitiveClosureNode.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/TransitiveClosureNode.java index 098110ef..092ee18e 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/TransitiveClosureNode.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/TransitiveClosureNode.java @@ -25,99 +25,99 @@ // TODO egyelore (i,j) elek, majd helyette mask megoldas // TODO bemeneti index /** - * This class represents a transitive closure node in the rete net. + * This class represents a transitive closure node in the rete net. * * @author Gabor Bergmann - * + * */ public class TransitiveClosureNode extends SingleInputNode implements Clearable, ITcObserver { - - private Graph graphDataSource; - private ITcDataSource transitiveClosureAlgorithm; - - /** - * Create a new transitive closure rete node. - * Initializes the graph data source with the given collection of tuples. - * - * @param reteContainer the rete container of the node - * @param tuples the initial collection of tuples - */ - public TransitiveClosureNode(ReteContainer reteContainer, Collection tuples) { - super(reteContainer); - graphDataSource = new Graph(); - - for (org.eclipse.incquery.runtime.rete.tuple.Tuple t : tuples) { - graphDataSource.insertNode(t.get(0)); - graphDataSource.insertNode(t.get(1)); - graphDataSource.insertEdge(t.get(0), t.get(1)); - } - transitiveClosureAlgorithm = new IncSCCAlg(graphDataSource); - transitiveClosureAlgorithm.attachObserver(this); - reteContainer.registerClearable(this); - } - - public TransitiveClosureNode(ReteContainer reteContainer) { - super(reteContainer); - graphDataSource = new Graph(); - transitiveClosureAlgorithm = new IncSCCAlg(graphDataSource); - transitiveClosureAlgorithm.attachObserver(this); - reteContainer.registerClearable(this); - } - @Override - public void pullInto(Collection collector) { - for (Tuple tuple : ((IncSCCAlg) transitiveClosureAlgorithm).getTcRelation()) { - collector.add(new FlatTuple(tuple.getSource(), tuple.getTarget())); - } - } + private Graph graphDataSource; + private ITcDataSource transitiveClosureAlgorithm; + + /** + * Create a new transitive closure rete node. Initializes the graph data source with the given collection of tuples. + * + * @param reteContainer + * the rete container of the node + * @param tuples + * the initial collection of tuples + */ + public TransitiveClosureNode(ReteContainer reteContainer, + Collection tuples) { + super(reteContainer); + graphDataSource = new Graph(); + + for (org.eclipse.incquery.runtime.rete.tuple.Tuple t : tuples) { + graphDataSource.insertNode(t.get(0)); + graphDataSource.insertNode(t.get(1)); + graphDataSource.insertEdge(t.get(0), t.get(1)); + } + transitiveClosureAlgorithm = new IncSCCAlg(graphDataSource); + transitiveClosureAlgorithm.attachObserver(this); + reteContainer.registerClearable(this); + } + + public TransitiveClosureNode(ReteContainer reteContainer) { + super(reteContainer); + graphDataSource = new Graph(); + transitiveClosureAlgorithm = new IncSCCAlg(graphDataSource); + transitiveClosureAlgorithm.attachObserver(this); + reteContainer.registerClearable(this); + } + + @Override + public void pullInto(Collection collector) { + for (Tuple tuple : ((IncSCCAlg) transitiveClosureAlgorithm).getTcRelation()) { + collector.add(new FlatTuple(tuple.getSource(), tuple.getTarget())); + } + } + + @Override + public void update(Direction direction, org.eclipse.incquery.runtime.rete.tuple.Tuple updateElement) { + if (updateElement.getSize() == 2) { + Object source = updateElement.get(0); + Object target = updateElement.get(1); + + if (direction == Direction.INSERT) { + graphDataSource.insertNode(source); + graphDataSource.insertNode(target); + graphDataSource.insertEdge(source, target); + } + if (direction == Direction.REVOKE) { + graphDataSource.deleteEdge(source, target); + + if (((IncSCCAlg) transitiveClosureAlgorithm).isIsolated(source)) { + graphDataSource.deleteNode(source); + } + if (!source.equals(target) && ((IncSCCAlg) transitiveClosureAlgorithm).isIsolated(target)) { + graphDataSource.deleteNode(target); + } + } + } + } - @Override - public void update(Direction direction, org.eclipse.incquery.runtime.rete.tuple.Tuple updateElement) { - if (updateElement.getSize() == 2) { - Object source = updateElement.get(0); - Object target = updateElement.get(1); - - if (direction == Direction.INSERT) { - graphDataSource.insertNode(source); - graphDataSource.insertNode(target); - graphDataSource.insertEdge(source, target); - } - if (direction == Direction.REVOKE) { - graphDataSource.deleteEdge(source, target); - - if (((IncSCCAlg) transitiveClosureAlgorithm).isIsolated(source)) { - graphDataSource.deleteNode(source); - } - if (!source.equals(target) && ((IncSCCAlg) transitiveClosureAlgorithm).isIsolated(target)) { - graphDataSource.deleteNode(target); - } - } - } - } - - @Override - public void clear() { - transitiveClosureAlgorithm.dispose(); - graphDataSource = new Graph(); - transitiveClosureAlgorithm = new IncSCCAlg(graphDataSource); - } + @Override + public void clear() { + transitiveClosureAlgorithm.dispose(); + graphDataSource = new Graph(); + transitiveClosureAlgorithm = new IncSCCAlg(graphDataSource); + } - @Override - public void tupleInserted(Object source, Object target) { - org.eclipse.incquery.runtime.rete.tuple.Tuple tuple = new FlatTuple(source, target); - propagateUpdate(Direction.INSERT, tuple); - } + @Override + public void tupleInserted(Object source, Object target) { + org.eclipse.incquery.runtime.rete.tuple.Tuple tuple = new FlatTuple(source, target); + propagateUpdate(Direction.INSERT, tuple); + } - @Override - public void tupleDeleted(Object source, Object target) { - org.eclipse.incquery.runtime.rete.tuple.Tuple tuple = new FlatTuple(source, target); - propagateUpdate(Direction.REVOKE, tuple); - } - + @Override + public void tupleDeleted(Object source, Object target) { + org.eclipse.incquery.runtime.rete.tuple.Tuple tuple = new FlatTuple(source, target); + propagateUpdate(Direction.REVOKE, tuple); + } - @Override - protected void propagateUpdate(Direction direction, org.eclipse.incquery.runtime.rete.tuple.Tuple updateElement) - { - super.propagateUpdate(direction, updateElement); - } + @Override + protected void propagateUpdate(Direction direction, org.eclipse.incquery.runtime.rete.tuple.Tuple updateElement) { + super.propagateUpdate(direction, updateElement); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/TransparentNode.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/TransparentNode.java index 670a83e1..9ae90ab7 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/TransparentNode.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/TransparentNode.java @@ -17,7 +17,6 @@ import org.eclipse.incquery.runtime.rete.network.ReteContainer; import org.eclipse.incquery.runtime.rete.tuple.Tuple; - /** * Simply propagates everything. Might be used to join or fork. * @@ -25,19 +24,19 @@ */ public class TransparentNode extends SingleInputNode { - public TransparentNode(ReteContainer reteContainer) { - super(reteContainer); - } + public TransparentNode(ReteContainer reteContainer) { + super(reteContainer); + } - @Override + @Override public void update(Direction direction, Tuple updateElement) { - propagateUpdate(direction, updateElement); + propagateUpdate(direction, updateElement); - } + } - @Override + @Override public void pullInto(Collection collector) { - propagatePullInto(collector); - } + propagatePullInto(collector); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/TrimmerNode.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/TrimmerNode.java index ee7d1eca..98caa89d 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/TrimmerNode.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/TrimmerNode.java @@ -23,46 +23,46 @@ */ public class TrimmerNode extends TransformerNode { - protected TupleMask mask; + protected TupleMask mask; - /** - * @param reteContainer - * @param mask - * The mask used to trim substitutions. - */ - public TrimmerNode(ReteContainer reteContainer, TupleMask mask) { - super(reteContainer); - this.mask = mask; - } + /** + * @param reteContainer + * @param mask + * The mask used to trim substitutions. + */ + public TrimmerNode(ReteContainer reteContainer, TupleMask mask) { + super(reteContainer); + this.mask = mask; + } - /** - * @param reteContainer - * @param mask - * The mask used to trim substitutions. - */ - public TrimmerNode(ReteContainer reteContainer) { - super(reteContainer); - this.mask = null; - } + /** + * @param reteContainer + * @param mask + * The mask used to trim substitutions. + */ + public TrimmerNode(ReteContainer reteContainer) { + super(reteContainer); + this.mask = null; + } - /** - * @return the mask - */ - public TupleMask getMask() { - return mask; - } + /** + * @return the mask + */ + public TupleMask getMask() { + return mask; + } - /** - * @param mask - * the mask to set - */ - public void setMask(TupleMask mask) { - this.mask = mask; - } + /** + * @param mask + * the mask to set + */ + public void setMask(TupleMask mask) { + this.mask = mask; + } - @Override - protected Tuple transform(Tuple input) { - return mask.transform(input); - } + @Override + protected Tuple transform(Tuple input) { + return mask.transform(input); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/UniquenessEnforcerNode.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/UniquenessEnforcerNode.java index e8ab1ca1..0f05920b 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/UniquenessEnforcerNode.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/UniquenessEnforcerNode.java @@ -27,129 +27,138 @@ import org.eclipse.incquery.runtime.rete.tuple.TupleMemory; import org.eclipse.incquery.runtime.rete.util.Options; - /** - * Ensures that no identical copies get to the output. Only one replica of each - * pattern substitution may traverse this node. + * Ensures that no identical copies get to the output. Only one replica of each pattern substitution may traverse this + * node. * * @author Gabor Bergmann */ public class UniquenessEnforcerNode extends StandardNode implements Tunnel { - protected Collection parents; - protected TupleMemory memory; - public TupleMemory getMemory() { - return memory; - } - - protected MemoryNullIndexer memoryNullIndexer; - protected MemoryIdentityIndexer memoryIdentityIndexer; - protected final int tupleWidth; - - private final TupleMask nullMask; - private final TupleMask identityMask; - - public UniquenessEnforcerNode(ReteContainer reteContainer, int tupleWidth) { - super(reteContainer); - parents = new ArrayList(); - memory = new TupleMemory(); - this.tupleWidth = tupleWidth; - reteContainer.registerClearable(memory); - nullMask = TupleMask.linear(0, tupleWidth); - identityMask = TupleMask.identity(tupleWidth); -// if (Options.employTrivialIndexers) { -// memoryNullIndexer = new MemoryNullIndexer(reteContainer, tupleWidth, memory, this, this); -// reteContainer.getLibrary().registerSpecializedProjectionIndexer(this, memoryNullIndexer); -// memoryIdentityIndexer = new MemoryIdentityIndexer(reteContainer, tupleWidth, memory, this, this); -// reteContainer.getLibrary().registerSpecializedProjectionIndexer(this, memoryIdentityIndexer); -// } - } - - @Override + protected Collection parents; + protected TupleMemory memory; + + public TupleMemory getMemory() { + return memory; + } + + protected MemoryNullIndexer memoryNullIndexer; + protected MemoryIdentityIndexer memoryIdentityIndexer; + protected final int tupleWidth; + + private final TupleMask nullMask; + private final TupleMask identityMask; + + public UniquenessEnforcerNode(ReteContainer reteContainer, int tupleWidth) { + super(reteContainer); + parents = new ArrayList(); + memory = new TupleMemory(); + this.tupleWidth = tupleWidth; + reteContainer.registerClearable(memory); + nullMask = TupleMask.linear(0, tupleWidth); + identityMask = TupleMask.identity(tupleWidth); + // if (Options.employTrivialIndexers) { + // memoryNullIndexer = new MemoryNullIndexer(reteContainer, tupleWidth, memory, this, this); + // reteContainer.getLibrary().registerSpecializedProjectionIndexer(this, memoryNullIndexer); + // memoryIdentityIndexer = new MemoryIdentityIndexer(reteContainer, tupleWidth, memory, this, this); + // reteContainer.getLibrary().registerSpecializedProjectionIndexer(this, memoryIdentityIndexer); + // } + } + + @Override public void update(Direction direction, Tuple updateElement) { - boolean change; - if (direction == Direction.INSERT) { - change = memory.add(updateElement); - } else { // REVOKE - try { - change = memory.remove(updateElement); - } catch (java.lang.NullPointerException ex) { - // TODO UGLY, but will it find our problems? - change = false; - reteContainer.getNetwork().getContext().logError("[INTERNAL ERROR] Duplicate deletion of " + updateElement + " was detected in UniquenessEnforcer " + this, ex); - } - } - if (change) { - propagateUpdate(direction, updateElement); - - // trivial projectionIndexers - if (memoryIdentityIndexer != null) memoryIdentityIndexer.propagate(direction, updateElement); - if (memoryNullIndexer != null) memoryNullIndexer.propagate(direction, updateElement); - - } - } - - @Override - public ProjectionIndexer constructIndex(TupleMask mask) { - if (Options.employTrivialIndexers) { - if (nullMask.equals(mask)) return getNullIndexer(); - if (identityMask.equals(mask)) return getIdentityIndexer(); - } - return super.constructIndex(mask); - } - - @Override + boolean change; + if (direction == Direction.INSERT) { + change = memory.add(updateElement); + } else { // REVOKE + try { + change = memory.remove(updateElement); + } catch (java.lang.NullPointerException ex) { + // TODO UGLY, but will it find our problems? + change = false; + reteContainer + .getNetwork() + .getContext() + .logError( + "[INTERNAL ERROR] Duplicate deletion of " + updateElement + + " was detected in UniquenessEnforcer " + this, ex); + } + } + if (change) { + propagateUpdate(direction, updateElement); + + // trivial projectionIndexers + if (memoryIdentityIndexer != null) + memoryIdentityIndexer.propagate(direction, updateElement); + if (memoryNullIndexer != null) + memoryNullIndexer.propagate(direction, updateElement); + + } + } + + @Override + public ProjectionIndexer constructIndex(TupleMask mask) { + if (Options.employTrivialIndexers) { + if (nullMask.equals(mask)) + return getNullIndexer(); + if (identityMask.equals(mask)) + return getIdentityIndexer(); + } + return super.constructIndex(mask); + } + + @Override public void pullInto(Collection collector) { - collector.addAll(memory); - } - - public MemoryNullIndexer getNullIndexer() { - if (memoryNullIndexer == null) memoryNullIndexer = new MemoryNullIndexer(reteContainer, tupleWidth, memory, this, this); - return memoryNullIndexer; - } - - public MemoryIdentityIndexer getIdentityIndexer() { - if (memoryIdentityIndexer == null) memoryIdentityIndexer = new MemoryIdentityIndexer(reteContainer, tupleWidth, memory, this, this); - return memoryIdentityIndexer; - } - - @Override - public void appendParent(Supplier supplier) { - parents.add(supplier); - } - - @Override - public void removeParent(Supplier supplier) { - parents.remove(supplier); - } - - @Override - public Collection getParents() { - return parents; - } - - - // - // public void tearOff() { - // for (Supplier parent : new LinkedList(parents) ) - // { - // network.disconnectAndDesynchronize(parent, this); - // } - // } - // - // /** - // * @return the dirty - // */ - // public boolean isDirty() { - // return dirty; - // } - // - // /** - // * @param dirty the dirty to set - // */ - // public void setDirty(boolean dirty) { - // this.dirty = dirty; - // } - + collector.addAll(memory); + } + + public MemoryNullIndexer getNullIndexer() { + if (memoryNullIndexer == null) + memoryNullIndexer = new MemoryNullIndexer(reteContainer, tupleWidth, memory, this, this); + return memoryNullIndexer; + } + + public MemoryIdentityIndexer getIdentityIndexer() { + if (memoryIdentityIndexer == null) + memoryIdentityIndexer = new MemoryIdentityIndexer(reteContainer, tupleWidth, memory, this, this); + return memoryIdentityIndexer; + } + + @Override + public void appendParent(Supplier supplier) { + parents.add(supplier); + } + + @Override + public void removeParent(Supplier supplier) { + parents.remove(supplier); + } + + @Override + public Collection getParents() { + return parents; + } + + // + // public void tearOff() { + // for (Supplier parent : new LinkedList(parents) ) + // { + // network.disconnectAndDesynchronize(parent, this); + // } + // } + // + // /** + // * @return the dirty + // */ + // public boolean isDirty() { + // return dirty; + // } + // + // /** + // * @param dirty the dirty to set + // */ + // public void setDirty(boolean dirty) { + // this.dirty = dirty; + // } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/ValueBinderFilterNode.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/ValueBinderFilterNode.java index 141907e4..d8baa61f 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/ValueBinderFilterNode.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/single/ValueBinderFilterNode.java @@ -16,32 +16,31 @@ /** * A filter node that keeps only those tuples that contain a certain value at a certain position. + * * @author Bergmann G�bor - * + * */ public class ValueBinderFilterNode extends FilterNode { - int bindingIndex; - Object bindingValue; - - - /** - * @param reteContainer - * @param bindingIndex the position in the tuple that should be bound - * @param bindingValue the value to which the tuple has to be bound - */ - public ValueBinderFilterNode(ReteContainer reteContainer, int bindingIndex, - Object bindingValue) { - super(reteContainer); - this.bindingIndex = bindingIndex; - this.bindingValue = bindingValue; - } - - - - @Override - public boolean check(Tuple ps) { - return bindingValue.equals(ps.get(bindingIndex)); - } + int bindingIndex; + Object bindingValue; + + /** + * @param reteContainer + * @param bindingIndex + * the position in the tuple that should be bound + * @param bindingValue + * the value to which the tuple has to be bound + */ + public ValueBinderFilterNode(ReteContainer reteContainer, int bindingIndex, Object bindingValue) { + super(reteContainer); + this.bindingIndex = bindingIndex; + this.bindingValue = bindingValue; + } + + @Override + public boolean check(Tuple ps) { + return bindingValue.equals(ps.get(bindingIndex)); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/tuple/Clearable.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/tuple/Clearable.java index e1cd2356..d23efdc1 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/tuple/Clearable.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/tuple/Clearable.java @@ -17,9 +17,9 @@ * An instance of clearable pattern memory. */ public interface Clearable { - /** - * Clear all partial matchings stored in memory - * - */ - void clear(); + /** + * Clear all partial matchings stored in memory + * + */ + void clear(); } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/tuple/FlatTuple.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/tuple/FlatTuple.java index 72b082f3..73d5d1fc 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/tuple/FlatTuple.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/tuple/FlatTuple.java @@ -18,81 +18,82 @@ */ public class FlatTuple extends Tuple { - /** - * Array of substituted values. DO NOT MODIFY! Use Constructor to build a - * new instance instead. - */ - private final Object[] elements; + /** + * Array of substituted values. DO NOT MODIFY! Use Constructor to build a new instance instead. + */ + private final Object[] elements; - /** - * Creates a Tuple instance, fills it with the given array. @pre: no elements - * are null - * - * @param elements - * array of substitution values - */ - public FlatTuple(Object[] elements) { - this.elements = elements; - calcHash(); - } + /** + * Creates a Tuple instance, fills it with the given array. @pre: no elements are null + * + * @param elements + * array of substitution values + */ + public FlatTuple(Object[] elements) { + this.elements = elements; + calcHash(); + } - /** - * Creates a Tuple instance of size one, fills it with the given object. - * @pre: o!=null - * - * @param o - * the single substitution - */ - public FlatTuple(Object o) { - elements = new Object[1]; - elements[0] = o; - calcHash(); - } + /** + * Creates a Tuple instance of size one, fills it with the given object. + * + * @pre: o!=null + * + * @param o + * the single substitution + */ + public FlatTuple(Object o) { + elements = new Object[1]; + elements[0] = o; + calcHash(); + } - /** - * Creates a Tuple instance of size two, fills it with the given objects. - * @pre: o1!=null, o2!=null - */ - public FlatTuple(Object o1, Object o2) { - elements = new Object[2]; - elements[0] = o1; - elements[1] = o2; - calcHash(); - } + /** + * Creates a Tuple instance of size two, fills it with the given objects. + * + * @pre: o1!=null, o2!=null + */ + public FlatTuple(Object o1, Object o2) { + elements = new Object[2]; + elements[0] = o1; + elements[1] = o2; + calcHash(); + } - /** - * Creates a Tuple instance of size three, fills it with the given objects. - * @pre: o1!=null, o2!=null, o3!=null - */ - public FlatTuple(Object o1, Object o2, Object o3) { - elements = new Object[3]; - elements[0] = o1; - elements[1] = o2; - elements[2] = o3; - calcHash(); - } + /** + * Creates a Tuple instance of size three, fills it with the given objects. + * + * @pre: o1!=null, o2!=null, o3!=null + */ + public FlatTuple(Object o1, Object o2, Object o3) { + elements = new Object[3]; + elements[0] = o1; + elements[1] = o2; + elements[2] = o3; + calcHash(); + } - @Override - public Object get(int index) { - return elements[index]; - } + @Override + public Object get(int index) { + return elements[index]; + } - @Override - public int getSize() { - return elements.length; - } + @Override + public int getSize() { + return elements.length; + } - @Override - public Object[] getElements() { - return elements; - } + @Override + public Object[] getElements() { + return elements; + } - @Override - protected boolean internalEquals(Tuple other) { - if (other instanceof FlatTuple) { - return Arrays.equals(elements, ((FlatTuple) other).elements); - } else - return super.internalEquals(other); - } + @Override + protected boolean internalEquals(Tuple other) { + if (other instanceof FlatTuple) { + return Arrays.equals(elements, ((FlatTuple) other).elements); + } else + return super.internalEquals(other); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/tuple/LeftInheritanceTuple.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/tuple/LeftInheritanceTuple.java index c5505894..b0c5bfea 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/tuple/LeftInheritanceTuple.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/tuple/LeftInheritanceTuple.java @@ -21,155 +21,150 @@ * */ public class LeftInheritanceTuple extends Tuple { - /** - * The number of elements that aren't stored locally, but inherited from an - * ancestor Tuple instead. - */ - private final int inheritedIndex; + /** + * The number of elements that aren't stored locally, but inherited from an ancestor Tuple instead. + */ + private final int inheritedIndex; - /** - * This object contains the same elements as the ancestor on the first - * inheritedIndex positions - */ - private final Tuple ancestor; + /** + * This object contains the same elements as the ancestor on the first inheritedIndex positions + */ + private final Tuple ancestor; - /** - * Array of substituted values above inheritedIndex. DO NOT MODIFY! Use - * Constructor to build a new instance instead. - */ - private final Object[] localElements; + /** + * Array of substituted values above inheritedIndex. DO NOT MODIFY! Use Constructor to build a new instance instead. + */ + private final Object[] localElements; - // - // /** - // * Creates a Tuple instance, fills it with the given array. - // * @pre: no elements are null - // * @param elements array of substitution values - // */ - // public Tuple(Object[] elements) - // { - // this.localElements = elements; - // this.ancestor=null; - // this.inheritedIndex = 0; - // calcHash(); - // } + // + // /** + // * Creates a Tuple instance, fills it with the given array. + // * @pre: no elements are null + // * @param elements array of substitution values + // */ + // public Tuple(Object[] elements) + // { + // this.localElements = elements; + // this.ancestor=null; + // this.inheritedIndex = 0; + // calcHash(); + // } - /** - * Creates a Tuple instance, lets it inherit from an ancestor, extends it - * with a given array. @pre: no elements are null - * - * @param elements - * array of substitution values - */ - public LeftInheritanceTuple(Tuple ancestor, Object[] localElements) { - this.localElements = localElements; - this.ancestor = ancestor; - this.inheritedIndex = ancestor.getSize(); - calcHash(); - } + /** + * Creates a Tuple instance, lets it inherit from an ancestor, extends it with a given array. @pre: no elements are + * null + * + * @param elements + * array of substitution values + */ + public LeftInheritanceTuple(Tuple ancestor, Object[] localElements) { + this.localElements = localElements; + this.ancestor = ancestor; + this.inheritedIndex = ancestor.getSize(); + calcHash(); + } - // - // /** - // * Creates a Tuple instance of size one, fills it with the given object. - // * @pre: o!=null - // * @param o the single substitution - // */ - // public Tuple(Object o) - // { - // localElements = new Object [1]; - // localElements[0] = o; - // this.ancestor=null; - // this.inheritedIndex = 0; - // calcHash(); - // } - // - // /** - // * Creates a Tuple instance of size two, fills it with the given objects. - // * @pre: o1!=null, o2!=null - // */ - // public Tuple(Object o1, Object o2) - // { - // localElements = new Object [2]; - // localElements[0] = o1; - // localElements[1] = o2; - // this.ancestor=null; - // this.inheritedIndex = 0; - // calcHash(); - // } - // - // /** - // * Creates a Tuple instance of size three, fills it with the given - // objects. - // * @pre: o1!=null, o2!=null, o3!=null - // */ - // public Tuple(Object o1, Object o2, Object o3) - // { - // localElements = new Object [3]; - // localElements[0] = o1; - // localElements[1] = o2; - // localElements[2] = o3; - // this.ancestor=null; - // this.inheritedIndex = 0; - // calcHash(); - // } + // + // /** + // * Creates a Tuple instance of size one, fills it with the given object. + // * @pre: o!=null + // * @param o the single substitution + // */ + // public Tuple(Object o) + // { + // localElements = new Object [1]; + // localElements[0] = o; + // this.ancestor=null; + // this.inheritedIndex = 0; + // calcHash(); + // } + // + // /** + // * Creates a Tuple instance of size two, fills it with the given objects. + // * @pre: o1!=null, o2!=null + // */ + // public Tuple(Object o1, Object o2) + // { + // localElements = new Object [2]; + // localElements[0] = o1; + // localElements[1] = o2; + // this.ancestor=null; + // this.inheritedIndex = 0; + // calcHash(); + // } + // + // /** + // * Creates a Tuple instance of size three, fills it with the given + // objects. + // * @pre: o1!=null, o2!=null, o3!=null + // */ + // public Tuple(Object o1, Object o2, Object o3) + // { + // localElements = new Object [3]; + // localElements[0] = o1; + // localElements[1] = o2; + // localElements[2] = o3; + // this.ancestor=null; + // this.inheritedIndex = 0; + // calcHash(); + // } - /** - * @return number of elements - */ - public int getSize() { - return inheritedIndex + localElements.length; - } + /** + * @return number of elements + */ + public int getSize() { + return inheritedIndex + localElements.length; + } - /** - * @pre: 0 <= index < getSize() - * - * @return the element at the specified index - */ - public Object get(int index) { - return (index < inheritedIndex) ? ancestor.get(index) - : localElements[index - inheritedIndex]; - } + /** + * @pre: 0 <= index < getSize() + * + * @return the element at the specified index + */ + public Object get(int index) { + return (index < inheritedIndex) ? ancestor.get(index) : localElements[index - inheritedIndex]; + } - /** - * Optimized hash calculation - */ - @Override - void calcHash() { - final int PRIME = 31; - cachedHash = ancestor.hashCode(); - for (int i = 0; i < localElements.length; i++) { - cachedHash = PRIME * cachedHash; - Object element = localElements[i]; - if (element != null) - cachedHash += element.hashCode(); - } - } + /** + * Optimized hash calculation + */ + @Override + void calcHash() { + final int PRIME = 31; + cachedHash = ancestor.hashCode(); + for (int i = 0; i < localElements.length; i++) { + cachedHash = PRIME * cachedHash; + Object element = localElements[i]; + if (element != null) + cachedHash += element.hashCode(); + } + } - /** - * Optimized equals calculation (prediction: true, since hash values match) - */ - @Override - protected boolean internalEquals(Tuple other) { - if (other instanceof LeftInheritanceTuple) { - LeftInheritanceTuple lit = (LeftInheritanceTuple) other; - if (lit.inheritedIndex == this.inheritedIndex - && this.ancestor.equals(lit.ancestor)) - return Arrays.equals(this.localElements, lit.localElements); - } - return super.internalEquals(other); - } + /** + * Optimized equals calculation (prediction: true, since hash values match) + */ + @Override + protected boolean internalEquals(Tuple other) { + if (other instanceof LeftInheritanceTuple) { + LeftInheritanceTuple lit = (LeftInheritanceTuple) other; + if (lit.inheritedIndex == this.inheritedIndex && this.ancestor.equals(lit.ancestor)) + return Arrays.equals(this.localElements, lit.localElements); + } + return super.internalEquals(other); + } - // public int compareTo(Object arg0) { - // Tuple other = (Tuple) arg0; - // - // int retVal = cachedHash - other.cachedHash; - // if (retVal==0) retVal = elements.length - other.elements.length; - // for (int i=0; retVal==0 && i { - /** - * Counts the number of occurences of each pattern. Element is deleted if # - * of occurences drops to 0. - */ - protected Map> matchings; - - /** - * The mask used to index the matchings - */ - protected TupleMask mask; - - /** - * @param mask - * The mask used to index the matchings - */ - public MaskedTupleMemory(TupleMask mask) { - super(); - this.mask = mask; - matchings = new HashMap>(); - } - - /** - * Adds a pattern occurence to the memory - * @param ps - * - * @return true if new signature encountered - */ - public boolean add(Tuple ps) { - Tuple signature = mask.transform(ps); - return add(ps, signature); - } - - /** - * Adds a pattern occurence to the memory, with given signature - * @param ps - * @param signature - * - * @return true if new signature encountered - */ - public boolean add(Tuple ps, Tuple signature) { - Collection coll = matchings.get(signature); - boolean change = (coll == null); - - if (change) { - coll = new TupleMemory(); - matchings.put(signature, coll); - } - if (!coll.add(ps)) { - throw new IllegalStateException(); - } - - return change; - } - - /** - * Removes a pattern occurence from the memory - * - * @return true if this was the the last occurence of the signature - */ - public boolean remove(Tuple ps) { - Tuple signature = mask.transform(ps); - return remove(ps, signature); - } - - /** - * Removes a pattern occurence from the memory, with given signature - * - * @return true if this was the the last occurence of the signature - */ - public boolean remove(Tuple ps, Tuple signature) { - Collection coll = matchings.get(signature); - if (!coll.remove(ps)) { - throw new IllegalStateException(); - } - - boolean change = coll.isEmpty(); - if (change) - matchings.remove(signature); - - return change; - } - - /** - * Retrieves entries that have the specified signature - * - * @return collection of matchings found - */ - public Collection get(Tuple signature) { - return matchings.get(signature); - } - - public void clear() { - matchings.clear(); - } - /** - * Retrieves a read-only collection of exactly those signatures for which at least one tuple is stored - * - * @return collection of significant signatures - */ - public Collection getSignatures() { - return matchings.keySet(); - } - public Iterator iterator() { - return new MaskedPatternIterator(this); - } - - class MaskedPatternIterator implements Iterator { - // private MaskedTupleMemory memory; - Iterator> signatureGroup; - Iterator element; - - public MaskedPatternIterator(MaskedTupleMemory memory) { - // this.memory = memory; - signatureGroup = memory.matchings.values().iterator(); - Set emptySet = Collections.emptySet(); - element = emptySet.iterator(); - } - - public boolean hasNext() { - return (element.hasNext() || signatureGroup.hasNext()); - } - - public Tuple next() throws NoSuchElementException { - if (element.hasNext()) - return element.next(); - else if (signatureGroup.hasNext()) { - element = signatureGroup.next().iterator(); - return element.next(); - } else - throw new NoSuchElementException(); - } - - /** - * Not implemented - */ - public void remove() { - - } - - } - - /* (non-Javadoc) - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return "MTM<"+mask+"|"+matchings+">"; - } - - public int getSize() { - return matchings.values().size(); - } + /** + * Counts the number of occurences of each pattern. Element is deleted if # of occurences drops to 0. + */ + protected Map> matchings; + + /** + * The mask used to index the matchings + */ + protected TupleMask mask; + + /** + * @param mask + * The mask used to index the matchings + */ + public MaskedTupleMemory(TupleMask mask) { + super(); + this.mask = mask; + matchings = new HashMap>(); + } + + /** + * Adds a pattern occurence to the memory + * + * @param ps + * + * @return true if new signature encountered + */ + public boolean add(Tuple ps) { + Tuple signature = mask.transform(ps); + return add(ps, signature); + } + + /** + * Adds a pattern occurence to the memory, with given signature + * + * @param ps + * @param signature + * + * @return true if new signature encountered + */ + public boolean add(Tuple ps, Tuple signature) { + Collection coll = matchings.get(signature); + boolean change = (coll == null); + + if (change) { + coll = new TupleMemory(); + matchings.put(signature, coll); + } + if (!coll.add(ps)) { + throw new IllegalStateException(); + } + + return change; + } + + /** + * Removes a pattern occurence from the memory + * + * @return true if this was the the last occurence of the signature + */ + public boolean remove(Tuple ps) { + Tuple signature = mask.transform(ps); + return remove(ps, signature); + } + + /** + * Removes a pattern occurence from the memory, with given signature + * + * @return true if this was the the last occurence of the signature + */ + public boolean remove(Tuple ps, Tuple signature) { + Collection coll = matchings.get(signature); + if (!coll.remove(ps)) { + throw new IllegalStateException(); + } + + boolean change = coll.isEmpty(); + if (change) + matchings.remove(signature); + + return change; + } + + /** + * Retrieves entries that have the specified signature + * + * @return collection of matchings found + */ + public Collection get(Tuple signature) { + return matchings.get(signature); + } + + public void clear() { + matchings.clear(); + } + + /** + * Retrieves a read-only collection of exactly those signatures for which at least one tuple is stored + * + * @return collection of significant signatures + */ + public Collection getSignatures() { + return matchings.keySet(); + } + + public Iterator iterator() { + return new MaskedPatternIterator(this); + } + + class MaskedPatternIterator implements Iterator { + // private MaskedTupleMemory memory; + Iterator> signatureGroup; + Iterator element; + + public MaskedPatternIterator(MaskedTupleMemory memory) { + // this.memory = memory; + signatureGroup = memory.matchings.values().iterator(); + Set emptySet = Collections.emptySet(); + element = emptySet.iterator(); + } + + public boolean hasNext() { + return (element.hasNext() || signatureGroup.hasNext()); + } + + public Tuple next() throws NoSuchElementException { + if (element.hasNext()) + return element.next(); + else if (signatureGroup.hasNext()) { + element = signatureGroup.next().iterator(); + return element.next(); + } else + throw new NoSuchElementException(); + } + + /** + * Not implemented + */ + public void remove() { + + } + + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "MTM<" + mask + "|" + matchings + ">"; + } + + public int getSize() { + return matchings.values().size(); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/tuple/Tuple.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/tuple/Tuple.java index 4a5dce54..16b8b88d 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/tuple/Tuple.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/tuple/Tuple.java @@ -24,192 +24,188 @@ */ public abstract class Tuple { - /** - * Caches precalculated hash value - */ - protected int cachedHash; - - /** - * Creates a Tuple instance Derivatives should call calcHash() - */ - protected Tuple() { - // calcHash(); - } - - /** - * @return number of elements - */ - public abstract int getSize(); - - /** - * @pre: 0 <= index < getSize() - * - * @return the element at the specified index - */ - public abstract Object get(int index); - - /** - * @return the array containing all elements of this Tuple - */ - public Object[] getElements() { - Object[] allElements = new Object[getSize()]; - for (int i = 0; i < allElements.length; ++i) - allElements[i] = get(i); - return allElements; - } - - /** - * @return the set containing all distinct elements of this Tuple, cast as type T - */ - @SuppressWarnings("unchecked") - public Set getDistinctElements() { - Set result = new HashSet(); - Object[] elements = getElements(); - for (Object object : elements) { - result.add((T) object); - } - return result; - } - /** - * Hash calculation. Overrides should keep semantics. - */ - void calcHash() { - final int PRIME = 31; - cachedHash = 1; - for (int i = 0; i < getSize(); i++) { - cachedHash = PRIME * cachedHash; - Object element = get(i); - if (element != null) - cachedHash += element.hashCode(); - } - } - - /** - * Calculates an inverted index of the elements of this pattern. For each - * element, the index of the (last) occurrence is calculated. - * - * @return the inverted index mapping each element of this pattern to its - * index in the array - */ - public Map invertIndex() { - Map result = new HashMap(); - for (int i = 0; i < getSize(); i++) - result.put(get(i), i); - return result; - } - - /** - * Calculates an inverted index of the elements of this pattern. For each - * element, the index of all of its occurrences is calculated. - * - * @return the inverted index mapping each element of this pattern to its - * index in the array - */ - public Map> invertIndexWithMupliplicity() { - Map> result = new HashMap>(); - for (int i = 0; i < getSize(); i++) { - Object value = get(i); - List indices = result.get(value); - if (indices == null) { - indices = new ArrayList(); - result.put(value, indices); - } - indices.add(i); - } - return result; - } - - // public int compareTo(Object arg0) { - // Tuple other = (Tuple) arg0; - // - // int retVal = cachedHash - other.cachedHash; - // if (retVal==0) retVal = elements.length - other.elements.length; - // for (int i=0; retVal==0 && i Set getDistinctElements() { + Set result = new HashSet(); + Object[] elements = getElements(); + for (Object object : elements) { + result.add((T) object); + } + return result; + } + + /** + * Hash calculation. Overrides should keep semantics. + */ + void calcHash() { + final int PRIME = 31; + cachedHash = 1; + for (int i = 0; i < getSize(); i++) { + cachedHash = PRIME * cachedHash; + Object element = get(i); + if (element != null) + cachedHash += element.hashCode(); + } + } + + /** + * Calculates an inverted index of the elements of this pattern. For each element, the index of the (last) + * occurrence is calculated. + * + * @return the inverted index mapping each element of this pattern to its index in the array + */ + public Map invertIndex() { + Map result = new HashMap(); + for (int i = 0; i < getSize(); i++) + result.put(get(i), i); + return result; + } + + /** + * Calculates an inverted index of the elements of this pattern. For each element, the index of all of its + * occurrences is calculated. + * + * @return the inverted index mapping each element of this pattern to its index in the array + */ + public Map> invertIndexWithMupliplicity() { + Map> result = new HashMap>(); + for (int i = 0; i < getSize(); i++) { + Object value = get(i); + List indices = result.get(value); + if (indices == null) { + indices = new ArrayList(); + result.put(value, indices); + } + indices.add(i); + } + return result; + } + + // public int compareTo(Object arg0) { + // Tuple other = (Tuple) arg0; + // + // int retVal = cachedHash - other.cachedHash; + // if (retVal==0) retVal = elements.length - other.elements.length; + // for (int i=0; retVal==0 && i=from && ito && i<=from) indices[i]=i-1; - else indices[i]=i; - return new TupleMask(indices, sourceWidth); - } - /** - * Creates a TupleMask instance that selects a single element of the tuple. - */ - public static TupleMask selectSingle(int selected, int sourceWidth) { - int[] indices = {selected}; - return new TupleMask(indices, sourceWidth); - } - /** - * Creates a TupleMask instance that selects whatever is selected by left, and appends whatever is selected by right. - * PRE: left and right have the same sourcewidth - */ - public static TupleMask append(TupleMask left, TupleMask right) { - int leftLength = left.indices.length; - int rightLength = right.indices.length; - int[] indices = new int[leftLength + rightLength]; - for (int i=0; i list = new LinkedList(); - for (int i = 0; i < indices.length; ++i) - list.add(indices[i]); - java.util.Collections.sort(list); - int i = 0; - for (Integer a : list) - indicesSorted[i++] = a; - } + /** + * Creates a TupleMask instance of the given size that does not emit output. + */ + public static TupleMask empty(int sourceWidth) { + return linear(0, sourceWidth); + } - /** - * Generates a masked view of the original pattern. - */ - public Tuple transform(Tuple original) { - Object signature[] = new Object[indices.length]; - for (int i = 0; i < indices.length; ++i) - signature[i] = original.get(indices[i]); - return new FlatTuple(signature); - } - - /** - * Transforms a given mask directly, instead of transforming tuples that were transformed by the other mask. - * @return a mask that cascades the effects this mask after the mask provided as parameter. - */ - public TupleMask transform(TupleMask mask) { - int[] cascadeIndices = new int[indices.length]; - for (int i = 0; i < indices.length; ++i) - cascadeIndices[i] = mask.indices[indices[i]]; - return new TupleMask(cascadeIndices, mask.sourceWidth); - } + /** + * Creates a TupleMask instance that maps the tuple intact save for a single element at the specified index which is + * omitted + */ + public static TupleMask omit(int omission, int sourceWidth) { + int size = sourceWidth - 1; + int[] indices = new int[size]; + for (int i = 0; i < omission; i++) + indices[i] = i; + for (int i = omission; i < size; i++) + indices[i] = i + 1; + return new TupleMask(indices, sourceWidth); + } - // /** - // * Generates a complementer mask that maps those elements that were - // untouched by the original mask. - // * Ordering is left intact. - // * A Tuple is used for reference concerning possible equalities among - // elements. - // */ - // public TupleMask complementer(Tuple reference) - // { - // HashSet touched = new HashSet(); - // LinkedList untouched = new LinkedList(); - // - // for (int index : indices) touched.add(reference.get(index)); - // for (int index=0; index= from && i < to) + indices[i] = i + 1; + else if (i > to && i <= from) + indices[i] = i - 1; + else + indices[i] = i; + return new TupleMask(indices, sourceWidth); + } - int combinedLength = asComplementer ? indices.length : masked.getSize() - - indices.length; - if (!useInheritance) - combinedLength += unmasked.getSize(); - Object combined[] = new Object[combinedLength]; + /** + * Creates a TupleMask instance that selects a single element of the tuple. + */ + public static TupleMask selectSingle(int selected, int sourceWidth) { + int[] indices = { selected }; + return new TupleMask(indices, sourceWidth); + } - int cPos = 0; - if (!useInheritance) { - for (int i = 0; i < unmasked.getSize(); ++i) - combined[cPos++] = unmasked.get(i); - } + /** + * Creates a TupleMask instance that selects whatever is selected by left, and appends whatever is selected by + * right. PRE: left and right have the same sourcewidth + */ + public static TupleMask append(TupleMask left, TupleMask right) { + int leftLength = left.indices.length; + int rightLength = right.indices.length; + int[] indices = new int[leftLength + rightLength]; + for (int i = 0; i < leftLength; ++i) + indices[i] = left.indices[i]; + for (int i = 0; i < rightLength; ++i) + indices[i + leftLength] = right.indices[i]; + return new TupleMask(indices, left.sourceWidth); + } - if (asComplementer) { - for (int i = 0; i < indices.length; ++i) - combined[cPos++] = masked.get(indices[i]); - } else { - if (indicesSorted == null) - sort(); - int mPos = 0; - for (int i = 0; i < masked.getSize(); ++i) - if (mPos < indicesSorted.length && i == indicesSorted[mPos]) - mPos++; - else - combined[cPos++] = masked.get(i); - } + /** + * Generates indicesSorted from indices + * + */ + public void sort() { + indicesSorted = new int[indices.length]; + List list = new LinkedList(); + for (int i = 0; i < indices.length; ++i) + list.add(indices[i]); + java.util.Collections.sort(list); + int i = 0; + for (Integer a : list) + indicesSorted[i++] = a; + } - return useInheritance ? new LeftInheritanceTuple(unmasked, combined) - : new FlatTuple(combined); - } + /** + * Generates a masked view of the original pattern. + */ + public Tuple transform(Tuple original) { + Object signature[] = new Object[indices.length]; + for (int i = 0; i < indices.length; ++i) + signature[i] = original.get(indices[i]); + return new FlatTuple(signature); + } - /* - * (non-Javadoc) - * - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - final int PRIME = 31; - int result = sourceWidth; - for (int i : indices) - result = PRIME * result + i; - return result; - } + /** + * Transforms a given mask directly, instead of transforming tuples that were transformed by the other mask. + * + * @return a mask that cascades the effects this mask after the mask provided as parameter. + */ + public TupleMask transform(TupleMask mask) { + int[] cascadeIndices = new int[indices.length]; + for (int i = 0; i < indices.length; ++i) + cascadeIndices[i] = mask.indices[indices[i]]; + return new TupleMask(cascadeIndices, mask.sourceWidth); + } - /* - * (non-Javadoc) - * - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - final TupleMask other = (TupleMask) obj; - if (sourceWidth != other.sourceWidth) - return false; - if (indices.length != other.indices.length) - return false; - for (int k = 0; k < indices.length; k++) - if (indices[k] != other.indices[k]) - return false; - return true; - } - - /* (non-Javadoc) - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - StringBuilder s = new StringBuilder(); - s.append("M("+sourceWidth+"->"); - for (int i : indices) { - s.append(i); - s.append(','); - } - s.append(')'); - return s.toString(); - } + // /** + // * Generates a complementer mask that maps those elements that were + // untouched by the original mask. + // * Ordering is left intact. + // * A Tuple is used for reference concerning possible equalities among + // elements. + // */ + // public TupleMask complementer(Tuple reference) + // { + // HashSet touched = new HashSet(); + // LinkedList untouched = new LinkedList(); + // + // for (int index : indices) touched.add(reference.get(index)); + // for (int index=0; index"); + for (int i : indices) { + s.append(i); + s.append(','); + } + s.append(')'); + return s.toString(); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/tuple/TupleMemory.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/tuple/TupleMemory.java index 694117a6..b571f053 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/tuple/TupleMemory.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/tuple/TupleMemory.java @@ -23,152 +23,153 @@ * */ public class TupleMemory implements Clearable, Collection { - /** - * Counts the number of occurences of each pattern. Element is deleted if # - * of occurences drops to 0. - */ - protected Map occurences; - - /** - * - */ - public TupleMemory() { - super(); - occurences = new HashMap(); - } + /** + * Counts the number of occurences of each pattern. Element is deleted if # of occurences drops to 0. + */ + protected Map occurences; - /** - * Adds a pattern occurence to the memory + /** * - * @return true if a new pattern is entered */ - @Override + public TupleMemory() { + super(); + occurences = new HashMap(); + } + + /** + * Adds a pattern occurence to the memory + * + * @return true if a new pattern is entered + */ + @Override public boolean add(Tuple ps) { - boolean exists = occurences.containsKey(ps); - - if (exists) - occurences.put(ps, occurences.get(ps) + 1); - else - occurences.put(ps, 1); - - return !exists; - } - - /** - * Removes a pattern occurence from the memory - * - * @return true if this was the the last occurence of pattern - */ - public boolean remove(Tuple ps) { - int rest = occurences.get(ps) - 1; - boolean empty = rest == 0; - - if (!empty) - occurences.put(ps, rest); - else - occurences.remove(ps); - - return empty; - } - - @Override + boolean exists = occurences.containsKey(ps); + + if (exists) + occurences.put(ps, occurences.get(ps) + 1); + else + occurences.put(ps, 1); + + return !exists; + } + + /** + * Removes a pattern occurence from the memory + * + * @return true if this was the the last occurence of pattern + */ + public boolean remove(Tuple ps) { + int rest = occurences.get(ps) - 1; + boolean empty = rest == 0; + + if (!empty) + occurences.put(ps, rest); + else + occurences.remove(ps); + + return empty; + } + + @Override public void clear() { - occurences.clear(); + occurences.clear(); - } + } - @Override + @Override public Iterator iterator() { - return occurences.keySet().iterator(); - } + return occurences.keySet().iterator(); + } - @Override + @Override public boolean addAll(Collection arg0) { - boolean change = false; - for (Tuple ps : arg0) - change |= add(ps); - return change; - } + boolean change = false; + for (Tuple ps : arg0) + change |= add(ps); + return change; + } - @Override + @Override public boolean contains(Object arg0) { - return occurences.containsKey(arg0); - } + return occurences.containsKey(arg0); + } - @Override + @Override public boolean containsAll(Collection arg0) { - return occurences.keySet().containsAll(arg0); -// for (Object o : arg0) -// if (!occurences.containsKey(o)) -// return false; -// return true; - } - - @Override + return occurences.keySet().containsAll(arg0); + // for (Object o : arg0) + // if (!occurences.containsKey(o)) + // return false; + // return true; + } + + @Override public boolean isEmpty() { - return occurences.isEmpty(); - } + return occurences.isEmpty(); + } - @Override + @Override public boolean remove(Object arg0) { - return remove((Tuple) arg0); - } + return remove((Tuple) arg0); + } - @Override + @Override public boolean removeAll(Collection arg0) { - boolean change = false; - for (Object o : arg0) - change |= remove(o); - return change; - } + boolean change = false; + for (Object o : arg0) + change |= remove(o); + return change; + } - @Override + @Override public boolean retainAll(Collection arg0) { - return occurences.keySet().retainAll(arg0); -// HashSet obsolete = new HashSet(); -// for (Tuple key : occurences.keySet()) -// if (!arg0.contains(key)) -// obsolete.add(key); -// for (Tuple key : obsolete) -// occurences.remove(key); -// return !obsolete.isEmpty(); - } - - @Override + return occurences.keySet().retainAll(arg0); + // HashSet obsolete = new HashSet(); + // for (Tuple key : occurences.keySet()) + // if (!arg0.contains(key)) + // obsolete.add(key); + // for (Tuple key : obsolete) + // occurences.remove(key); + // return !obsolete.isEmpty(); + } + + @Override public int size() { -// int sum = 0; -// for (Integer count : occurences.values()) -// sum += count; -// return sum; - return occurences.size(); - } - - @Override + // int sum = 0; + // for (Integer count : occurences.values()) + // sum += count; + // return sum; + return occurences.size(); + } + + @Override public Object[] toArray() { - return toArray(new Object[0]); - } + return toArray(new Object[0]); + } -// @SuppressWarnings("unchecked") - @Override + // @SuppressWarnings("unchecked") + @Override public T[] toArray(T[] arg0) { - return occurences.keySet().toArray(arg0); -// int length = size(); -// T[] result = (T[]) java.lang.reflect.Array.newInstance(arg0.getClass() -// .getComponentType(), length); -// int next = 0; -// for (Tuple key : occurences.keySet()) { -// for (int counter = occurences.get(key); counter > 0; --counter) -// result[next++] = (T) key; -// } -// return result; - } - - /* (non-Javadoc) - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return "TM"+occurences.keySet(); - } + return occurences.keySet().toArray(arg0); + // int length = size(); + // T[] result = (T[]) java.lang.reflect.Array.newInstance(arg0.getClass() + // .getComponentType(), length); + // int next = 0; + // for (Tuple key : occurences.keySet()) { + // for (int counter = occurences.get(key); counter > 0; --counter) + // result[next++] = (T) key; + // } + // return result; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "TM" + occurences.keySet(); + } } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/util/Options.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/util/Options.java index a56abfe9..e567da19 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/util/Options.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/util/Options.java @@ -17,55 +17,54 @@ public class Options { - public enum NodeSharingOption { - NEVER, // not recommended, patternmatcher leaks possible - INDEXER_AND_REMOTEPROXY, ALL - } + public enum NodeSharingOption { + NEVER, // not recommended, patternmatcher leaks possible + INDEXER_AND_REMOTEPROXY, ALL + } - public final static NodeSharingOption nodeSharingOption = NodeSharingOption.ALL; - public static final boolean releaseOnetimeIndexers = true; // effective only - // with - // nodesharing - // ==NEVER + public final static NodeSharingOption nodeSharingOption = NodeSharingOption.ALL; + public static final boolean releaseOnetimeIndexers = true; // effective only + // with + // nodesharing + // ==NEVER - public enum InjectivityStrategy { - EAGER, LAZY - } + public enum InjectivityStrategy { + EAGER, LAZY + } - public final static InjectivityStrategy injectivityStrategy = InjectivityStrategy.EAGER; + public final static InjectivityStrategy injectivityStrategy = InjectivityStrategy.EAGER; - public final static boolean enableInheritance = true; + public final static boolean enableInheritance = true; - //public final static boolean useComplementerMask = true; - - public static final boolean calcImpliedTypes = true; // if true, shrinks the net by avoiding unnecessary typechecks - public static final boolean employTrivialIndexers = true; + // public final static boolean useComplementerMask = true; + public static final boolean calcImpliedTypes = true; // if true, shrinks the net by avoiding unnecessary typechecks + public static final boolean employTrivialIndexers = true; - // public final static boolean synchronous = false; + // public final static boolean synchronous = false; - public final static int numberOfLocalContainers = 1; - public final static int firstFreeContainer = 0; // 0 if head container is - // free to contain pattern - // bodies, 1 otherwise - - public enum BuilderMethod { - LEGACY, // ONLY with GTASM - PSYSTEM_BASIC_LINEAR, - PSYSTEM_QUASITREE; - public IReteLayoutStrategy layoutStrategy() { - switch (this) { - case PSYSTEM_BASIC_LINEAR: - return new BasicLinearLayout(); - case PSYSTEM_QUASITREE: - return new QuasiTreeLayout(); - default: - return null; - } - } - } - public final static BuilderMethod builderMethod = - //BuilderMethod.PSYSTEM_BASIC_LINEAR; - BuilderMethod.PSYSTEM_QUASITREE; + public final static int numberOfLocalContainers = 1; + public final static int firstFreeContainer = 0; // 0 if head container is + // free to contain pattern + // bodies, 1 otherwise + + public enum BuilderMethod { + LEGACY, // ONLY with GTASM + PSYSTEM_BASIC_LINEAR, PSYSTEM_QUASITREE; + public IReteLayoutStrategy layoutStrategy() { + switch (this) { + case PSYSTEM_BASIC_LINEAR: + return new BasicLinearLayout(); + case PSYSTEM_QUASITREE: + return new QuasiTreeLayout(); + default: + return null; + } + } + } + + public final static BuilderMethod builderMethod = + // BuilderMethod.PSYSTEM_BASIC_LINEAR; + BuilderMethod.PSYSTEM_QUASITREE; } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/util/OrderingCompareAgent.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/util/OrderingCompareAgent.java index a5548fc3..0f6ae94a 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/util/OrderingCompareAgent.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/util/OrderingCompareAgent.java @@ -12,67 +12,70 @@ package org.eclipse.incquery.runtime.rete.util; /** - * Comparing agent for an ordering. - * Terminology: the "preferred" item will register as LESS. + * Comparing agent for an ordering. Terminology: the "preferred" item will register as LESS. + * * @author Bergmann Gábor - * + * */ public abstract class OrderingCompareAgent { - protected T a; - protected T b; - - /** - * @param a - * @param b - */ - public OrderingCompareAgent(T a, T b) { - super(); - this.a = a; - this.b = b; - } + protected T a; + protected T b; + + /** + * @param a + * @param b + */ + public OrderingCompareAgent(T a, T b) { + super(); + this.a = a; + this.b = b; + } + + int result = 0; + + protected abstract void doCompare(); + + /** + * @return the result + */ + public int compare() { + doCompare(); + return result; + } + + // COMPARISON HELPERS + protected boolean unknown() { + return result == 0; + } + + /** + * @pre result == 0 + */ + protected boolean consider(int partial) { + if (unknown()) + result = partial; + return unknown(); + } + + protected boolean swallowBoolean(boolean x) { + return x; + } + + // PREFERENCE FUNCTIONS + protected static int preferTrue(boolean b1, boolean b2) { + return (b1 ^ b2) ? (b1 ? -1 : +1) : 0; + } - int result = 0; - - - protected abstract void doCompare(); - /** - * @return the result - */ - public int compare() { - doCompare(); - return result; - } - - // COMPARISON HELPERS - protected boolean unknown() { - return result == 0; - } - /** - * @pre result == 0 - */ - protected boolean consider(int partial) { - if (unknown()) result = partial; - return unknown(); - } + protected static int preferFalse(boolean b1, boolean b2) { + return (b1 ^ b2) ? (b2 ? -1 : +1) : 0; + } - protected boolean swallowBoolean(boolean x) {return x;} - - // PREFERENCE FUNCTIONS - protected static int preferTrue(boolean b1, boolean b2) { - return (b1^b2) ? (b1 ? -1: +1) : 0; - } - protected static int preferFalse(boolean b1, boolean b2) { - return (b1^b2) ? (b2 ? -1: +1) : 0; - } - protected static int preferLess(Comparable c1, U c2) { - return c1.compareTo(c2); - } - protected static int preferMore(Comparable c1, U c2) { - return -c1.compareTo(c2); - } + protected static int preferLess(Comparable c1, U c2) { + return c1.compareTo(c2); + } + protected static int preferMore(Comparable c1, U c2) { + return -c1.compareTo(c2); + } - - - } diff --git a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/util/UnionFind.java b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/util/UnionFind.java index bbd34ef8..7065415b 100644 --- a/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/util/UnionFind.java +++ b/plugins/org.eclipse.incquery.runtime.rete/src/org/eclipse/incquery/runtime/rete/util/UnionFind.java @@ -21,111 +21,119 @@ * */ public class UnionFind implements Map { - class Node { - public T value; - public Node parent; - public int rank; - - public Node(T value) { - this.value = value; - parent = this; - rank = 0; - } - } - - protected HashMap nodes; - - public UnionFind() { - nodes = new HashMap(); - } - - protected Node find(Node n) { - if (n.parent == n) - return n; - n.parent = find(n.parent); - return n.parent; - } - - public T find(T x) { - Node node = nodes.get(x); - if (node == null) - return x; - else - return find(node).value; - } - - public boolean isRoot(T x) { - Node node = nodes.get(x); - if (node == null) - return true; - else - return node == node.parent; - } - - protected Node retrieveOrCreate(T x) { - Node node = nodes.get(x); - if (node == null) { - node = new Node(x); - nodes.put(x, node); - return node; - } else - return find(node); - } - - public void unite(T a, T b) { - Node aRoot = retrieveOrCreate(a); - Node bRoot = retrieveOrCreate(b); - - if (aRoot.rank > bRoot.rank) - bRoot.parent = aRoot; - else if (aRoot.rank < bRoot.rank) - aRoot.parent = bRoot; - else if (aRoot != bRoot) { - bRoot.parent = aRoot; - aRoot.rank++; - } - - } - - public void clear() { - nodes.clear(); - } - - @SuppressWarnings("unchecked") - public T get(Object key) { - return find((T)key); - } - - public boolean containsKey(Object key) { - throw new UnsupportedOperationException(); - } - public boolean containsValue(Object value) { - throw new UnsupportedOperationException(); - } - public Set> entrySet() { - throw new UnsupportedOperationException(); - } - public boolean isEmpty() { - throw new UnsupportedOperationException(); - } - public Set keySet() { - throw new UnsupportedOperationException(); - } - public T put(T key, T value) { - throw new UnsupportedOperationException(); - } - public void putAll(Map m) { - throw new UnsupportedOperationException(); - } - public T remove(Object key) { - throw new UnsupportedOperationException(); - } - public int size() { - throw new UnsupportedOperationException(); - } - public Collection values() { - throw new UnsupportedOperationException(); - } - - + class Node { + public T value; + public Node parent; + public int rank; + + public Node(T value) { + this.value = value; + parent = this; + rank = 0; + } + } + + protected HashMap nodes; + + public UnionFind() { + nodes = new HashMap(); + } + + protected Node find(Node n) { + if (n.parent == n) + return n; + n.parent = find(n.parent); + return n.parent; + } + + public T find(T x) { + Node node = nodes.get(x); + if (node == null) + return x; + else + return find(node).value; + } + + public boolean isRoot(T x) { + Node node = nodes.get(x); + if (node == null) + return true; + else + return node == node.parent; + } + + protected Node retrieveOrCreate(T x) { + Node node = nodes.get(x); + if (node == null) { + node = new Node(x); + nodes.put(x, node); + return node; + } else + return find(node); + } + + public void unite(T a, T b) { + Node aRoot = retrieveOrCreate(a); + Node bRoot = retrieveOrCreate(b); + + if (aRoot.rank > bRoot.rank) + bRoot.parent = aRoot; + else if (aRoot.rank < bRoot.rank) + aRoot.parent = bRoot; + else if (aRoot != bRoot) { + bRoot.parent = aRoot; + aRoot.rank++; + } + + } + + public void clear() { + nodes.clear(); + } + + @SuppressWarnings("unchecked") + public T get(Object key) { + return find((T) key); + } + + public boolean containsKey(Object key) { + throw new UnsupportedOperationException(); + } + + public boolean containsValue(Object value) { + throw new UnsupportedOperationException(); + } + + public Set> entrySet() { + throw new UnsupportedOperationException(); + } + + public boolean isEmpty() { + throw new UnsupportedOperationException(); + } + + public Set keySet() { + throw new UnsupportedOperationException(); + } + + public T put(T key, T value) { + throw new UnsupportedOperationException(); + } + + public void putAll(Map m) { + throw new UnsupportedOperationException(); + } + + public T remove(Object key) { + throw new UnsupportedOperationException(); + } + + public int size() { + throw new UnsupportedOperationException(); + } + + public Collection values() { + throw new UnsupportedOperationException(); + } + } diff --git a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/AbstractRule.java b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/AbstractRule.java index 49a14757..85b9ab80 100644 --- a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/AbstractRule.java +++ b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/AbstractRule.java @@ -16,46 +16,45 @@ import org.eclipse.incquery.runtime.triggerengine.notification.IAttributeMonitorListener; /** - * A {@link AbstractRule} defines a transformation step in the context of the AbstractRule Engine. - * Each rule is assigned a precondition (Left Hand Side - LHS) which is an EMF-IncQuery pattern and - * a postcondition (Right Hand Side - RHS) which is an {@link IMatchProcessor} instance. + * A {@link AbstractRule} defines a transformation step in the context of the AbstractRule Engine. Each rule is assigned + * a precondition (Left Hand Side - LHS) which is an EMF-IncQuery pattern and a postcondition (Right Hand Side - RHS) + * which is an {@link IMatchProcessor} instance. * - *

    The {@link AbstractRule} keeps track of its activations and they can be queried and executed at some - * point in time. + *

    + * The {@link AbstractRule} keeps track of its activations and they can be queried and executed at some point in time. * * @author Tamas Szabo - * - * @param the type of the pattern match + * + * @param + * the type of the pattern match */ -public abstract class AbstractRule implements - IAttributeMonitorListener, IMatchUpdateListener, IRule { - - private IMatchProcessor afterAppearanceJob; - private IMatchProcessor afterDisappearanceJob; - private IMatchProcessor afterModificationJob; - protected IAgenda agenda; - protected boolean upgradedStateUsed; - protected boolean disappearedStateUsed; - protected IncQueryMatcher matcher; - protected Map>> stateMap; - protected AttributeMonitor attributeMonitor; - protected ActivationNotificationProvider activationProvider; - - public AbstractRule(IAgenda agenda, - IncQueryMatcher matcher, - boolean upgradedStateUsed, - boolean disappearedStateUsed) { - this.agenda = agenda; - this.matcher = matcher; - this.upgradedStateUsed = upgradedStateUsed; - this.disappearedStateUsed = disappearedStateUsed; - this.stateMap = new HashMap>>(); - this.stateMap.put(ActivationState.APPEARED, new HashMap>()); - this.stateMap.put(ActivationState.DISAPPEARED, new HashMap>()); - this.stateMap.put(ActivationState.UPDATED, new HashMap>()); - - this.activationProvider = new ActivationNotificationProvider() { - +public abstract class AbstractRule implements IAttributeMonitorListener, + IMatchUpdateListener, IRule { + + private IMatchProcessor afterAppearanceJob; + private IMatchProcessor afterDisappearanceJob; + private IMatchProcessor afterModificationJob; + protected IAgenda agenda; + protected boolean upgradedStateUsed; + protected boolean disappearedStateUsed; + protected IncQueryMatcher matcher; + protected Map>> stateMap; + protected AttributeMonitor attributeMonitor; + protected ActivationNotificationProvider activationProvider; + + public AbstractRule(IAgenda agenda, IncQueryMatcher matcher, boolean upgradedStateUsed, + boolean disappearedStateUsed) { + this.agenda = agenda; + this.matcher = matcher; + this.upgradedStateUsed = upgradedStateUsed; + this.disappearedStateUsed = disappearedStateUsed; + this.stateMap = new HashMap>>(); + this.stateMap.put(ActivationState.APPEARED, new HashMap>()); + this.stateMap.put(ActivationState.DISAPPEARED, new HashMap>()); + this.stateMap.put(ActivationState.UPDATED, new HashMap>()); + + this.activationProvider = new ActivationNotificationProvider() { + @Override protected void listenerAdded(IActivationNotificationListener listener, boolean fireNow) { if (fireNow) { @@ -65,143 +64,141 @@ protected void listenerAdded(IActivationNotificationListener listener, boolean f } } }; - } + } - @Override + @Override public Pattern getPattern() { - return matcher.getPattern(); - } - - /** - * This method is called when the activation for the rule is fired. - * Subtypes may use this to step the state machine of the activation. - * - * @param activation the activation that was fired - */ - public abstract void activationFired(Activation activation); - - @Override + return matcher.getPattern(); + } + + /** + * This method is called when the activation for the rule is fired. Subtypes may use this to step the state machine + * of the activation. + * + * @param activation + * the activation that was fired + */ + public abstract void activationFired(Activation activation); + + @Override public IAgenda getAgenda() { - return agenda; - } + return agenda; + } - @Override + @Override public List> getActivations() { - List> activations = new ArrayList>(); - for (ActivationState as : stateMap.keySet()) { - for (MatchType match : stateMap.get(as).keySet()) { - Activation a = stateMap.get(as).get(match); - if (!a.isFired()) { - activations.add(a); - } - } - } - return activations; - } + List> activations = new ArrayList>(); + for (ActivationState as : stateMap.keySet()) { + for (MatchType match : stateMap.get(as).keySet()) { + Activation a = stateMap.get(as).get(match); + if (!a.isFired()) { + activations.add(a); + } + } + } + return activations; + } /** * This method is only used when upgradedStateUsed flag is true + * * @param match */ protected void processMatchModification(MatchType match) { - Map> updatedMap = stateMap.get(ActivationState.UPDATED); - Map> appearedMap = stateMap.get(ActivationState.APPEARED); - Activation activation = updatedMap.get(match); - - //if this method is called the activation associated to the match must be in either appeared or upgraded state - if (activation != null) { - //upgraded state is not changed - activation.setFired(false); - activationProvider.notifyActivationAppearance(activation); - } - else { - activation = appearedMap.get(match); - if (activation != null && activation.isFired()) { - //changing activation state from appeared to upgraded - appearedMap.remove(match); - activation.setFired(false); - activation.setState(ActivationState.UPDATED); - updatedMap.put(match, activation); - activationProvider.notifyActivationAppearance(activation); - } - } + Map> updatedMap = stateMap.get(ActivationState.UPDATED); + Map> appearedMap = stateMap.get(ActivationState.APPEARED); + Activation activation = updatedMap.get(match); + + // if this method is called the activation associated to the match must be in either appeared or upgraded state + if (activation != null) { + // upgraded state is not changed + activation.setFired(false); + activationProvider.notifyActivationAppearance(activation); + } else { + activation = appearedMap.get(match); + if (activation != null && activation.isFired()) { + // changing activation state from appeared to upgraded + appearedMap.remove(match); + activation.setFired(false); + activation.setState(ActivationState.UPDATED); + updatedMap.put(match, activation); + activationProvider.notifyActivationAppearance(activation); + } + } } protected void processMatchAppearance(MatchType match) { - Map> disappearedMap = stateMap.get(ActivationState.DISAPPEARED); - Map> appearedMap = stateMap.get(ActivationState.APPEARED); - - //activation can be in not exists or disappeared state - Activation activation = disappearedMap.get(match); - if (activation != null) { - //if disappearedStateUsed flag is false no activation will be inserted into disappearedMap - disappearedMap.remove(match); - activation.setFired(true); - activation.setState(ActivationState.APPEARED); - appearedMap.put(match, activation); - activationProvider.notifyActivationDisappearance(activation); - } - else { - activation = createActivation(match); - appearedMap.put(match, activation); - - if (upgradedStateUsed) { - attributeMonitor.registerFor(match); - } - - activationProvider.notifyActivationAppearance(activation); - } + Map> disappearedMap = stateMap.get(ActivationState.DISAPPEARED); + Map> appearedMap = stateMap.get(ActivationState.APPEARED); + + // activation can be in not exists or disappeared state + Activation activation = disappearedMap.get(match); + if (activation != null) { + // if disappearedStateUsed flag is false no activation will be inserted into disappearedMap + disappearedMap.remove(match); + activation.setFired(true); + activation.setState(ActivationState.APPEARED); + appearedMap.put(match, activation); + activationProvider.notifyActivationDisappearance(activation); + } else { + activation = createActivation(match); + appearedMap.put(match, activation); + + if (upgradedStateUsed) { + attributeMonitor.registerFor(match); + } + + activationProvider.notifyActivationAppearance(activation); + } } protected abstract Activation createActivation(MatchType match); protected void processMatchDisappearance(MatchType match) { - Map> disappearedMap = stateMap.get(ActivationState.DISAPPEARED); - Map> appearedMap = stateMap.get(ActivationState.APPEARED); - Map> updatedMap = stateMap.get(ActivationState.UPDATED); - - //activation can be in appeared or updated state - Activation activation = appearedMap.get(match); - if (activation != null) { - //changing activation state from appeared to disappeared if it was fired - if (activation.isFired() && disappearedStateUsed) { - appearedMap.remove(match); - activation.setFired(false); - activation.setState(ActivationState.DISAPPEARED); - disappearedMap.put(match, activation); - activationProvider.notifyActivationAppearance(activation); - } - else { - appearedMap.remove(match); - //unregistering change listener from the affected observable values - attributeMonitor.unregisterFor(match); - activationProvider.notifyActivationDisappearance(activation); - } - } - else { - //changing activation state from updated to disappeared if it was fired - activation = updatedMap.get(match); - activation.setFired(false); + Map> disappearedMap = stateMap.get(ActivationState.DISAPPEARED); + Map> appearedMap = stateMap.get(ActivationState.APPEARED); + Map> updatedMap = stateMap.get(ActivationState.UPDATED); + + // activation can be in appeared or updated state + Activation activation = appearedMap.get(match); + if (activation != null) { + // changing activation state from appeared to disappeared if it was fired + if (activation.isFired() && disappearedStateUsed) { + appearedMap.remove(match); + activation.setFired(false); + activation.setState(ActivationState.DISAPPEARED); + disappearedMap.put(match, activation); + activationProvider.notifyActivationAppearance(activation); + } else { + appearedMap.remove(match); + // unregistering change listener from the affected observable values + attributeMonitor.unregisterFor(match); + activationProvider.notifyActivationDisappearance(activation); + } + } else { + // changing activation state from updated to disappeared if it was fired + activation = updatedMap.get(match); + activation.setFired(false); updatedMap.remove(match); activation.setState(ActivationState.DISAPPEARED); disappearedMap.put(match, activation); - activationProvider.notifyActivationAppearance(activation); - } + activationProvider.notifyActivationAppearance(activation); + } } @Override public void notifyAppearance(MatchType match) { - processMatchAppearance(match); + processMatchAppearance(match); } @Override public void notifyDisappearance(MatchType match) { - processMatchDisappearance(match); + processMatchDisappearance(match); } @Override public void notifyUpdate(MatchType match) { - processMatchModification(match); + processMatchModification(match); } @Override @@ -241,5 +238,5 @@ public IMatchProcessor getStateChangeProcessor(ActivationState newSta default: return null; } - } + } } diff --git a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/Activation.java b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/Activation.java index d391c2a8..977043e4 100644 --- a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/Activation.java +++ b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/Activation.java @@ -4,94 +4,91 @@ import org.eclipse.incquery.runtime.api.IPatternMatch; /** - * An {@link Activation} is a created for a {@link AbstractRule} when the - * preconditions (LHS) are fully satisfied with some domain model - * elements and the rule becomes eligible for execution. + * An {@link Activation} is a created for a {@link AbstractRule} when the preconditions (LHS) are fully satisfied with + * some domain model elements and the rule becomes eligible for execution. * - *

    An Activation holds a state, a pattern match, the corresponding rule - * and whether it was fired yet. The state of the Activation can be - * either Inactive, Appeared, Disappeared, Upgraded or Fired. Upon - * {@link AbstractRule} instantiation, one may set whether the Disappeared and - * Upgraded states will be used during the lifecycle of the Activation. - * If multiple firing is allowed for the Activation then only - * the Appeared state will be used. + *

    + * An Activation holds a state, a pattern match, the corresponding rule and whether it was fired yet. The state of the + * Activation can be either Inactive, Appeared, Disappeared, Upgraded or Fired. Upon {@link AbstractRule} instantiation, + * one may set whether the Disappeared and Upgraded states will be used during the lifecycle of the Activation. If + * multiple firing is allowed for the Activation then only the Appeared state will be used. * * @author Tamas Szabo - * - * @param the type of the pattern match + * + * @param + * the type of the pattern match */ public abstract class Activation { - protected MatchType patternMatch; - protected boolean fired; - protected ActivationState state; - protected AbstractRule rule; - private int cachedHash = -1; - - public Activation(AbstractRule rule, MatchType patternMatch) { - this.patternMatch = patternMatch; - this.fired = false; - this.rule = rule; - } - - public void setFired(boolean fired) { - this.fired = fired; - } - - public boolean isFired() { - return this.fired; - } - - public MatchType getPatternMatch() { - return patternMatch; - } - - public ActivationState getState() { - return state; - } - - public void setState(ActivationState state) { - this.state = state; - } - - /** - * The activation will be fired; the appropriate job of the rule will be executed based on the activation state. - */ - public void fire() { - IMatchProcessor processor = rule.getStateChangeProcessor(this.state); - if (processor != null) { - processor.process(patternMatch); - } - - if (!rule.getAgenda().isAllowMultipleFiring()) { - this.fired = true; - this.rule.activationFired(this); - } - } - - @SuppressWarnings("unchecked") - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - else if (obj == null || !(obj instanceof Activation)) { - return false; - } - else { - Activation other = (Activation) obj; - return (other.fired == this.fired) && (other.rule.equals(this.rule)) && (other.patternMatch.equals(this.patternMatch)) && (other.state == this.state); - } - } - - @Override - public int hashCode() { - if (cachedHash == -1) { - final int prime = 31; - cachedHash = 1; - cachedHash = prime * cachedHash + state.hashCode(); - cachedHash = prime * cachedHash + patternMatch.hashCode(); - } - return cachedHash; - } + protected MatchType patternMatch; + protected boolean fired; + protected ActivationState state; + protected AbstractRule rule; + private int cachedHash = -1; + + public Activation(AbstractRule rule, MatchType patternMatch) { + this.patternMatch = patternMatch; + this.fired = false; + this.rule = rule; + } + + public void setFired(boolean fired) { + this.fired = fired; + } + + public boolean isFired() { + return this.fired; + } + + public MatchType getPatternMatch() { + return patternMatch; + } + + public ActivationState getState() { + return state; + } + + public void setState(ActivationState state) { + this.state = state; + } + + /** + * The activation will be fired; the appropriate job of the rule will be executed based on the activation state. + */ + public void fire() { + IMatchProcessor processor = rule.getStateChangeProcessor(this.state); + if (processor != null) { + processor.process(patternMatch); + } + + if (!rule.getAgenda().isAllowMultipleFiring()) { + this.fired = true; + this.rule.activationFired(this); + } + } + + @SuppressWarnings("unchecked") + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } else if (obj == null || !(obj instanceof Activation)) { + return false; + } else { + Activation other = (Activation) obj; + return (other.fired == this.fired) && (other.rule.equals(this.rule)) + && (other.patternMatch.equals(this.patternMatch)) && (other.state == this.state); + } + } + + @Override + public int hashCode() { + if (cachedHash == -1) { + final int prime = 31; + cachedHash = 1; + cachedHash = prime * cachedHash + state.hashCode(); + cachedHash = prime * cachedHash + patternMatch.hashCode(); + } + return cachedHash; + } } diff --git a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/ActivationMonitor.java b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/ActivationMonitor.java index b1a7752e..bc39e513 100644 --- a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/ActivationMonitor.java +++ b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/ActivationMonitor.java @@ -7,40 +7,37 @@ import org.eclipse.incquery.runtime.api.IPatternMatch; /** - * Instances of this class are used by clients to - * monitor and process the collection of activations within an {@link Agenda} on an - * individual basis. This means that while the {@link Agenda} always provides an - * up-to-date view of the applicable activations, an {@link ActivationMonitor} instance - * accumulates all the activations and the user can clear the collection in the - * monitor when it is needed (for example after those have been processed). Upon - * instantiation it can be set to be filled with the initial collection of - * activations. + * Instances of this class are used by clients to monitor and process the collection of activations within an + * {@link Agenda} on an individual basis. This means that while the {@link Agenda} always provides an up-to-date view of + * the applicable activations, an {@link ActivationMonitor} instance accumulates all the activations and the user can + * clear the collection in the monitor when it is needed (for example after those have been processed). Upon + * instantiation it can be set to be filled with the initial collection of activations. * * @author Tamas Szabo - * + * */ public class ActivationMonitor { - private Set> activations; - - public ActivationMonitor() { - activations = new HashSet>(); - } - - public Set> getActivations() { - return Collections.unmodifiableSet(activations); - } - - protected void addActivation(Activation activation) { - this.activations.add(activation); - } - - protected void removeActivation(Activation activation) { - this.activations.remove(activation); - } - - public void clear() { - this.activations.clear(); - } - + private Set> activations; + + public ActivationMonitor() { + activations = new HashSet>(); + } + + public Set> getActivations() { + return Collections.unmodifiableSet(activations); + } + + protected void addActivation(Activation activation) { + this.activations.add(activation); + } + + protected void removeActivation(Activation activation) { + this.activations.remove(activation); + } + + public void clear() { + this.activations.clear(); + } + } diff --git a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/ActivationState.java b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/ActivationState.java index 34cb9618..5888d517 100644 --- a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/ActivationState.java +++ b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/ActivationState.java @@ -1,7 +1,5 @@ package org.eclipse.incquery.runtime.triggerengine.api; public enum ActivationState { - APPEARED, - DISAPPEARED, - UPDATED + APPEARED, DISAPPEARED, UPDATED } diff --git a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/Agenda.java b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/Agenda.java index 805ceef9..ee4e6d41 100644 --- a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/Agenda.java +++ b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/Agenda.java @@ -25,75 +25,78 @@ import org.eclipse.incquery.runtime.triggerengine.notification.IActivationNotificationListener; /** - * An Agenda is associated to each EMF instance model (more precisely {@link IncQueryEngine} - * or equivalently {@link Notifier} in the context of EMF-IncQuery) and it is - * responsible for creating, managing and disposing rules in the AbstractRule Engine. - * It provides an unmodifiable view for the collection of applicable activations. + * An Agenda is associated to each EMF instance model (more precisely {@link IncQueryEngine} or equivalently + * {@link Notifier} in the context of EMF-IncQuery) and it is responsible for creating, managing and disposing rules in + * the AbstractRule Engine. It provides an unmodifiable view for the collection of applicable activations. * - *

    One must register an {@link IActivationNotificationListener} in order to receive - * notifications automatically about the changes in the collection of activations. + *

    + * One must register an {@link IActivationNotificationListener} in order to receive notifications automatically about + * the changes in the collection of activations. * - *

    The Trigger Engine is a collection of strategies which can be used to - * fire these activations with pre-defined timings. Such strategies include - * the {@link AutomaticFiringStrategy} and {@link TimedFiringStrategy} at the current - * state of development. + *

    + * The Trigger Engine is a collection of strategies which can be used to fire these activations with pre-defined + * timings. Such strategies include the {@link AutomaticFiringStrategy} and {@link TimedFiringStrategy} at the current + * state of development. * - *

    Note that, one may instantiate an {@link ActivationMonitor} in order to - * process the activations on an individual basis, because the {@link Agenda} always reflects - * the most up-to-date state of the activations. + *

    + * Note that, one may instantiate an {@link ActivationMonitor} in order to process the activations on an individual + * basis, because the {@link Agenda} always reflects the most up-to-date state of the activations. * - *

    One may define whether multiple firing of the same activation is allowed; that is, only - * the Appeared state will be used from the lifecycle of {@link Activation}s and consecutive - * firing of a previously applied {@link Activation} is possible. For more - * information on the lifecycle see {@link Activation}. Multiple firing is used - * for example in Design Space Exploration scenarios. + *

    + * One may define whether multiple firing of the same activation is allowed; that is, only the Appeared state will be + * used from the lifecycle of {@link Activation}s and consecutive firing of a previously applied {@link Activation} is + * possible. For more information on the lifecycle see {@link Activation}. Multiple firing is used for example in Design + * Space Exploration scenarios. * * @author Tamas Szabo - * + * */ public class Agenda implements IAgenda { - private final IncQueryEngine iqEngine; - private final Set> rules; - private final Set monitors; - private final Notifier notifier; - private final TransactionalEditingDomain editingDomain; - private final boolean allowMultipleFiring; - private IRuleFactory ruleFactory; - private final Collection> activations; - private IUpdateCompleteProvider updateCompleteProvider; - private final IActivationNotificationListener activationListener; - private final ActivationNotificationProvider activationProvider; - - /** - * Instantiates a new Agenda instance with the given {@link IncQueryEngine}. - * Multiple firing of the same activation is not allowed. - * - * @param iqEngine the {@link IncQueryEngine} instance - */ - protected Agenda(IncQueryEngine iqEngine) { - this(iqEngine, false); - } - - /** - * Instantiates a new Agenda instance with the given {@link IncQueryEngine} - * and sets whether multiple allowing is allowed. - * - * @param iqEngine the {@link IncQueryEngine} instance - * @param allowMultipleFiring indicates whether multiple firing is allowed - */ - protected Agenda(IncQueryEngine iqEngine, boolean allowMultipleFiring) { - this.iqEngine = iqEngine; - this.rules = new HashSet>(); - this.monitors = new HashSet(); - this.notifier = iqEngine.getEmfRoot(); - this.editingDomain = TransactionUtil.getEditingDomain(notifier); - this.allowMultipleFiring = allowMultipleFiring; - this.activations = new HashSet>(); - - this.activationProvider = new ActivationNotificationProvider() { - - @Override + private final IncQueryEngine iqEngine; + private final Set> rules; + private final Set monitors; + private final Notifier notifier; + private final TransactionalEditingDomain editingDomain; + private final boolean allowMultipleFiring; + private IRuleFactory ruleFactory; + private final Collection> activations; + private IUpdateCompleteProvider updateCompleteProvider; + private final IActivationNotificationListener activationListener; + private final ActivationNotificationProvider activationProvider; + + /** + * Instantiates a new Agenda instance with the given {@link IncQueryEngine}. Multiple firing of the same activation + * is not allowed. + * + * @param iqEngine + * the {@link IncQueryEngine} instance + */ + protected Agenda(IncQueryEngine iqEngine) { + this(iqEngine, false); + } + + /** + * Instantiates a new Agenda instance with the given {@link IncQueryEngine} and sets whether multiple allowing is + * allowed. + * + * @param iqEngine + * the {@link IncQueryEngine} instance + * @param allowMultipleFiring + * indicates whether multiple firing is allowed + */ + protected Agenda(IncQueryEngine iqEngine, boolean allowMultipleFiring) { + this.iqEngine = iqEngine; + this.rules = new HashSet>(); + this.monitors = new HashSet(); + this.notifier = iqEngine.getEmfRoot(); + this.editingDomain = TransactionUtil.getEditingDomain(notifier); + this.allowMultipleFiring = allowMultipleFiring; + this.activations = new HashSet>(); + + this.activationProvider = new ActivationNotificationProvider() { + + @Override protected void listenerAdded(IActivationNotificationListener listener, boolean fireNow) { if (fireNow) { for (Activation activation : activations) { @@ -101,11 +104,11 @@ protected void listenerAdded(IActivationNotificationListener listener, boolean f } } } - + }; - - this.activationListener = new IActivationNotificationListener() { - + + this.activationListener = new IActivationNotificationListener() { + @Override public void activationDisappeared(Activation activation) { activations.remove(activation); @@ -114,7 +117,7 @@ public void activationDisappeared(Activation activation } activationProvider.notifyActivationDisappearance(activation); } - + @Override public void activationAppeared(Activation activation) { activations.add(activation); @@ -124,95 +127,95 @@ public void activationAppeared(Activation activation) { activationProvider.notifyActivationAppearance(activation); } }; - - if (this.editingDomain != null) { - updateCompleteProvider = new TransactionUpdateCompleteProvider(editingDomain); - } else { - NavigationHelper helper; + + if (this.editingDomain != null) { + updateCompleteProvider = new TransactionUpdateCompleteProvider(editingDomain); + } else { + NavigationHelper helper; try { helper = iqEngine.getBaseIndex(); updateCompleteProvider = new IQBaseCallbackUpdateCompleteProvider(helper); } catch (IncQueryException e) { getLogger().error("The base index cannot be constructed for the engine!", e); } - } - } - - /** - * Sets the {@link IRuleFactory} for the Agenda. - * - * @param ruleFactory the {@link IRuleFactory} instance - */ - public void setRuleFactory(IRuleFactory ruleFactory) { - this.ruleFactory = ruleFactory; - } - - @Override + } + } + + /** + * Sets the {@link IRuleFactory} for the Agenda. + * + * @param ruleFactory + * the {@link IRuleFactory} instance + */ + public void setRuleFactory(IRuleFactory ruleFactory) { + this.ruleFactory = ruleFactory; + } + + @Override public Notifier getNotifier() { - return notifier; - } + return notifier; + } - @Override + @Override public TransactionalEditingDomain getEditingDomain() { - return editingDomain; - } + return editingDomain; + } @Override public boolean isAllowMultipleFiring() { return allowMultipleFiring; } - @Override - public > - IRule createRule(IMatcherFactory factory) { - return createRule(factory, false, false); - } - - @Override - public > - IRule createRule(IMatcherFactory factory, boolean upgradedStateUsed, boolean disappearedStateUsed) { - AbstractRule rule = ruleFactory. - createRule(iqEngine, factory, upgradedStateUsed, disappearedStateUsed); - rule.addActivationNotificationListener(activationListener, true); - rules.add(rule); - return rule; - } - - @Override + @Override + public > IRule createRule( + IMatcherFactory factory) { + return createRule(factory, false, false); + } + + @Override + public > IRule createRule( + IMatcherFactory factory, boolean upgradedStateUsed, boolean disappearedStateUsed) { + AbstractRule rule = ruleFactory.createRule(iqEngine, factory, upgradedStateUsed, disappearedStateUsed); + rule.addActivationNotificationListener(activationListener, true); + rules.add(rule); + return rule; + } + + @Override public void removeRule(AbstractRule rule) { - if (rules.contains(rule)) { - rule.removeActivationNotificationListener(activationListener); - rule.dispose(); - rules.remove(rule); - } - } - - @Override + if (rules.contains(rule)) { + rule.removeActivationNotificationListener(activationListener); + rule.dispose(); + rules.remove(rule); + } + } + + @Override public Collection> getRules() { - return rules; - } + return rules; + } - @Override + @Override public void dispose() { - if(updateCompleteProvider != null) { - updateCompleteProvider.dispose(); - } - for (IRule rule : rules) { - rule.dispose(); - } - } - - @Override + if (updateCompleteProvider != null) { + updateCompleteProvider.dispose(); + } + for (IRule rule : rules) { + rule.dispose(); + } + } + + @Override public Logger getLogger() { - return iqEngine.getLogger(); - } + return iqEngine.getLogger(); + } - @Override + @Override public Collection> getActivations() { - return Collections.unmodifiableCollection(activations); - } - - /** + return Collections.unmodifiableCollection(activations); + } + + /** * @return the updateCompleteProvider */ public IUpdateCompleteProvider getUpdateCompleteProvider() { @@ -220,27 +223,28 @@ public IUpdateCompleteProvider getUpdateCompleteProvider() { } /** - * @param updateCompleteProvider the updateCompleteProvider to set + * @param updateCompleteProvider + * the updateCompleteProvider to set */ public void setUpdateCompleteProvider(IUpdateCompleteProvider updateCompleteProvider) { this.updateCompleteProvider = updateCompleteProvider; } - @Override + @Override public ActivationMonitor newActivationMonitor(boolean fillAtStart) { - ActivationMonitor monitor = new ActivationMonitor(); - if (fillAtStart) { - for (Activation activation : activations) { - monitor.addActivation(activation); - } - } - monitors.add(monitor); - return monitor; - } + ActivationMonitor monitor = new ActivationMonitor(); + if (fillAtStart) { + for (Activation activation : activations) { + monitor.addActivation(activation); + } + } + monitors.add(monitor); + return monitor; + } @Override public boolean addUpdateCompleteListener(IUpdateCompleteListener listener, boolean fireNow) { - if(updateCompleteProvider != null) { + if (updateCompleteProvider != null) { return updateCompleteProvider.addUpdateCompleteListener(listener, fireNow); } else { return false; @@ -249,7 +253,7 @@ public boolean addUpdateCompleteListener(IUpdateCompleteListener listener, boole @Override public boolean removeUpdateCompleteListener(IUpdateCompleteListener listener) { - if(updateCompleteProvider != null) { + if (updateCompleteProvider != null) { return updateCompleteProvider.removeUpdateCompleteListener(listener); } else { return false; @@ -265,5 +269,5 @@ public boolean addActivationNotificationListener(IActivationNotificationListener public boolean removeActivationNotificationListener(IActivationNotificationListener listener) { return activationProvider.removeActivationNotificationListener(listener); } - + } diff --git a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/IAgenda.java b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/IAgenda.java index e57a3c55..02f623c7 100644 --- a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/IAgenda.java +++ b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/IAgenda.java @@ -23,20 +23,20 @@ /** * @author Abel Hegedus - * + * */ -public interface IAgenda extends IUpdateCompleteProvider, IActivationNotificationProvider{ +public interface IAgenda extends IUpdateCompleteProvider, IActivationNotificationProvider { /** - * Returns the {@link Notifier} instance associated to the Agenda. + * Returns the {@link Notifier} instance associated to the Agenda. * * @return the {@link Notifier} instance */ Notifier getNotifier(); /** - * Returns the {@link TransactionalEditingDomain} for the underlying {@link Notifier} - * (associated to the Agenda) if it is available. + * Returns the {@link TransactionalEditingDomain} for the underlying {@link Notifier} (associated to the Agenda) if + * it is available. * * @return the {@link TransactionalEditingDomain} instance or null if it is not available */ @@ -48,11 +48,11 @@ public interface IAgenda extends IUpdateCompleteProvider, IActivationNotificatio boolean isAllowMultipleFiring(); /** - * Creates a new rule with the specified {@link IRuleFactory}. - * The upgraded and disappeared states will not be used in the - * lifecycle of rule's activations. + * Creates a new rule with the specified {@link IRuleFactory}. The upgraded and disappeared states will not be used + * in the lifecycle of rule's activations. * - * @param factory the {@link IMatcherFactory} of the {@link IncQueryMatcher} + * @param factory + * the {@link IMatcherFactory} of the {@link IncQueryMatcher} * @return the {@link AbstractRule} instance */ > IRule createRule( @@ -61,30 +61,34 @@ > IRule> IRule createRule( IMatcherFactory factory, boolean upgradedStateUsed, boolean disappearedStateUsed); /** - * Removes a rule from the Agenda. + * Removes a rule from the Agenda. * - * @param rule the rule to remove + * @param rule + * the rule to remove */ void removeRule(AbstractRule rule); /** - * Returns the rules that were created in this Agenda instance. + * Returns the rules that were created in this Agenda instance. * * @return the collection of rules */ Collection> getRules(); /** - * Call this method to properly dispose the Agenda. + * Call this method to properly dispose the Agenda. */ void dispose(); diff --git a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/IRule.java b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/IRule.java index a8b3fb76..20be487c 100644 --- a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/IRule.java +++ b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/IRule.java @@ -20,21 +20,23 @@ /** * Basic interface for rules, for the default implementation, see {@link AbstractRule}. * - *

    The interface allows acces to the precondition pattern, the corresponding agenda - * and the unmodifiable list of activations. - * - *

    The {@link #setStateChangeProcessor(ActivationState, IMatchProcessor)} method allows - * the registration of processors that will be invoked when an activation changes states. - * - *

    The {@link #getStateChangeProcessor(ActivationState)} method returns a registered processor - * for a given state. + *

    + * The interface allows acces to the precondition pattern, the corresponding agenda and the unmodifiable list of + * activations. + * + *

    + * The {@link #setStateChangeProcessor(ActivationState, IMatchProcessor)} method allows the registration of processors + * that will be invoked when an activation changes states. + * + *

    + * The {@link #getStateChangeProcessor(ActivationState)} method returns a registered processor for a given state. * * * @author Abel Hegedus - * + * * @param */ -public interface IRule extends IActivationNotificationProvider{ +public interface IRule extends IActivationNotificationProvider { /** * Returns the precondition pattern defined for the rule. @@ -56,21 +58,23 @@ public interface IRule extends IActivationNotif * @return the list of activations */ List> getActivations(); - + /** - * Registers a processor for the given state. The processor will be invoked, if an activation - * that is in the given state is fired. + * Registers a processor for the given state. The processor will be invoked, if an activation that is in the given + * state is fired. * - * @param newState the state where the processor is used - * @param processor the processor to use in the given state + * @param newState + * the state where the processor is used + * @param processor + * the processor to use in the given state */ void setStateChangeProcessor(ActivationState newState, IMatchProcessor processor); - + /** - * Returns the processor registered for the given state. If no processor is registered, it returns - * null instead. + * Returns the processor registered for the given state. If no processor is registered, it returns null instead. * - * @param newState the state for which the processor is requested + * @param newState + * the state for which the processor is requested * @return the processor, if set, null otherwise */ IMatchProcessor getStateChangeProcessor(ActivationState newState); @@ -79,6 +83,5 @@ public interface IRule extends IActivationNotif * This method is called when the rule is no longer managed by the agenda */ void dispose(); - } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/IRuleFactory.java b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/IRuleFactory.java index 91df590c..b7e5518f 100644 --- a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/IRuleFactory.java +++ b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/IRuleFactory.java @@ -9,14 +9,12 @@ * The {@link IRuleFactory} defines the way a {@link AbstractRule} instance is created. * * @author Tamas Szabo - * + * */ public interface IRuleFactory { - public > - AbstractRule createRule(IncQueryEngine engine, - IMatcherFactory factory, - boolean upgradedStateUsed, - boolean disappearedStateUsed); - + public > AbstractRule createRule( + IncQueryEngine engine, IMatcherFactory factory, boolean upgradedStateUsed, + boolean disappearedStateUsed); + } diff --git a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/RuleEngine.java b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/RuleEngine.java index ddd45697..ff4df86b 100644 --- a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/RuleEngine.java +++ b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/api/RuleEngine.java @@ -11,73 +11,71 @@ import org.eclipse.incquery.runtime.triggerengine.specific.DefaultRuleFactory; /** - * The AbstractRule engine extends the functionality of EMF-IncQuery by - * providing the basic facilities to create transformation rules. - * A transformation rule consists of the precondition being an EMF-IncQuery pattern - * and the postcondition defined as a portion of an arbitrary Java code. + * The AbstractRule engine extends the functionality of EMF-IncQuery by providing the basic facilities to create + * transformation rules. A transformation rule consists of the precondition being an EMF-IncQuery pattern and the + * postcondition defined as a portion of an arbitrary Java code. * - *

    This class can be used to instantiate and lookup Agendas for a specific - * {@link Notifier} or {@link IncQueryEngine} instance. The Agenda acts as - * an up-to-date collection of the fireable rule activations (similar to the - * term known from the context of rule based expert systems). + *

    + * This class can be used to instantiate and lookup Agendas for a specific {@link Notifier} or {@link IncQueryEngine} + * instance. The Agenda acts as an up-to-date collection of the fireable rule activations (similar to the term known + * from the context of rule based expert systems). * * @author Tamas Szabo - * + * */ public class RuleEngine { - private static RuleEngine instance; - private Map> agendaMap; - private IRuleFactory defaultRuleFactory; - - public static synchronized RuleEngine getInstance() { - if (instance == null) { - instance = new RuleEngine(); - } - return instance; - } - - protected RuleEngine() { - this.agendaMap = new WeakHashMap>(); - this.defaultRuleFactory = new DefaultRuleFactory(); - } - - public IAgenda getOrCreateAgenda(Notifier notifier) { - return getOrCreateAgenda(notifier, false); - } - - public IAgenda getOrCreateAgenda(Notifier notifier, boolean allowMultipleFiring) { - IncQueryEngine engine; - try { - engine = EngineManager.getInstance().getIncQueryEngine(notifier); - return getOrCreateAgenda(engine, allowMultipleFiring); - } catch (IncQueryException e) { - return null; - } - } - - public IAgenda getOrCreateAgenda(IncQueryEngine engine) { - return getOrCreateAgenda(engine, false); - } - - public IAgenda getOrCreateAgenda(IncQueryEngine engine, boolean allowMultipleFiring) { - IAgenda agenda = getAgenda(engine); - if (agenda == null) { - Agenda newAgenda = new Agenda(engine, allowMultipleFiring); - newAgenda.setRuleFactory(defaultRuleFactory); - agenda = newAgenda; - agendaMap.put(engine, new WeakReference(agenda)); - } - return agenda; - } - - private IAgenda getAgenda(IncQueryEngine iqEngine) { - WeakReference agendaRef = agendaMap.get(iqEngine); - if (agendaRef != null) { - return agendaRef.get(); - } - else { - return null; - } - } + private static RuleEngine instance; + private Map> agendaMap; + private IRuleFactory defaultRuleFactory; + + public static synchronized RuleEngine getInstance() { + if (instance == null) { + instance = new RuleEngine(); + } + return instance; + } + + protected RuleEngine() { + this.agendaMap = new WeakHashMap>(); + this.defaultRuleFactory = new DefaultRuleFactory(); + } + + public IAgenda getOrCreateAgenda(Notifier notifier) { + return getOrCreateAgenda(notifier, false); + } + + public IAgenda getOrCreateAgenda(Notifier notifier, boolean allowMultipleFiring) { + IncQueryEngine engine; + try { + engine = EngineManager.getInstance().getIncQueryEngine(notifier); + return getOrCreateAgenda(engine, allowMultipleFiring); + } catch (IncQueryException e) { + return null; + } + } + + public IAgenda getOrCreateAgenda(IncQueryEngine engine) { + return getOrCreateAgenda(engine, false); + } + + public IAgenda getOrCreateAgenda(IncQueryEngine engine, boolean allowMultipleFiring) { + IAgenda agenda = getAgenda(engine); + if (agenda == null) { + Agenda newAgenda = new Agenda(engine, allowMultipleFiring); + newAgenda.setRuleFactory(defaultRuleFactory); + agenda = newAgenda; + agendaMap.put(engine, new WeakReference(agenda)); + } + return agenda; + } + + private IAgenda getAgenda(IncQueryEngine iqEngine) { + WeakReference agendaRef = agendaMap.get(iqEngine); + if (agendaRef != null) { + return agendaRef.get(); + } else { + return null; + } + } } diff --git a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/Action.java b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/Action.java index 37ca43e1..516b43d6 100644 --- a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/Action.java +++ b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/Action.java @@ -5,16 +5,16 @@ public class Action extends RecordingCommand { - private Runnable task; + private Runnable task; - public Action(TransactionalEditingDomain domain, Runnable task) { - super(domain); - this.task = task; - } + public Action(TransactionalEditingDomain domain, Runnable task) { + super(domain); + this.task = task; + } - @Override - protected void doExecute() { - task.run(); - } + @Override + protected void doExecute() { + task.run(); + } } diff --git a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/AutomaticFiringStrategy.java b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/AutomaticFiringStrategy.java index 5b9c6963..d26684d3 100644 --- a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/AutomaticFiringStrategy.java +++ b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/AutomaticFiringStrategy.java @@ -5,30 +5,28 @@ import org.eclipse.incquery.runtime.triggerengine.api.ActivationMonitor; /** - * This class automatically fires the applicable activations - * which are present in the given {@link ActivationMonitor}. - * It is used by the Validation Framework to automatically - * create/update/remove problem markers when it is needed. + * This class automatically fires the applicable activations which are present in the given {@link ActivationMonitor}. + * It is used by the Validation Framework to automatically create/update/remove problem markers when it is needed. * * @author Tamas Szabo - * + * */ public class AutomaticFiringStrategy implements IUpdateCompleteListener { private final ActivationMonitor monitor; - + public AutomaticFiringStrategy(ActivationMonitor monitor) { this.monitor = monitor; } @Override public void updateComplete() { - if(monitor != null) { + if (monitor != null) { for (Activation a : monitor.getActivations()) { a.fire(); } monitor.clear(); } } - + } diff --git a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/IQBaseCallbackUpdateCompleteProvider.java b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/IQBaseCallbackUpdateCompleteProvider.java index 78a01824..756c288d 100644 --- a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/IQBaseCallbackUpdateCompleteProvider.java +++ b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/IQBaseCallbackUpdateCompleteProvider.java @@ -14,7 +14,7 @@ /** * @author Abel Hegedus - * + * */ public class IQBaseCallbackUpdateCompleteProvider extends UpdateCompleteProvider { diff --git a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/IUpdateCompleteListener.java b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/IUpdateCompleteListener.java index 287daf59..4be8e861 100644 --- a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/IUpdateCompleteListener.java +++ b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/IUpdateCompleteListener.java @@ -12,10 +12,10 @@ /** * @author Abel Hegedus - * + * */ public interface IUpdateCompleteListener { void updateComplete(); - + } diff --git a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/IUpdateCompleteProvider.java b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/IUpdateCompleteProvider.java index a52c617b..3ac7bde7 100644 --- a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/IUpdateCompleteProvider.java +++ b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/IUpdateCompleteProvider.java @@ -14,27 +14,30 @@ /** * @author Abel Hegedus - * + * */ public interface IUpdateCompleteProvider { - /** - * Registers an {@link IUpdateCompleteListener} to receive notification on completed updates. + /** + * Registers an {@link IUpdateCompleteListener} to receive notification on completed updates. + * + *

    + * The listener can be unregistered via {@link #removeUpdateCompleteListener(IUpdateCompleteListener)}. + * + * @param fireNow + * if true, listener will be immediately invoked without waiting for the next update * - *

    The listener can be unregistered via - * {@link #removeUpdateCompleteListener(IUpdateCompleteListener)}. - * - * @param fireNow if true, listener will be immediately invoked without waiting for the next update - * - * @param listener the listener that will be notified of each completed update + * @param listener + * the listener that will be notified of each completed update */ boolean addUpdateCompleteListener(IUpdateCompleteListener listener, boolean fireNow); /** - * Unregisters a listener registered by + * Unregisters a listener registered by * {@link #addActivationNotificationListener(IActivationNotificationListener, boolean)}. * - * @param listener the listener that will no longer be notified. + * @param listener + * the listener that will no longer be notified. */ boolean removeUpdateCompleteListener(IUpdateCompleteListener listener); diff --git a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/TimedFiringStrategy.java b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/TimedFiringStrategy.java index c3f924ad..fb467f2c 100644 --- a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/TimedFiringStrategy.java +++ b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/TimedFiringStrategy.java @@ -5,55 +5,52 @@ import org.eclipse.incquery.runtime.triggerengine.api.ActivationMonitor; /** - * A timed firing strategy is similar to the {@link AutomaticFiringStrategy} - * as it also fires all the applicable activations but it does so in a - * periodic manner. One must define the interval between two consecutive - * firings. + * A timed firing strategy is similar to the {@link AutomaticFiringStrategy} as it also fires all the applicable + * activations but it does so in a periodic manner. One must define the interval between two consecutive firings. * * @author Tamas Szabo - * + * */ public class TimedFiringStrategy { - private long interval; - private volatile boolean interrupted = false; - private ActivationMonitor monitor; - private FiringThread firingThread; - - public TimedFiringStrategy(ActivationMonitor monitor, long interval) { - this.interval = interval; - this.monitor = monitor; - this.firingThread = new FiringThread(); - } - - public void start() { - this.firingThread.start(); - } - - private class FiringThread extends Thread { - - public FiringThread() { - this.setName("TimedFiringStrategy [interval: "+interval+"]"); - } - - @Override - public void run() { - while (!interrupted) { - for (Activation a : monitor.getActivations()) { - a.fire(); - } - monitor.clear(); - try { - Thread.sleep(interval); - } - catch (InterruptedException e) { - //e.printStackTrace(); - } - } - } - } - - public void dispose() { - interrupted = true; - } + private long interval; + private volatile boolean interrupted = false; + private ActivationMonitor monitor; + private FiringThread firingThread; + + public TimedFiringStrategy(ActivationMonitor monitor, long interval) { + this.interval = interval; + this.monitor = monitor; + this.firingThread = new FiringThread(); + } + + public void start() { + this.firingThread.start(); + } + + private class FiringThread extends Thread { + + public FiringThread() { + this.setName("TimedFiringStrategy [interval: " + interval + "]"); + } + + @Override + public void run() { + while (!interrupted) { + for (Activation a : monitor.getActivations()) { + a.fire(); + } + monitor.clear(); + try { + Thread.sleep(interval); + } catch (InterruptedException e) { + // e.printStackTrace(); + } + } + } + } + + public void dispose() { + interrupted = true; + } } diff --git a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/TransactionUpdateCompleteProvider.java b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/TransactionUpdateCompleteProvider.java index ca6a6fd4..897e2f2e 100644 --- a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/TransactionUpdateCompleteProvider.java +++ b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/TransactionUpdateCompleteProvider.java @@ -19,7 +19,7 @@ /** * @author Abel Hegedus - * + * */ public class TransactionUpdateCompleteProvider extends UpdateCompleteProvider { private TransactionListener transactionListener; @@ -36,24 +36,29 @@ public TransactionUpdateCompleteProvider(TransactionalEditingDomain editingDomai private class TransactionListener implements TransactionalEditingDomainListener { @Override - public void transactionStarting(TransactionalEditingDomainEvent event) {} + public void transactionStarting(TransactionalEditingDomainEvent event) { + } @Override - public void transactionInterrupted(TransactionalEditingDomainEvent event) {} + public void transactionInterrupted(TransactionalEditingDomainEvent event) { + } @Override - public void transactionStarted(TransactionalEditingDomainEvent event) {} + public void transactionStarted(TransactionalEditingDomainEvent event) { + } @Override - public void transactionClosing(TransactionalEditingDomainEvent event) {} + public void transactionClosing(TransactionalEditingDomainEvent event) { + } @Override public void transactionClosed(TransactionalEditingDomainEvent event) { boolean needsNotification = true; - /*Omit notifications about the executions of the assigned jobs in the RecordingActivation - Applying a rule in the IRule Engine will result the job to be executed under an - EMFOperationTransaction transaction*/ + /* + * Omit notifications about the executions of the assigned jobs in the RecordingActivation Applying a rule + * in the IRule Engine will result the job to be executed under an EMFOperationTransaction transaction + */ if (event.getTransaction() instanceof EMFOperationTransaction) { EMFOperationTransaction transaction = (EMFOperationTransaction) event.getTransaction(); // FIXME this is a really ugly hack! @@ -68,7 +73,8 @@ public void transactionClosed(TransactionalEditingDomainEvent event) { } @Override - public void editingDomainDisposing(TransactionalEditingDomainEvent event) {} + public void editingDomainDisposing(TransactionalEditingDomainEvent event) { + } } @Override diff --git a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/UpdateCompleteProvider.java b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/UpdateCompleteProvider.java index c77eaed8..2e70ec59 100644 --- a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/UpdateCompleteProvider.java +++ b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/firing/UpdateCompleteProvider.java @@ -15,30 +15,30 @@ /** * @author Abel Hegedus - * + * */ public abstract class UpdateCompleteProvider implements IUpdateCompleteProvider { private final Set listeners; - + public UpdateCompleteProvider() { listeners = new HashSet(); } - + @Override public boolean addUpdateCompleteListener(IUpdateCompleteListener listener, boolean fireNow) { boolean added = listeners.add(listener); - if(added) { + if (added) { listener.updateComplete(); } return added; } - + @Override public boolean removeUpdateCompleteListener(IUpdateCompleteListener listener) { return this.listeners.remove(listener); } - + protected void updateCompleted() { for (IUpdateCompleteListener listener : this.listeners) { listener.updateComplete(); @@ -49,5 +49,5 @@ protected void updateCompleted() { public void dispose() { listeners.clear(); } - + } diff --git a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/notification/ActivationNotificationProvider.java b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/notification/ActivationNotificationProvider.java index bbaa333d..58144840 100644 --- a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/notification/ActivationNotificationProvider.java +++ b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/notification/ActivationNotificationProvider.java @@ -7,45 +7,45 @@ import org.eclipse.incquery.runtime.triggerengine.api.Activation; /** - * Classes implement this interface to provide notifications about the changes in the - * collection of activations within the AbstractRule Engine. + * Classes implement this interface to provide notifications about the changes in the collection of activations within + * the AbstractRule Engine. * * @author Tamas Szabo - * + * */ public abstract class ActivationNotificationProvider implements IActivationNotificationProvider { - - protected Set activationNotificationListeners; - - public ActivationNotificationProvider() { - this.activationNotificationListeners = new HashSet(); - } - - @Override + + protected Set activationNotificationListeners; + + public ActivationNotificationProvider() { + this.activationNotificationListeners = new HashSet(); + } + + @Override public boolean addActivationNotificationListener(IActivationNotificationListener listener, boolean fireNow) { - boolean notContained = this.activationNotificationListeners.add(listener); + boolean notContained = this.activationNotificationListeners.add(listener); if (notContained) { listenerAdded(listener, fireNow); } return notContained; - } - - protected abstract void listenerAdded(IActivationNotificationListener listener, boolean fireNow); + } + + protected abstract void listenerAdded(IActivationNotificationListener listener, boolean fireNow); - @Override + @Override public boolean removeActivationNotificationListener(IActivationNotificationListener listener) { - return this.activationNotificationListeners.remove(listener); - } - - public void notifyActivationAppearance(Activation activation) { - for (IActivationNotificationListener listener : this.activationNotificationListeners) { - listener.activationAppeared(activation); - } - } - - public void notifyActivationDisappearance(Activation activation) { - for (IActivationNotificationListener listener : this.activationNotificationListeners) { - listener.activationDisappeared(activation); - } - } + return this.activationNotificationListeners.remove(listener); + } + + public void notifyActivationAppearance(Activation activation) { + for (IActivationNotificationListener listener : this.activationNotificationListeners) { + listener.activationAppeared(activation); + } + } + + public void notifyActivationDisappearance(Activation activation) { + for (IActivationNotificationListener listener : this.activationNotificationListeners) { + listener.activationDisappeared(activation); + } + } } diff --git a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/notification/AttributeMonitor.java b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/notification/AttributeMonitor.java index f58a5cda..ffff0f1a 100644 --- a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/notification/AttributeMonitor.java +++ b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/notification/AttributeMonitor.java @@ -6,42 +6,41 @@ import org.eclipse.incquery.runtime.api.IPatternMatch; /** - * The class defines the operations that are required to observ - * the EMF attribute changes on pattern match objects. + * The class defines the operations that are required to observ the EMF attribute changes on pattern match objects. * * @author Tamas Szabo - * + * * @param */ public abstract class AttributeMonitor { - private List> listeners; - - public AttributeMonitor() { - this.listeners = new ArrayList>(); - } - - public void addCallbackOnMatchUpdate(IAttributeMonitorListener listener) { - this.listeners.add(listener); - } - - public void removeCallbackOnMatchUpdate(IAttributeMonitorListener listener) { - this.listeners.remove(listener); - } - - public abstract void registerFor(MatchType match); - - public abstract void unregisterForAll(); - - public abstract void unregisterFor(MatchType match); - - protected void notifyListeners(MatchType match) { - for (IAttributeMonitorListener listener : listeners) { - listener.notifyUpdate(match); - } - } - - public void dispose() { - this.unregisterForAll(); - } + private List> listeners; + + public AttributeMonitor() { + this.listeners = new ArrayList>(); + } + + public void addCallbackOnMatchUpdate(IAttributeMonitorListener listener) { + this.listeners.add(listener); + } + + public void removeCallbackOnMatchUpdate(IAttributeMonitorListener listener) { + this.listeners.remove(listener); + } + + public abstract void registerFor(MatchType match); + + public abstract void unregisterForAll(); + + public abstract void unregisterFor(MatchType match); + + protected void notifyListeners(MatchType match) { + for (IAttributeMonitorListener listener : listeners) { + listener.notifyUpdate(match); + } + } + + public void dispose() { + this.unregisterForAll(); + } } diff --git a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/notification/IActivationNotificationListener.java b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/notification/IActivationNotificationListener.java index af1f3c22..c581252c 100644 --- a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/notification/IActivationNotificationListener.java +++ b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/notification/IActivationNotificationListener.java @@ -4,19 +4,18 @@ import org.eclipse.incquery.runtime.triggerengine.api.Activation; /** - * The interface is used to observe the changes in the collection of activations. - *

    - * An implementing class is for example the {@link Agenda} - * which is called back by the {@link AbstractRule} instances when - * those have updated the activations after an EMF operation. + * The interface is used to observe the changes in the collection of activations.
    + *
    + * An implementing class is for example the {@link Agenda} which is called back by the {@link AbstractRule} instances + * when those have updated the activations after an EMF operation. * * @author Tamas Szabo - * + * */ public interface IActivationNotificationListener { - public void activationAppeared(Activation activation); - - public void activationDisappeared(Activation activation); - + public void activationAppeared(Activation activation); + + public void activationDisappeared(Activation activation); + } diff --git a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/notification/IActivationNotificationProvider.java b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/notification/IActivationNotificationProvider.java index 67d51977..e5c17212 100644 --- a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/notification/IActivationNotificationProvider.java +++ b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/notification/IActivationNotificationProvider.java @@ -12,29 +12,33 @@ /** * @author Abel Hegedus - * + * */ public interface IActivationNotificationProvider { - /** - * Registers an {@link IActivationNotificationListener} to receive updates on activation - * appearance and disappearance. + /** + * Registers an {@link IActivationNotificationListener} to receive updates on activation appearance and + * disappearance. * - *

    The listener can be unregistered via + *

    + * The listener can be unregistered via * {@link #removeActivationNotificationListener(IActivationNotificationListener)}. - * - * @param fireNow if true, listener will be immediately invoked on all current activations as a one-time effect. - * - * @param listener the listener that will be notified of each new activation that appears or disappears, - * starting from now. + * + * @param fireNow + * if true, listener will be immediately invoked on all current activations as a one-time effect. + * + * @param listener + * the listener that will be notified of each new activation that appears or disappears, starting from + * now. */ boolean addActivationNotificationListener(IActivationNotificationListener listener, boolean fireNow); /** - * Unregisters a listener registered by + * Unregisters a listener registered by * {@link #addActivationNotificationListener(IActivationNotificationListener, boolean)}. * - * @param listener the listener that will no longer be notified. + * @param listener + * the listener that will no longer be notified. */ boolean removeActivationNotificationListener(IActivationNotificationListener listener); diff --git a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/notification/IAttributeMonitorListener.java b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/notification/IAttributeMonitorListener.java index 76b38d94..947ba278 100644 --- a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/notification/IAttributeMonitorListener.java +++ b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/notification/IAttributeMonitorListener.java @@ -3,15 +3,15 @@ import org.eclipse.incquery.runtime.api.IPatternMatch; /** - * The interface exposes the {@link #notifyUpdate(IPatternMatch)} method - * to receive notifications when the attributes of the match objects have changed. + * The interface exposes the {@link #notifyUpdate(IPatternMatch)} method to receive notifications when the attributes of + * the match objects have changed. * * @author Tamas Szabo - * + * * @param */ public interface IAttributeMonitorListener { - public void notifyUpdate(MatchType match); - + public void notifyUpdate(MatchType match); + } diff --git a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/qrm/TriggeredQueryResultMultimap.java b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/qrm/TriggeredQueryResultMultimap.java index a76d1a53..33eb2398 100644 --- a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/qrm/TriggeredQueryResultMultimap.java +++ b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/qrm/TriggeredQueryResultMultimap.java @@ -25,25 +25,26 @@ /** * @author Abel Hegedus - * + * */ -public abstract class TriggeredQueryResultMultimap extends QueryResultMultimap { +public abstract class TriggeredQueryResultMultimap extends + QueryResultMultimap { private IMatchProcessor appearanceProcessor; private IMatchProcessor disappearanceProcessor; private IAgenda agenda; - + /** * @param agenda */ protected TriggeredQueryResultMultimap(IAgenda agenda) { super(agenda.getLogger()); this.agenda = agenda; - + AutomaticFiringStrategy firingStrategy = new AutomaticFiringStrategy(agenda.newActivationMonitor(true)); agenda.addUpdateCompleteListener(firingStrategy, true); - + appearanceProcessor = new IMatchProcessor() { @Override public void process(MatchType match) { @@ -52,7 +53,7 @@ public void process(MatchType match) { internalPut(key, value); } }; - + disappearanceProcessor = new IMatchProcessor() { @Override public void process(MatchType match) { @@ -62,25 +63,26 @@ public void process(MatchType match) { } }; } - + protected TriggeredQueryResultMultimap(IncQueryEngine engine) { this(RuleEngine.getInstance().getOrCreateAgenda(engine)); } - + protected TriggeredQueryResultMultimap(Notifier notifier) { this(RuleEngine.getInstance().getOrCreateAgenda(notifier)); } - - public > void addMatcherToMultimapResults(IMatcherFactory factory) { + + public > void addMatcherToMultimapResults( + IMatcherFactory factory) { IRule newRule = agenda.createRule(factory, false, true); - if(newRule != null) { + if (newRule != null) { newRule.setStateChangeProcessor(ActivationState.APPEARED, appearanceProcessor); newRule.setStateChangeProcessor(ActivationState.DISAPPEARED, disappearanceProcessor); } } - protected abstract KeyType getKeyFromMatch(MatchType match); - + protected abstract KeyType getKeyFromMatch(MatchType match); + protected abstract ValueType getValueFromMatch(MatchType match); - + } diff --git a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/specific/DefaultAttributeMonitor.java b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/specific/DefaultAttributeMonitor.java index 14dc659a..75b52a07 100644 --- a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/specific/DefaultAttributeMonitor.java +++ b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/specific/DefaultAttributeMonitor.java @@ -16,71 +16,71 @@ public class DefaultAttributeMonitor extends AttributeMonitor { - private ChangeListener changeListener; - private Map observableMap; - private Map> observableMapReversed; - - public DefaultAttributeMonitor() { - super(); - this.changeListener = new ChangeListener(); - this.observableMap = new HashMap(); - this.observableMapReversed = new HashMap>(); - } - - private class ChangeListener implements IValueChangeListener { - @Override - public void handleValueChange(ValueChangeEvent event) { - IObservableValue val = event.getObservableValue(); - if (val != null) { - notifyListeners(observableMap.get(val)); - } - } - } - - @Override - public void registerFor(MatchType match) { - List values = new ArrayList(); - for (String param : match.parameterNames()) { - Object location = match.get(param); - List observableValues = observeAllAttributes(changeListener, location); - values.addAll(observableValues); - } + private ChangeListener changeListener; + private Map observableMap; + private Map> observableMapReversed; - //inserting {observable,match} pairs - for (IObservableValue val : values) { - observableMap.put(val, match); - } + public DefaultAttributeMonitor() { + super(); + this.changeListener = new ChangeListener(); + this.observableMap = new HashMap(); + this.observableMapReversed = new HashMap>(); + } - //inserting {match, list(observable)} pairs - observableMapReversed.put(match, values); - } + private class ChangeListener implements IValueChangeListener { + @Override + public void handleValueChange(ValueChangeEvent event) { + IObservableValue val = event.getObservableValue(); + if (val != null) { + notifyListeners(observableMap.get(val)); + } + } + } - private List observeAllAttributes(IValueChangeListener changeListener, Object object) { - List affectedValues = new ArrayList(); - if (object instanceof EObject) { - for (EStructuralFeature feature : ((EObject) object).eClass().getEAllStructuralFeatures()) { - IObservableValue val = EMFProperties.value(feature).observe(object); - affectedValues.add(val); - val.addValueChangeListener(changeListener); - } - } - return affectedValues; - } - - @Override - public void unregisterForAll() { - for (MatchType match : observableMapReversed.keySet()) { - unregisterFor(match); - } - } - - @Override - public void unregisterFor(MatchType match) { - List observables = observableMapReversed.get(match); - if (observables != null) { - for (IObservableValue val : observables) { - val.removeValueChangeListener(changeListener); - } - } - } + @Override + public void registerFor(MatchType match) { + List values = new ArrayList(); + for (String param : match.parameterNames()) { + Object location = match.get(param); + List observableValues = observeAllAttributes(changeListener, location); + values.addAll(observableValues); + } + + // inserting {observable,match} pairs + for (IObservableValue val : values) { + observableMap.put(val, match); + } + + // inserting {match, list(observable)} pairs + observableMapReversed.put(match, values); + } + + private List observeAllAttributes(IValueChangeListener changeListener, Object object) { + List affectedValues = new ArrayList(); + if (object instanceof EObject) { + for (EStructuralFeature feature : ((EObject) object).eClass().getEAllStructuralFeatures()) { + IObservableValue val = EMFProperties.value(feature).observe(object); + affectedValues.add(val); + val.addValueChangeListener(changeListener); + } + } + return affectedValues; + } + + @Override + public void unregisterForAll() { + for (MatchType match : observableMapReversed.keySet()) { + unregisterFor(match); + } + } + + @Override + public void unregisterFor(MatchType match) { + List observables = observableMapReversed.get(match); + if (observables != null) { + for (IObservableValue val : observables) { + val.removeValueChangeListener(changeListener); + } + } + } } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/specific/DefaultRuleFactory.java b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/specific/DefaultRuleFactory.java index 41884c28..e56f7598 100644 --- a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/specific/DefaultRuleFactory.java +++ b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/specific/DefaultRuleFactory.java @@ -11,23 +11,19 @@ public class DefaultRuleFactory implements IRuleFactory { - @Override - public > AbstractRule createRule( - IncQueryEngine engine, - IMatcherFactory factory, - boolean upgradedStateUsed, - boolean disappearedStateUsed) { - - AbstractRule rule = null; - try { - rule = new RecordingRule(RuleEngine.getInstance().getOrCreateAgenda(engine), - factory.getMatcher(engine), - upgradedStateUsed, - disappearedStateUsed); - } catch (IncQueryException e) { - engine.getLogger().error("Error while creating RecordingRule!", e); - } - return rule; - } + @Override + public > AbstractRule createRule( + IncQueryEngine engine, IMatcherFactory factory, boolean upgradedStateUsed, + boolean disappearedStateUsed) { + + AbstractRule rule = null; + try { + rule = new RecordingRule(RuleEngine.getInstance().getOrCreateAgenda(engine), + factory.getMatcher(engine), upgradedStateUsed, disappearedStateUsed); + } catch (IncQueryException e) { + engine.getLogger().error("Error while creating RecordingRule!", e); + } + return rule; + } } diff --git a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/specific/RecordingActivation.java b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/specific/RecordingActivation.java index ce155e85..08a5edf3 100644 --- a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/specific/RecordingActivation.java +++ b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/specific/RecordingActivation.java @@ -7,64 +7,62 @@ public class RecordingActivation extends Activation { - private RecordingRule rule; - - public RecordingActivation(RecordingRule rule, MatchType patternMatch) { - super(rule, patternMatch); - this.rule = rule; - } + private RecordingRule rule; - //Overridden because of DSE purposes - @SuppressWarnings("unchecked") - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - else if (obj == null || this.getClass() != obj.getClass()) { - return false; - } - - RecordingActivation oA = (RecordingActivation) obj; - if (oA.patternMatch.equals(this.patternMatch) && oA.rule.equals(this.rule)) { - return true; - } - else { - return false; - } - } + public RecordingActivation(RecordingRule rule, MatchType patternMatch) { + super(rule, patternMatch); + this.rule = rule; + } - @Override - public String toString() { - return "[AbstractRule: "+rule+"][Match: "+patternMatch+"][State: "+state+"][Fired: "+fired+"]"; - } + // Overridden because of DSE purposes + @SuppressWarnings("unchecked") + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } else if (obj == null || this.getClass() != obj.getClass()) { + return false; + } - /** - * Fires the activation and records the EMF model manipulations within a {@link RecordingCommand}. - * This way the model manipulations can be re- or undone. - * - * Note that, if the {@link RecordingRule} is not registered on a {@link TransactionalEditingDomain} - * then the model manipulation will not be recorded and null will be returned. - * - * @return the {@link RecordingCommand} which recorded the model manipulations during firing or null if recording was not possible - */ - public RecordingCommand fireWithRecording() { - TransactionalEditingDomain domain = this.rule.getEditingDomain(); - if (domain == null) { - fire(); - return null; - } - else { - final RecordingCommand command = new RecordingCommand(domain) { - @Override - protected void doExecute() { - fire(); - } - }; - command.setLabel("RecordingActivation"); - domain.getCommandStack().execute(command); - - return command; - } - } + RecordingActivation oA = (RecordingActivation) obj; + if (oA.patternMatch.equals(this.patternMatch) && oA.rule.equals(this.rule)) { + return true; + } else { + return false; + } + } + + @Override + public String toString() { + return "[AbstractRule: " + rule + "][Match: " + patternMatch + "][State: " + state + "][Fired: " + fired + "]"; + } + + /** + * Fires the activation and records the EMF model manipulations within a {@link RecordingCommand}. This way the + * model manipulations can be re- or undone. + * + * Note that, if the {@link RecordingRule} is not registered on a {@link TransactionalEditingDomain} then the model + * manipulation will not be recorded and null will be returned. + * + * @return the {@link RecordingCommand} which recorded the model manipulations during firing or null if recording + * was not possible + */ + public RecordingCommand fireWithRecording() { + TransactionalEditingDomain domain = this.rule.getEditingDomain(); + if (domain == null) { + fire(); + return null; + } else { + final RecordingCommand command = new RecordingCommand(domain) { + @Override + protected void doExecute() { + fire(); + } + }; + command.setLabel("RecordingActivation"); + domain.getCommandStack().execute(command); + + return command; + } + } } diff --git a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/specific/RecordingRule.java b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/specific/RecordingRule.java index d77b2814..2f9df963 100644 --- a/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/specific/RecordingRule.java +++ b/plugins/org.eclipse.incquery.runtime.triggerengine/src/org/eclipse/incquery/runtime/triggerengine/specific/RecordingRule.java @@ -1,6 +1,5 @@ package org.eclipse.incquery.runtime.triggerengine.specific; - import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.incquery.runtime.api.IPatternMatch; import org.eclipse.incquery.runtime.api.IncQueryMatcher; @@ -10,48 +9,47 @@ import org.eclipse.incquery.runtime.triggerengine.api.IAgenda; public class RecordingRule extends AbstractRule { - - public RecordingRule(IAgenda agenda, IncQueryMatcher matcher, - final boolean upgradedStateUsed, - final boolean disappearedStateUsed) { - super(agenda, matcher, upgradedStateUsed, disappearedStateUsed); - - this.attributeMonitor = new DefaultAttributeMonitor(); - this.matcher.addCallbackOnMatchUpdate(this, true); - this.attributeMonitor.addCallbackOnMatchUpdate(this); - } - - public RecordingRule(IAgenda agenda, IncQueryMatcher matcher) { - this(agenda, matcher, false, false); - } - - public TransactionalEditingDomain getEditingDomain() { - return this.agenda.getEditingDomain(); - } - - @Override - public void activationFired(Activation activation) { - if (activation.getState() == ActivationState.APPEARED && !disappearedStateUsed && !upgradedStateUsed) { - stateMap.get(ActivationState.APPEARED).remove(activation.getPatternMatch()); - } - if (activation.getState() == ActivationState.DISAPPEARED) { - attributeMonitor.unregisterFor(activation.getPatternMatch()); - stateMap.get(ActivationState.DISAPPEARED).remove(activation.getPatternMatch()); - } - } - - @Override - public void dispose() { - this.attributeMonitor.removeCallbackOnMatchUpdate(this); - this.attributeMonitor.dispose(); - this.matcher.removeCallbackOnMatchUpdate(this); - } + + public RecordingRule(IAgenda agenda, IncQueryMatcher matcher, final boolean upgradedStateUsed, + final boolean disappearedStateUsed) { + super(agenda, matcher, upgradedStateUsed, disappearedStateUsed); + + this.attributeMonitor = new DefaultAttributeMonitor(); + this.matcher.addCallbackOnMatchUpdate(this, true); + this.attributeMonitor.addCallbackOnMatchUpdate(this); + } + + public RecordingRule(IAgenda agenda, IncQueryMatcher matcher) { + this(agenda, matcher, false, false); + } + + public TransactionalEditingDomain getEditingDomain() { + return this.agenda.getEditingDomain(); + } + + @Override + public void activationFired(Activation activation) { + if (activation.getState() == ActivationState.APPEARED && !disappearedStateUsed && !upgradedStateUsed) { + stateMap.get(ActivationState.APPEARED).remove(activation.getPatternMatch()); + } + if (activation.getState() == ActivationState.DISAPPEARED) { + attributeMonitor.unregisterFor(activation.getPatternMatch()); + stateMap.get(ActivationState.DISAPPEARED).remove(activation.getPatternMatch()); + } + } + + @Override + public void dispose() { + this.attributeMonitor.removeCallbackOnMatchUpdate(this); + this.attributeMonitor.dispose(); + this.matcher.removeCallbackOnMatchUpdate(this); + } @Override protected Activation createActivation(MatchType match) { - Activation activation; - activation = new RecordingActivation(this, match); - activation.setState(ActivationState.APPEARED); - return activation; + Activation activation; + activation = new RecordingActivation(this, match); + activation.setState(ActivationState.APPEARED); + return activation; } } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/IExtensions.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/IExtensions.java index 836f4659..190e9139 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/IExtensions.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/IExtensions.java @@ -9,21 +9,21 @@ * Istvan Rath - initial API and implementation *******************************************************************************/ - package org.eclipse.incquery.runtime; /** * Interface for storing string constants related to IncQuery's extension points. + * * @author Istvan Rath - * + * */ public interface IExtensions { - public static final String MATCHERFACTORY_EXTENSION_POINT_ID = IncQueryRuntimePlugin.PLUGIN_ID + ".matcherfactory"; - - // Extension point for registering the generated java codes from the xbase xexpressions + public static final String MATCHERFACTORY_EXTENSION_POINT_ID = IncQueryRuntimePlugin.PLUGIN_ID + ".matcherfactory"; + + // Extension point for registering the generated java codes from the xbase xexpressions public static final String XEXPRESSIONEVALUATOR_EXTENSION_POINT_ID = IncQueryRuntimePlugin.PLUGIN_ID + ".xexpressionevaluator"; - - public static final String INJECTOREXTENSIONID = IncQueryRuntimePlugin.PLUGIN_ID + ".injectorprovider"; + + public static final String INJECTOREXTENSIONID = IncQueryRuntimePlugin.PLUGIN_ID + ".injectorprovider"; } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/IncQueryRuntimePlugin.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/IncQueryRuntimePlugin.java index b3c3c4bc..e6478d83 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/IncQueryRuntimePlugin.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/IncQueryRuntimePlugin.java @@ -26,54 +26,57 @@ */ public class IncQueryRuntimePlugin extends Plugin { - // The shared instance - private static IncQueryRuntimePlugin plugin; - - public static final String PLUGIN_ID="org.eclipse.incquery.runtime"; + // The shared instance + private static IncQueryRuntimePlugin plugin; - /* - * (non-Javadoc) - * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext) - */ - @Override - public void start(BundleContext context) throws Exception { - super.start(context); - plugin = this; - // TODO Builder registry may be used later - //BuilderRegistry.initRegistry(); - XtextInjectorProvider.INSTANCE.setInjector(createInjector()); - //MatcherFactoryRegistry.initRegistry(); - } + public static final String PLUGIN_ID = "org.eclipse.incquery.runtime"; - /* - * (non-Javadoc) - * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) - */ - @Override - public void stop(BundleContext context) throws Exception { - plugin = null; - XtextInjectorProvider.INSTANCE.setInjector(null); - super.stop(context); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext) + */ + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + // TODO Builder registry may be used later + // BuilderRegistry.initRegistry(); + XtextInjectorProvider.INSTANCE.setInjector(createInjector()); + // MatcherFactoryRegistry.initRegistry(); + } - /** - * Returns the shared instance - * - * @return the shared instance - */ - public static IncQueryRuntimePlugin getDefault() { - return plugin; - } + /* + * (non-Javadoc) + * + * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) + */ + @Override + public void stop(BundleContext context) throws Exception { + plugin = null; + XtextInjectorProvider.INSTANCE.setInjector(null); + super.stop(context); + } - private Injector createInjector() throws CoreException { - IConfigurationElement[] providers = Platform.getExtensionRegistry().getConfigurationElementsFor(IExtensions.INJECTOREXTENSIONID); - if (providers.length > 0) { - IConfigurationElement provider = providers[0]; //XXX multiple providers not supported - IInjectorProvider injectorProvider = (IInjectorProvider) provider.createExecutableExtension("injector"); - return injectorProvider.getInjector(); - } else { - return new EMFPatternLanguageStandaloneSetup().createInjector(); - } - } + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static IncQueryRuntimePlugin getDefault() { + return plugin; + } + + private Injector createInjector() throws CoreException { + IConfigurationElement[] providers = Platform.getExtensionRegistry().getConfigurationElementsFor( + IExtensions.INJECTOREXTENSIONID); + if (providers.length > 0) { + IConfigurationElement provider = providers[0]; // XXX multiple providers not supported + IInjectorProvider injectorProvider = (IInjectorProvider) provider.createExecutableExtension("injector"); + return injectorProvider.getInjector(); + } else { + return new EMFPatternLanguageStandaloneSetup().createInjector(); + } + } } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/EngineManager.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/EngineManager.java index 9b61b270..b4a662bd 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/EngineManager.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/EngineManager.java @@ -18,136 +18,142 @@ import org.eclipse.emf.common.notify.Notifier; import org.eclipse.incquery.runtime.exception.IncQueryException; - - /** * Global registry of active EMF-IncQuery engines. * *

    - * Manages an {@link IncQueryEngine} for each EMF model, that is created on demand. - * Managed engines are shared between clients querying the same EMF model. + * Manages an {@link IncQueryEngine} for each EMF model, that is created on demand. Managed engines are shared between + * clients querying the same EMF model. * *

    * It is also possible to create private, unmanaged engines that are not shared between clients. * *

    - * Only weak references are retained on the managed engines. - * So if there are no other references to the matchers or the engine, - * they can eventually be GC'ed, - * and they won't block the EMF model from being GC'ed either. + * Only weak references are retained on the managed engines. So if there are no other references to the matchers or the + * engine, they can eventually be GC'ed, and they won't block the EMF model from being GC'ed either. * * * @author Bergmann Gabor - * + * */ public class EngineManager { - private static EngineManager instance = new EngineManager(); + private static EngineManager instance = new EngineManager(); - /** - * @return the singleton instance - */ - public static EngineManager getInstance() { - return instance; - } - /** - * Only a weak reference is kept on engine, - * so that it can be GC'ed if the model becomes unreachable. - * - *

    it will not be GC'ed before because of {@link BaseIndexListener#iqEngine} - */ - Map> engines; - - EngineManager() { - super(); - engines = new WeakHashMap>(); - } - - /** - * Creates a managed EMF-IncQuery engine at an EMF model root (recommended: Resource or ResourceSet) or retrieves an already existing one. - * Repeated invocations for a single model root will return the same engine. - * Consequently, the engine will be reused between different clients querying the same model, providing performance benefits. - * + /** + * @return the singleton instance + */ + public static EngineManager getInstance() { + return instance; + } + + /** + * Only a weak reference is kept on engine, so that it can be GC'ed if the model becomes unreachable. + * *

    - * The scope of pattern matching will be the given EMF model root and below (see FAQ for more precise definition). - * The match set of any patterns will be incrementally refreshed upon updates from this scope. - * - * @param emfRoot the root of the EMF containment hierarchy where this engine should operate. Recommended: Resource or ResourceSet. - * @return a new or previously existing engine - * @throws IncQueryException - */ - public IncQueryEngine getIncQueryEngine(Notifier emfRoot) throws IncQueryException { - IncQueryEngine engine = getEngineInternal(emfRoot); - if (engine == null) { - engine = new IncQueryEngine(this, emfRoot); - engines.put(emfRoot, new WeakReference(engine)); - } - return engine; - } + * it will not be GC'ed before because of {@link BaseIndexListener#iqEngine} + */ + Map> engines; + + EngineManager() { + super(); + engines = new WeakHashMap>(); + } - /** - * Retrieves an already existing managed EMF-IncQuery engine. - * - * @param emfRoot the root of the EMF containment hierarchy where this engine operates. - * @return a previously existing engine, or null if no engine is active for the given EMF model root - */ - public IncQueryEngine getIncQueryEngineIfExists(Notifier emfRoot) { - return getEngineInternal(emfRoot); - } + /** + * Creates a managed EMF-IncQuery engine at an EMF model root (recommended: Resource or ResourceSet) or retrieves an + * already existing one. Repeated invocations for a single model root will return the same engine. Consequently, the + * engine will be reused between different clients querying the same model, providing performance benefits. + * + *

    + * The scope of pattern matching will be the given EMF model root and below (see FAQ for more precise definition). + * The match set of any patterns will be incrementally refreshed upon updates from this scope. + * + * @param emfRoot + * the root of the EMF containment hierarchy where this engine should operate. Recommended: Resource or + * ResourceSet. + * @return a new or previously existing engine + * @throws IncQueryException + */ + public IncQueryEngine getIncQueryEngine(Notifier emfRoot) throws IncQueryException { + IncQueryEngine engine = getEngineInternal(emfRoot); + if (engine == null) { + engine = new IncQueryEngine(this, emfRoot); + engines.put(emfRoot, new WeakReference(engine)); + } + return engine; + } + + /** + * Retrieves an already existing managed EMF-IncQuery engine. + * + * @param emfRoot + * the root of the EMF containment hierarchy where this engine operates. + * @return a previously existing engine, or null if no engine is active for the given EMF model root + */ + public IncQueryEngine getIncQueryEngineIfExists(Notifier emfRoot) { + return getEngineInternal(emfRoot); + } + + /** + * Creates a new unmanaged EMF-IncQuery engine at an EMF model root (recommended: Resource or ResourceSet). Repeated + * invocations will return different instances, so other clients are unable to independently access and influence + * the returned engine. Note that unmanaged engines do not benefit from some performance improvements that stem from + * sharing incrementally maintained indices and caches. + * + *

    + * The scope of pattern matching will be the given EMF model root and below (see FAQ for more precise definition). + * The match set of any patterns will be incrementally refreshed upon updates from this scope. + * + * @param emfRoot + * the root of the EMF containment hierarchy where this engine should operate. Recommended: Resource or + * ResourceSet. + * @return a new existing engine + * @throws IncQueryException + */ + public IncQueryEngine createUnmanagedIncQueryEngine(Notifier emfRoot) throws IncQueryException { + return new IncQueryEngine(null, emfRoot); + } + + /** + * Disconnects the managed engine that was previously attached at the given EMF model root. Matcher objects will + * continue to return stale results. Subsequent invocations of {@link #getIncQueryEngine(Notifier)} with the same + * EMF root will return a new managed engine. + * + *

    + * The engine will not impose on the model its update overhead anymore. If no references are retained to the + * matchers or the engine, GC'ing the engine and its caches is presumably made easier, although (due to weak + * references) a dispose() call is not strictly necessary. + *

    + * If the engine is managed (see {@link IncQueryEngine#isManaged()}), there may be other clients using it. Care + * should be taken with disposing such engines. + * + * @return true is an engine was found and disconnected, false if no engine was found for the given root. + */ + public boolean disposeEngine(Notifier emfRoot) { + IncQueryEngine engine = getEngineInternal(emfRoot); + if (engine == null) + return false; + else { + engine.dispose(); + return true; + } + } - /** - * Creates a new unmanaged EMF-IncQuery engine at an EMF model root (recommended: Resource or ResourceSet). - * Repeated invocations will return different instances, so other clients are unable to independently access and influence the returned engine. - * Note that unmanaged engines do not benefit from some performance improvements that stem from sharing incrementally maintained indices and caches. - * - *

    - * The scope of pattern matching will be the given EMF model root and below (see FAQ for more precise definition). - * The match set of any patterns will be incrementally refreshed upon updates from this scope. - * - * @param emfRoot the root of the EMF containment hierarchy where this engine should operate. Recommended: Resource or ResourceSet. - * @return a new existing engine - * @throws IncQueryException - */ - public IncQueryEngine createUnmanagedIncQueryEngine(Notifier emfRoot) throws IncQueryException { - return new IncQueryEngine(null, emfRoot); - } + /** + * @param emfRoot + */ + void killInternal(Notifier emfRoot) { + engines.remove(emfRoot); + } - /** - * Disconnects the managed engine that was previously attached at the given EMF model root. - * Matcher objects will continue to return stale results. - * Subsequent invocations of {@link #getIncQueryEngine(Notifier)} with the same - * EMF root will return a new managed engine. - * - *

    The engine will not impose on the model its update overhead anymore. - * If no references are retained to the matchers or the engine, GC'ing the engine and its caches is - * presumably made easier, although (due to weak references) a dispose() call is not strictly necessary. - *

    If the engine is managed (see {@link IncQueryEngine#isManaged()}), there may be other clients using it. - * Care should be taken with disposing such engines. - * - * @return true is an engine was found and disconnected, false if no engine was found for the given root. - */ - public boolean disposeEngine(Notifier emfRoot) { - IncQueryEngine engine = getEngineInternal(emfRoot); - if (engine == null) return false; - else { - engine.dispose(); - return true; - } - } + /** + * @param emfRoot + * @return + */ + private IncQueryEngine getEngineInternal(Notifier emfRoot) { + final WeakReference engineRef = engines.get(emfRoot); + IncQueryEngine engine = engineRef == null ? null : engineRef.get(); + return engine; + } - /** - * @param emfRoot - */ - void killInternal(Notifier emfRoot) { - engines.remove(emfRoot); - } - /** - * @param emfRoot - * @return - */ - private IncQueryEngine getEngineInternal(Notifier emfRoot) { - final WeakReference engineRef = engines.get(emfRoot); - IncQueryEngine engine = engineRef == null ? null : engineRef.get(); - return engine; - } - } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/GenericMatchProcessor.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/GenericMatchProcessor.java index ceca5204..64fc97ca 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/GenericMatchProcessor.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/GenericMatchProcessor.java @@ -12,7 +12,7 @@ package org.eclipse.incquery.runtime.api; /** - * A generic, abstract match processor for handling matches as arrays. + * A generic, abstract match processor for handling matches as arrays. * * Clients should derive an (anonymous) class that implements the abstract process(). * @@ -20,16 +20,18 @@ */ public abstract class GenericMatchProcessor implements IMatchProcessor { - @Override - public void process(IPatternMatch match) { - process(match.toArray()); - } + @Override + public void process(IPatternMatch match) { + process(match.toArray()); + } - /** - * Defines the action that is to be executed on each match. - * @param parameters a single match of the pattern that must be processed by the implementation of this method, - * represented as an array containing the values of each pattern parameter - */ - public abstract void process(Object[] parameters); + /** + * Defines the action that is to be executed on each match. + * + * @param parameters + * a single match of the pattern that must be processed by the implementation of this method, represented + * as an array containing the values of each pattern parameter + */ + public abstract void process(Object[] parameters); } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/GenericMatcherFactory.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/GenericMatcherFactory.java index 569309e1..f409cf04 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/GenericMatcherFactory.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/GenericMatcherFactory.java @@ -16,43 +16,45 @@ import org.eclipse.incquery.runtime.exception.IncQueryException; /** - * This is a generic factory for EMF-IncQuery pattern matchers, for "interpretative" query execution. - * Instantiate the factory with any registered pattern, - * and then use the factory to obtain an actual pattern matcher operating on a given model. + * This is a generic factory for EMF-IncQuery pattern matchers, for "interpretative" query execution. Instantiate the + * factory with any registered pattern, and then use the factory to obtain an actual pattern matcher operating on a + * given model. * - *

    When available, consider using the pattern-specific generated matcher API instead. - * - *

    The created matcher will be of type GenericPatternMatcher. - * Matches of the pattern will be represented as GenericPatternMatch. + *

    + * When available, consider using the pattern-specific generated matcher API instead. + * + *

    + * The created matcher will be of type GenericPatternMatcher. Matches of the pattern will be represented as + * GenericPatternMatch. * * @see GenericPatternMatcher * @see GenericPatternMatch * @see GenericMatchProcessor * @author Bergmann Gábor */ -public class GenericMatcherFactory extends BaseMatcherFactory - implements IMatcherFactory -{ - public Pattern pattern; - - /** - * Initializes a generic pattern factory for a given pattern. - * @param patternName the name of the pattern for which matchers are to be constructed. - */ - public GenericMatcherFactory(Pattern pattern) { - super(); - this.pattern = pattern; - } - - @Override - public Pattern getPattern() { - return pattern; - } - - @Override - public GenericPatternMatcher instantiate(IncQueryEngine engine) throws IncQueryException { - return new GenericPatternMatcher(pattern, engine); - } +public class GenericMatcherFactory extends BaseMatcherFactory implements + IMatcherFactory { + public Pattern pattern; + + /** + * Initializes a generic pattern factory for a given pattern. + * + * @param patternName + * the name of the pattern for which matchers are to be constructed. + */ + public GenericMatcherFactory(Pattern pattern) { + super(); + this.pattern = pattern; + } + + @Override + public Pattern getPattern() { + return pattern; + } + @Override + public GenericPatternMatcher instantiate(IncQueryEngine engine) throws IncQueryException { + return new GenericPatternMatcher(pattern, engine); + } } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/GenericPatternGroup.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/GenericPatternGroup.java index 492e40e6..fc755287 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/GenericPatternGroup.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/GenericPatternGroup.java @@ -18,76 +18,71 @@ import org.eclipse.incquery.runtime.api.impl.BasePatternGroup; /** - * Generic implementation of {@link IPatternGroup}, covering an arbitrarily chosen set of patterns. - * Use the public constructor or static GenericPatternGroup.of(...) methods to instantiate. + * Generic implementation of {@link IPatternGroup}, covering an arbitrarily chosen set of patterns. Use the public + * constructor or static GenericPatternGroup.of(...) methods to instantiate. * * @author Mark Czotter * */ public class GenericPatternGroup extends BasePatternGroup { - - private final Set patterns; - - /** - * Creates a GenericPatternGroup object with a set of patterns. - * - * @param patterns - */ - public GenericPatternGroup(Set patterns) { - this.patterns = patterns; - } - - @Override - public Set getPatterns() { - return patterns; - } - - /** - * Creates a generic {@link IPatternGroup} instance from - * {@link IMatcherFactory} objects. - * - * @param matcherFactories - * @return - */ - public static IPatternGroup of(Set> matcherFactories) { - return new GenericPatternGroup(patterns(matcherFactories)); - } - /** - * Creates a generic {@link IPatternGroup} instance from - * {@link Pattern} objects. - * - * @param matcherFactories - * @return - */ - public static IPatternGroup of(Pattern... patterns) { - return new GenericPatternGroup(new HashSet(Arrays.asList(patterns))); - } + private final Set patterns; - /** - * Creates a generic {@link IPatternGroup} instance from - * {@link IMatcherFactory} objects. - * - * @param matcherFactories - * @return - */ - public static IPatternGroup of(IMatcherFactory... matcherFactories) { - return of(new HashSet>(Arrays.asList(matcherFactories))); - } + /** + * Creates a GenericPatternGroup object with a set of patterns. + * + * @param patterns + */ + public GenericPatternGroup(Set patterns) { + this.patterns = patterns; + } - /** - * Creates a generic {@link IPatternGroup} instance from other - * {@link IPatternGroup} objects (subgroups). - * - * @param matcherFactories - * @return - */ - public static IPatternGroup of(IPatternGroup... subGroups) { - Set patterns = new HashSet(); - for (IPatternGroup group : subGroups) { - patterns.addAll(group.getPatterns()); - } - return new GenericPatternGroup(patterns); - } -} + @Override + public Set getPatterns() { + return patterns; + } + + /** + * Creates a generic {@link IPatternGroup} instance from {@link IMatcherFactory} objects. + * + * @param matcherFactories + * @return + */ + public static IPatternGroup of(Set> matcherFactories) { + return new GenericPatternGroup(patterns(matcherFactories)); + } + + /** + * Creates a generic {@link IPatternGroup} instance from {@link Pattern} objects. + * + * @param matcherFactories + * @return + */ + public static IPatternGroup of(Pattern... patterns) { + return new GenericPatternGroup(new HashSet(Arrays.asList(patterns))); + } + /** + * Creates a generic {@link IPatternGroup} instance from {@link IMatcherFactory} objects. + * + * @param matcherFactories + * @return + */ + public static IPatternGroup of(IMatcherFactory... matcherFactories) { + return of(new HashSet>(Arrays.asList(matcherFactories))); + } + + /** + * Creates a generic {@link IPatternGroup} instance from other {@link IPatternGroup} objects (subgroups). + * + * @param matcherFactories + * @return + */ + public static IPatternGroup of(IPatternGroup... subGroups) { + Set patterns = new HashSet(); + for (IPatternGroup group : subGroups) { + patterns.addAll(group.getPatterns()); + } + return new GenericPatternGroup(patterns); + } +} diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/GenericPatternMatch.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/GenericPatternMatch.java index 7ae0435f..c47d08d8 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/GenericPatternMatch.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/GenericPatternMatch.java @@ -17,97 +17,98 @@ import org.eclipse.incquery.runtime.api.impl.BasePatternMatch; /** - * Generic signature object implementation. - * Please instantiate using GenericPatternMatcher.arrayToSignature(). - * + * Generic signature object implementation. Please instantiate using GenericPatternMatcher.arrayToSignature(). + * * See also the generated matcher and signature of the pattern, with pattern-specific API simplifications. - * + * * @author Bergmann Gábor - * + * */ public class GenericPatternMatch extends BasePatternMatch implements IPatternMatch { - private final GenericPatternMatcher matcher; - private final Object[] array; - - /** - * @param posMapping - * @param array - */ - GenericPatternMatch(GenericPatternMatcher matcher, Object[] array) { - super(); - this.matcher = matcher; - this.array = array; - } - - @Override - public Object get(String parameterName) { - Integer index = matcher.getPositionOfParameter(parameterName); - return index == null? null : array[index]; - } - - @Override - public boolean set(String parameterName, Object newValue) { - Integer index = matcher.getPositionOfParameter(parameterName); - if (index == null) return false; - array[index] = newValue; - return true; - } - - @Override - public Object[] toArray() { - return array; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - for (int i=0; iWhen available, consider using the pattern-specific generated matcher API instead. + *

    + * When available, consider using the pattern-specific generated matcher API instead. * - *

    Matches of the pattern will be represented as GenericPatternMatch. + *

    + * Matches of the pattern will be represented as GenericPatternMatch. * * @author Bergmann Gábor * @see GenericPatternMatch * @see GenericMatcherFactory * @see GenericMatchProcessor */ -public class GenericPatternMatcher extends BaseMatcher implements IncQueryMatcher { +public class GenericPatternMatcher extends BaseMatcher implements + IncQueryMatcher { - Pattern pattern; - - - /** - * Initializes the pattern matcher over a given EMF model root (recommended: Resource or ResourceSet). - * If a pattern matcher is already constructed with the same root, only a lightweight reference is created. - * - * The scope of pattern matching will be the given EMF model root and below (see FAQ for more precise definition). - * The match set will be incrementally refreshed upon updates from this scope. - * - *

    The matcher will be created within the managed {@link IncQueryEngine} belonging to the EMF model root, so - * multiple matchers will reuse the same engine and benefit from increased performance and reduced memory footprint. - * - * @param pattern the EMF-IncQuery pattern for which the matcher is to be constructed. - * @param emfRoot the root of the EMF containment hierarchy where the pattern matcher will operate. Recommended: Resource or ResourceSet. - * @throws IncQueryException if an error occurs during pattern matcher creation - */ - public GenericPatternMatcher(Pattern pattern, Notifier emfRoot) - throws IncQueryException - { - this(pattern, EngineManager.getInstance().getIncQueryEngine(emfRoot)); - } - - /** - * Initializes the pattern matcher within an existing EMF-IncQuery engine. - * If the pattern matcher is already constructed in the engine, only a lightweight reference is created. - * The match set will be incrementally refreshed upon updates. - * @param pattern the EMF-IncQuery pattern for which the matcher is to be constructed. - * @param engine the existing EMF-IncQuery engine in which this matcher will be created. - * @throws IncQueryException if an error occurs during pattern matcher creation - */ - public GenericPatternMatcher(Pattern pattern, IncQueryEngine engine) - throws IncQueryException - { - super(engine, accessMatcher(pattern, engine), pattern); - this.pattern = pattern; - } - - @Override - public Pattern getPattern() { - return pattern; - } - - private String fullyQualifiedName; + Pattern pattern; - @Override - public String getPatternName() { - if (fullyQualifiedName == null) - fullyQualifiedName = CorePatternLanguageHelper.getFullyQualifiedName(getPattern()); - return fullyQualifiedName; - } + /** + * Initializes the pattern matcher over a given EMF model root (recommended: Resource or ResourceSet). If a pattern + * matcher is already constructed with the same root, only a lightweight reference is created. + * + * The scope of pattern matching will be the given EMF model root and below (see FAQ for more precise definition). + * The match set will be incrementally refreshed upon updates from this scope. + * + *

    + * The matcher will be created within the managed {@link IncQueryEngine} belonging to the EMF model root, so + * multiple matchers will reuse the same engine and benefit from increased performance and reduced memory footprint. + * + * @param pattern + * the EMF-IncQuery pattern for which the matcher is to be constructed. + * @param emfRoot + * the root of the EMF containment hierarchy where the pattern matcher will operate. Recommended: + * Resource or ResourceSet. + * @throws IncQueryException + * if an error occurs during pattern matcher creation + */ + public GenericPatternMatcher(Pattern pattern, Notifier emfRoot) throws IncQueryException { + this(pattern, EngineManager.getInstance().getIncQueryEngine(emfRoot)); + } - @Override - public GenericPatternMatch arrayToMatch(Object[] parameters) { - return new GenericPatternMatch(this, parameters); - } + /** + * Initializes the pattern matcher within an existing EMF-IncQuery engine. If the pattern matcher is already + * constructed in the engine, only a lightweight reference is created. The match set will be incrementally refreshed + * upon updates. + * + * @param pattern + * the EMF-IncQuery pattern for which the matcher is to be constructed. + * @param engine + * the existing EMF-IncQuery engine in which this matcher will be created. + * @throws IncQueryException + * if an error occurs during pattern matcher creation + */ + public GenericPatternMatcher(Pattern pattern, IncQueryEngine engine) throws IncQueryException { + super(engine, accessMatcher(pattern, engine), pattern); + this.pattern = pattern; + } + @Override + public Pattern getPattern() { + return pattern; + } - @Override - protected GenericPatternMatch tupleToMatch(Tuple t) { - return new GenericPatternMatch(this, t.getElements()); - } + private String fullyQualifiedName; - private static RetePatternMatcher accessMatcher(Pattern pattern, IncQueryEngine engine) - throws IncQueryException - { - checkPattern(engine, pattern); - try { - return engine.getReteEngine().accessMatcher(pattern); - } catch (RetePatternBuildException e) { - throw new IncQueryException(e); - } - } + @Override + public String getPatternName() { + if (fullyQualifiedName == null) + fullyQualifiedName = CorePatternLanguageHelper.getFullyQualifiedName(getPattern()); + return fullyQualifiedName; + } + + @Override + public GenericPatternMatch arrayToMatch(Object[] parameters) { + return new GenericPatternMatch(this, parameters); + } + + @Override + protected GenericPatternMatch tupleToMatch(Tuple t) { + return new GenericPatternMatch(this, t.getElements()); + } + + private static RetePatternMatcher accessMatcher(Pattern pattern, IncQueryEngine engine) throws IncQueryException { + checkPattern(engine, pattern); + try { + return engine.getReteEngine().accessMatcher(pattern); + } catch (RetePatternBuildException e) { + throw new IncQueryException(e); + } + } } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/IMatchProcessor.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/IMatchProcessor.java index 645b49d5..a56ef6bc 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/IMatchProcessor.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/IMatchProcessor.java @@ -14,16 +14,18 @@ /** * A "lambda" action that can be executed on each match of a pattern. * - * Clients can manually implement process() in an (anonymous) class, or alternatively, - * extend either {@link GenericMatchProcessor} or the user-friendly pattern-specific generated match processor classes. + * Clients can manually implement process() in an (anonymous) class, or alternatively, extend either + * {@link GenericMatchProcessor} or the user-friendly pattern-specific generated match processor classes. * * @author Bergmann Gábor - * + * */ -public interface IMatchProcessor { - /** - * Defines the action that is to be executed on each match. - * @param match a single match of the pattern that must be processed by the implementation of this method - */ - public void process(Match match); +public interface IMatchProcessor { + /** + * Defines the action that is to be executed on each match. + * + * @param match + * a single match of the pattern that must be processed by the implementation of this method + */ + public void process(Match match); } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/IMatchUpdateListener.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/IMatchUpdateListener.java index ff568efc..af8ab8ed 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/IMatchUpdateListener.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/IMatchUpdateListener.java @@ -10,25 +10,30 @@ *******************************************************************************/ package org.eclipse.incquery.runtime.api; - /** * An interface for low-level notifications about match appearance and disappearance. * - *

    See {@link IncQueryMatcher#addCallbackOnMatchUpdate(IMatchUpdateListener, boolean)} for usage. - * Clients should consider using {@link MatchUpdateAdapter} or deriving their implementation from it. + *

    + * See {@link IncQueryMatcher#addCallbackOnMatchUpdate(IMatchUpdateListener, boolean)} for usage. Clients should + * consider using {@link MatchUpdateAdapter} or deriving their implementation from it. * * @author Bergmann Gabor - * + * */ public interface IMatchUpdateListener { - /** - * Will be invoked on each new match that appears. - * @param match the match that has just appeared. - */ - public void notifyAppearance(Match match); - /** - * Will be invoked on each existing match that disappears. - * @param match the match that has just disappeared. - */ - public void notifyDisappearance(Match match); + /** + * Will be invoked on each new match that appears. + * + * @param match + * the match that has just appeared. + */ + public void notifyAppearance(Match match); + + /** + * Will be invoked on each existing match that disappears. + * + * @param match + * the match that has just disappeared. + */ + public void notifyDisappearance(Match match); } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/IMatcherFactory.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/IMatcherFactory.java index 84dbd959..46337314 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/IMatcherFactory.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/IMatcherFactory.java @@ -16,84 +16,98 @@ import org.eclipse.incquery.runtime.exception.IncQueryException; /** - * Interface for an IncQuery matcher factory. - * Each factory is associated with a pattern. - * Methods instantiate a matcher of the pattern with various parameters. + * Interface for an IncQuery matcher factory. Each factory is associated with a pattern. Methods instantiate a matcher + * of the pattern with various parameters. * * @author Bergmann Gábor - * + * */ public interface IMatcherFactory> { - - /** - * @throws IncQueryException if there was an error loading the pattern definition - * @returns the pattern for which matchers can be instantiated. - */ - public Pattern getPattern(); - /** - * Identifies the pattern for which matchers can be instantiated. - */ - public String getPatternFullyQualifiedName(); - - /** - * Initializes the pattern matcher over a given EMF model root (recommended: Resource or ResourceSet). - * If a pattern matcher is already constructed with the same root, only a lightweight reference is created. - * - *

    The scope of pattern matching will be the given EMF model root and below (see FAQ for more precise definition). - *

    The match set will be incrementally refreshed upon updates from this scope. - * - *

    The matcher will be created within the managed {@link IncQueryEngine} belonging to the EMF model root, so - * multiple matchers will reuse the same engine and benefit from increased performance and reduced memory footprint. - * - * @param emfRoot the root of the EMF tree where the pattern matcher will operate. Recommended: Resource or ResourceSet. - * @throws IncQueryException if an error occurs during pattern matcher creation - */ - public Matcher getMatcher(Notifier emfRoot) throws IncQueryException; - - /** - * Initializes the pattern matcher within an existing {@link IncQueryEngine}. - * If the pattern matcher is already constructed in the engine, only a lightweight reference is created. - *

    The match set will be incrementally refreshed upon updates. - * @param engine the existing EMF-IncQuery engine in which this matcher will be created. - * @throws IncQueryException if an error occurs during pattern matcher creation - */ - public Matcher getMatcher(IncQueryEngine engine) throws IncQueryException; -// // EXPERIMENTAL -// -// /** -// * Initializes the pattern matcher over a given EMF root (recommended: Resource or ResourceSet). -// * If a pattern matcher is already constructed with the same root, only a lightweight reference is created. -// * The match set will be incrementally refreshed upon updates from the given EMF root and below. -// * -// * Note: if emfRoot is a resourceSet, the scope will include even those resources that are not part of the resourceSet but are referenced. -// * This is mainly to support nsURI-based instance-level references to registered EPackages. -// * -// * @param emfRoot the root of the EMF tree where the pattern matcher will operate. Recommended: Resource or ResourceSet. -// * @param numThreads 0 for single-threaded execution (recommended), -// * or a positive number of separate threads of pattern matter execution (experimental). -// * @throws IncQueryRuntimeException if an error occurs during pattern matcher creation -// */ -// public Matcher getMatcher(Notifier emfRoot, int numThreads) throws IncQueryRuntimeException; + /** + * @throws IncQueryException + * if there was an error loading the pattern definition + * @returns the pattern for which matchers can be instantiated. + */ + public Pattern getPattern(); + + /** + * Identifies the pattern for which matchers can be instantiated. + */ + public String getPatternFullyQualifiedName(); + + /** + * Initializes the pattern matcher over a given EMF model root (recommended: Resource or ResourceSet). If a pattern + * matcher is already constructed with the same root, only a lightweight reference is created. + * + *

    + * The scope of pattern matching will be the given EMF model root and below (see FAQ for more precise definition). + *

    + * The match set will be incrementally refreshed upon updates from this scope. + * + *

    + * The matcher will be created within the managed {@link IncQueryEngine} belonging to the EMF model root, so + * multiple matchers will reuse the same engine and benefit from increased performance and reduced memory footprint. + * + * @param emfRoot + * the root of the EMF tree where the pattern matcher will operate. Recommended: Resource or ResourceSet. + * @throws IncQueryException + * if an error occurs during pattern matcher creation + */ + public Matcher getMatcher(Notifier emfRoot) throws IncQueryException; + + /** + * Initializes the pattern matcher within an existing {@link IncQueryEngine}. If the pattern matcher is already + * constructed in the engine, only a lightweight reference is created. + *

    + * The match set will be incrementally refreshed upon updates. + * + * @param engine + * the existing EMF-IncQuery engine in which this matcher will be created. + * @throws IncQueryException + * if an error occurs during pattern matcher creation + */ + public Matcher getMatcher(IncQueryEngine engine) throws IncQueryException; + + // // EXPERIMENTAL + // + // /** + // * Initializes the pattern matcher over a given EMF root (recommended: Resource or ResourceSet). + // * If a pattern matcher is already constructed with the same root, only a lightweight reference is created. + // * The match set will be incrementally refreshed upon updates from the given EMF root and below. + // * + // * Note: if emfRoot is a resourceSet, the scope will include even those resources that are not part of the + // resourceSet but are referenced. + // * This is mainly to support nsURI-based instance-level references to registered EPackages. + // * + // * @param emfRoot the root of the EMF tree where the pattern matcher will operate. Recommended: Resource or + // ResourceSet. + // * @param numThreads 0 for single-threaded execution (recommended), + // * or a positive number of separate threads of pattern matter execution (experimental). + // * @throws IncQueryRuntimeException if an error occurs during pattern matcher creation + // */ + // public Matcher getMatcher(Notifier emfRoot, int numThreads) throws IncQueryRuntimeException; -// // EXPERIMENTAL -// -// /** -// * Initializes the pattern matcher over a given EMF transactional editing domain. -// * If a pattern matcher is already constructed with the same editing domain, only a lightweight reference is created. -// * The match set will be incrementally refreshed upon committed EMF transactions. -// * @param trDomain the EMF transactional editing domain over which the pattern matcher will operate. -// * @param numThreads 0 for single-threaded execution (recommended), -// * or a positive number of separate threads of pattern matter execution (experimental). -// * @throws IncQueryRuntimeException if an error occurs during pattern matcher creation -// */ -// public Matcher getMatcher(TransactionalEditingDomain trDomain) throws IncQueryRuntimeException; -// /** -// * Initializes the pattern matcher over a given EMF transactional editing domain. -// * If a pattern matcher is already constructed with the same editing domain, only a lightweight reference is created. -// * The match set will be incrementally refreshed upon committed EMF transactions. -// * @param trDomain the EMF transactional editing domain over which the pattern matcher will operate. -// * @throws IncQueryRuntimeException if an error occurs during pattern matcher creation -// */ -// public Matcher getMatcher(TransactionalEditingDomain trDomain, int numThreads) throws IncQueryRuntimeException; + // // EXPERIMENTAL + // + // /** + // * Initializes the pattern matcher over a given EMF transactional editing domain. + // * If a pattern matcher is already constructed with the same editing domain, only a lightweight reference is + // created. + // * The match set will be incrementally refreshed upon committed EMF transactions. + // * @param trDomain the EMF transactional editing domain over which the pattern matcher will operate. + // * @param numThreads 0 for single-threaded execution (recommended), + // * or a positive number of separate threads of pattern matter execution (experimental). + // * @throws IncQueryRuntimeException if an error occurs during pattern matcher creation + // */ + // public Matcher getMatcher(TransactionalEditingDomain trDomain) throws IncQueryRuntimeException; + // /** + // * Initializes the pattern matcher over a given EMF transactional editing domain. + // * If a pattern matcher is already constructed with the same editing domain, only a lightweight reference is + // created. + // * The match set will be incrementally refreshed upon committed EMF transactions. + // * @param trDomain the EMF transactional editing domain over which the pattern matcher will operate. + // * @throws IncQueryRuntimeException if an error occurs during pattern matcher creation + // */ + // public Matcher getMatcher(TransactionalEditingDomain trDomain, int numThreads) throws IncQueryRuntimeException; } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/IPatternGroup.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/IPatternGroup.java index 3738bb9c..a33b9ab5 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/IPatternGroup.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/IPatternGroup.java @@ -19,44 +19,50 @@ /** * Generic interface for group of patterns. * - * It handles more than one patterns as a group, and provides functionality to - * initialize the patterns together (which has performance benefits). + * It handles more than one patterns as a group, and provides functionality to initialize the patterns together (which + * has performance benefits). * * @author Mark Czotter * */ public interface IPatternGroup { - /** - * Initializes the contained patterns within an {@link IncQueryEngine}. - * If some of the pattern matchers are already constructed in the engine, no task is performed for them. - * - *

    This preparation step has the advantage that it build pattern matchers for an arbitrary number of - * patterns in a single-pass traversal of the EMF model. This performance benefit only manifests itself - * if the engine is not in wildcard mode). - * - * @param engine the existing EMF-IncQuery engine in which this matcher will be created. - * @throws IncQueryException if there was an error in preparing the engine - */ - public void prepare(IncQueryEngine engine) throws IncQueryException; - - /** - * Initializes the contained patterns over a given EMF model root (recommended: Resource or ResourceSet). - * If a pattern matcher engine with the same root already exists, it will be reused. - * - * The scope of pattern matching will be the given EMF model root and below (see FAQ for more precise definition). - * The match set will be incrementally refreshed upon updates from this scope. - * - * @param emfRoot the root of the EMF tree where the pattern matchers will operate. Recommended: Resource or ResourceSet. - * @throws IncQueryException if an error occurs during pattern matcher creation - */ - public void prepare(Notifier emfRoot) throws IncQueryException; + /** + * Initializes the contained patterns within an {@link IncQueryEngine}. If some of the pattern matchers are already + * constructed in the engine, no task is performed for them. + * + *

    + * This preparation step has the advantage that it build pattern matchers for an arbitrary number of patterns in a + * single-pass traversal of the EMF model. This performance benefit only manifests itself if the engine is not in + * wildcard mode). + * + * @param engine + * the existing EMF-IncQuery engine in which this matcher will be created. + * @throws IncQueryException + * if there was an error in preparing the engine + */ + public void prepare(IncQueryEngine engine) throws IncQueryException; - /** - * Returns the currently assigned {@link Pattern}s. - * - * @return - */ - public Set getPatterns(); + /** + * Initializes the contained patterns over a given EMF model root (recommended: Resource or ResourceSet). If a + * pattern matcher engine with the same root already exists, it will be reused. + * + * The scope of pattern matching will be the given EMF model root and below (see FAQ for more precise definition). + * The match set will be incrementally refreshed upon updates from this scope. + * + * @param emfRoot + * the root of the EMF tree where the pattern matchers will operate. Recommended: Resource or + * ResourceSet. + * @throws IncQueryException + * if an error occurs during pattern matcher creation + */ + public void prepare(Notifier emfRoot) throws IncQueryException; + + /** + * Returns the currently assigned {@link Pattern}s. + * + * @return + */ + public Set getPatterns(); } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/IPatternMatch.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/IPatternMatch.java index 06692055..5b253541 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/IPatternMatch.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/IPatternMatch.java @@ -13,47 +13,50 @@ import org.eclipse.incquery.patternlanguage.patternLanguage.Pattern; - /** - * Generic interface for a single match of a pattern. - * Each instance is a (partial) substitution of pattern parameters, essentially a parameter to value mapping. + * Generic interface for a single match of a pattern. Each instance is a (partial) substitution of pattern parameters, + * essentially a parameter to value mapping. * - * Can also represent a partial match; unsubstituted parameters are assigned to null. - * Pattern matchers must never return a partial match, but they accept partial matches as method parameters. + * Can also represent a partial match; unsubstituted parameters are assigned to null. Pattern matchers must never return + * a partial match, but they accept partial matches as method parameters. * * @author Bergmann Gábor */ -public interface IPatternMatch extends Cloneable /*, Map*/ { - /** @return the pattern for which this is a match. */ - public Pattern pattern(); - - /** Identifies the name of the pattern for which this is a match. */ - public String patternName(); - - /** Returns the list of symbolic parameter names. */ - public String[] parameterNames(); - - /** Returns the value of the parameter with the given name, or null if name is invalid. */ - public Object get(String parameterName); - - /** Returns the value of the parameter at the given position, or null if position is invalid. */ - public Object get(int position); - - /** - * Sets the parameter with the given name to the given value. - * @returns true if successful, false if parameter name is invalid. May also fail and return false if the value type is incompatible. - */ - public boolean set(String parameterName, Object newValue); - - /** - * Sets the parameter at the given position to the given value. - * @returns true if successful, false if position is invalid. May also fail and return false if the value type is incompatible. - */ - public boolean set(int position, Object newValue); - - /** Converts the match to an array representation, with each pattern parameter at their respective position */ - public Object[] toArray(); - - /** Prints the list of parameter-value pairs. */ - public String prettyPrint(); +public interface IPatternMatch extends Cloneable /* , Map */{ + /** @return the pattern for which this is a match. */ + public Pattern pattern(); + + /** Identifies the name of the pattern for which this is a match. */ + public String patternName(); + + /** Returns the list of symbolic parameter names. */ + public String[] parameterNames(); + + /** Returns the value of the parameter with the given name, or null if name is invalid. */ + public Object get(String parameterName); + + /** Returns the value of the parameter at the given position, or null if position is invalid. */ + public Object get(int position); + + /** + * Sets the parameter with the given name to the given value. + * + * @returns true if successful, false if parameter name is invalid. May also fail and return false if the value type + * is incompatible. + */ + public boolean set(String parameterName, Object newValue); + + /** + * Sets the parameter at the given position to the given value. + * + * @returns true if successful, false if position is invalid. May also fail and return false if the value type is + * incompatible. + */ + public boolean set(int position, Object newValue); + + /** Converts the match to an array representation, with each pattern parameter at their respective position */ + public Object[] toArray(); + + /** Prints the list of parameter-value pairs. */ + public String prettyPrint(); } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/IncQueryEngine.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/IncQueryEngine.java index 2803f86e..4b182886 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/IncQueryEngine.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/IncQueryEngine.java @@ -11,7 +11,6 @@ package org.eclipse.incquery.runtime.api; - import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.HashSet; @@ -65,397 +64,415 @@ */ public class IncQueryEngine { - /** - * The engine manager responsible for this engine. Null if this engine is unmanaged. - */ - private final EngineManager manager; - /** - * The model to which the engine is attached. - */ - private final Notifier emfRoot; - - /** - * The base index keeping track of basic EMF contents of the model. - */ - private NavigationHelper baseIndex; - /** - * Whether to initialize the base index in wildcard mode. - */ - private static final boolean WILDCARD_MODE_DEFAULT = false; - /** - * The RETE pattern matcher component of the EMF-IncQuery engine. - */ - private ReteEngine reteEngine = null; - /** - * A sanitizer to catch faulty patterns. - */ - private PatternSanitizer sanitizer = null; - - /** - * Indicates whether the engine is in a tainted, inconsistent state. - */ - private boolean tainted = false; - private EngineTaintListener taintListener; - private static class SelfTaintListener extends EngineTaintListener { - WeakReference iqEngRef; - public SelfTaintListener(IncQueryEngine iqEngine) { - this.iqEngRef = new WeakReference(iqEngine); - } - @Override - public void engineBecameTainted() { - final IncQueryEngine iqEngine = iqEngRef.get(); - iqEngine.tainted = true; - } - } - - /** - * EXPERIMENTAL - */ - private final int reteThreads = 0; - - private Logger logger; - private final Set afterWipeCallbacks; - - /** - * @param manager null if unmanaged - * @param emfRoot - * @throws IncQueryException if the emf root is invalid - */ - IncQueryEngine(EngineManager manager, Notifier emfRoot) throws IncQueryException { - super(); - this.manager = manager; - this.emfRoot = emfRoot; - this.afterWipeCallbacks = new HashSet(); - if (! (emfRoot instanceof EObject || emfRoot instanceof Resource || emfRoot instanceof ResourceSet)) - throw new IncQueryException( - IncQueryException.INVALID_EMFROOT + (emfRoot == null ? "(null)" : emfRoot.getClass().getName()), - IncQueryException.INVALID_EMFROOT_SHORT); - } - - /** - * @return the root of the EMF model tree that this engine is attached to. - */ - public Notifier getEmfRoot() { - return emfRoot; - } - - /** - * Internal accessor for the base index. - * @return the baseIndex the NavigationHelper maintaining the base index - * @throws IncQueryException if the base index could not be constructed - */ - protected NavigationHelper getBaseIndexInternal() throws IncQueryException { - return getBaseIndexInternal(WILDCARD_MODE_DEFAULT, true); - } - - /** - * Internal accessor for the base index. - * @return the baseIndex the NavigationHelper maintaining the base index - * @throws IncQueryException if the base index could not be initialized - * @throws IncQueryBaseException if the base index could not be constructed - */ - protected NavigationHelper getBaseIndexInternal(boolean wildcardMode, boolean initNow) throws IncQueryException { - if (baseIndex == null) { - try { - // sync to avoid crazy compiler reordering which would matter if derived features use eIQ and call this reentrantly - synchronized (this) { - baseIndex = IncQueryBaseFactory.getInstance().createNavigationHelper(null, wildcardMode, getLogger()); + /** + * The engine manager responsible for this engine. Null if this engine is unmanaged. + */ + private final EngineManager manager; + /** + * The model to which the engine is attached. + */ + private final Notifier emfRoot; + + /** + * The base index keeping track of basic EMF contents of the model. + */ + private NavigationHelper baseIndex; + /** + * Whether to initialize the base index in wildcard mode. + */ + private static final boolean WILDCARD_MODE_DEFAULT = false; + /** + * The RETE pattern matcher component of the EMF-IncQuery engine. + */ + private ReteEngine reteEngine = null; + /** + * A sanitizer to catch faulty patterns. + */ + private PatternSanitizer sanitizer = null; + + /** + * Indicates whether the engine is in a tainted, inconsistent state. + */ + private boolean tainted = false; + private EngineTaintListener taintListener; + + private static class SelfTaintListener extends EngineTaintListener { + WeakReference iqEngRef; + + public SelfTaintListener(IncQueryEngine iqEngine) { + this.iqEngRef = new WeakReference(iqEngine); + } + + @Override + public void engineBecameTainted() { + final IncQueryEngine iqEngine = iqEngRef.get(); + iqEngine.tainted = true; + } + } + + /** + * EXPERIMENTAL + */ + private final int reteThreads = 0; + + private Logger logger; + private final Set afterWipeCallbacks; + + /** + * @param manager + * null if unmanaged + * @param emfRoot + * @throws IncQueryException + * if the emf root is invalid + */ + IncQueryEngine(EngineManager manager, Notifier emfRoot) throws IncQueryException { + super(); + this.manager = manager; + this.emfRoot = emfRoot; + this.afterWipeCallbacks = new HashSet(); + if (!(emfRoot instanceof EObject || emfRoot instanceof Resource || emfRoot instanceof ResourceSet)) + throw new IncQueryException(IncQueryException.INVALID_EMFROOT + + (emfRoot == null ? "(null)" : emfRoot.getClass().getName()), + IncQueryException.INVALID_EMFROOT_SHORT); + } + + /** + * @return the root of the EMF model tree that this engine is attached to. + */ + public Notifier getEmfRoot() { + return emfRoot; + } + + /** + * Internal accessor for the base index. + * + * @return the baseIndex the NavigationHelper maintaining the base index + * @throws IncQueryException + * if the base index could not be constructed + */ + protected NavigationHelper getBaseIndexInternal() throws IncQueryException { + return getBaseIndexInternal(WILDCARD_MODE_DEFAULT, true); + } + + /** + * Internal accessor for the base index. + * + * @return the baseIndex the NavigationHelper maintaining the base index + * @throws IncQueryException + * if the base index could not be initialized + * @throws IncQueryBaseException + * if the base index could not be constructed + */ + protected NavigationHelper getBaseIndexInternal(boolean wildcardMode, boolean initNow) throws IncQueryException { + if (baseIndex == null) { + try { + // sync to avoid crazy compiler reordering which would matter if derived features use eIQ and call this + // reentrantly + synchronized (this) { + baseIndex = IncQueryBaseFactory.getInstance().createNavigationHelper(null, wildcardMode, + getLogger()); + } + } catch (IncQueryBaseException e) { + throw new IncQueryException("Could not create EMF-IncQuery base index", "Could not create base index", + e); + } + + if (initNow) { + initBaseIndex(); + } + + } + return baseIndex; + } + + /** + * @throws IncQueryException + */ + private synchronized void initBaseIndex() throws IncQueryException { + try { + baseIndex.addRoot(getEmfRoot()); + } catch (IncQueryBaseException e) { + throw new IncQueryException("Could not initialize EMF-IncQuery base index", + "Could not initialize base index", e); + } + } + + /** + * Provides access to the internal base index component of the engine, responsible for keeping track of basic EMF + * contents of the model. + * + * @return the baseIndex the NavigationHelper maintaining the base index + * @throws IncQueryException + * if the base index could not be constructed + */ + public NavigationHelper getBaseIndex() throws IncQueryException { + return getBaseIndexInternal(); + } + + /** + * Provides access to the internal RETE pattern matcher component of the EMF-IncQuery engine. + * + * @noreference A typical user would not need to call this method. + */ + public ReteEngine getReteEngine() throws IncQueryException { + if (reteEngine == null) { + // if uninitialized, don't initialize yet + getBaseIndexInternal(WILDCARD_MODE_DEFAULT, false); + + EMFPatternMatcherRuntimeContext context = new EMFPatternMatcherRuntimeContext(this, baseIndex); + // if (emfRoot instanceof EObject) + // context = new EMFPatternMatcherRuntimeContext.ForEObject((EObject)emfRoot, this); + // else if (emfRoot instanceof Resource) + // context = new EMFPatternMatcherRuntimeContext.ForResource((Resource)emfRoot, this); + // else if (emfRoot instanceof ResourceSet) + // context = new EMFPatternMatcherRuntimeContext.ForResourceSet((ResourceSet)emfRoot, this); + // else throw new IncQueryRuntimeException(IncQueryRuntimeException.INVALID_EMFROOT); + + synchronized (this) { + reteEngine = buildReteEngineInternal(context); + } + + // lazy initialization now, + initBaseIndex(); + + // if (reteEngine != null) engines.put(emfRoot, new WeakReference>(engine)); } - } catch (IncQueryBaseException e) { - throw new IncQueryException( - "Could not create EMF-IncQuery base index", - "Could not create base index", - e); - } - - if (initNow) { - initBaseIndex(); - } - - } - return baseIndex; - } - - /** - * @throws IncQueryException - */ - private synchronized void initBaseIndex() throws IncQueryException { - try { - baseIndex.addRoot(getEmfRoot()); - } catch (IncQueryBaseException e) { - throw new IncQueryException( - "Could not initialize EMF-IncQuery base index", - "Could not initialize base index", - e); + return reteEngine; + } - } - - /** - * Provides access to the internal base index component of the engine, responsible for keeping track of basic EMF contents of the model. - * @return the baseIndex the NavigationHelper maintaining the base index - * @throws IncQueryException if the base index could not be constructed - */ - public NavigationHelper getBaseIndex() throws IncQueryException { - return getBaseIndexInternal(); - } - - - - /** - * Provides access to the internal RETE pattern matcher component of the EMF-IncQuery engine. - * @noreference A typical user would not need to call this method. - */ - public ReteEngine getReteEngine() throws IncQueryException { - if (reteEngine == null) { - // if uninitialized, don't initialize yet - getBaseIndexInternal(WILDCARD_MODE_DEFAULT, false); - - EMFPatternMatcherRuntimeContext context = new EMFPatternMatcherRuntimeContext(this, baseIndex); -// if (emfRoot instanceof EObject) -// context = new EMFPatternMatcherRuntimeContext.ForEObject((EObject)emfRoot, this); -// else if (emfRoot instanceof Resource) -// context = new EMFPatternMatcherRuntimeContext.ForResource((Resource)emfRoot, this); -// else if (emfRoot instanceof ResourceSet) -// context = new EMFPatternMatcherRuntimeContext.ForResourceSet((ResourceSet)emfRoot, this); -// else throw new IncQueryRuntimeException(IncQueryRuntimeException.INVALID_EMFROOT); - - synchronized (this) { - reteEngine = buildReteEngineInternal(context); - } - - // lazy initialization now, - initBaseIndex(); - - //if (reteEngine != null) engines.put(emfRoot, new WeakReference>(engine)); - } - return reteEngine; - - } - /** - * Completely disconnects and dismantles the engine. - *

    Matcher objects will continue to return stale results. - * If no references are retained to the matchers or the engine, they can eventually be GC'ed, - * and they won't block the EMF model from being GC'ed anymore. - * - *

    Cannot be reversed. - *

    If the engine is managed (see {@link #isManaged()}), there may be other clients using it. - * Care should be taken with disposing such engines. - */ - public void dispose() { - if(manager != null) { - manager.killInternal(emfRoot); - logger.warn(String.format("Managed engine disposed for notifier %s !", emfRoot)); - } - killInternal(); - } - - /** - * Discards any pattern matcher caches and forgets known patterns. - * The base index built directly on the underlying EMF model, however, - * is kept in memory to allow reuse when new pattern matchers are built. - * Use this method if you have e.g. new versions of the same patterns, to be matched on the same model. - * - *

    Matcher objects will continue to return stale results. - * If no references are retained to the matchers, they can eventually be GC'ed. - *

    If the engine is managed (see {@link #isManaged()}), there may be other clients using it. - * Care should be taken with wiping such engines. - * - */ - public void wipe() { - if(manager != null) { - logger.warn(String.format("Managed engine wiped for notifier %s !", emfRoot)); - } - if (reteEngine != null) { - reteEngine.killEngine(); - reteEngine = null; - } - sanitizer = null; - runAfterWipeCallbacks(); - } - - /** - * This will run before wipes. - */ - // * If there are any such, updates are settled before they are run. - public void runAfterWipeCallbacks() { - try { - if (!afterWipeCallbacks.isEmpty()) { - //settle(); - for (Runnable runnable : new ArrayList(afterWipeCallbacks)) { - runnable.run(); + + /** + * Completely disconnects and dismantles the engine. + *

    + * Matcher objects will continue to return stale results. If no references are retained to the matchers or the + * engine, they can eventually be GC'ed, and they won't block the EMF model from being GC'ed anymore. + * + *

    + * Cannot be reversed. + *

    + * If the engine is managed (see {@link #isManaged()}), there may be other clients using it. Care should be taken + * with disposing such engines. + */ + public void dispose() { + if (manager != null) { + manager.killInternal(emfRoot); + logger.warn(String.format("Managed engine disposed for notifier %s !", emfRoot)); } - } - } catch (Exception ex) { - logger.fatal( - "EMF-IncQuery encountered an error in delivering notifications about wipe. " , ex); + killInternal(); } - } - - private ReteEngine buildReteEngineInternal(IPatternMatcherRuntimeContext context) - { - ReteEngine engine; - engine = new ReteEngine(context, reteThreads); - ReteContainerBuildable buildable = new ReteContainerBuildable(engine); - EPMBuilder, Address> builder = - new EPMBuilder, Address> (buildable, context); - engine.setBuilder(builder); - return engine; - } - - - /** - * To be called after already removed from engineManager. - */ - void killInternal() { - wipe(); - if (baseIndex != null) { - baseIndex.dispose(); - } - getLogger().removeAppender(taintListener); - } - - /** - * Run-time events (such as exceptions during expression evaluation) will be logged to this logger. - *

    - * DEFAULT BEHAVIOUR: - * If Eclipse is running, the default logger pipes to the Eclipse Error Log. - * Otherwise, messages are written to stderr. - *

    - * @return the logger that errors will be logged to during runtime execution. - */ - public Logger getLogger() { - if (logger == null) { - final int hash = System.identityHashCode(this); - logger = Logger.getLogger(getDefaultLogger().getName() + "." + hash); - if (logger == null) - throw new AssertionError("Configuration error: unable to create EMF-IncQuery runtime logger for engine " + hash); - - // if an error is logged, the engine becomes tainted - taintListener = new SelfTaintListener(this); - logger.addAppender(taintListener); - } - return logger; - } -// -// -// /** -// * Run-time events (such as exceptions during expression evaluation) will be logged to the specified logger. -// *

    -// * DEFAULT BEHAVIOUR: -// * If Eclipse is running, the default logger pipes to the Eclipse Error Log. -// * Otherwise, messages are written to stderr. -// * In both cases, debug messages are ignored. -// *

    -// * @param logger a custom logger that errors will be logged to during runtime execution. -// */ -// public void setLogger(EMFIncQueryRuntimeLogger logger) { -// this.logger = logger; -// } - - - - /** - * @return the sanitizer - */ - public PatternSanitizer getSanitizer() { - if (sanitizer == null) { - sanitizer = new PatternSanitizer(getLogger()); - } - return sanitizer; - } - - /** - * Provides a static default logger. - */ - public static Logger getDefaultLogger() { - if (defaultRuntimeLogger == null) { - final Injector injector = XtextInjectorProvider.INSTANCE.getInjector(); - if (injector==null) - throw new AssertionError("Configuration error: EMF-IncQuery injector not initialized."); - Logger parentLogger = injector.getInstance(Logger.class); - if (parentLogger == null) - throw new AssertionError("Configuration error: EMF-IncQuery logger not found."); - - defaultRuntimeLogger = Logger.getLogger(parentLogger.getName() + ".runtime"); - if (defaultRuntimeLogger == null) - throw new AssertionError("Configuration error: unable to create default EMF-IncQuery runtime logger."); - } - - return defaultRuntimeLogger; - } - private static Logger defaultRuntimeLogger; - - /** - * Specifies whether the base index should be built in wildcard mode. See {@link NavigationHelper} for the explanation of wildcard mode. - * @param wildcardMode the wildcardMode to set - * @throws IncQueryException if the base index could not be initialized - * @throws IllegalStateException if baseIndex is already constructed in the opposite mode, since the mode can not be changed once applied - */ - public void setWildcardMode(boolean wildcardMode) throws IncQueryException { - if (baseIndex != null && baseIndex.isInWildcardMode() != wildcardMode) - throw new IllegalStateException("Base index already built, cannot change wildcard mode anymore"); - - if (wildcardMode != WILDCARD_MODE_DEFAULT) - getBaseIndexInternal(wildcardMode, true); - } - - /** - * Indicates whether the engine is in a tainted, inconsistent state due to some internal errors. - * If true, results are no longer reliable; engine should be disposed. - * - *

    The engine is defined to be in a tainted state if any of its internal processes has logged a fatal error to the engine's logger. - * The cause of the error can therefore be determined by checking the contents of the log. - * This is possible e.g. through a custom {@link Appender} that was attached to the engine's logger. - * - * @return the tainted state - */ - public boolean isTainted() { - return tainted; - } - - - /** - * Indicates whether the engine is managed by {@link EngineManager}. - * - *

    If the engine is managed, there may be other clients using it. - * Care should be taken with {@link #wipe()} and {@link #dispose()}. - * Register a callback using {@link IncQueryMatcher#addCallbackAfterWipes(Runnable)} - * or directly at {@link #getAfterWipeCallbacks()} to learn when a - * client has called these dangerous methods. - * - * @return true if the engine is managed, and therefore potentially - * shared with other clients querying the same EMF model - */ - public boolean isManaged() { - return manager != null; - } - - /** - * @return the set of callbacks that will be issued after a wipe - */ - public Set getAfterWipeCallbacks() { - return afterWipeCallbacks; - } - - - -// /** -// * EXPERIMENTAL: Creates an EMF-IncQuery engine that executes post-commit, or retrieves an already existing one. -// * @param emfRoot the EMF root where this engine should operate -// * @param reteThreads experimental feature; 0 is recommended -// * @return a new or previously existing engine -// * @throws IncQueryRuntimeException -// */ -// public ReteEngine getReteEngine(final TransactionalEditingDomain editingDomain, int reteThreads) throws IncQueryRuntimeException { -// final ResourceSet resourceSet = editingDomain.getResourceSet(); -// WeakReference> weakReference = engines.get(resourceSet); -// ReteEngine engine = weakReference != null ? weakReference.get() : null; -// if (engine == null) { -// IPatternMatcherRuntimeContext context = new EMFPatternMatcherRuntimeContext.ForTransactionalEditingDomain(editingDomain); -// engine = buildReteEngine(context, reteThreads); -// if (engine != null) engines.put(resourceSet, new WeakReference>(engine)); -// } -// return engine; -// } - + + /** + * Discards any pattern matcher caches and forgets known patterns. The base index built directly on the underlying + * EMF model, however, is kept in memory to allow reuse when new pattern matchers are built. Use this method if you + * have e.g. new versions of the same patterns, to be matched on the same model. + * + *

    + * Matcher objects will continue to return stale results. If no references are retained to the matchers, they can + * eventually be GC'ed. + *

    + * If the engine is managed (see {@link #isManaged()}), there may be other clients using it. Care should be taken + * with wiping such engines. + * + */ + public void wipe() { + if (manager != null) { + logger.warn(String.format("Managed engine wiped for notifier %s !", emfRoot)); + } + if (reteEngine != null) { + reteEngine.killEngine(); + reteEngine = null; + } + sanitizer = null; + runAfterWipeCallbacks(); + } + + /** + * This will run before wipes. + */ + // * If there are any such, updates are settled before they are run. + public void runAfterWipeCallbacks() { + try { + if (!afterWipeCallbacks.isEmpty()) { + // settle(); + for (Runnable runnable : new ArrayList(afterWipeCallbacks)) { + runnable.run(); + } + } + } catch (Exception ex) { + logger.fatal("EMF-IncQuery encountered an error in delivering notifications about wipe. ", ex); + } + } + + private ReteEngine buildReteEngineInternal(IPatternMatcherRuntimeContext context) { + ReteEngine engine; + engine = new ReteEngine(context, reteThreads); + ReteContainerBuildable buildable = new ReteContainerBuildable(engine); + EPMBuilder, Address> builder = new EPMBuilder, Address>( + buildable, context); + engine.setBuilder(builder); + return engine; + } + + /** + * To be called after already removed from engineManager. + */ + void killInternal() { + wipe(); + if (baseIndex != null) { + baseIndex.dispose(); + } + getLogger().removeAppender(taintListener); + } + + /** + * Run-time events (such as exceptions during expression evaluation) will be logged to this logger. + *

    + * DEFAULT BEHAVIOUR: If Eclipse is running, the default logger pipes to the Eclipse Error Log. Otherwise, messages + * are written to stderr. + *

    + * + * @return the logger that errors will be logged to during runtime execution. + */ + public Logger getLogger() { + if (logger == null) { + final int hash = System.identityHashCode(this); + logger = Logger.getLogger(getDefaultLogger().getName() + "." + hash); + if (logger == null) + throw new AssertionError( + "Configuration error: unable to create EMF-IncQuery runtime logger for engine " + hash); + + // if an error is logged, the engine becomes tainted + taintListener = new SelfTaintListener(this); + logger.addAppender(taintListener); + } + return logger; + } + + // + // + // /** + // * Run-time events (such as exceptions during expression evaluation) will be logged to the specified logger. + // *

    + // * DEFAULT BEHAVIOUR: + // * If Eclipse is running, the default logger pipes to the Eclipse Error Log. + // * Otherwise, messages are written to stderr. + // * In both cases, debug messages are ignored. + // *

    + // * @param logger a custom logger that errors will be logged to during runtime execution. + // */ + // public void setLogger(EMFIncQueryRuntimeLogger logger) { + // this.logger = logger; + // } + + /** + * @return the sanitizer + */ + public PatternSanitizer getSanitizer() { + if (sanitizer == null) { + sanitizer = new PatternSanitizer(getLogger()); + } + return sanitizer; + } + + /** + * Provides a static default logger. + */ + public static Logger getDefaultLogger() { + if (defaultRuntimeLogger == null) { + final Injector injector = XtextInjectorProvider.INSTANCE.getInjector(); + if (injector == null) + throw new AssertionError("Configuration error: EMF-IncQuery injector not initialized."); + Logger parentLogger = injector.getInstance(Logger.class); + if (parentLogger == null) + throw new AssertionError("Configuration error: EMF-IncQuery logger not found."); + + defaultRuntimeLogger = Logger.getLogger(parentLogger.getName() + ".runtime"); + if (defaultRuntimeLogger == null) + throw new AssertionError("Configuration error: unable to create default EMF-IncQuery runtime logger."); + } + + return defaultRuntimeLogger; + } + + private static Logger defaultRuntimeLogger; + + /** + * Specifies whether the base index should be built in wildcard mode. See {@link NavigationHelper} for the + * explanation of wildcard mode. + * + * @param wildcardMode + * the wildcardMode to set + * @throws IncQueryException + * if the base index could not be initialized + * @throws IllegalStateException + * if baseIndex is already constructed in the opposite mode, since the mode can not be changed once + * applied + */ + public void setWildcardMode(boolean wildcardMode) throws IncQueryException { + if (baseIndex != null && baseIndex.isInWildcardMode() != wildcardMode) + throw new IllegalStateException("Base index already built, cannot change wildcard mode anymore"); + + if (wildcardMode != WILDCARD_MODE_DEFAULT) + getBaseIndexInternal(wildcardMode, true); + } + + /** + * Indicates whether the engine is in a tainted, inconsistent state due to some internal errors. If true, results + * are no longer reliable; engine should be disposed. + * + *

    + * The engine is defined to be in a tainted state if any of its internal processes has logged a + * fatal error to the engine's logger. The cause of the error can therefore be determined by + * checking the contents of the log. This is possible e.g. through a custom {@link Appender} that was attached to + * the engine's logger. + * + * @return the tainted state + */ + public boolean isTainted() { + return tainted; + } + + /** + * Indicates whether the engine is managed by {@link EngineManager}. + * + *

    + * If the engine is managed, there may be other clients using it. Care should be taken with {@link #wipe()} and + * {@link #dispose()}. Register a callback using {@link IncQueryMatcher#addCallbackAfterWipes(Runnable)} or directly + * at {@link #getAfterWipeCallbacks()} to learn when a client has called these dangerous methods. + * + * @return true if the engine is managed, and therefore potentially shared with other clients querying the same EMF + * model + */ + public boolean isManaged() { + return manager != null; + } + + /** + * @return the set of callbacks that will be issued after a wipe + */ + public Set getAfterWipeCallbacks() { + return afterWipeCallbacks; + } + + // /** + // * EXPERIMENTAL: Creates an EMF-IncQuery engine that executes post-commit, or retrieves an already existing one. + // * @param emfRoot the EMF root where this engine should operate + // * @param reteThreads experimental feature; 0 is recommended + // * @return a new or previously existing engine + // * @throws IncQueryRuntimeException + // */ + // public ReteEngine getReteEngine(final TransactionalEditingDomain editingDomain, int reteThreads) throws + // IncQueryRuntimeException { + // final ResourceSet resourceSet = editingDomain.getResourceSet(); + // WeakReference> weakReference = engines.get(resourceSet); + // ReteEngine engine = weakReference != null ? weakReference.get() : null; + // if (engine == null) { + // IPatternMatcherRuntimeContext context = new + // EMFPatternMatcherRuntimeContext.ForTransactionalEditingDomain(editingDomain); + // engine = buildReteEngine(context, reteThreads); + // if (engine != null) engines.put(resourceSet, new WeakReference>(engine)); + // } + // return engine; + // } + } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/IncQueryMatcher.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/IncQueryMatcher.java index 5591c5d8..18b7625b 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/IncQueryMatcher.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/IncQueryMatcher.java @@ -20,298 +20,404 @@ /** * Interface for an EMF-IncQuery matcher associated with a graph pattern. * - * @param the IPatternMatch type representing a single match of this pattern. + * @param + * the IPatternMatch type representing a single match of this pattern. * @author Bergmann Gábor */ public interface IncQueryMatcher { - // REFLECTION - /** The pattern that will be matched. */ - public abstract Pattern getPattern(); - /** Fully qualified name of the pattern. */ - public abstract String getPatternName(); - /** Returns the index of the symbolic parameter with the given name. */ - public abstract Integer getPositionOfParameter(String parameterName); - /** Returns the array of symbolic parameter names. */ - public abstract String[] getParameterNames(); - - // ALL MATCHES - /** - * Returns the set of all pattern matches. - * @return matches represented as a Match object. - */ - public abstract Collection getAllMatches(); - /** - * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. - * @param partialMatch a partial match of the pattern where each non-null field binds the corresponding pattern parameter to a fixed value. - * @return matches represented as a Match object. - */ - public abstract Collection getAllMatches(Match partialMatch); - // variant(s) with input binding as pattern-specific parameters: not declared in interface - - // SINGLE MATCH - /** - * Returns an arbitrarily chosen pattern match. - * Neither determinism nor randomness of selection is guaranteed. - * @return a match represented as a Match object, or null if no match is found. - */ - public abstract Match getOneArbitraryMatch(); - /** - * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. - * Neither determinism nor randomness of selection is guaranteed. - * @param partialMatch a partial match of the pattern where each non-null field binds the corresponding pattern parameter to a fixed value. - * @return a match represented as a Match object, or null if no match is found. - */ - public abstract Match getOneArbitraryMatch(Match partialMatch); - // variant(s) with input binding as pattern-specific parameters: not declared in interface - - // MATCH CHECKING - /** - * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, - * under any possible substitution of the unspecified parameters (if any). - * @param partialMatch a (partial) match of the pattern where each non-null field binds the corresponding pattern parameter to a fixed value. - * @return true if the input is a valid (partial) match of the pattern. - */ - public abstract boolean hasMatch(Match partialMatch); - // variant(s) with input binding as pattern-specific parameters: not declared in interface - - // NUMBER OF MATCHES - /** - * Returns the number of all pattern matches. - * @return the number of pattern matches found. - */ - public abstract int countMatches(); - /** - * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. - * @param partialMatch a partial match of the pattern where each non-null field binds the corresponding pattern parameter to a fixed value. - * @return the number of pattern matches found. - */ - public abstract int countMatches(Match partialMatch); - // variant(s) with input binding as pattern-specific parameters: not declared in interface - - // FOR EACH MATCH - /** - * Executes the given processor on each match of the pattern. - * @param action the action that will process each pattern match. - */ - public abstract void forEachMatch(IMatchProcessor processor); - /** - * Executes the given processor on each match of the pattern that conforms to the given fixed values of some parameters. - * @param parameters array where each non-null element binds the corresponding pattern parameter to a fixed value. - * @param processor the action that will process each pattern match. - */ - public abstract void forEachMatch(Match partialMatch, IMatchProcessor processor); - // variant(s) with input binding as pattern-specific parameters: not declared in interface - - // FOR ONE ARBITRARY MATCH - /** - * Executes the given processor on an arbitrarily chosen match of the pattern. - * Neither determinism nor randomness of selection is guaranteed. - * - * @param processor the action that will process the selected match. - * @return true if the pattern has at least one match, false if the processor was not invoked - */ - public abstract boolean forOneArbitraryMatch(IMatchProcessor processor); - /** - * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. - * Neither determinism nor randomness of selection is guaranteed. - * - * @param parameters array where each non-null element binds the corresponding pattern parameter to a fixed value. - * @param processor the action that will process the selected match. - * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked - */ - public abstract boolean forOneArbitraryMatch(Match partialMatch, IMatchProcessor processor); - // variant(s) with input binding as pattern-specific parameters: not declared in interface - - // CHANGE MONITORING - // attach delta monitor for high-level change detection - /** - * Registers low-level callbacks for match appearance and disappearance on this pattern matcher. - * - *

    This is a low-level callback that is invoked when the pattern matcher is not necessarily in a consistent state yet. - * Most users should use the agenda and trigger engine instead. TODO reference - * - *

    Performance note: expected to be much more efficient than polling at {@link #addCallbackAfterUpdates(Runnable)}, - * but prone to "signal hazards", e.g. spurious match appearances that will disappear immediately afterwards. - * - *

    The callback can be unregistered via {@link #removeCallbackOnMatchUpdate(IMatchUpdateListener)}. - * - * @param fireNow if true, appearCallback will be immediately invoked on all current matches as a one-time effect. - * See also {@link IncQueryMatcher#forEachMatch(IMatchProcessor)}. - * @param listener the listener that will be notified of each new match that appears or disappears, starting from now. - */ - public abstract void addCallbackOnMatchUpdate(IMatchUpdateListener listener, boolean fireNow); - /** - * Unregisters a callback registered by {@link #addCallbackOnMatchUpdate(IMatchUpdateListener, boolean)}. - * @param listener the listener that will no longer be notified. - */ - public abstract void removeCallbackOnMatchUpdate(IMatchUpdateListener listener); - /** - * Registers a new delta monitor on this pattern matcher. - * The DeltaMonitor can be used to track changes (delta) in the set of pattern matches from now on. - * It can also be reset to track changes from a later point in time, - * and changes can even be acknowledged on an individual basis. - * See {@link DeltaMonitor} for details. - * @param fillAtStart if true, all current matches are reported as new match events; if false, the delta monitor starts empty. - * @return the delta monitor. - */ - public abstract DeltaMonitor newDeltaMonitor(boolean fillAtStart); - /** - * Registers a new filtered delta monitor on this pattern matcher. - * The DeltaMonitor can be used to track changes (delta) in the set of filtered pattern matches from now on, - * considering those matches only that conform to the given fixed values of some parameters. - * It can also be reset to track changes from a later point in time, - * and changes can even be acknowledged on an individual basis. - * See {@link DeltaMonitor} for details. - * @param fillAtStart if true, all current matches are reported as new match events; if false, the delta monitor starts empty. - * @param partialMatch a partial match of the pattern where each non-null field binds the corresponding pattern parameter to a fixed value. - * @return the delta monitor. - */ - public abstract DeltaMonitor newFilteredDeltaMonitor(boolean fillAtStart, Match partialMatch); - /** - * Registers a callback that will be run each time EMF-IncQuery match sets are refreshed after a model update. - * Typically useful to check delta monitors. - * When the callback is issued, the pattern match sets are guaranteed to reflect the post-state after the update. - *

    Callbacks are issued after each elementary change (i.e. possibly at incomplete transient states). - * This can have a negative effect on performance, therefore clients are advised to use it as a last resort only. - * Consider coarser-grained timing (e.g EMF Transaction pre/post-commit) instead, whenever available. - * @param callback a Runnable to execute after each update. - * @return false if the callback was already registered. - */ - public boolean addCallbackAfterUpdates(Runnable callback); - /** - * Removes a previously registered callback. See addCallbackAfterUpdates(). - * @param callback the callback to remove. - * @return false if the callback was not registered. - */ - public boolean removeCallbackAfterUpdates(Runnable callback); - /** - * Registers a callback that will be run each time the EMF-IncQuery engine is wiped or disposed. - * Typically useful if delta monitors are used, especially of the {@link IncQueryEngine} is managed. - * - *

    When the callback is issued, the wipe has already occurred and pattern matchers will continue to return stale results. - * @param callback a Runnable to execute after each wipe. - * @return false if the callback was already registered. - */ - public boolean addCallbackAfterWipes(Runnable callback); - /** - * Removes a previously registered callback. See {@link #addCallbackAfterWipes()}. - * @param callback the callback to remove. - * @return false if the callback was not registered. - */ - public boolean removeCallbackAfterWipes(Runnable callback); - - // ARRAY-BASED INTERFACE - - /** Converts the array representation of a pattern match to a Match object. */ - public Match arrayToMatch(Object[] parameters); - /** Converts the Match object of a pattern match to the array representation. */ - public Object[] matchToArray(Match partialMatch); - - /** - * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. - * @param parameters array where each non-null element binds the corresponding pattern parameter to a fixed value. - * @pre size of input array must be equal to the number of parameters. - * @return matches represented as a Match object. - */ - public abstract Collection rawGetAllMatches(Object[] parameters); - /** - * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. - * Neither determinism nor randomness of selection is guaranteed. - * - * @param parameters array where each non-null element binds the corresponding pattern parameter to a fixed value. - * @pre size of input array must be equal to the number of parameters. - * @return a match represented as a Match object, or null if no match is found. - */ - public abstract Match rawGetOneArbitraryMatch(Object[] parameters); - /** - * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, - * under any possible substitution of the unspecified parameters. - * @param parameters array where each non-null element binds the corresponding pattern parameter to a fixed value. - * @return true if the input is a valid (partial) match of the pattern. - */ - public abstract boolean rawHasMatch(Object[] parameters); - /** - * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. - * @param parameters array where each non-null element binds the corresponding pattern parameter to a fixed value. - * @pre size of input array must be equal to the number of parameters. - * @return the number of pattern matches found. - */ - public abstract int rawCountMatches(Object[] parameters); - /** - * Executes the given processor on each match of the pattern that conforms to the given fixed values of some parameters. - * @param parameters array where each non-null element binds the corresponding pattern parameter to a fixed value. - * @pre size of input array must be equal to the number of parameters. - * @param action the action that will process each pattern match. - */ - public abstract void rawForEachMatch(Object[] parameters, IMatchProcessor processor); - /** - * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. - * Neither determinism nor randomness of selection is guaranteed. - * - * @param parameters array where each non-null element binds the corresponding pattern parameter to a fixed value. - * @pre size of input array must be equal to the number of parameters. - * @param processor the action that will process the selected match. - * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked - */ - public abstract boolean rawForOneArbitraryMatch(Object[] parameters, IMatchProcessor processor); - /** - * Registers a new filtered delta monitor on this pattern matcher. - * The DeltaMonitor can be used to track changes (delta) in the set of filtered pattern matches from now on, - * considering those matches only that conform to the given fixed values of some parameters. - * It can also be reset to track changes from a later point in time, - * and changes can even be acknowledged on an individual basis. - * See {@link DeltaMonitor} for details. - * @param fillAtStart if true, all current matches are reported as new match events; if false, the delta monitor starts empty. - * @param parameters array where each non-null element binds the corresponding pattern parameter to a fixed value. - * @return the delta monitor. - */ - public abstract DeltaMonitor rawNewFilteredDeltaMonitor(boolean fillAtStart, final Object[] parameters); - /** - * Returns an empty Match for the matcher. This can be used to call the matcher with a partial match even - * if the specific class of the matcher or the match is unknown. - * - * @return the empty match - */ - public abstract Match newEmptyMatch(); - /** - * Returns a new (partial) Match object for the matcher. - * This can be used e.g. to call the matcher with a partial match. - * @param parameters the fixed value of pattern parameters, or null if not bound. - * @return the (partial) match object. - */ - public abstract Match newMatch(Object... parameters); - /** - * Retrieve the set of values that occur in matches for the given parameterName. - * - * @param parameterName name of the parameter for which values are returned - * @return the Set of all values for the given parameter, - * null if the parameter with the given name does not exists, - * empty set if there are no matches - */ - public abstract Set getAllValues(final String parameterName); - /** - * Retrieve the set of values that occur in matches for the given parameterName, that conforms to the given fixed values of some parameters. - * @param parameterName name of the parameter for which values are returned - * @param partialMatch a partial match of the pattern where each non-null field binds the corresponding pattern parameter to a fixed value. - * @return the Set of all values for the given parameter, - * null if the parameter with the given name does not exists or if the parameter with the given name is set in partialMatch, - * empty set if there are no matches - */ - public abstract Set getAllValues(final String parameterName, Match partialMatch); - /** - * Retrieve the set of values that occur in matches for the given parameterName, that conforms to the given fixed values of some parameters. - * @param position position of the parameter for which values are returned - * @param parameters a parameter array corresponding to a partial match of the - * pattern where each non-null field binds the corresponding pattern parameter to a fixed value. - * @return the Set of all values in the given position, - * null if no parameter with the given position exists or if parameters[position] is set, - * empty set if there are no matches - */ - public abstract Set rawGetAllValues(final int position, Object[] parameters); - /** - * Returns the engine that the matcher uses. - * - * @return the engine - */ - public abstract IncQueryEngine getEngine(); + // REFLECTION + /** The pattern that will be matched. */ + public abstract Pattern getPattern(); + + /** Fully qualified name of the pattern. */ + public abstract String getPatternName(); + + /** Returns the index of the symbolic parameter with the given name. */ + public abstract Integer getPositionOfParameter(String parameterName); + + /** Returns the array of symbolic parameter names. */ + public abstract String[] getParameterNames(); + + // ALL MATCHES + /** + * Returns the set of all pattern matches. + * + * @return matches represented as a Match object. + */ + public abstract Collection getAllMatches(); + + /** + * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. + * + * @param partialMatch + * a partial match of the pattern where each non-null field binds the corresponding pattern parameter to + * a fixed value. + * @return matches represented as a Match object. + */ + public abstract Collection getAllMatches(Match partialMatch); + + // variant(s) with input binding as pattern-specific parameters: not declared in interface + + // SINGLE MATCH + /** + * Returns an arbitrarily chosen pattern match. Neither determinism nor randomness of selection is guaranteed. + * + * @return a match represented as a Match object, or null if no match is found. + */ + public abstract Match getOneArbitraryMatch(); + + /** + * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * + * @param partialMatch + * a partial match of the pattern where each non-null field binds the corresponding pattern parameter to + * a fixed value. + * @return a match represented as a Match object, or null if no match is found. + */ + public abstract Match getOneArbitraryMatch(Match partialMatch); + + // variant(s) with input binding as pattern-specific parameters: not declared in interface + + // MATCH CHECKING + /** + * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, under + * any possible substitution of the unspecified parameters (if any). + * + * @param partialMatch + * a (partial) match of the pattern where each non-null field binds the corresponding pattern parameter + * to a fixed value. + * @return true if the input is a valid (partial) match of the pattern. + */ + public abstract boolean hasMatch(Match partialMatch); + + // variant(s) with input binding as pattern-specific parameters: not declared in interface + + // NUMBER OF MATCHES + /** + * Returns the number of all pattern matches. + * + * @return the number of pattern matches found. + */ + public abstract int countMatches(); + + /** + * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. + * + * @param partialMatch + * a partial match of the pattern where each non-null field binds the corresponding pattern parameter to + * a fixed value. + * @return the number of pattern matches found. + */ + public abstract int countMatches(Match partialMatch); + + // variant(s) with input binding as pattern-specific parameters: not declared in interface + + // FOR EACH MATCH + /** + * Executes the given processor on each match of the pattern. + * + * @param action + * the action that will process each pattern match. + */ + public abstract void forEachMatch(IMatchProcessor processor); + + /** + * Executes the given processor on each match of the pattern that conforms to the given fixed values of some + * parameters. + * + * @param parameters + * array where each non-null element binds the corresponding pattern parameter to a fixed value. + * @param processor + * the action that will process each pattern match. + */ + public abstract void forEachMatch(Match partialMatch, IMatchProcessor processor); + + // variant(s) with input binding as pattern-specific parameters: not declared in interface + + // FOR ONE ARBITRARY MATCH + /** + * Executes the given processor on an arbitrarily chosen match of the pattern. Neither determinism nor randomness of + * selection is guaranteed. + * + * @param processor + * the action that will process the selected match. + * @return true if the pattern has at least one match, false if the processor was not invoked + */ + public abstract boolean forOneArbitraryMatch(IMatchProcessor processor); + + /** + * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed + * values of some parameters. Neither determinism nor randomness of selection is guaranteed. + * + * @param parameters + * array where each non-null element binds the corresponding pattern parameter to a fixed value. + * @param processor + * the action that will process the selected match. + * @return true if the pattern has at least one match with the given parameter values, false if the processor was + * not invoked + */ + public abstract boolean forOneArbitraryMatch(Match partialMatch, IMatchProcessor processor); + + // variant(s) with input binding as pattern-specific parameters: not declared in interface + + // CHANGE MONITORING + // attach delta monitor for high-level change detection + /** + * Registers low-level callbacks for match appearance and disappearance on this pattern matcher. + * + *

    + * This is a low-level callback that is invoked when the pattern matcher is not necessarily in a consistent state + * yet. Most users should use the agenda and trigger engine instead. TODO reference + * + *

    + * Performance note: expected to be much more efficient than polling at {@link #addCallbackAfterUpdates(Runnable)}, + * but prone to "signal hazards", e.g. spurious match appearances that will disappear immediately afterwards. + * + *

    + * The callback can be unregistered via {@link #removeCallbackOnMatchUpdate(IMatchUpdateListener)}. + * + * @param fireNow + * if true, appearCallback will be immediately invoked on all current matches as a one-time effect. See + * also {@link IncQueryMatcher#forEachMatch(IMatchProcessor)}. + * @param listener + * the listener that will be notified of each new match that appears or disappears, starting from now. + */ + public abstract void addCallbackOnMatchUpdate(IMatchUpdateListener listener, boolean fireNow); + + /** + * Unregisters a callback registered by {@link #addCallbackOnMatchUpdate(IMatchUpdateListener, boolean)}. + * + * @param listener + * the listener that will no longer be notified. + */ + public abstract void removeCallbackOnMatchUpdate(IMatchUpdateListener listener); + + /** + * Registers a new delta monitor on this pattern matcher. The DeltaMonitor can be used to track changes (delta) in + * the set of pattern matches from now on. It can also be reset to track changes from a later point in time, and + * changes can even be acknowledged on an individual basis. See {@link DeltaMonitor} for details. + * + * @param fillAtStart + * if true, all current matches are reported as new match events; if false, the delta monitor starts + * empty. + * @return the delta monitor. + */ + public abstract DeltaMonitor newDeltaMonitor(boolean fillAtStart); + + /** + * Registers a new filtered delta monitor on this pattern matcher. The DeltaMonitor can be used to track changes + * (delta) in the set of filtered pattern matches from now on, considering those matches only that conform to the + * given fixed values of some parameters. It can also be reset to track changes from a later point in time, and + * changes can even be acknowledged on an individual basis. See {@link DeltaMonitor} for details. + * + * @param fillAtStart + * if true, all current matches are reported as new match events; if false, the delta monitor starts + * empty. + * @param partialMatch + * a partial match of the pattern where each non-null field binds the corresponding pattern parameter to + * a fixed value. + * @return the delta monitor. + */ + public abstract DeltaMonitor newFilteredDeltaMonitor(boolean fillAtStart, Match partialMatch); + + /** + * Registers a callback that will be run each time EMF-IncQuery match sets are refreshed after a model update. + * Typically useful to check delta monitors. When the callback is issued, the pattern match sets are guaranteed to + * reflect the post-state after the update. + *

    + * Callbacks are issued after each elementary change (i.e. possibly at incomplete transient states). This can have a + * negative effect on performance, therefore clients are advised to use it as a last resort only. Consider + * coarser-grained timing (e.g EMF Transaction pre/post-commit) instead, whenever available. + * + * @param callback + * a Runnable to execute after each update. + * @return false if the callback was already registered. + */ + public boolean addCallbackAfterUpdates(Runnable callback); + + /** + * Removes a previously registered callback. See addCallbackAfterUpdates(). + * + * @param callback + * the callback to remove. + * @return false if the callback was not registered. + */ + public boolean removeCallbackAfterUpdates(Runnable callback); + + /** + * Registers a callback that will be run each time the EMF-IncQuery engine is wiped or disposed. Typically useful if + * delta monitors are used, especially of the {@link IncQueryEngine} is managed. + * + *

    + * When the callback is issued, the wipe has already occurred and pattern matchers will continue to return stale + * results. + * + * @param callback + * a Runnable to execute after each wipe. + * @return false if the callback was already registered. + */ + public boolean addCallbackAfterWipes(Runnable callback); + + /** + * Removes a previously registered callback. See {@link #addCallbackAfterWipes()}. + * + * @param callback + * the callback to remove. + * @return false if the callback was not registered. + */ + public boolean removeCallbackAfterWipes(Runnable callback); + + // ARRAY-BASED INTERFACE + + /** Converts the array representation of a pattern match to a Match object. */ + public Match arrayToMatch(Object[] parameters); + + /** Converts the Match object of a pattern match to the array representation. */ + public Object[] matchToArray(Match partialMatch); + + /** + * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. + * + * @param parameters + * array where each non-null element binds the corresponding pattern parameter to a fixed value. + * @pre size of input array must be equal to the number of parameters. + * @return matches represented as a Match object. + */ + public abstract Collection rawGetAllMatches(Object[] parameters); + + /** + * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * + * @param parameters + * array where each non-null element binds the corresponding pattern parameter to a fixed value. + * @pre size of input array must be equal to the number of parameters. + * @return a match represented as a Match object, or null if no match is found. + */ + public abstract Match rawGetOneArbitraryMatch(Object[] parameters); + + /** + * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, under + * any possible substitution of the unspecified parameters. + * + * @param parameters + * array where each non-null element binds the corresponding pattern parameter to a fixed value. + * @return true if the input is a valid (partial) match of the pattern. + */ + public abstract boolean rawHasMatch(Object[] parameters); + + /** + * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. + * + * @param parameters + * array where each non-null element binds the corresponding pattern parameter to a fixed value. + * @pre size of input array must be equal to the number of parameters. + * @return the number of pattern matches found. + */ + public abstract int rawCountMatches(Object[] parameters); + + /** + * Executes the given processor on each match of the pattern that conforms to the given fixed values of some + * parameters. + * + * @param parameters + * array where each non-null element binds the corresponding pattern parameter to a fixed value. + * @pre size of input array must be equal to the number of parameters. + * @param action + * the action that will process each pattern match. + */ + public abstract void rawForEachMatch(Object[] parameters, IMatchProcessor processor); + + /** + * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed + * values of some parameters. Neither determinism nor randomness of selection is guaranteed. + * + * @param parameters + * array where each non-null element binds the corresponding pattern parameter to a fixed value. + * @pre size of input array must be equal to the number of parameters. + * @param processor + * the action that will process the selected match. + * @return true if the pattern has at least one match with the given parameter values, false if the processor was + * not invoked + */ + public abstract boolean rawForOneArbitraryMatch(Object[] parameters, IMatchProcessor processor); + + /** + * Registers a new filtered delta monitor on this pattern matcher. The DeltaMonitor can be used to track changes + * (delta) in the set of filtered pattern matches from now on, considering those matches only that conform to the + * given fixed values of some parameters. It can also be reset to track changes from a later point in time, and + * changes can even be acknowledged on an individual basis. See {@link DeltaMonitor} for details. + * + * @param fillAtStart + * if true, all current matches are reported as new match events; if false, the delta monitor starts + * empty. + * @param parameters + * array where each non-null element binds the corresponding pattern parameter to a fixed value. + * @return the delta monitor. + */ + public abstract DeltaMonitor rawNewFilteredDeltaMonitor(boolean fillAtStart, final Object[] parameters); + + /** + * Returns an empty Match for the matcher. This can be used to call the matcher with a partial match even if the + * specific class of the matcher or the match is unknown. + * + * @return the empty match + */ + public abstract Match newEmptyMatch(); + + /** + * Returns a new (partial) Match object for the matcher. This can be used e.g. to call the matcher with a partial + * match. + * + * @param parameters + * the fixed value of pattern parameters, or null if not bound. + * @return the (partial) match object. + */ + public abstract Match newMatch(Object... parameters); + + /** + * Retrieve the set of values that occur in matches for the given parameterName. + * + * @param parameterName + * name of the parameter for which values are returned + * @return the Set of all values for the given parameter, null if the parameter with the given name does not exists, + * empty set if there are no matches + */ + public abstract Set getAllValues(final String parameterName); + + /** + * Retrieve the set of values that occur in matches for the given parameterName, that conforms to the given fixed + * values of some parameters. + * + * @param parameterName + * name of the parameter for which values are returned + * @param partialMatch + * a partial match of the pattern where each non-null field binds the corresponding pattern parameter to + * a fixed value. + * @return the Set of all values for the given parameter, null if the parameter with the given name does not exists + * or if the parameter with the given name is set in partialMatch, empty set if there are no matches + */ + public abstract Set getAllValues(final String parameterName, Match partialMatch); + + /** + * Retrieve the set of values that occur in matches for the given parameterName, that conforms to the given fixed + * values of some parameters. + * + * @param position + * position of the parameter for which values are returned + * @param parameters + * a parameter array corresponding to a partial match of the pattern where each non-null field binds the + * corresponding pattern parameter to a fixed value. + * @return the Set of all values in the given position, null if no parameter with the given position exists or if + * parameters[position] is set, empty set if there are no matches + */ + public abstract Set rawGetAllValues(final int position, Object[] parameters); + + /** + * Returns the engine that the matcher uses. + * + * @return the engine + */ + public abstract IncQueryEngine getEngine(); } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/MatchUpdateAdapter.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/MatchUpdateAdapter.java index 019ade17..c9043985 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/MatchUpdateAdapter.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/MatchUpdateAdapter.java @@ -11,91 +11,90 @@ package org.eclipse.incquery.runtime.api; /** - * A default implementation of {@link IMatchUpdateListener} that contains two match processors, one for appearance, one for disappearance. - * Any of the two can be null; in this case, corresponding notifications will be ignored. + * A default implementation of {@link IMatchUpdateListener} that contains two match processors, one for appearance, one + * for disappearance. Any of the two can be null; in this case, corresponding notifications will be ignored. * - *

    Instantiate using either constructor. + *

    + * Instantiate using either constructor. * * @author Bergmann Gabor - * + * */ public class MatchUpdateAdapter implements IMatchUpdateListener { - IMatchProcessor appearCallback; - IMatchProcessor disappearCallback; - - - /** - * Constructs an instance without any match processors registered yet. - * - * Use {@link #setAppearCallback(IMatchProcessor)} and {@link #setDisappearCallback(IMatchProcessor)} - * to specify optional match processors for match appearance and disappearance, respectively. - */ - public MatchUpdateAdapter() { - super(); - } - - - /** - * Constructs an instance by specifying match processors. - * - * @param appearCallback a match processor that will be invoked on each new match that appears. - * If null, no callback will be executed on match appearance. See {@link IMatchProcessor} for details on how to implement. - * @param disappearCallback a match processor that will be invoked on each existing match that disappears. - * If null, no callback will be executed on match disappearance. See {@link IMatchProcessor} for details on how to implement. - */ - public MatchUpdateAdapter( - IMatchProcessor appearCallback, - IMatchProcessor disappearCallback) { - super(); - setAppearCallback(appearCallback); - setDisappearCallback(disappearCallback); - } + IMatchProcessor appearCallback; + IMatchProcessor disappearCallback; + /** + * Constructs an instance without any match processors registered yet. + * + * Use {@link #setAppearCallback(IMatchProcessor)} and {@link #setDisappearCallback(IMatchProcessor)} to specify + * optional match processors for match appearance and disappearance, respectively. + */ + public MatchUpdateAdapter() { + super(); + } - /** - * @return the match processor that will be invoked on each new match that appears. - * If null, no callback will be executed on match appearance. - */ - public IMatchProcessor getAppearCallback() { - return appearCallback; - } + /** + * Constructs an instance by specifying match processors. + * + * @param appearCallback + * a match processor that will be invoked on each new match that appears. If null, no callback will be + * executed on match appearance. See {@link IMatchProcessor} for details on how to implement. + * @param disappearCallback + * a match processor that will be invoked on each existing match that disappears. If null, no callback + * will be executed on match disappearance. See {@link IMatchProcessor} for details on how to implement. + */ + public MatchUpdateAdapter(IMatchProcessor appearCallback, IMatchProcessor disappearCallback) { + super(); + setAppearCallback(appearCallback); + setDisappearCallback(disappearCallback); + } + /** + * @return the match processor that will be invoked on each new match that appears. If null, no callback will be + * executed on match appearance. + */ + public IMatchProcessor getAppearCallback() { + return appearCallback; + } - /** - * @param appearCallback a match processor that will be invoked on each new match that appears. - * If null, no callback will be executed on match appearance. See {@link IMatchProcessor} for details on how to implement. - */ - public void setAppearCallback(IMatchProcessor appearCallback) { - this.appearCallback = appearCallback; - } + /** + * @param appearCallback + * a match processor that will be invoked on each new match that appears. If null, no callback will be + * executed on match appearance. See {@link IMatchProcessor} for details on how to implement. + */ + public void setAppearCallback(IMatchProcessor appearCallback) { + this.appearCallback = appearCallback; + } + /** + * @return the match processor that will be invoked on each existing match that disappears. If null, no callback + * will be executed on match disappearance. + */ + public IMatchProcessor getDisappearCallback() { + return disappearCallback; + } - /** - * @return the match processor that will be invoked on each existing match that disappears. - * If null, no callback will be executed on match disappearance. - */ - public IMatchProcessor getDisappearCallback() { - return disappearCallback; - } + /** + * @param disappearCallback + * a match processor that will be invoked on each existing match that disappears. If null, no callback + * will be executed on match disappearance. See {@link IMatchProcessor} for details on how to implement. + */ + public void setDisappearCallback(IMatchProcessor disappearCallback) { + this.disappearCallback = disappearCallback; + } - - /** - * @param disappearCallback a match processor that will be invoked on each existing match that disappears. - * If null, no callback will be executed on match disappearance. See {@link IMatchProcessor} for details on how to implement. - */ - public void setDisappearCallback(IMatchProcessor disappearCallback) { - this.disappearCallback = disappearCallback; - } - - @Override + @Override public void notifyAppearance(Match match) { - if (appearCallback != null) appearCallback.process(match); - }; - - @Override + if (appearCallback != null) + appearCallback.process(match); + }; + + @Override public void notifyDisappearance(Match match) { - if (disappearCallback != null) disappearCallback.process(match); - }; - + if (disappearCallback != null) + disappearCallback.process(match); + }; + } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/PackageBasedPatternGroup.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/PackageBasedPatternGroup.java index 90283149..b735fae0 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/PackageBasedPatternGroup.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/PackageBasedPatternGroup.java @@ -18,70 +18,67 @@ import org.eclipse.incquery.runtime.extensibility.MatcherFactoryRegistry; /** - * Package based {@link BasePatternGroup} implementation. It handles patterns as - * a group within the same package. + * Package based {@link BasePatternGroup} implementation. It handles patterns as a group within the same package. * * @author Abel Hegedus, Mark Czotter * */ public class PackageBasedPatternGroup extends BasePatternGroup { - private final Set> matcherFactories = new HashSet>(); - private final String packageName; - private final boolean includeSubPackages; - - public PackageBasedPatternGroup(String packageName) { - this(packageName, false); - } + private final Set> matcherFactories = new HashSet>(); + private final String packageName; + private final boolean includeSubPackages; - public PackageBasedPatternGroup(String packageName, - boolean includeSubPackages) { - super(); - this.packageName = packageName; - this.includeSubPackages = includeSubPackages; - refresh(); - } - - @Override - public Set getPatterns() { - return patterns(getMatcherFactories()); - } - - /** - * @return the packageName - */ - public String getPackageName() { - return packageName; - } - - /** - * @return the matcherFactories - */ - public Set> getMatcherFactories() { - return matcherFactories; - } - - /** - * @return the includeSubPackages - */ - public boolean isIncludeSubPackages() { - return includeSubPackages; - } + public PackageBasedPatternGroup(String packageName) { + this(packageName, false); + } - /** - * Refreshes the pattern group from the matcher registry based on the - * parameters used during the initialization - */ - public void refresh() { - refreshInternal(); - } + public PackageBasedPatternGroup(String packageName, boolean includeSubPackages) { + super(); + this.packageName = packageName; + this.includeSubPackages = includeSubPackages; + refresh(); + } - private void refreshInternal() { - if(isIncludeSubPackages()) { - this.matcherFactories.addAll(MatcherFactoryRegistry.getPatternSubTree(this.packageName)); - } else { - this.matcherFactories.addAll(MatcherFactoryRegistry.getPatternGroup(this.packageName)); - } - } + @Override + public Set getPatterns() { + return patterns(getMatcherFactories()); + } + + /** + * @return the packageName + */ + public String getPackageName() { + return packageName; + } + + /** + * @return the matcherFactories + */ + public Set> getMatcherFactories() { + return matcherFactories; + } + + /** + * @return the includeSubPackages + */ + public boolean isIncludeSubPackages() { + return includeSubPackages; + } + + /** + * Refreshes the pattern group from the matcher registry based on the parameters used during the initialization + */ + public void refresh() { + refreshInternal(); + } + + private void refreshInternal() { + if (isIncludeSubPackages()) { + this.matcherFactories.addAll(MatcherFactoryRegistry.getPatternSubTree(this.packageName)); + } else { + this.matcherFactories.addAll(MatcherFactoryRegistry.getPatternGroup(this.packageName)); + } + } } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/impl/BaseGeneratedMatcher.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/impl/BaseGeneratedMatcher.java index a01bbea1..5a91d940 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/impl/BaseGeneratedMatcher.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/impl/BaseGeneratedMatcher.java @@ -21,41 +21,38 @@ /** * Provides common functionality of pattern-specific generated matchers. + * * @author Bergmann Gábor * @param - * + * */ public abstract class BaseGeneratedMatcher extends BaseMatcher { - - protected IMatcherFactory> factory; - - public BaseGeneratedMatcher( - IncQueryEngine engine, - IMatcherFactory> factory) - throws IncQueryException - { - super(engine, accessMatcher(engine, factory.getPattern()), factory.getPattern()); - this.factory = factory; - } - - static RetePatternMatcher accessMatcher(IncQueryEngine engine, Pattern pattern) throws IncQueryException { - checkPattern(engine, pattern); - try { - return engine.getReteEngine().accessMatcher(pattern); - } catch (RetePatternBuildException e) { - throw new IncQueryException(e); - } - } - - - @Override - public Pattern getPattern() { - return factory.getPattern(); - } - - @Override - public String getPatternName() { - return factory.getPatternFullyQualifiedName(); - } - + + protected IMatcherFactory> factory; + + public BaseGeneratedMatcher(IncQueryEngine engine, + IMatcherFactory> factory) throws IncQueryException { + super(engine, accessMatcher(engine, factory.getPattern()), factory.getPattern()); + this.factory = factory; + } + + static RetePatternMatcher accessMatcher(IncQueryEngine engine, Pattern pattern) throws IncQueryException { + checkPattern(engine, pattern); + try { + return engine.getReteEngine().accessMatcher(pattern); + } catch (RetePatternBuildException e) { + throw new IncQueryException(e); + } + } + + @Override + public Pattern getPattern() { + return factory.getPattern(); + } + + @Override + public String getPatternName() { + return factory.getPatternFullyQualifiedName(); + } + } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/impl/BaseGeneratedMatcherFactory.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/impl/BaseGeneratedMatcherFactory.java index 6ff756ca..e56541be 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/impl/BaseGeneratedMatcherFactory.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/impl/BaseGeneratedMatcherFactory.java @@ -34,9 +34,9 @@ public abstract class BaseGeneratedMatcherFactory { private static Map bundleNameToPatternModelMap = new HashMap(); - + private static Map bundleNameToResourceMap = new HashMap(); - + private final Pattern pattern; public BaseGeneratedMatcherFactory() throws IncQueryException { diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/impl/BaseGeneratedPatternGroup.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/impl/BaseGeneratedPatternGroup.java index d451e1ee..186cb928 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/impl/BaseGeneratedPatternGroup.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/impl/BaseGeneratedPatternGroup.java @@ -18,18 +18,17 @@ /** * @author Mark Czotter - * + * */ public abstract class BaseGeneratedPatternGroup extends BasePatternGroup { - @Override - public Set getPatterns() { - return patterns(matcherFactories); - } + @Override + public Set getPatterns() { + return patterns(matcherFactories); + } - /** - * Returns {@link IMatcherFactory} objects for handling them as a group. - * To be filled by constructors of subclasses. - */ - protected Set> matcherFactories = new HashSet>(); + /** + * Returns {@link IMatcherFactory} objects for handling them as a group. To be filled by constructors of subclasses. + */ + protected Set> matcherFactories = new HashSet>(); } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/impl/BaseMatcher.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/impl/BaseMatcher.java index 3ad01126..2de886fb 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/impl/BaseMatcher.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/impl/BaseMatcher.java @@ -35,333 +35,351 @@ /** * Base implementation of IncQueryMatcher. + * * @author Bergmann Gábor - * + * * @param */ public abstract class BaseMatcher implements IncQueryMatcher { - // FIELDS AND CONSTRUCTOR - - protected IncQueryEngine engine; - protected RetePatternMatcher patternMatcher; - protected ReteEngine reteEngine; - protected NavigationHelper baseIndex; - - public BaseMatcher(IncQueryEngine engine, RetePatternMatcher patternMatcher, Pattern pattern) throws IncQueryException { - super(); - this.engine = engine; - this.patternMatcher = patternMatcher; - this.reteEngine = engine.getReteEngine(); - this.baseIndex = engine.getBaseIndex(); - } - - - - // HELPERS - - /** - * Call this to sanitize the pattern before usage. - * @throws IncQueryException if the pattern has errors - */ - protected static void checkPattern(IncQueryEngine engine, Pattern pattern) throws IncQueryException { - final boolean admissible = engine.getSanitizer().admit(pattern); - if (!admissible) - throw new IncQueryException( - String.format("Could not initialize matcher for pattern %s because sanity check failed; see Error Log for details.", - CorePatternLanguageHelper.getFullyQualifiedName(pattern)), - "Pattern contains errors"); - } - - protected abstract Match tupleToMatch(Tuple t); - - private static Object[] fEmptyArray; - protected Object[] emptyArray() { - if (fEmptyArray == null) fEmptyArray = new Object[getPattern().getParameters().size()]; - return fEmptyArray; - } - - private boolean[] notNull(Object[] parameters) { - boolean[] notNull = new boolean[parameters.length]; - for (int i=0; i posMapping; - protected Map getPosMapping() { - if (posMapping == null) - { - posMapping = CorePatternLanguageHelper.getParameterPositionsByName(getPattern()); - } - return posMapping; - } - @Override - public Integer getPositionOfParameter(String parameterName) { - return getPosMapping().get(parameterName); - } - - private String[] parameterNames; - - @Override - public String[] getParameterNames() { - if (parameterNames == null) { - Map rawPosMapping = getPosMapping(); - parameterNames = new String[rawPosMapping.size()]; - for (Entry entry : rawPosMapping.entrySet()) { - parameterNames[entry.getValue()] = entry.getKey(); - } - } - return parameterNames; - } - - // BASE IMPLEMENTATION - - @Override - public Collection getAllMatches() { - return rawGetAllMatches(emptyArray()); - } - - @Override - public Collection rawGetAllMatches(Object[] parameters) { - ArrayList m = patternMatcher.matchAll(parameters, notNull(parameters)); - ArrayList matches = new ArrayList(); - //clones the tuples into a match object to protect the Tuples from modifications outside of the ReteMatcher - for(Tuple t: m) matches.add(tupleToMatch(t)); - return matches; - } - - @Override - public Collection getAllMatches(Match partialMatch) { - return rawGetAllMatches(partialMatch.toArray()); - } - // with input binding as pattern-specific parameters: not declared in interface - - @Override - public Match getOneArbitraryMatch() { - return rawGetOneArbitraryMatch(emptyArray()); - } - - @Override - public Match rawGetOneArbitraryMatch(Object[] parameters) { - Tuple t = patternMatcher.matchOne(parameters, notNull(parameters)); - if(t != null) - return tupleToMatch(t); - else - return null; - } - - @Override - public Match getOneArbitraryMatch(Match partialMatch) { - return rawGetOneArbitraryMatch(partialMatch.toArray()); - } - // with input binding as pattern-specific parameters: not declared in interface - - @Override - public boolean rawHasMatch(Object[] parameters) { - return patternMatcher.count(parameters, notNull(parameters)) > 0; - } - - @Override - public boolean hasMatch(Match partialMatch) { - return rawHasMatch(partialMatch.toArray()); - } - // with input binding as pattern-specific parameters: not declared in interface - - @Override - public int countMatches() { - return rawCountMatches(emptyArray()); - } - - @Override - public int rawCountMatches(Object[] parameters) { - return patternMatcher.count(parameters, notNull(parameters)); - } - - @Override - public int countMatches(Match partialMatch) { - return rawCountMatches(partialMatch.toArray()); - } - // with input binding as pattern-specific parameters: not declared in interface - - - @Override - public void rawForEachMatch(Object[] parameters, IMatchProcessor processor) { - ArrayList m = patternMatcher.matchAll(parameters, notNull(parameters)); - //clones the tuples into match objects to protect the Tuples from modifications outside of the ReteMatcher - for(Tuple t: m) processor.process(tupleToMatch(t)); - } - - @Override - public void forEachMatch(IMatchProcessor processor) { - rawForEachMatch(emptyArray(), processor); - }; - - @Override - public void forEachMatch(Match match, IMatchProcessor processor) { - rawForEachMatch(match.toArray(), processor); - }; - // with input binding as pattern-specific parameters: not declared in interface - - @Override - public boolean forOneArbitraryMatch(IMatchProcessor processor) { - return rawForOneArbitraryMatch(emptyArray(), processor); - } - - @Override - public boolean forOneArbitraryMatch(Match partialMatch, IMatchProcessor processor) { - return rawForOneArbitraryMatch(partialMatch.toArray(), processor); - }; - - @Override - public boolean rawForOneArbitraryMatch(Object[] parameters, IMatchProcessor processor) { - Tuple t = patternMatcher.matchOne(parameters, notNull(parameters)); - if(t != null) { - processor.process(tupleToMatch(t)); - return true; - } else { - return false; - } - } - // with input binding as pattern-specific parameters: not declared in interface - - @Override - public void addCallbackOnMatchUpdate(IMatchUpdateListener listener, boolean fireNow) { - final CallbackNode callbackNode = new CallbackNode(reteEngine.getReteNet().getHeadContainer(), engine, listener) { - @Override - public Match statelessConvert(Tuple t) { - return tupleToMatch(t); - } - }; - patternMatcher.connect(callbackNode, listener, fireNow); - } - - @Override - public void removeCallbackOnMatchUpdate(IMatchUpdateListener listener) { - patternMatcher.disconnectByTag(listener); - } - - @Override - public DeltaMonitor newDeltaMonitor(boolean fillAtStart) { - DeltaMonitor dm = new DeltaMonitor(reteEngine.getReteNet().getHeadContainer()) { - @Override - public Match statelessConvert(Tuple t) { - return tupleToMatch(t); - } + // FIELDS AND CONSTRUCTOR + + protected IncQueryEngine engine; + protected RetePatternMatcher patternMatcher; + protected ReteEngine reteEngine; + protected NavigationHelper baseIndex; + + public BaseMatcher(IncQueryEngine engine, RetePatternMatcher patternMatcher, Pattern pattern) + throws IncQueryException { + super(); + this.engine = engine; + this.patternMatcher = patternMatcher; + this.reteEngine = engine.getReteEngine(); + this.baseIndex = engine.getBaseIndex(); + } + + // HELPERS + + /** + * Call this to sanitize the pattern before usage. + * + * @throws IncQueryException + * if the pattern has errors + */ + protected static void checkPattern(IncQueryEngine engine, Pattern pattern) throws IncQueryException { + final boolean admissible = engine.getSanitizer().admit(pattern); + if (!admissible) + throw new IncQueryException( + String.format( + "Could not initialize matcher for pattern %s because sanity check failed; see Error Log for details.", + CorePatternLanguageHelper.getFullyQualifiedName(pattern)), "Pattern contains errors"); + } + + protected abstract Match tupleToMatch(Tuple t); + + private static Object[] fEmptyArray; + + protected Object[] emptyArray() { + if (fEmptyArray == null) + fEmptyArray = new Object[getPattern().getParameters().size()]; + return fEmptyArray; + } + + private boolean[] notNull(Object[] parameters) { + boolean[] notNull = new boolean[parameters.length]; + for (int i = 0; i < parameters.length; ++i) + notNull[i] = parameters[i] != null; + return notNull; + } + + // REFLECTION + + private Map posMapping; + + protected Map getPosMapping() { + if (posMapping == null) { + posMapping = CorePatternLanguageHelper.getParameterPositionsByName(getPattern()); + } + return posMapping; + } + + @Override + public Integer getPositionOfParameter(String parameterName) { + return getPosMapping().get(parameterName); + } + + private String[] parameterNames; + + @Override + public String[] getParameterNames() { + if (parameterNames == null) { + Map rawPosMapping = getPosMapping(); + parameterNames = new String[rawPosMapping.size()]; + for (Entry entry : rawPosMapping.entrySet()) { + parameterNames[entry.getValue()] = entry.getKey(); + } + } + return parameterNames; + } + + // BASE IMPLEMENTATION + + @Override + public Collection getAllMatches() { + return rawGetAllMatches(emptyArray()); + } + + @Override + public Collection rawGetAllMatches(Object[] parameters) { + ArrayList m = patternMatcher.matchAll(parameters, notNull(parameters)); + ArrayList matches = new ArrayList(); + // clones the tuples into a match object to protect the Tuples from modifications outside of the ReteMatcher + for (Tuple t : m) + matches.add(tupleToMatch(t)); + return matches; + } + + @Override + public Collection getAllMatches(Match partialMatch) { + return rawGetAllMatches(partialMatch.toArray()); + } + + // with input binding as pattern-specific parameters: not declared in interface + + @Override + public Match getOneArbitraryMatch() { + return rawGetOneArbitraryMatch(emptyArray()); + } + + @Override + public Match rawGetOneArbitraryMatch(Object[] parameters) { + Tuple t = patternMatcher.matchOne(parameters, notNull(parameters)); + if (t != null) + return tupleToMatch(t); + else + return null; + } + + @Override + public Match getOneArbitraryMatch(Match partialMatch) { + return rawGetOneArbitraryMatch(partialMatch.toArray()); + } + + // with input binding as pattern-specific parameters: not declared in interface + + @Override + public boolean rawHasMatch(Object[] parameters) { + return patternMatcher.count(parameters, notNull(parameters)) > 0; + } + + @Override + public boolean hasMatch(Match partialMatch) { + return rawHasMatch(partialMatch.toArray()); + } + + // with input binding as pattern-specific parameters: not declared in interface + + @Override + public int countMatches() { + return rawCountMatches(emptyArray()); + } + + @Override + public int rawCountMatches(Object[] parameters) { + return patternMatcher.count(parameters, notNull(parameters)); + } + + @Override + public int countMatches(Match partialMatch) { + return rawCountMatches(partialMatch.toArray()); + } + + // with input binding as pattern-specific parameters: not declared in interface + + @Override + public void rawForEachMatch(Object[] parameters, IMatchProcessor processor) { + ArrayList m = patternMatcher.matchAll(parameters, notNull(parameters)); + // clones the tuples into match objects to protect the Tuples from modifications outside of the ReteMatcher + for (Tuple t : m) + processor.process(tupleToMatch(t)); + } + + @Override + public void forEachMatch(IMatchProcessor processor) { + rawForEachMatch(emptyArray(), processor); }; - patternMatcher.connect(dm, fillAtStart); - return dm; - } - - @Override - public DeltaMonitor rawNewFilteredDeltaMonitor(boolean fillAtStart, final Object[] parameters) { - final int length = parameters.length; - DeltaMonitor dm = new DeltaMonitor(reteEngine.getReteNet().getHeadContainer()) { - @Override - public boolean statelessFilter(Tuple tuple) { - for (int i=0; i processor) { + rawForEachMatch(match.toArray(), processor); + }; + + // with input binding as pattern-specific parameters: not declared in interface + + @Override + public boolean forOneArbitraryMatch(IMatchProcessor processor) { + return rawForOneArbitraryMatch(emptyArray(), processor); + } + + @Override + public boolean forOneArbitraryMatch(Match partialMatch, IMatchProcessor processor) { + return rawForOneArbitraryMatch(partialMatch.toArray(), processor); + }; + + @Override + public boolean rawForOneArbitraryMatch(Object[] parameters, IMatchProcessor processor) { + Tuple t = patternMatcher.matchOne(parameters, notNull(parameters)); + if (t != null) { + processor.process(tupleToMatch(t)); + return true; + } else { return false; } - return true; - } - @Override - public Match statelessConvert(Tuple t) { - return tupleToMatch(t); - } + } + + // with input binding as pattern-specific parameters: not declared in interface + + @Override + public void addCallbackOnMatchUpdate(IMatchUpdateListener listener, boolean fireNow) { + final CallbackNode callbackNode = new CallbackNode(reteEngine.getReteNet().getHeadContainer(), + engine, listener) { + @Override + public Match statelessConvert(Tuple t) { + return tupleToMatch(t); + } + }; + patternMatcher.connect(callbackNode, listener, fireNow); + } + + @Override + public void removeCallbackOnMatchUpdate(IMatchUpdateListener listener) { + patternMatcher.disconnectByTag(listener); + } + + @Override + public DeltaMonitor newDeltaMonitor(boolean fillAtStart) { + DeltaMonitor dm = new DeltaMonitor(reteEngine.getReteNet().getHeadContainer()) { + @Override + public Match statelessConvert(Tuple t) { + return tupleToMatch(t); + } + }; + patternMatcher.connect(dm, fillAtStart); + return dm; + } + + @Override + public DeltaMonitor rawNewFilteredDeltaMonitor(boolean fillAtStart, final Object[] parameters) { + final int length = parameters.length; + DeltaMonitor dm = new DeltaMonitor(reteEngine.getReteNet().getHeadContainer()) { + @Override + public boolean statelessFilter(Tuple tuple) { + for (int i = 0; i < length; ++i) { + final Object positionalFilter = parameters[i]; + if (positionalFilter != null && !positionalFilter.equals(tuple.get(i))) + return false; + } + return true; + } + + @Override + public Match statelessConvert(Tuple t) { + return tupleToMatch(t); + } + }; + patternMatcher.connect(dm, fillAtStart); + return dm; + } + + @Override + public DeltaMonitor newFilteredDeltaMonitor(boolean fillAtStart, Match partialMatch) { + return rawNewFilteredDeltaMonitor(fillAtStart, partialMatch.toArray()); + } + + @Override + public boolean addCallbackAfterUpdates(Runnable callback) { + return baseIndex.getAfterUpdateCallbacks().add(callback); + } + + @Override + public boolean removeCallbackAfterUpdates(Runnable callback) { + return baseIndex.getAfterUpdateCallbacks().remove(callback); + } + + @Override + public boolean addCallbackAfterWipes(Runnable callback) { + return engine.getAfterWipeCallbacks().add(callback); + } + + @Override + public boolean removeCallbackAfterWipes(Runnable callback) { + return engine.getAfterWipeCallbacks().remove(callback); + } + + @Override + public Object[] matchToArray(Match partialMatch) { + return partialMatch.toArray(); + } + + @Override + public Match newEmptyMatch() { + return arrayToMatch(new Object[getParameterNames().length]); + } + + @Override + public Match newMatch(Object... parameters) { + return arrayToMatch(parameters); + } + + @Override + public Set getAllValues(final String parameterName) { + return rawGetAllValues(getPositionOfParameter(parameterName), emptyArray()); + } + + @Override + public Set getAllValues(final String parameterName, Match partialMatch) { + return rawGetAllValues(getPositionOfParameter(parameterName), partialMatch.toArray()); }; - patternMatcher.connect(dm, fillAtStart); - return dm; - } - - @Override - public DeltaMonitor newFilteredDeltaMonitor(boolean fillAtStart, Match partialMatch) { - return rawNewFilteredDeltaMonitor(fillAtStart, partialMatch.toArray()); - } - - @Override - public boolean addCallbackAfterUpdates(Runnable callback) { - return baseIndex.getAfterUpdateCallbacks().add(callback); - } - - @Override - public boolean removeCallbackAfterUpdates(Runnable callback) { - return baseIndex.getAfterUpdateCallbacks().remove(callback); - } - - @Override - public boolean addCallbackAfterWipes(Runnable callback) { - return engine.getAfterWipeCallbacks().add(callback); - } - - @Override - public boolean removeCallbackAfterWipes(Runnable callback) { - return engine.getAfterWipeCallbacks().remove(callback); - } - - @Override - public Object[] matchToArray(Match partialMatch) { - return partialMatch.toArray(); - } - - @Override - public Match newEmptyMatch() { - return arrayToMatch(new Object[getParameterNames().length]); - } - - @Override - public Match newMatch(Object... parameters) { - return arrayToMatch(parameters); - } - - @Override - public Set getAllValues(final String parameterName) { - return rawGetAllValues(getPositionOfParameter(parameterName), emptyArray()); - } - - @Override -public Set getAllValues(final String parameterName, Match partialMatch) { - return rawGetAllValues(getPositionOfParameter(parameterName), partialMatch.toArray()); - }; - - @Override - public Set rawGetAllValues(final int position, Object[] parameters) { - if(position >= 0 && position < getParameterNames().length) { - if(parameters.length == getParameterNames().length) { - if(parameters[position] == null) { - final Set results = new HashSet(); - rawAccumulateAllValues(position, parameters, results); - return results; + + @Override + public Set rawGetAllValues(final int position, Object[] parameters) { + if (position >= 0 && position < getParameterNames().length) { + if (parameters.length == getParameterNames().length) { + if (parameters[position] == null) { + final Set results = new HashSet(); + rawAccumulateAllValues(position, parameters, results); + return results; + } + } } - } - } - return null; - } - - /** - * Uses an existing set to accumulate all values of the parameter with the given name. - * Since it is a protected method, no error checking or input validation is performed! - * - * @param position position of the parameter for which values are returned - * @param parameters a parameter array corresponding to a partial match of the - * pattern where each non-null field binds the corresponding pattern parameter to a fixed value. - * @param accumulator the existing set to fill with the values - */ - protected void rawAccumulateAllValues(final int position, Object[] parameters, final Set accumulator) { - rawForEachMatch(parameters, new IMatchProcessor() { - - @SuppressWarnings("unchecked") - @Override - public void process(Match match) { - accumulator.add((T) match.get(position)); - } - }); - } - - @Override - public IncQueryEngine getEngine() { - return engine; - } + return null; + } + + /** + * Uses an existing set to accumulate all values of the parameter with the given name. Since it is a protected + * method, no error checking or input validation is performed! + * + * @param position + * position of the parameter for which values are returned + * @param parameters + * a parameter array corresponding to a partial match of the pattern where each non-null field binds the + * corresponding pattern parameter to a fixed value. + * @param accumulator + * the existing set to fill with the values + */ + protected void rawAccumulateAllValues(final int position, Object[] parameters, final Set accumulator) { + rawForEachMatch(parameters, new IMatchProcessor() { + + @SuppressWarnings("unchecked") + @Override + public void process(Match match) { + accumulator.add((T) match.get(position)); + } + }); + } + + @Override + public IncQueryEngine getEngine() { + return engine; + } } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/impl/BaseMatcherFactory.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/impl/BaseMatcherFactory.java index 1e8b9a82..484caf08 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/impl/BaseMatcherFactory.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/impl/BaseMatcherFactory.java @@ -22,51 +22,50 @@ /** * Base implementation of IMatcherFactory. + * * @author Bergmann Gábor - * + * */ -public abstract class BaseMatcherFactory> - implements IMatcherFactory -{ +public abstract class BaseMatcherFactory> implements + IMatcherFactory { - protected abstract Matcher instantiate(IncQueryEngine engine) throws IncQueryException; - - @Override - public Matcher getMatcher(Notifier emfRoot) throws IncQueryException { - IncQueryEngine engine = EngineManager.getInstance().getIncQueryEngine(emfRoot); - return instantiate(engine); - } + protected abstract Matcher instantiate(IncQueryEngine engine) throws IncQueryException; - @Override - public Matcher getMatcher(IncQueryEngine engine) throws IncQueryException { - return instantiate(engine); - } + @Override + public Matcher getMatcher(Notifier emfRoot) throws IncQueryException { + IncQueryEngine engine = EngineManager.getInstance().getIncQueryEngine(emfRoot); + return instantiate(engine); + } - private String fullyQualifiedName; + @Override + public Matcher getMatcher(IncQueryEngine engine) throws IncQueryException { + return instantiate(engine); + } - @Override - public String getPatternFullyQualifiedName() { - if (fullyQualifiedName == null) - fullyQualifiedName = CorePatternLanguageHelper.getFullyQualifiedName(getPattern()); - return fullyQualifiedName; - } + private String fullyQualifiedName; + @Override + public String getPatternFullyQualifiedName() { + if (fullyQualifiedName == null) + fullyQualifiedName = CorePatternLanguageHelper.getFullyQualifiedName(getPattern()); + return fullyQualifiedName; + } -// // EXPERIMENTAL -// -// @Override -// public Matcher getMatcher(TransactionalEditingDomain trDomain) throws IncQueryRuntimeException { -// return getMatcher(trDomain, 0); -// } -// -// @Override -// public Matcher getMatcher(TransactionalEditingDomain trDomain, int numThreads) throws IncQueryRuntimeException { -// try { -// IncQueryEngine engine = EngineManager.getInstance().getReteEngine(trDomain, numThreads); -// return instantiate(engine); -// } catch (RetePatternBuildException e) { -// throw new IncQueryRuntimeException(e); -// } -// } + // // EXPERIMENTAL + // + // @Override + // public Matcher getMatcher(TransactionalEditingDomain trDomain) throws IncQueryRuntimeException { + // return getMatcher(trDomain, 0); + // } + // + // @Override + // public Matcher getMatcher(TransactionalEditingDomain trDomain, int numThreads) throws IncQueryRuntimeException { + // try { + // IncQueryEngine engine = EngineManager.getInstance().getReteEngine(trDomain, numThreads); + // return instantiate(engine); + // } catch (RetePatternBuildException e) { + // throw new IncQueryRuntimeException(e); + // } + // } } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/impl/BasePatternGroup.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/impl/BasePatternGroup.java index 57e7bcb5..a27e0b5d 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/impl/BasePatternGroup.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/impl/BasePatternGroup.java @@ -29,37 +29,36 @@ * */ public abstract class BasePatternGroup implements IPatternGroup { - - @Override - public void prepare(Notifier emfRoot) throws IncQueryException { - prepare(EngineManager.getInstance().getIncQueryEngine(emfRoot)); - } - - @Override - public void prepare(IncQueryEngine engine) throws IncQueryException { - try { - final Set patterns = getPatterns(); - engine.getSanitizer().admit(patterns); - engine.getReteEngine().buildMatchersCoalesced(patterns); - } catch (RetePatternBuildException e) { - throw new IncQueryException(e); - } - } - - /** - * Returns a set of {@link Pattern} objects, accessible from the - * {@link IMatcherFactory} objects. - * - * @see IMatcherFactory#getPattern() - * @param matcherFactories - * @return - */ - public static Set patterns(Set> matcherFactories) { - Set result = new HashSet(); - for (IMatcherFactory factory : matcherFactories) { - result.add(factory.getPattern()); - } - return result; - } - + + @Override + public void prepare(Notifier emfRoot) throws IncQueryException { + prepare(EngineManager.getInstance().getIncQueryEngine(emfRoot)); + } + + @Override + public void prepare(IncQueryEngine engine) throws IncQueryException { + try { + final Set patterns = getPatterns(); + engine.getSanitizer().admit(patterns); + engine.getReteEngine().buildMatchersCoalesced(patterns); + } catch (RetePatternBuildException e) { + throw new IncQueryException(e); + } + } + + /** + * Returns a set of {@link Pattern} objects, accessible from the {@link IMatcherFactory} objects. + * + * @see IMatcherFactory#getPattern() + * @param matcherFactories + * @return + */ + public static Set patterns(Set> matcherFactories) { + Set result = new HashSet(); + for (IMatcherFactory factory : matcherFactories) { + result.add(factory.getPattern()); + } + return result; + } + } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/impl/BasePatternMatch.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/impl/BasePatternMatch.java index 46d17969..b0f7e831 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/impl/BasePatternMatch.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/api/impl/BasePatternMatch.java @@ -17,60 +17,65 @@ /** * Base implementation of IPatternMatch. + * * @author Bergmann Gábor - * + * */ public abstract class BasePatternMatch implements IPatternMatch { - public static String prettyPrintValue(Object o) { - if (o == null) return "(null)"; - String name = prettyPrintFeature(o, "name"); - if(name != null){ - return name; - } - /*if (o instanceof EObject) { - EStructuralFeature feature = ((EObject)o).eClass().getEStructuralFeature("name"); - if (feature != null) { - Object name = ((EObject)o).eGet(feature); - if (name != null) return name.toString(); - } - }*/ - return o.toString(); - } - - public static String prettyPrintFeature(Object o, String featureName) { - if (o != null && o instanceof EObject) { - EStructuralFeature feature = ((EObject)o).eClass().getEStructuralFeature(featureName); - if (feature != null) { - Object value = ((EObject)o).eGet(feature); - if (value != null) return value.toString(); - } - } - return null; - } - - // TODO performance can be improved here somewhat - - @Override - public Object get(int position) { - if (position >= 0 && position < parameterNames().length) - return get(parameterNames()[position]); - else return null; - } + public static String prettyPrintValue(Object o) { + if (o == null) + return "(null)"; + String name = prettyPrintFeature(o, "name"); + if (name != null) { + return name; + } + /* + * if (o instanceof EObject) { EStructuralFeature feature = ((EObject)o).eClass().getEStructuralFeature("name"); + * if (feature != null) { Object name = ((EObject)o).eGet(feature); if (name != null) return name.toString(); } + * } + */ + return o.toString(); + } + + public static String prettyPrintFeature(Object o, String featureName) { + if (o != null && o instanceof EObject) { + EStructuralFeature feature = ((EObject) o).eClass().getEStructuralFeature(featureName); + if (feature != null) { + Object value = ((EObject) o).eGet(feature); + if (value != null) + return value.toString(); + } + } + return null; + } + + // TODO performance can be improved here somewhat + + @Override + public Object get(int position) { + if (position >= 0 && position < parameterNames().length) + return get(parameterNames()[position]); + else + return null; + } + + @Override + public boolean set(int position, Object newValue) { + if (position >= 0 && position < parameterNames().length) + return set(parameterNames()[position], newValue); + else + return false; + } - @Override - public boolean set(int position, Object newValue) { - if (position >= 0 && position < parameterNames().length) - return set(parameterNames()[position], newValue); - else return false; - } - - /* (non-Javadoc) - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return "Match<" + patternName() + ">{" + prettyPrint() + "}"; - } + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "Match<" + patternName() + ">{" + prettyPrint() + "}"; + } } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/extensibility/EngineTaintListener.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/extensibility/EngineTaintListener.java index 4bd3e8b8..8bfd2b28 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/extensibility/EngineTaintListener.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/extensibility/EngineTaintListener.java @@ -18,33 +18,36 @@ /** * Listens for the event of the engine becoming tainted. * - * Attach this listener to the logger of the engine as an appender. - * Do not forget to remove when losing interest or when engine is disposed. + * Attach this listener to the logger of the engine as an appender. Do not forget to remove when losing interest or when + * engine is disposed. * * @author Bergmann Gabor * @see IncQueryEngine#isTainted() */ public abstract class EngineTaintListener extends AppenderSkeleton { - public static final Level TRESHOLD = Level.FATAL; + public static final Level TRESHOLD = Level.FATAL; - /** - * This callback will be alerted at most once, when the engine becomes tainted. - */ - public abstract void engineBecameTainted(); - - private boolean noTaintDetectedYet = true; + /** + * This callback will be alerted at most once, when the engine becomes tainted. + */ + public abstract void engineBecameTainted(); - @Override - public boolean requiresLayout() {return false;} + private boolean noTaintDetectedYet = true; - @Override - public void close() {} + @Override + public boolean requiresLayout() { + return false; + } - @Override - protected void append(LoggingEvent event) { - if (event.getLevel().isGreaterOrEqual(TRESHOLD) && noTaintDetectedYet) { - noTaintDetectedYet = false; - engineBecameTainted(); - } - } + @Override + public void close() { + } + + @Override + protected void append(LoggingEvent event) { + if (event.getLevel().isGreaterOrEqual(TRESHOLD) && noTaintDetectedYet) { + noTaintDetectedYet = false; + engineBecameTainted(); + } + } } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/extensibility/IInjectorProvider.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/extensibility/IInjectorProvider.java index c7cbe655..8dddbf28 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/extensibility/IInjectorProvider.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/extensibility/IInjectorProvider.java @@ -14,10 +14,11 @@ /** * Interface for providing external Guice modules for EMF-IncQuery + * * @author Zoltan Ujhelyi - * + * */ public interface IInjectorProvider { - public Injector getInjector(); + public Injector getInjector(); } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/extensibility/IMatchChecker.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/extensibility/IMatchChecker.java index 2602735a..61a37b02 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/extensibility/IMatchChecker.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/extensibility/IMatchChecker.java @@ -20,16 +20,14 @@ */ public interface IMatchChecker { - /** - * The implementation should return the result value of the xexpression. - * - * @param tuple - * which holds the actual values for this expression - * @param tupleNameMap - * which holds the used name-integer pairs, to be able to get out - * the attributes from the tuple - */ - public Object evaluateXExpression(final Tuple tuple, - final Map tupleNameMap); + /** + * The implementation should return the result value of the xexpression. + * + * @param tuple + * which holds the actual values for this expression + * @param tupleNameMap + * which holds the used name-integer pairs, to be able to get out the attributes from the tuple + */ + public Object evaluateXExpression(final Tuple tuple, final Map tupleNameMap); } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/extensibility/IMatcherFactoryProvider.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/extensibility/IMatcherFactoryProvider.java index da72c1b3..93c94dfa 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/extensibility/IMatcherFactoryProvider.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/extensibility/IMatcherFactoryProvider.java @@ -14,12 +14,11 @@ import org.eclipse.incquery.runtime.exception.IncQueryException; /** - * Provides a MatcherFactory. - * Used e.g. as a plug-in extension. + * Provides a MatcherFactory. Used e.g. as a plug-in extension. * * @author Bergmann Gabor - * + * */ public interface IMatcherFactoryProvider> { - public Factory get() throws IncQueryException; + public Factory get() throws IncQueryException; } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/extensibility/MatcherFactoryRegistry.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/extensibility/MatcherFactoryRegistry.java index 0dfc9160..e9a810ec 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/extensibility/MatcherFactoryRegistry.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/extensibility/MatcherFactoryRegistry.java @@ -34,55 +34,51 @@ * Registry for accessing matcher factory instances based on Pattern or pattern ID * * @author Abel Hegedus - * + * */ public final class MatcherFactoryRegistry { - private static final Map> MATCHER_FACTORIES = createMatcherFactories(); - - /** - * Utility class constructor hidden - */ - private MatcherFactoryRegistry() { - } - - private static Map> createMatcherFactories() { - final Map> factories = new HashMap>(); - initRegistry(factories); - return factories; - } - - // Does not use the field MATCHER_FACTORIES as it may still be uninitialized - private static void initRegistry(Map> factories) - { - factories.clear(); - - IExtensionRegistry reg = Platform.getExtensionRegistry(); - if (reg == null) { - return; - } - - IExtensionPoint poi = - reg.getExtensionPoint(IExtensions.MATCHERFACTORY_EXTENSION_POINT_ID); - if (poi != null) - { - IExtension[] exts = poi.getExtensions(); - - Set duplicates = new HashSet(); - - for (IExtension ext: exts) - { - - IConfigurationElement[] els = ext.getConfigurationElements(); - for (IConfigurationElement el : els) - { - if (el.getName().equals("matcher")) { - prepareMatcherFactory(factories, duplicates, el); - } else { - IncQueryEngine.getDefaultLogger().error("[MatcherFactoryRegistry] Unknown configuration element " + el.getName() + " in plugin.xml of " - + el.getDeclaringExtension().getUniqueIdentifier()); - } - } - } + private static final Map> MATCHER_FACTORIES = createMatcherFactories(); + + /** + * Utility class constructor hidden + */ + private MatcherFactoryRegistry() { + } + + private static Map> createMatcherFactories() { + final Map> factories = new HashMap>(); + initRegistry(factories); + return factories; + } + + // Does not use the field MATCHER_FACTORIES as it may still be uninitialized + private static void initRegistry(Map> factories) { + factories.clear(); + + IExtensionRegistry reg = Platform.getExtensionRegistry(); + if (reg == null) { + return; + } + + IExtensionPoint poi = reg.getExtensionPoint(IExtensions.MATCHERFACTORY_EXTENSION_POINT_ID); + if (poi != null) { + IExtension[] exts = poi.getExtensions(); + + Set duplicates = new HashSet(); + + for (IExtension ext : exts) { + + IConfigurationElement[] els = ext.getConfigurationElements(); + for (IConfigurationElement el : els) { + if (el.getName().equals("matcher")) { + prepareMatcherFactory(factories, duplicates, el); + } else { + IncQueryEngine.getDefaultLogger().error( + "[MatcherFactoryRegistry] Unknown configuration element " + el.getName() + + " in plugin.xml of " + el.getDeclaringExtension().getUniqueIdentifier()); + } + } + } if (!duplicates.isEmpty()) { StringBuilder duplicateSB = new StringBuilder( "[MatcherFactoryRegistry] Trying to register patterns with the same FQN multiple times. Check your plug-in configuration!\n"); @@ -92,162 +88,180 @@ private static void initRegistry(Map> factories) } IncQueryEngine.getDefaultLogger().warn(duplicateSB.toString()); } - } - } + } + } private static void prepareMatcherFactory(Map> factories, Set duplicates, IConfigurationElement el) { - try - { - String id = el.getAttribute("id"); - @SuppressWarnings("unchecked") - IMatcherFactoryProvider>> provider = (IMatcherFactoryProvider>>)el.createExecutableExtension("factoryProvider"); - IMatcherFactory> matcherFactory = provider.get(); - String fullyQualifiedName = matcherFactory.getPatternFullyQualifiedName(); - if(id.equals(fullyQualifiedName)) { - if(factories.containsKey(fullyQualifiedName)) { - duplicates.add(fullyQualifiedName); - } else { - factories.put(fullyQualifiedName, matcherFactory); - } - } else { - throw new UnsupportedOperationException( - "Id attribute value " + id + " does not equal pattern FQN of factory " + fullyQualifiedName + " in plugin.xml of " - + el.getDeclaringExtension().getUniqueIdentifier()); - } + try { + String id = el.getAttribute("id"); + @SuppressWarnings("unchecked") + IMatcherFactoryProvider>> provider = (IMatcherFactoryProvider>>) el + .createExecutableExtension("factoryProvider"); + IMatcherFactory> matcherFactory = provider.get(); + String fullyQualifiedName = matcherFactory.getPatternFullyQualifiedName(); + if (id.equals(fullyQualifiedName)) { + if (factories.containsKey(fullyQualifiedName)) { + duplicates.add(fullyQualifiedName); + } else { + factories.put(fullyQualifiedName, matcherFactory); + } + } else { + throw new UnsupportedOperationException("Id attribute value " + id + + " does not equal pattern FQN of factory " + fullyQualifiedName + " in plugin.xml of " + + el.getDeclaringExtension().getUniqueIdentifier()); + } + } catch (Exception e) { + IncQueryEngine.getDefaultLogger().error( + "[MatcherFactoryRegistry] Exception during matcher factory registry initialization " + + e.getMessage(), e); + } + } + + /** + * Puts the factory in the registry, unless it already contains a factory for the given pattern FQN + * + * @param factory + */ + public static void registerMatcherFactory(IMatcherFactory factory) { + String qualifiedName = factory.getPatternFullyQualifiedName(); + if (!MATCHER_FACTORIES.containsKey(qualifiedName)) { + MATCHER_FACTORIES.put(qualifiedName, factory); + } else { + IncQueryEngine + .getDefaultLogger() + .warn(String + .format("[MatcherFactoryRegistry] Trying to register duplicate FQN (%s). Check your plug-in configuration!", + qualifiedName)); + } + } + + /** + * @return a copy of the set of contributed matcher factories + */ + public static Set> getContributedMatcherFactories() { + return new HashSet>(MATCHER_FACTORIES.values()); + } + + /** + * Returns the specific pattern matcher factory, if it is registered, null otherwise + * + * @param patternFqn + * @return + */ + public static IMatcherFactory getMatcherFactory(String patternFqn) { + if (MATCHER_FACTORIES.containsKey(patternFqn)) { + return MATCHER_FACTORIES.get(patternFqn); + } + return null; + } + + /** + * Returns the specific pattern matcher factory, if it is registered, null otherwise + * + * @param pattern + * @return + */ + public static IMatcherFactory getMatcherFactory(Pattern pattern) { + String fullyQualifiedName = CorePatternLanguageHelper.getFullyQualifiedName(pattern); + if (MATCHER_FACTORIES.containsKey(fullyQualifiedName)) { + return MATCHER_FACTORIES.get(fullyQualifiedName); } - catch (Exception e) - { - IncQueryEngine.getDefaultLogger().error("[MatcherFactoryRegistry] Exception during matcher factory registry initialization " + e.getMessage(),e); + return null; + } + + /** + * Returns a generic pattern matcher factory if a specific factory is not registered + * + * @param pattern + * @return + */ + public static IMatcherFactory getOrCreateMatcherFactory(Pattern pattern) { + String fullyQualifiedName = CorePatternLanguageHelper.getFullyQualifiedName(pattern); + if (MATCHER_FACTORIES.containsKey(fullyQualifiedName)) { + return MATCHER_FACTORIES.get(fullyQualifiedName); } + return new GenericMatcherFactory(pattern); } - /** - * Puts the factory in the registry, unless it already contains a factory for the given pattern FQN - * - * @param factory - */ - public static void registerMatcherFactory(IMatcherFactory factory) { - String qualifiedName = factory.getPatternFullyQualifiedName(); - if(!MATCHER_FACTORIES.containsKey(qualifiedName)) { - MATCHER_FACTORIES.put(qualifiedName, factory); - } else { - IncQueryEngine.getDefaultLogger().warn(String.format("[MatcherFactoryRegistry] Trying to register duplicate FQN (%s). Check your plug-in configuration!", qualifiedName)); - } - } - - /** - * @return a copy of the set of contributed matcher factories - */ - public static Set> getContributedMatcherFactories() { - return new HashSet>(MATCHER_FACTORIES.values()); - } - - /** - * Returns the specific pattern matcher factory, if it is registered, null otherwise - * @param patternFqn - * @return - */ - public static IMatcherFactory getMatcherFactory(String patternFqn) { - if(MATCHER_FACTORIES.containsKey(patternFqn)) { - return MATCHER_FACTORIES.get(patternFqn); - } - return null; - } - - /** - * Returns the specific pattern matcher factory, if it is registered, null otherwise - * - * @param pattern - * @return - */ - public static IMatcherFactory getMatcherFactory(Pattern pattern) { - String fullyQualifiedName = CorePatternLanguageHelper.getFullyQualifiedName(pattern); - if(MATCHER_FACTORIES.containsKey(fullyQualifiedName)) { - return MATCHER_FACTORIES.get(fullyQualifiedName); - } - return null; - } - - /** - * Returns a generic pattern matcher factory if a specific factory is not registered - * @param pattern - * @return - */ - public static IMatcherFactory getOrCreateMatcherFactory(Pattern pattern) { - String fullyQualifiedName = CorePatternLanguageHelper.getFullyQualifiedName(pattern); - if(MATCHER_FACTORIES.containsKey(fullyQualifiedName)) { - return MATCHER_FACTORIES.get(fullyQualifiedName); - } - return new GenericMatcherFactory(pattern); - } - - /** - * Returns the set of matcher factories in a given package. Only matcher factories with the exact package fully qualified name are returned. - * - * @param packageFQN the fully qualified name of the package - * @return the set of matcher factories inside the given package, empty set otherwise. - */ - public static Set> getPatternGroup(String packageFQN) { - return getPatternGroupOrSubTree(packageFQN, false); - } - - /** - * Returns the set of matcher factories in a given package. Matcher factories with package names starting with the given package are returned. - * - * @param packageFQN the fully qualified name of the package - * @return the set of matcher factories in the given package subtree, empty set otherwise. - */ - public static Set> getPatternSubTree(String packageFQN) { - return getPatternGroupOrSubTree(packageFQN, true); - } - - /** - * Returns a pattern group for the given package - * - * @param packageFQN the fully qualified name of the package - * @param includeSubPackages if true, the pattern is added if it is in the package hierarchy, - * if false, the pattern is added only if it is in the given package - * @return the matcher factories in the group - */ - private static Set> getPatternGroupOrSubTree(String packageFQN, boolean includeSubPackages) { - Map>> map = new HashMap>>(); - if(map.containsKey(packageFQN)) { - return map.get(packageFQN); - } else { - Set> group = new HashSet>(); - for (Entry> entry : MATCHER_FACTORIES.entrySet()) { - addPatternToGroup(packageFQN, group, entry.getKey(), entry.getValue(), includeSubPackages); - } - if(group.size() > 0) { - map.put(packageFQN, group); - } - return group; - } - } - - /** - * Adds the factory to an existing group if the package of the factory's pattern matches the given package name. - * - * @param packageFQN the fully qualified name of the package - * @param group the group to add the factory to - * @param patternFQN the fully qualified name of the pattern - * @param factory the matcher factory of the pattern - * @param includeSubPackages if true, the pattern is added if it is in the package hierarchy, - * if false, the pattern is added only if it is in the given package - */ - private static void addPatternToGroup(String packageFQN, Set> group, String patternFQN, IMatcherFactory factory, boolean includeSubPackages) { - if(packageFQN.length() + 1 < patternFQN.length()) { - if(includeSubPackages) { - if(patternFQN.startsWith(packageFQN+'.')) { - group.add(factory); - } - } else { - String name = patternFQN.substring(patternFQN.lastIndexOf('.')+1,patternFQN.length()); - if(patternFQN.equals(packageFQN+'.'+name)) { - group.add(factory); - } - } - } - } + /** + * Returns the set of matcher factories in a given package. Only matcher factories with the exact package fully + * qualified name are returned. + * + * @param packageFQN + * the fully qualified name of the package + * @return the set of matcher factories inside the given package, empty set otherwise. + */ + public static Set> getPatternGroup(String packageFQN) { + return getPatternGroupOrSubTree(packageFQN, false); + } + + /** + * Returns the set of matcher factories in a given package. Matcher factories with package names starting with the + * given package are returned. + * + * @param packageFQN + * the fully qualified name of the package + * @return the set of matcher factories in the given package subtree, empty set otherwise. + */ + public static Set> getPatternSubTree(String packageFQN) { + return getPatternGroupOrSubTree(packageFQN, true); + } + + /** + * Returns a pattern group for the given package + * + * @param packageFQN + * the fully qualified name of the package + * @param includeSubPackages + * if true, the pattern is added if it is in the package hierarchy, if false, the pattern is added only + * if it is in the given package + * @return the matcher factories in the group + */ + private static Set> getPatternGroupOrSubTree(String packageFQN, boolean includeSubPackages) { + Map>> map = new HashMap>>(); + if (map.containsKey(packageFQN)) { + return map.get(packageFQN); + } else { + Set> group = new HashSet>(); + for (Entry> entry : MATCHER_FACTORIES.entrySet()) { + addPatternToGroup(packageFQN, group, entry.getKey(), entry.getValue(), includeSubPackages); + } + if (group.size() > 0) { + map.put(packageFQN, group); + } + return group; + } + } + + /** + * Adds the factory to an existing group if the package of the factory's pattern matches the given package name. + * + * @param packageFQN + * the fully qualified name of the package + * @param group + * the group to add the factory to + * @param patternFQN + * the fully qualified name of the pattern + * @param factory + * the matcher factory of the pattern + * @param includeSubPackages + * if true, the pattern is added if it is in the package hierarchy, if false, the pattern is added only + * if it is in the given package + */ + private static void addPatternToGroup(String packageFQN, Set> group, String patternFQN, + IMatcherFactory factory, boolean includeSubPackages) { + if (packageFQN.length() + 1 < patternFQN.length()) { + if (includeSubPackages) { + if (patternFQN.startsWith(packageFQN + '.')) { + group.add(factory); + } + } else { + String name = patternFQN.substring(patternFQN.lastIndexOf('.') + 1, patternFQN.length()); + if (patternFQN.equals(packageFQN + '.' + name)) { + group.add(factory); + } + } + } + } } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/BaseIndexListener.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/BaseIndexListener.java index 3c733c81..7ecc8c78 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/BaseIndexListener.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/BaseIndexListener.java @@ -32,113 +32,114 @@ /** * A listener binding as Rete boundary to an eiqBase index + * * @author Bergmann Gábor - * + * */ public class BaseIndexListener implements FeatureListener, InstanceListener, DataTypeListener, IManipulationListener { - private final ReteBoundary boundary; - private final NavigationHelper baseIndex; - - /** - * This reference is vital, to avoid the premature GC of the engine while the EMF model is still reachable. - * Retention path: EMF model -> IQBase -> BaseIndexListener -> IQEngine - */ - @SuppressWarnings("unused") - private final IncQueryEngine iqEngine; - - private final Set classes = new HashSet(); - private final Set dataTypes = new HashSet(); - private final Set features = new HashSet(); - - /** - * @param boundary - */ - public BaseIndexListener(IncQueryEngine iqEngine, ReteEngine engine, NavigationHelper baseIndex) { - super(); - this.iqEngine = iqEngine; - this.boundary = engine.getBoundary(); - this.baseIndex = baseIndex; - engine.addDisconnectable(this); - - } - - public void ensure(EClass eClass) { - if (classes.add(eClass)) { - final Set newClasses = Collections.singleton(eClass); - if (!baseIndex.isInWildcardMode()) - baseIndex.registerEClasses(newClasses); - baseIndex.registerInstanceListener(newClasses, this); - } - } - public void ensure(EDataType eDataType) { - if (dataTypes.add(eDataType)) { - final Set newDataTypes = Collections.singleton(eDataType); - if (!baseIndex.isInWildcardMode()) - baseIndex.registerEDataTypes(newDataTypes); - baseIndex.registerDataTypeListener(newDataTypes, this); - } - } - public void ensure(EStructuralFeature feature) { - if (features.add(feature)) { - final Set newFeatures = Collections.singleton(feature); - if (!baseIndex.isInWildcardMode()) - baseIndex.registerEStructuralFeatures(newFeatures); - baseIndex.registerFeatureListener(newFeatures, this); - } - } - - - @Override - public void instanceInserted(EClass clazz, EObject instance) { - boundary.updateUnary(Direction.INSERT, instance, clazz); - boundary.updateInstantiation(Direction.INSERT, clazz, instance); - } - - @Override - public void instanceDeleted(EClass clazz, EObject instance) { - boundary.updateUnary(Direction.REVOKE, instance, clazz); - boundary.updateInstantiation(Direction.REVOKE, clazz, instance); - } - - @Override - public void dataTypeInstanceInserted(EDataType type, Object instance) { - boundary.updateUnary(Direction.INSERT, instance, type); - boundary.updateInstantiation(Direction.INSERT, type, instance); - } - - @Override - public void dataTypeInstanceDeleted(EDataType type, Object instance) { - boundary.updateUnary(Direction.REVOKE, instance, type); - boundary.updateInstantiation(Direction.REVOKE, type, instance); - } - - @Override - public void featureInserted(EObject host, EStructuralFeature feature, Object value) { - boundary.updateBinaryEdge(Direction.INSERT, host, value, feature); - } - - @Override - public void featureDeleted(EObject host, EStructuralFeature feature, Object value) { - boundary.updateBinaryEdge(Direction.REVOKE, host, value, feature); - } - - - @Override - public void registerSensitiveTerm(Object element, - PredicateEvaluatorNode termEvaluatorNode) { - } - - @Override - public void unregisterSensitiveTerm(Object element, - PredicateEvaluatorNode termEvaluatorNode) { - } - - @Override - public void disconnect() { - baseIndex.unregisterFeatureListener(features, this); features.clear(); - baseIndex.unregisterInstanceListener(classes, this); classes.clear(); - baseIndex.unregisterDataTypeListener(dataTypes, this); dataTypes.clear(); - } - - + private final ReteBoundary boundary; + private final NavigationHelper baseIndex; + + /** + * This reference is vital, to avoid the premature GC of the engine while the EMF model is still reachable. + * Retention path: EMF model -> IQBase -> BaseIndexListener -> IQEngine + */ + @SuppressWarnings("unused") + private final IncQueryEngine iqEngine; + + private final Set classes = new HashSet(); + private final Set dataTypes = new HashSet(); + private final Set features = new HashSet(); + + /** + * @param boundary + */ + public BaseIndexListener(IncQueryEngine iqEngine, ReteEngine engine, NavigationHelper baseIndex) { + super(); + this.iqEngine = iqEngine; + this.boundary = engine.getBoundary(); + this.baseIndex = baseIndex; + engine.addDisconnectable(this); + + } + + public void ensure(EClass eClass) { + if (classes.add(eClass)) { + final Set newClasses = Collections.singleton(eClass); + if (!baseIndex.isInWildcardMode()) + baseIndex.registerEClasses(newClasses); + baseIndex.registerInstanceListener(newClasses, this); + } + } + + public void ensure(EDataType eDataType) { + if (dataTypes.add(eDataType)) { + final Set newDataTypes = Collections.singleton(eDataType); + if (!baseIndex.isInWildcardMode()) + baseIndex.registerEDataTypes(newDataTypes); + baseIndex.registerDataTypeListener(newDataTypes, this); + } + } + + public void ensure(EStructuralFeature feature) { + if (features.add(feature)) { + final Set newFeatures = Collections.singleton(feature); + if (!baseIndex.isInWildcardMode()) + baseIndex.registerEStructuralFeatures(newFeatures); + baseIndex.registerFeatureListener(newFeatures, this); + } + } + + @Override + public void instanceInserted(EClass clazz, EObject instance) { + boundary.updateUnary(Direction.INSERT, instance, clazz); + boundary.updateInstantiation(Direction.INSERT, clazz, instance); + } + + @Override + public void instanceDeleted(EClass clazz, EObject instance) { + boundary.updateUnary(Direction.REVOKE, instance, clazz); + boundary.updateInstantiation(Direction.REVOKE, clazz, instance); + } + + @Override + public void dataTypeInstanceInserted(EDataType type, Object instance) { + boundary.updateUnary(Direction.INSERT, instance, type); + boundary.updateInstantiation(Direction.INSERT, type, instance); + } + + @Override + public void dataTypeInstanceDeleted(EDataType type, Object instance) { + boundary.updateUnary(Direction.REVOKE, instance, type); + boundary.updateInstantiation(Direction.REVOKE, type, instance); + } + + @Override + public void featureInserted(EObject host, EStructuralFeature feature, Object value) { + boundary.updateBinaryEdge(Direction.INSERT, host, value, feature); + } + + @Override + public void featureDeleted(EObject host, EStructuralFeature feature, Object value) { + boundary.updateBinaryEdge(Direction.REVOKE, host, value, feature); + } + + @Override + public void registerSensitiveTerm(Object element, PredicateEvaluatorNode termEvaluatorNode) { + } + + @Override + public void unregisterSensitiveTerm(Object element, PredicateEvaluatorNode termEvaluatorNode) { + } + + @Override + public void disconnect() { + baseIndex.unregisterFeatureListener(features, this); + features.clear(); + baseIndex.unregisterInstanceListener(classes, this); + classes.clear(); + baseIndex.unregisterDataTypeListener(dataTypes, this); + dataTypes.clear(); + } + } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/EMFPatternMatcherContext.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/EMFPatternMatcherContext.java index a4f39ad4..8cd81218 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/EMFPatternMatcherContext.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/EMFPatternMatcherContext.java @@ -28,197 +28,215 @@ import org.eclipse.incquery.runtime.rete.matcher.IPatternMatcherContext; /** - * TODO generics? - * TODO TODO no subtyping between EDataTypes? no EDataTypes metainfo at all? + * TODO generics? TODO TODO no subtyping between EDataTypes? no EDataTypes metainfo at all? + * * @author Bergmann Gábor */ public class EMFPatternMatcherContext implements IPatternMatcherContext { - - protected IncQueryEngine iqEngine; - - /** - * @param iqEngine - */ - public EMFPatternMatcherContext(IncQueryEngine iqEngine) { - super(); - this.iqEngine = iqEngine; - } - - @Override - public EdgeInterpretation edgeInterpretation() { - return EdgeInterpretation.BINARY; - } - - @Override - public GeneralizationQueryDirection allowedGeneralizationQueryDirection() { - return GeneralizationQueryDirection.SUPERTYPE_ONLY_SMART_NOTIFICATIONS; - } - - @Override - public Collection enumerateDirectSupertypes(Object typeObject) { - if (typeObject==null) return null; - if (typeObject instanceof EClass || typeObject instanceof EDataType) return enumerateDirectUnarySupertypes(typeObject); - if (typeObject instanceof EStructuralFeature) return enumerateDirectBinaryEdgeSupertypes(typeObject); - else throw new IllegalArgumentException("typeObject has invalid type " + typeObject.getClass().getName()); - } - - @Override - public Collection enumerateDirectSubtypes(Object typeObject) { - if (typeObject==null) return null; - if (typeObject instanceof EClass || typeObject instanceof EDataType) return enumerateDirectUnarySubtypes(typeObject); - if (typeObject instanceof EStructuralFeature) return enumerateDirectBinaryEdgeSubtypes(typeObject); - else throw new IllegalArgumentException("typeObject has invalid type " + typeObject.getClass().getName()); - } - - @Override - public boolean isUnaryType(Object typeObject) { - return typeObject instanceof EClassifier; - } - @Override - public Collection enumerateDirectUnarySubtypes(Object typeObject) { - if (typeObject instanceof EClass) - throw new UnsupportedOperationException("EMF patternmatcher context only supports querying of supertypes, not subtypes."); - //return contextMapping.retrieveSubtypes((EClass)typeObject); - else if (typeObject instanceof EDataType) { - return Collections.emptyList();// no subtyping between EDataTypes? - } else throw new IllegalArgumentException("typeObject has invalid type " + typeObject.getClass().getName()); - } - - @Override - public Collection enumerateDirectUnarySupertypes(Object typeObject) { - if (typeObject instanceof EClass) - return ((EClass)typeObject).getESuperTypes(); - else if (typeObject instanceof EDataType) { - return Collections.emptyList();// no subtyping between EDataTypes? - } else throw new IllegalArgumentException("typeObject has invalid type " + typeObject.getClass().getName()); - } - - @Override - public boolean isBinaryEdgeType(Object typeObject) { - return typeObject instanceof EStructuralFeature; - } - @Override - public Collection enumerateDirectBinaryEdgeSubtypes( - Object typeObject) { - return Collections.emptyList();// no subtyping between structural features - } - - @Override - public Collection enumerateDirectBinaryEdgeSupertypes( - Object typeObject) { - return Collections.emptyList();// no subtyping between structural features - } - - @Override - public Collection enumerateDirectTernaryEdgeSubtypes( - Object typeObject) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isTernaryEdgeType(Object typeObject) { - return false; - } - @Override - public Collection enumerateDirectTernaryEdgeSupertypes( - Object typeObject) { - throw new UnsupportedOperationException(); - } - - @Override - public Object binaryEdgeSourceType(Object typeObject) { - EStructuralFeature feature = (EStructuralFeature)typeObject; - return feature.getEContainingClass(); - } - - @Override - public Object binaryEdgeTargetType(Object typeObject) { - if (typeObject instanceof EAttribute) { - EAttribute attribute = (EAttribute) typeObject; - return attribute.getEAttributeType(); - } else if (typeObject instanceof EReference) { - EReference reference = (EReference) typeObject; - return reference.getEReferenceType(); - } else throw new IllegalArgumentException("typeObject has invalid type " + typeObject.getClass().getName()); - } - - @Override - public Object ternaryEdgeSourceType(Object typeObject) { - throw new UnsupportedOperationException(); - } - - @Override - public Object ternaryEdgeTargetType(Object typeObject) { - throw new UnsupportedOperationException(); - } - - @Override - public void reportPatternDependency(Pattern pattern) { - // Ignore, because we don't support changing machines here - } - - public Logger getLogger() { - return iqEngine.getLogger(); - } - - @Override - public void logDebug(String message) { - if (getLogger()!=null) getLogger().debug(message); - } - - @Override - public void logError(String message) { - if (getLogger()!=null) getLogger().error(message); - } - - @Override - public void logError(String message, Throwable cause) { - if (getLogger()!=null) getLogger().error(message, cause); - } - - @Override - public void logFatal(String message) { - if (getLogger()!=null) getLogger().fatal(message); - } - - @Override - public void logFatal(String message, Throwable cause) { - if (getLogger()!=null) getLogger().fatal(message, cause); - } - - @Override - public void logWarning(String message) { - if (getLogger()!=null) getLogger().warn(message); - } - - @Override - public void logWarning(String message, Throwable cause) { - if (getLogger()!=null) getLogger().warn(message, cause); - } - - @Override - public String printPattern(Pattern pattern) { - if (pattern == null) { - return "(null)"; - } - return CorePatternLanguageHelper.getFullyQualifiedName(pattern); - } - - @Override - public String printType(Object typeObject) { - if (typeObject == null) { - return "(null)"; - } else if (typeObject instanceof EClassifier) { - final EClassifier eClassifier = (EClassifier) typeObject; - final EPackage ePackage = eClassifier.getEPackage(); - final String nsURI = ePackage == null ? null : ePackage.getNsURI(); - final String typeName = eClassifier.getName(); - return ""+nsURI+"/"+typeName; - } else if (typeObject instanceof EStructuralFeature) { - final EStructuralFeature feature = (EStructuralFeature) typeObject; - return printType(feature.getEContainingClass())+"."+feature.getName(); - } else return typeObject.toString(); - } + protected IncQueryEngine iqEngine; + + /** + * @param iqEngine + */ + public EMFPatternMatcherContext(IncQueryEngine iqEngine) { + super(); + this.iqEngine = iqEngine; + } + + @Override + public EdgeInterpretation edgeInterpretation() { + return EdgeInterpretation.BINARY; + } + + @Override + public GeneralizationQueryDirection allowedGeneralizationQueryDirection() { + return GeneralizationQueryDirection.SUPERTYPE_ONLY_SMART_NOTIFICATIONS; + } + + @Override + public Collection enumerateDirectSupertypes(Object typeObject) { + if (typeObject == null) + return null; + if (typeObject instanceof EClass || typeObject instanceof EDataType) + return enumerateDirectUnarySupertypes(typeObject); + if (typeObject instanceof EStructuralFeature) + return enumerateDirectBinaryEdgeSupertypes(typeObject); + else + throw new IllegalArgumentException("typeObject has invalid type " + typeObject.getClass().getName()); + } + + @Override + public Collection enumerateDirectSubtypes(Object typeObject) { + if (typeObject == null) + return null; + if (typeObject instanceof EClass || typeObject instanceof EDataType) + return enumerateDirectUnarySubtypes(typeObject); + if (typeObject instanceof EStructuralFeature) + return enumerateDirectBinaryEdgeSubtypes(typeObject); + else + throw new IllegalArgumentException("typeObject has invalid type " + typeObject.getClass().getName()); + } + + @Override + public boolean isUnaryType(Object typeObject) { + return typeObject instanceof EClassifier; + } + + @Override + public Collection enumerateDirectUnarySubtypes(Object typeObject) { + if (typeObject instanceof EClass) + throw new UnsupportedOperationException( + "EMF patternmatcher context only supports querying of supertypes, not subtypes."); + // return contextMapping.retrieveSubtypes((EClass)typeObject); + else if (typeObject instanceof EDataType) { + return Collections.emptyList();// no subtyping between EDataTypes? + } else + throw new IllegalArgumentException("typeObject has invalid type " + typeObject.getClass().getName()); + } + + @Override + public Collection enumerateDirectUnarySupertypes(Object typeObject) { + if (typeObject instanceof EClass) + return ((EClass) typeObject).getESuperTypes(); + else if (typeObject instanceof EDataType) { + return Collections.emptyList();// no subtyping between EDataTypes? + } else + throw new IllegalArgumentException("typeObject has invalid type " + typeObject.getClass().getName()); + } + + @Override + public boolean isBinaryEdgeType(Object typeObject) { + return typeObject instanceof EStructuralFeature; + } + + @Override + public Collection enumerateDirectBinaryEdgeSubtypes(Object typeObject) { + return Collections.emptyList();// no subtyping between structural features + } + + @Override + public Collection enumerateDirectBinaryEdgeSupertypes(Object typeObject) { + return Collections.emptyList();// no subtyping between structural features + } + + @Override + public Collection enumerateDirectTernaryEdgeSubtypes(Object typeObject) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isTernaryEdgeType(Object typeObject) { + return false; + } + + @Override + public Collection enumerateDirectTernaryEdgeSupertypes(Object typeObject) { + throw new UnsupportedOperationException(); + } + + @Override + public Object binaryEdgeSourceType(Object typeObject) { + EStructuralFeature feature = (EStructuralFeature) typeObject; + return feature.getEContainingClass(); + } + + @Override + public Object binaryEdgeTargetType(Object typeObject) { + if (typeObject instanceof EAttribute) { + EAttribute attribute = (EAttribute) typeObject; + return attribute.getEAttributeType(); + } else if (typeObject instanceof EReference) { + EReference reference = (EReference) typeObject; + return reference.getEReferenceType(); + } else + throw new IllegalArgumentException("typeObject has invalid type " + typeObject.getClass().getName()); + } + + @Override + public Object ternaryEdgeSourceType(Object typeObject) { + throw new UnsupportedOperationException(); + } + + @Override + public Object ternaryEdgeTargetType(Object typeObject) { + throw new UnsupportedOperationException(); + } + + @Override + public void reportPatternDependency(Pattern pattern) { + // Ignore, because we don't support changing machines here + } + + public Logger getLogger() { + return iqEngine.getLogger(); + } + + @Override + public void logDebug(String message) { + if (getLogger() != null) + getLogger().debug(message); + } + + @Override + public void logError(String message) { + if (getLogger() != null) + getLogger().error(message); + } + + @Override + public void logError(String message, Throwable cause) { + if (getLogger() != null) + getLogger().error(message, cause); + } + + @Override + public void logFatal(String message) { + if (getLogger() != null) + getLogger().fatal(message); + } + + @Override + public void logFatal(String message, Throwable cause) { + if (getLogger() != null) + getLogger().fatal(message, cause); + } + + @Override + public void logWarning(String message) { + if (getLogger() != null) + getLogger().warn(message); + } + + @Override + public void logWarning(String message, Throwable cause) { + if (getLogger() != null) + getLogger().warn(message, cause); + } + + @Override + public String printPattern(Pattern pattern) { + if (pattern == null) { + return "(null)"; + } + return CorePatternLanguageHelper.getFullyQualifiedName(pattern); + } + + @Override + public String printType(Object typeObject) { + if (typeObject == null) { + return "(null)"; + } else if (typeObject instanceof EClassifier) { + final EClassifier eClassifier = (EClassifier) typeObject; + final EPackage ePackage = eClassifier.getEPackage(); + final String nsURI = ePackage == null ? null : ePackage.getNsURI(); + final String typeName = eClassifier.getName(); + return "" + nsURI + "/" + typeName; + } else if (typeObject instanceof EStructuralFeature) { + final EStructuralFeature feature = (EStructuralFeature) typeObject; + return printType(feature.getEContainingClass()) + "." + feature.getName(); + } else + return typeObject.toString(); + } } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/EMFPatternMatcherRuntimeContext.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/EMFPatternMatcherRuntimeContext.java index 8e7dde67..9323130f 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/EMFPatternMatcherRuntimeContext.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/EMFPatternMatcherRuntimeContext.java @@ -29,456 +29,461 @@ import org.eclipse.incquery.runtime.rete.matcher.ReteEngine; import org.eclipse.incquery.runtime.rete.tuple.Tuple; - - /** * @author Bergmann Gábor - * + * */ -public class EMFPatternMatcherRuntimeContext - extends EMFPatternMatcherContext - implements IPatternMatcherRuntimeContext -{ - - -// protected abstract EMFContainmentHierarchyTraversal newTraversal(); -// protected abstract ExtensibleEMFManipulationListener newListener(ReteEngine engine); - -// protected Collection waitingVisitors; -// boolean traversalCoalescing; -// protected ExtensibleEMFManipulationListener listener; - private final NavigationHelper baseIndex; - private BaseIndexListener listener; - - -// protected void traverse(EMFVisitor visitor) { -// try { -// newTraversal().accept(visitor); -// } catch (Exception ex) { -// iqEngine.getLogger().logError( -// "EMF-IncQuery encountered an error in processing the EMF model. " + -// "This happened while traversing the model for the initialization of pattern match caches.", ex); -// } -// } - -// /** -// * @param visitor -// */ -// protected void doVisit(CustomizedEMFVisitor visitor) { -// if (traversalCoalescing) waitingVisitors.add(visitor); -// else traverse(visitor); -// } -// -// -// -// class CustomizedEMFVisitor extends EMFVisitor { -// @Override -// public final void visitNonContainmentReference(EObject source, EReference feature, EObject target) { -// if (target == null) return; // null-valued attributes / references are simply not stored -// if (feature.getEOpposite() != null && feature.getEOpposite().isContainment()) return; -// considerForExpansion(target); -// doVisitReference(source, feature, target); -// } -// -// @Override -// public void visitInternalContainment(EObject source,EReference feature, EObject target) { -// if (target == null) return; // null-valued attributes / references are simply not stored -// if (feature.getEOpposite() != null) { -// doVisitReference(target, feature.getEOpposite(), source); -// } -// doVisitReference(source, feature, target); -// } -//// @Override -//// public void visitExternalReference(EObject source, EReference feature, EObject target) { -//// if (target == null) return; // null-valued attributes / references are simply not stored -//// if (feature.getEOpposite() != null && feature.getEOpposite().isContainment()) return; -//// doVisitReference(source, feature, target); -//// } -// void doVisitReference(EObject source, EReference feature, EObject target) {} -// } - -// public static class ForResourceSet extends EMFPatternMatcherRuntimeContext { -// ResourceSet root; -// Collection additionalResources; -// public ForResourceSet(ResourceSet root, IncQueryEngine iqEngine) { -// super(iqEngine); -// this.root = root; -// this.additionalResources = new HashSet(); -// } -// @Override -// protected EMFContainmentHierarchyTraversal newTraversal() { -// return new EMFContainmentHierarchyTraversal(root, additionalResources); -// } -// @Override -// protected ExtensibleEMFManipulationListener newListener(ReteEngine engine) { -// ExtensibleEMFManipulationListener emfContentTreeViralListener = new EMFContentTreeViralListener(engine, root, this, iqEngine.getLogger()); -// for (Resource resource : additionalResources) { -// emfContentTreeViralListener.addRoot(resource); -// } -// return emfContentTreeViralListener; -// } -// @Override -// public void considerForExpansion(EObject obj) { -// Resource eResource = obj.eResource(); -// if (eResource != null && eResource.getResourceSet() == null && !additionalResources.contains(eResource)) { -// additionalResources.add(eResource); -// listener.addRoot(eResource); -// } -// } -// } -// public static class ForResource extends EMFPatternMatcherRuntimeContext { -// Resource root; -// public ForResource(Resource root, IncQueryEngine iqEngine) { -// super(iqEngine); -// this.root = root; -// } -// @Override -// protected EMFContainmentHierarchyTraversal newTraversal() { -// return new EMFContainmentHierarchyTraversal(root); -// } -// @Override -// protected ExtensibleEMFManipulationListener newListener(ReteEngine engine) { -// return new EMFContentTreeViralListener(engine, root, this, iqEngine.getLogger()); -// } -// @Override -// public void considerForExpansion(EObject obj) {} -// } -// public static class ForEObject extends EMFPatternMatcherRuntimeContext { -// EObject root; -// public ForEObject(EObject root, IncQueryEngine iqEngine) { -// super(iqEngine); -// this.root = root; -// } -// @Override -// protected EMFContainmentHierarchyTraversal newTraversal() { -// return new EMFContainmentHierarchyTraversal(root); -// } -// @Override -// protected ExtensibleEMFManipulationListener newListener(ReteEngine engine) { -// return new EMFContentTreeViralListener(engine, root, this, iqEngine.getLogger()); -// } -// @Override -// public void considerForExpansion(EObject obj) {} -// } -// public static class ForTransactionalEditingDomain extends EMFPatternMatcherRuntimeContext { -// TransactionalEditingDomain domain; -// public ForTransactionalEditingDomain(TransactionalEditingDomain domain) { -// super(); -// this.domain = domain; -// } -// @Override -// protected EMFContainmentHierarchyTraversal newTraversal() { -// return new EMFContainmentHierarchyTraversal(domain.getResourceSet()); -// } -// @Override -// protected ExtensibleEMFManipulationListener newListener(ReteEngine engine) { -// return new EMFTransactionalEditingDomainListener(engine, domain, this); -// } -// @Override -// public void considerForExpansion(EObject obj) {} -// -// } - - /** - * Notifier must be EObject, Resource or ResourceSet - * @param notifier - */ - public EMFPatternMatcherRuntimeContext(IncQueryEngine iqEngine, NavigationHelper baseIndex) { - super(iqEngine); - this.baseIndex = baseIndex; -// this.waitingVisitors = new ArrayList(); -// this.traversalCoalescing = false; - } - - @Override - public V coalesceTraversals(Callable callable) throws InvocationTargetException { - return baseIndex.coalesceTraversals(callable); - } - - -// @Override -// public void startCoalescing() { -// assert(!traversalCoalescing); -// traversalCoalescing = true; -// } -// @Override -// public void finishCoalescing() { -// assert(traversalCoalescing); -// traversalCoalescing = false; -// if (! waitingVisitors.isEmpty()){ -// ArrayList visitors = new ArrayList(waitingVisitors); -// waitingVisitors.clear(); -// newTraversal().accept(new MultiplexerVisitor(visitors)); -// } -// } - - @Override - public void enumerateAllBinaryEdges(final ModelElementPairCrawler crawler) { - throw new UnsupportedOperationException(); - -// CustomizedEMFVisitor visitor = new CustomizedEMFVisitor() { -// @Override -// public void visitAttribute(EObject source, EAttribute feature, Object target) { -// if (target != null) // Exclude NULL attribute values from RETE -// crawler.crawl(source, target); -// super.visitAttribute(source, feature, target); -// } -// @Override -// public void doVisitReference(EObject source, EReference feature, EObject target) { -// crawler.crawl(source, target); -// } -// }; -// doVisit(visitor); - } - - @Override - public void enumerateAllGeneralizations(ModelElementPairCrawler crawler) { - throw new UnsupportedOperationException(); - } - - @Override - // Only direct instantiation of unaries is supported now - public void enumerateAllInstantiations(final ModelElementPairCrawler crawler) { - throw new UnsupportedOperationException(); -// CustomizedEMFVisitor visitor = new CustomizedEMFVisitor() { -// @Override -// public void visitAttribute(EObject source, EAttribute feature, Object target) { -// if (target != null) // Exclude NULL attribute values from RETE -// crawler.crawl(feature.getEAttributeType(), target); -// } -// @Override -// public void visitElement(EObject source) { -// crawler.crawl(source.eClass(), source); -// } -// }; -// doVisit(visitor); - } - - @Override - public void enumerateAllTernaryEdges(final ModelElementCrawler crawler) { - throw new UnsupportedOperationException(); - } - - @Override - public void enumerateAllUnaries(final ModelElementCrawler crawler) { - throw new UnsupportedOperationException(); -// CustomizedEMFVisitor visitor = new CustomizedEMFVisitor() { -// @Override -// public void visitAttribute(EObject source, EAttribute feature, Object target) { -// if (target != null) // Exclude NULL attribute values from RETE -// crawler.crawl(target); -// super.visitAttribute(source, feature, target); -// } -// @Override -// public void visitElement(EObject source) { -// crawler.crawl(source); -// super.visitElement(source); -// } -// }; -// doVisit(visitor); - } - - @Override - public void enumerateAllUnaryContainments(final ModelElementPairCrawler crawler) { - throw new UnsupportedOperationException(); -// CustomizedEMFVisitor visitor = new CustomizedEMFVisitor() { -// // FIXME: containment no longer holds between EObject and its raw attribute values. -//// @Override -//// public void visitAttribute(EObject source, EAttribute feature, Object target) { -//// if (target != null) // Exclude NULL attribute values from RETE -//// crawler.crawl(source, target); -//// super.visitAttribute(source, feature, target); -//// } -// @Override -// public void doVisitReference(EObject source, EReference feature, EObject target) { -// if (feature.isContainment()) crawler.crawl(source, target); -// } -// }; -// doVisit(visitor); - } - - @Override - public void enumerateDirectBinaryEdgeInstances(Object typeObject, final ModelElementPairCrawler crawler) { - final EStructuralFeature structural = (EStructuralFeature) typeObject; - listener.ensure(structural); - final Collection holders = baseIndex.getHoldersOfFeature(structural); - for (EObject holder : holders) { - if (structural.isMany()) { - final Collection values = (Collection) holder.eGet(structural); - for (Object value : values) { - crawler.crawl(holder, value); - } - } else { - final Object value = holder.eGet(structural); - if (value != null) crawler.crawl(holder, value); - } - } -// CustomizedEMFVisitor visitor = new CustomizedEMFVisitor() { -// @Override -// public void visitAttribute(EObject source, EAttribute feature, Object target) { -// if (structural.equals(feature) && target != null) // NULL attribute values excluded from RETE -// crawler.crawl(source, target); -// super.visitAttribute(source, feature, target); -// } -// @Override -// public void doVisitReference(EObject source, EReference feature, EObject target) { -// if (structural.equals(feature)) crawler.crawl(source, target); -// } -// }; -// doVisit(visitor); - } - @Override - public void enumerateAllBinaryEdgeInstances(Object typeObject, final ModelElementPairCrawler crawler) { - enumerateDirectBinaryEdgeInstances(typeObject, crawler); // No edge subtyping - } - - @Override - public void enumerateDirectTernaryEdgeInstances(Object typeObject, final ModelElementCrawler crawler) { - throw new UnsupportedOperationException(); - } - @Override - public void enumerateAllTernaryEdgeInstances(Object typeObject, final ModelElementCrawler crawler) { - throw new UnsupportedOperationException(); - } - - @Override - public void enumerateDirectUnaryInstances(final Object typeObject, final ModelElementCrawler crawler) { - if (typeObject instanceof EClass) { - final EClass eClass = (EClass) typeObject; - listener.ensure(eClass); - final Collection allInstances = baseIndex.getDirectInstances(eClass); - for (EObject eObject : allInstances) { - crawler.crawl(eObject); - } -// CustomizedEMFVisitor visitor = new CustomizedEMFVisitor() { -// @Override -// public void visitElement(EObject source) { -// if (source.eClass().equals(typeObject)) crawler.crawl(source); -// super.visitElement(source); -// } -// }; -// doVisit(visitor); - } else if (typeObject instanceof EDataType) { - final EDataType eDataType = (EDataType) typeObject; - listener.ensure(eDataType); - final Collection allInstances = baseIndex.getDataTypeInstances(eDataType); - for (Object value : allInstances) { - crawler.crawl(value); - } -// CustomizedEMFVisitor visitor = new CustomizedEMFVisitor() { -// @Override -// public void visitAttribute(EObject source, EAttribute feature, Object target) { -// if (target != null && ((EDataType)typeObject).isInstance(target)) // Exclude NULL attribute values from RETE -// crawler.crawl(target); -// super.visitAttribute(source, feature, target); -// } -// }; -// doVisit(visitor); - } else throw new IllegalArgumentException("typeObject has invalid type " + typeObject.getClass().getName()); - } - @Override - public void enumerateAllUnaryInstances(final Object typeObject, final ModelElementCrawler crawler) { - if (typeObject instanceof EClass) { - final EClass eClass = (EClass) typeObject; - listener.ensure(eClass); - final Collection allInstances = baseIndex.getAllInstances(eClass); - for (EObject eObject : allInstances) { - crawler.crawl(eObject); - } -// CustomizedEMFVisitor visitor = new CustomizedEMFVisitor() { -// @Override -// public void visitElement(EObject source) { -// if (((EClass)typeObject).isInstance(source)) crawler.crawl(source); -// super.visitElement(source); -// } -// }; -// doVisit(visitor); - } else if (typeObject instanceof EDataType) { - final EDataType eDataType = (EDataType) typeObject; - listener.ensure(eDataType); - final Collection allInstances = baseIndex.getDataTypeInstances(eDataType); - for (Object value : allInstances) { - crawler.crawl(value); - } -// CustomizedEMFVisitor visitor = new CustomizedEMFVisitor() { -// @Override -// public void visitAttribute(EObject source, EAttribute feature, Object target) { -// if (target != null && ((EDataType)typeObject).isInstance(target)) // Exclude NULL attribute values from RETE -// crawler.crawl(target); -// super.visitAttribute(source, feature, target); -// } -// }; -// doVisit(visitor); - } else throw new IllegalArgumentException("typeObject has invalid type " + typeObject.getClass().getName()); - } - - @Override - public void modelReadLock() { - // TODO runnable? domain.runExclusive(read) - - } - - @Override - public void modelReadUnLock() { - // TODO runnable? domain.runExclusive(read) - - } - - // @Override - // public String retrieveUnaryTypeFQN(Object typeObject) { - // return contextMapping.retrieveFQN((EClassifier)typeObject); - // } - // - // @Override - // public String retrieveBinaryEdgeTypeFQN(Object typeObject) { - // return contextMapping.retrieveFQN((EStructuralFeature)typeObject); - // } - // - // @Override - // public String retrieveTernaryEdgeTypeFQN(Object typeObject) { - // throw new UnsupportedOperationException(); - // } - - - @Override - // TODO Transactional? - public IManipulationListener subscribePatternMatcherForUpdates(ReteEngine engine) { - if (listener == null) listener = new BaseIndexListener(iqEngine, engine, baseIndex); - return listener; - } - - @Override - public Object ternaryEdgeSource(Object relation) { - throw new UnsupportedOperationException(); - } - - @Override - public Object ternaryEdgeTarget(Object relation) { - throw new UnsupportedOperationException(); - } - - @Override - public IPredicateTraceListener subscribePatternMatcherForTraceInfluences(ReteEngine engine) { - // No ASMFunctions, use DUMMY - return new IPredicateTraceListener() { - @Override - public void registerSensitiveTrace(Tuple trace, - PredicateEvaluatorNode node) { - } - @Override - public void unregisterSensitiveTrace(Tuple trace, - PredicateEvaluatorNode node) { - } - @Override - public void disconnect() { - } - }; - } - -// /** -// * Consider expanding the notification scope to this object and surroundings. -// * Hack added primarily to handle EPackage instances referenced by nsUri -// * @param obj -// */ -// public abstract void considerForExpansion(EObject obj); +public class EMFPatternMatcherRuntimeContext extends EMFPatternMatcherContext implements + IPatternMatcherRuntimeContext { + + // protected abstract EMFContainmentHierarchyTraversal newTraversal(); + // protected abstract ExtensibleEMFManipulationListener newListener(ReteEngine engine); + + // protected Collection waitingVisitors; + // boolean traversalCoalescing; + // protected ExtensibleEMFManipulationListener listener; + private final NavigationHelper baseIndex; + private BaseIndexListener listener; + + // protected void traverse(EMFVisitor visitor) { + // try { + // newTraversal().accept(visitor); + // } catch (Exception ex) { + // iqEngine.getLogger().logError( + // "EMF-IncQuery encountered an error in processing the EMF model. " + + // "This happened while traversing the model for the initialization of pattern match caches.", ex); + // } + // } + + // /** + // * @param visitor + // */ + // protected void doVisit(CustomizedEMFVisitor visitor) { + // if (traversalCoalescing) waitingVisitors.add(visitor); + // else traverse(visitor); + // } + // + // + // + // class CustomizedEMFVisitor extends EMFVisitor { + // @Override + // public final void visitNonContainmentReference(EObject source, EReference feature, EObject target) { + // if (target == null) return; // null-valued attributes / references are simply not stored + // if (feature.getEOpposite() != null && feature.getEOpposite().isContainment()) return; + // considerForExpansion(target); + // doVisitReference(source, feature, target); + // } + // + // @Override + // public void visitInternalContainment(EObject source,EReference feature, EObject target) { + // if (target == null) return; // null-valued attributes / references are simply not stored + // if (feature.getEOpposite() != null) { + // doVisitReference(target, feature.getEOpposite(), source); + // } + // doVisitReference(source, feature, target); + // } + // // @Override + // // public void visitExternalReference(EObject source, EReference feature, EObject target) { + // // if (target == null) return; // null-valued attributes / references are simply not stored + // // if (feature.getEOpposite() != null && feature.getEOpposite().isContainment()) return; + // // doVisitReference(source, feature, target); + // // } + // void doVisitReference(EObject source, EReference feature, EObject target) {} + // } + + // public static class ForResourceSet extends + // EMFPatternMatcherRuntimeContext { + // ResourceSet root; + // Collection additionalResources; + // public ForResourceSet(ResourceSet root, IncQueryEngine iqEngine) { + // super(iqEngine); + // this.root = root; + // this.additionalResources = new HashSet(); + // } + // @Override + // protected EMFContainmentHierarchyTraversal newTraversal() { + // return new EMFContainmentHierarchyTraversal(root, additionalResources); + // } + // @Override + // protected ExtensibleEMFManipulationListener newListener(ReteEngine engine) { + // ExtensibleEMFManipulationListener emfContentTreeViralListener = new EMFContentTreeViralListener(engine, root, + // this, iqEngine.getLogger()); + // for (Resource resource : additionalResources) { + // emfContentTreeViralListener.addRoot(resource); + // } + // return emfContentTreeViralListener; + // } + // @Override + // public void considerForExpansion(EObject obj) { + // Resource eResource = obj.eResource(); + // if (eResource != null && eResource.getResourceSet() == null && !additionalResources.contains(eResource)) { + // additionalResources.add(eResource); + // listener.addRoot(eResource); + // } + // } + // } + // public static class ForResource extends EMFPatternMatcherRuntimeContext { + // Resource root; + // public ForResource(Resource root, IncQueryEngine iqEngine) { + // super(iqEngine); + // this.root = root; + // } + // @Override + // protected EMFContainmentHierarchyTraversal newTraversal() { + // return new EMFContainmentHierarchyTraversal(root); + // } + // @Override + // protected ExtensibleEMFManipulationListener newListener(ReteEngine engine) { + // return new EMFContentTreeViralListener(engine, root, this, iqEngine.getLogger()); + // } + // @Override + // public void considerForExpansion(EObject obj) {} + // } + // public static class ForEObject extends EMFPatternMatcherRuntimeContext { + // EObject root; + // public ForEObject(EObject root, IncQueryEngine iqEngine) { + // super(iqEngine); + // this.root = root; + // } + // @Override + // protected EMFContainmentHierarchyTraversal newTraversal() { + // return new EMFContainmentHierarchyTraversal(root); + // } + // @Override + // protected ExtensibleEMFManipulationListener newListener(ReteEngine engine) { + // return new EMFContentTreeViralListener(engine, root, this, iqEngine.getLogger()); + // } + // @Override + // public void considerForExpansion(EObject obj) {} + // } + // public static class ForTransactionalEditingDomain extends + // EMFPatternMatcherRuntimeContext { + // TransactionalEditingDomain domain; + // public ForTransactionalEditingDomain(TransactionalEditingDomain domain) { + // super(); + // this.domain = domain; + // } + // @Override + // protected EMFContainmentHierarchyTraversal newTraversal() { + // return new EMFContainmentHierarchyTraversal(domain.getResourceSet()); + // } + // @Override + // protected ExtensibleEMFManipulationListener newListener(ReteEngine engine) { + // return new EMFTransactionalEditingDomainListener(engine, domain, this); + // } + // @Override + // public void considerForExpansion(EObject obj) {} + // + // } + + /** + * Notifier must be EObject, Resource or ResourceSet + * + * @param notifier + */ + public EMFPatternMatcherRuntimeContext(IncQueryEngine iqEngine, NavigationHelper baseIndex) { + super(iqEngine); + this.baseIndex = baseIndex; + // this.waitingVisitors = new ArrayList(); + // this.traversalCoalescing = false; + } + + @Override + public V coalesceTraversals(Callable callable) throws InvocationTargetException { + return baseIndex.coalesceTraversals(callable); + } + + // @Override + // public void startCoalescing() { + // assert(!traversalCoalescing); + // traversalCoalescing = true; + // } + // @Override + // public void finishCoalescing() { + // assert(traversalCoalescing); + // traversalCoalescing = false; + // if (! waitingVisitors.isEmpty()){ + // ArrayList visitors = new ArrayList(waitingVisitors); + // waitingVisitors.clear(); + // newTraversal().accept(new MultiplexerVisitor(visitors)); + // } + // } + + @Override + public void enumerateAllBinaryEdges(final ModelElementPairCrawler crawler) { + throw new UnsupportedOperationException(); + + // CustomizedEMFVisitor visitor = new CustomizedEMFVisitor() { + // @Override + // public void visitAttribute(EObject source, EAttribute feature, Object target) { + // if (target != null) // Exclude NULL attribute values from RETE + // crawler.crawl(source, target); + // super.visitAttribute(source, feature, target); + // } + // @Override + // public void doVisitReference(EObject source, EReference feature, EObject target) { + // crawler.crawl(source, target); + // } + // }; + // doVisit(visitor); + } + + @Override + public void enumerateAllGeneralizations(ModelElementPairCrawler crawler) { + throw new UnsupportedOperationException(); + } + + @Override + // Only direct instantiation of unaries is supported now + public void enumerateAllInstantiations(final ModelElementPairCrawler crawler) { + throw new UnsupportedOperationException(); + // CustomizedEMFVisitor visitor = new CustomizedEMFVisitor() { + // @Override + // public void visitAttribute(EObject source, EAttribute feature, Object target) { + // if (target != null) // Exclude NULL attribute values from RETE + // crawler.crawl(feature.getEAttributeType(), target); + // } + // @Override + // public void visitElement(EObject source) { + // crawler.crawl(source.eClass(), source); + // } + // }; + // doVisit(visitor); + } + + @Override + public void enumerateAllTernaryEdges(final ModelElementCrawler crawler) { + throw new UnsupportedOperationException(); + } + + @Override + public void enumerateAllUnaries(final ModelElementCrawler crawler) { + throw new UnsupportedOperationException(); + // CustomizedEMFVisitor visitor = new CustomizedEMFVisitor() { + // @Override + // public void visitAttribute(EObject source, EAttribute feature, Object target) { + // if (target != null) // Exclude NULL attribute values from RETE + // crawler.crawl(target); + // super.visitAttribute(source, feature, target); + // } + // @Override + // public void visitElement(EObject source) { + // crawler.crawl(source); + // super.visitElement(source); + // } + // }; + // doVisit(visitor); + } + + @Override + public void enumerateAllUnaryContainments(final ModelElementPairCrawler crawler) { + throw new UnsupportedOperationException(); + // CustomizedEMFVisitor visitor = new CustomizedEMFVisitor() { + // // FIXME: containment no longer holds between EObject and its raw attribute values. + // // @Override + // // public void visitAttribute(EObject source, EAttribute feature, Object target) { + // // if (target != null) // Exclude NULL attribute values from RETE + // // crawler.crawl(source, target); + // // super.visitAttribute(source, feature, target); + // // } + // @Override + // public void doVisitReference(EObject source, EReference feature, EObject target) { + // if (feature.isContainment()) crawler.crawl(source, target); + // } + // }; + // doVisit(visitor); + } + + @Override + public void enumerateDirectBinaryEdgeInstances(Object typeObject, final ModelElementPairCrawler crawler) { + final EStructuralFeature structural = (EStructuralFeature) typeObject; + listener.ensure(structural); + final Collection holders = baseIndex.getHoldersOfFeature(structural); + for (EObject holder : holders) { + if (structural.isMany()) { + final Collection values = (Collection) holder.eGet(structural); + for (Object value : values) { + crawler.crawl(holder, value); + } + } else { + final Object value = holder.eGet(structural); + if (value != null) + crawler.crawl(holder, value); + } + } + // CustomizedEMFVisitor visitor = new CustomizedEMFVisitor() { + // @Override + // public void visitAttribute(EObject source, EAttribute feature, Object target) { + // if (structural.equals(feature) && target != null) // NULL attribute values excluded from RETE + // crawler.crawl(source, target); + // super.visitAttribute(source, feature, target); + // } + // @Override + // public void doVisitReference(EObject source, EReference feature, EObject target) { + // if (structural.equals(feature)) crawler.crawl(source, target); + // } + // }; + // doVisit(visitor); + } + + @Override + public void enumerateAllBinaryEdgeInstances(Object typeObject, final ModelElementPairCrawler crawler) { + enumerateDirectBinaryEdgeInstances(typeObject, crawler); // No edge subtyping + } + + @Override + public void enumerateDirectTernaryEdgeInstances(Object typeObject, final ModelElementCrawler crawler) { + throw new UnsupportedOperationException(); + } + + @Override + public void enumerateAllTernaryEdgeInstances(Object typeObject, final ModelElementCrawler crawler) { + throw new UnsupportedOperationException(); + } + + @Override + public void enumerateDirectUnaryInstances(final Object typeObject, final ModelElementCrawler crawler) { + if (typeObject instanceof EClass) { + final EClass eClass = (EClass) typeObject; + listener.ensure(eClass); + final Collection allInstances = baseIndex.getDirectInstances(eClass); + for (EObject eObject : allInstances) { + crawler.crawl(eObject); + } + // CustomizedEMFVisitor visitor = new CustomizedEMFVisitor() { + // @Override + // public void visitElement(EObject source) { + // if (source.eClass().equals(typeObject)) crawler.crawl(source); + // super.visitElement(source); + // } + // }; + // doVisit(visitor); + } else if (typeObject instanceof EDataType) { + final EDataType eDataType = (EDataType) typeObject; + listener.ensure(eDataType); + final Collection allInstances = baseIndex.getDataTypeInstances(eDataType); + for (Object value : allInstances) { + crawler.crawl(value); + } + // CustomizedEMFVisitor visitor = new CustomizedEMFVisitor() { + // @Override + // public void visitAttribute(EObject source, EAttribute feature, Object target) { + // if (target != null && ((EDataType)typeObject).isInstance(target)) // Exclude NULL attribute values from + // RETE + // crawler.crawl(target); + // super.visitAttribute(source, feature, target); + // } + // }; + // doVisit(visitor); + } else + throw new IllegalArgumentException("typeObject has invalid type " + typeObject.getClass().getName()); + } + + @Override + public void enumerateAllUnaryInstances(final Object typeObject, final ModelElementCrawler crawler) { + if (typeObject instanceof EClass) { + final EClass eClass = (EClass) typeObject; + listener.ensure(eClass); + final Collection allInstances = baseIndex.getAllInstances(eClass); + for (EObject eObject : allInstances) { + crawler.crawl(eObject); + } + // CustomizedEMFVisitor visitor = new CustomizedEMFVisitor() { + // @Override + // public void visitElement(EObject source) { + // if (((EClass)typeObject).isInstance(source)) crawler.crawl(source); + // super.visitElement(source); + // } + // }; + // doVisit(visitor); + } else if (typeObject instanceof EDataType) { + final EDataType eDataType = (EDataType) typeObject; + listener.ensure(eDataType); + final Collection allInstances = baseIndex.getDataTypeInstances(eDataType); + for (Object value : allInstances) { + crawler.crawl(value); + } + // CustomizedEMFVisitor visitor = new CustomizedEMFVisitor() { + // @Override + // public void visitAttribute(EObject source, EAttribute feature, Object target) { + // if (target != null && ((EDataType)typeObject).isInstance(target)) // Exclude NULL attribute values from + // RETE + // crawler.crawl(target); + // super.visitAttribute(source, feature, target); + // } + // }; + // doVisit(visitor); + } else + throw new IllegalArgumentException("typeObject has invalid type " + typeObject.getClass().getName()); + } + + @Override + public void modelReadLock() { + // TODO runnable? domain.runExclusive(read) + + } + + @Override + public void modelReadUnLock() { + // TODO runnable? domain.runExclusive(read) + + } + + // @Override + // public String retrieveUnaryTypeFQN(Object typeObject) { + // return contextMapping.retrieveFQN((EClassifier)typeObject); + // } + // + // @Override + // public String retrieveBinaryEdgeTypeFQN(Object typeObject) { + // return contextMapping.retrieveFQN((EStructuralFeature)typeObject); + // } + // + // @Override + // public String retrieveTernaryEdgeTypeFQN(Object typeObject) { + // throw new UnsupportedOperationException(); + // } + + @Override + // TODO Transactional? + public IManipulationListener subscribePatternMatcherForUpdates(ReteEngine engine) { + if (listener == null) + listener = new BaseIndexListener(iqEngine, engine, baseIndex); + return listener; + } + + @Override + public Object ternaryEdgeSource(Object relation) { + throw new UnsupportedOperationException(); + } + + @Override + public Object ternaryEdgeTarget(Object relation) { + throw new UnsupportedOperationException(); + } + + @Override + public IPredicateTraceListener subscribePatternMatcherForTraceInfluences(ReteEngine engine) { + // No ASMFunctions, use DUMMY + return new IPredicateTraceListener() { + @Override + public void registerSensitiveTrace(Tuple trace, PredicateEvaluatorNode node) { + } + + @Override + public void unregisterSensitiveTrace(Tuple trace, PredicateEvaluatorNode node) { + } + + @Override + public void disconnect() { + } + }; + } + + // /** + // * Consider expanding the notification scope to this object and surroundings. + // * Hack added primarily to handle EPackage instances referenced by nsUri + // * @param obj + // */ + // public abstract void considerForExpansion(EObject obj); } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/PatternSanitizer.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/PatternSanitizer.java index 6687346e..e9b2b0b3 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/PatternSanitizer.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/PatternSanitizer.java @@ -29,142 +29,139 @@ import com.google.inject.Injector; /** - * Stateful sanitizer that maintains a set of admitted patterns. - * Patterns go through sanitization checks (validation + name uniqueness) before they can be admitted. + * Stateful sanitizer that maintains a set of admitted patterns. Patterns go through sanitization checks (validation + + * name uniqueness) before they can be admitted. * - *

    INVARIANTS:

      + *

      + * INVARIANTS: + *

        *
      • the set of admitted patterns is closed with respect to references. *
      • the set of admitted patterns are free of errors. *
      • admitted patterns have unique qualified names. *
      * * @author Bergmann Gábor - * + * */ public class PatternSanitizer { - Set admittedPatterns = new HashSet(); - Map patternsByName = new HashMap(); - - Logger logger; - - - /** - * Creates an instance of the stateful sanitizer. - * - * @param logger where detected problems will be logged - */ - public PatternSanitizer(final Logger logger) { - super(); - - this.logger = logger; - } - - - - - /** - * Admits a new pattern, checking if it passes validation and name uniqueness checks. - * Referenced patterns likewise go through the checks. - * Transactional semantics: will only admit any patterns if none of them have any errors. - * - * @param pattern a pattern that should be validated. - * @return false if the pattern was not possible to admit, true if it passed all validation checks (or was already admitted before) - */ - public boolean admit(Pattern pattern) { - return admit(Collections.singletonList(pattern)); - } - - /** - * Admits new patterns, checking whether they all pass validation and name uniqueness checks. - * Referenced patterns likewise go through the checks. - * Transactional semantics: will only admit any patterns if none of them have any errors. - * - * @param patterns the collection of patterns that should be validated together. - * @return false if the patterns were not possible to admit, true if they passed all validation checks (or were already admitted before) - */ - public boolean admit(Collection patterns) { - Set newPatterns = getAllReferencedUnvalidatedPatterns(patterns); - if (newPatterns.isEmpty()) return true; - - // TODO validate(toBeValidated) as a group - Set inadmissible = new HashSet(); - Map newPatternsByName = new HashMap(); - for (Pattern current : newPatterns) { - if (current == null) { - inadmissible.add(current); - logger.error("Null pattern value"); - } - - final String fullyQualifiedName = CorePatternLanguageHelper.getFullyQualifiedName(current); - final boolean duplicate = patternsByName.containsKey(fullyQualifiedName) || newPatternsByName.containsKey(fullyQualifiedName); - if (duplicate) { - inadmissible.add(current); - logger.error("Duplicate (qualified) name of pattern: " + fullyQualifiedName); - } else { - newPatternsByName.put(fullyQualifiedName, current); - } - - final boolean validationPassed = true; //validator == null || validator.validate(current, errorOnlyLogger); - if (!validationPassed) { - inadmissible.add(current); - } - - } - Injector injector = XtextInjectorProvider.INSTANCE.getInjector(); - PatternSetValidator validator = injector.getInstance(PatternSetValidator.class); - PatternSetValidationDiagnostics validatorResult = validator.validate(patterns); - validatorResult.logErrors(logger); - - boolean ok = inadmissible.isEmpty() && !validatorResult.getStatus().equals(PatternValidationStatus.ERROR); - if (ok) { - admittedPatterns.addAll(newPatterns); - patternsByName.putAll(newPatternsByName); - } - return ok; - } - - - - - /** - * Gathers all patterns that are not admitted yet, but are transitively referenced from the given patterns. - */ - protected Set getAllReferencedUnvalidatedPatterns(Collection patterns) { - Set toBeValidated = new HashSet(); - - LinkedList unexplored = new LinkedList(); - - for (Pattern pattern : patterns) { - if (!admittedPatterns.contains(pattern)) { - toBeValidated.add(pattern); - unexplored.add(pattern); - } - } - - while (!unexplored.isEmpty()) { - Pattern current = unexplored.pollFirst(); - final Set referencedPatterns = CorePatternLanguageHelper.getReferencedPatterns(current); - for (Pattern referenced : referencedPatterns) { - if (!admittedPatterns.contains(referenced) && !toBeValidated.contains(referenced)) { - toBeValidated.add(referenced); - unexplored.add(referenced); - } - } - } - return toBeValidated; - } - - - - - /** - * Returns the set of patterns that have been admitted so far. - * @return the admitted patterns - */ - public Set getAdmittedPatterns() { - return Collections.unmodifiableSet(admittedPatterns); - } - - - + Set admittedPatterns = new HashSet(); + Map patternsByName = new HashMap(); + + Logger logger; + + /** + * Creates an instance of the stateful sanitizer. + * + * @param logger + * where detected problems will be logged + */ + public PatternSanitizer(final Logger logger) { + super(); + + this.logger = logger; + } + + /** + * Admits a new pattern, checking if it passes validation and name uniqueness checks. Referenced patterns likewise + * go through the checks. Transactional semantics: will only admit any patterns if none of them have any errors. + * + * @param pattern + * a pattern that should be validated. + * @return false if the pattern was not possible to admit, true if it passed all validation checks (or was already + * admitted before) + */ + public boolean admit(Pattern pattern) { + return admit(Collections.singletonList(pattern)); + } + + /** + * Admits new patterns, checking whether they all pass validation and name uniqueness checks. Referenced patterns + * likewise go through the checks. Transactional semantics: will only admit any patterns if none of them have any + * errors. + * + * @param patterns + * the collection of patterns that should be validated together. + * @return false if the patterns were not possible to admit, true if they passed all validation checks (or were + * already admitted before) + */ + public boolean admit(Collection patterns) { + Set newPatterns = getAllReferencedUnvalidatedPatterns(patterns); + if (newPatterns.isEmpty()) + return true; + + // TODO validate(toBeValidated) as a group + Set inadmissible = new HashSet(); + Map newPatternsByName = new HashMap(); + for (Pattern current : newPatterns) { + if (current == null) { + inadmissible.add(current); + logger.error("Null pattern value"); + } + + final String fullyQualifiedName = CorePatternLanguageHelper.getFullyQualifiedName(current); + final boolean duplicate = patternsByName.containsKey(fullyQualifiedName) + || newPatternsByName.containsKey(fullyQualifiedName); + if (duplicate) { + inadmissible.add(current); + logger.error("Duplicate (qualified) name of pattern: " + fullyQualifiedName); + } else { + newPatternsByName.put(fullyQualifiedName, current); + } + + final boolean validationPassed = true; // validator == null || validator.validate(current, errorOnlyLogger); + if (!validationPassed) { + inadmissible.add(current); + } + + } + Injector injector = XtextInjectorProvider.INSTANCE.getInjector(); + PatternSetValidator validator = injector.getInstance(PatternSetValidator.class); + PatternSetValidationDiagnostics validatorResult = validator.validate(patterns); + validatorResult.logErrors(logger); + + boolean ok = inadmissible.isEmpty() && !validatorResult.getStatus().equals(PatternValidationStatus.ERROR); + if (ok) { + admittedPatterns.addAll(newPatterns); + patternsByName.putAll(newPatternsByName); + } + return ok; + } + + /** + * Gathers all patterns that are not admitted yet, but are transitively referenced from the given patterns. + */ + protected Set getAllReferencedUnvalidatedPatterns(Collection patterns) { + Set toBeValidated = new HashSet(); + + LinkedList unexplored = new LinkedList(); + + for (Pattern pattern : patterns) { + if (!admittedPatterns.contains(pattern)) { + toBeValidated.add(pattern); + unexplored.add(pattern); + } + } + + while (!unexplored.isEmpty()) { + Pattern current = unexplored.pollFirst(); + final Set referencedPatterns = CorePatternLanguageHelper.getReferencedPatterns(current); + for (Pattern referenced : referencedPatterns) { + if (!admittedPatterns.contains(referenced) && !toBeValidated.contains(referenced)) { + toBeValidated.add(referenced); + unexplored.add(referenced); + } + } + } + return toBeValidated; + } + + /** + * Returns the set of patterns that have been admitted so far. + * + * @return the admitted patterns + */ + public Set getAdmittedPatterns() { + return Collections.unmodifiableSet(admittedPatterns); + } + } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/XtextInjectorProvider.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/XtextInjectorProvider.java index da4bda60..0c31d887 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/XtextInjectorProvider.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/XtextInjectorProvider.java @@ -16,30 +16,28 @@ /** * A singleton provider for Xtext injectors + * * @author Zoltan Ujhelyi - * + * */ public final class XtextInjectorProvider { - public final static XtextInjectorProvider INSTANCE = new XtextInjectorProvider(); - private Injector injector; - - - private XtextInjectorProvider() {} + public final static XtextInjectorProvider INSTANCE = new XtextInjectorProvider(); + private Injector injector; + private XtextInjectorProvider() { + } - public Injector getInjector() { - return injector; - } + public Injector getInjector() { + return injector; + } + public void setInjector(Injector injector) { + this.injector = injector; + } - public void setInjector(Injector injector) { - this.injector = injector; - } - - public void initializeHeadlessInjector() { - EMFPatternLanguageStandaloneSetup setup = - new EMFPatternLanguageStandaloneSetup(); - injector = setup.createInjectorAndDoEMFRegistration(); - } + public void initializeHeadlessInjector() { + EMFPatternLanguageStandaloneSetup setup = new EMFPatternLanguageStandaloneSetup(); + injector = setup.createInjectorAndDoEMFRegistration(); + } } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/boundary/CallbackNode.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/boundary/CallbackNode.java index 4e18d239..8b6a352e 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/boundary/CallbackNode.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/boundary/CallbackNode.java @@ -10,7 +10,6 @@ *******************************************************************************/ package org.eclipse.incquery.runtime.internal.boundary; - import org.eclipse.incquery.runtime.api.IMatchUpdateListener; import org.eclipse.incquery.runtime.api.IPatternMatch; import org.eclipse.incquery.runtime.api.IncQueryEngine; @@ -21,45 +20,38 @@ /** * @author Bergmann Gabor - * + * */ public abstract class CallbackNode extends SimpleReceiver { - IncQueryEngine engine; - IMatchUpdateListener listener; - - public abstract Match statelessConvert(Tuple t); - - - public CallbackNode(ReteContainer reteContainer, IncQueryEngine engine, - IMatchUpdateListener listener) { - super(reteContainer); - this.engine = engine; - this.listener = listener; - } + IncQueryEngine engine; + IMatchUpdateListener listener; + public abstract Match statelessConvert(Tuple t); + public CallbackNode(ReteContainer reteContainer, IncQueryEngine engine, IMatchUpdateListener listener) { + super(reteContainer); + this.engine = engine; + this.listener = listener; + } + + @Override + public void update(Direction direction, Tuple updateElement) { + Match match = statelessConvert(updateElement); + try { + if (direction == Direction.INSERT) + listener.notifyAppearance(match); + else + listener.notifyDisappearance(match); + } catch (Throwable e) { // NOPMD + if (e instanceof Error) + throw (Error) e; + engine.getLogger() + .warn(String.format( + "The incremental pattern matcher encountered an error during executing a callback on %s of match %s of pattern %s. Error message: %s. (Developer note: %s in %s called from CallbackNode)", + direction == Direction.INSERT ? "insertion" : "removal", match.prettyPrint(), + match.patternName(), e.getMessage(), e.getClass().getSimpleName(), listener), e); + } + } - @Override - public void update(Direction direction, Tuple updateElement) { - Match match = statelessConvert(updateElement); - try { - if (direction == Direction.INSERT) - listener.notifyAppearance(match); - else - listener.notifyDisappearance(match); - } catch (Throwable e) { //NOPMD - if (e instanceof Error) throw (Error)e; - engine.getLogger().warn(String.format( - "The incremental pattern matcher encountered an error during executing a callback on %s of match %s of pattern %s. Error message: %s. (Developer note: %s in %s called from CallbackNode)", - direction == Direction.INSERT ? "insertion" : "removal", - match.prettyPrint(), - match.patternName(), - e.getMessage(), - e.getClass().getSimpleName(), - listener - ), e); - } - } - } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/boundary/EClassUnaryInputNode.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/boundary/EClassUnaryInputNode.java index 3a2747b1..32c12d7a 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/boundary/EClassUnaryInputNode.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/boundary/EClassUnaryInputNode.java @@ -1,4 +1,5 @@ package org.eclipse.incquery.runtime.internal.boundary; + ///******************************************************************************* // * Copyright (c) 2004-2012 Gabor Bergmann and Daniel Varro // * All rights reserved. This program and the accompanying materials @@ -199,4 +200,4 @@ // return identityIndexer; // } // -//} +// } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/boundary/EStructuralFeatureBinaryInputNode.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/boundary/EStructuralFeatureBinaryInputNode.java index c1eb84c5..84181553 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/boundary/EStructuralFeatureBinaryInputNode.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/boundary/EStructuralFeatureBinaryInputNode.java @@ -1,4 +1,5 @@ package org.eclipse.incquery.runtime.internal.boundary; + ///******************************************************************************* // * Copyright (c) 2004-2012 Gabor Bergmann and Daniel Varro // * All rights reserved. This program and the accompanying materials @@ -316,4 +317,4 @@ // } // // -//} +// } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/matcherbuilder/EPMBodyToPSystem.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/matcherbuilder/EPMBodyToPSystem.java index dcdf5ccf..8d570439 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/matcherbuilder/EPMBodyToPSystem.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/matcherbuilder/EPMBodyToPSystem.java @@ -66,337 +66,329 @@ /** * @author Bergmann Gábor - * + * */ public class EPMBodyToPSystem { - - protected Pattern pattern; - protected PatternBody body; - protected IPatternMatcherContext context; - protected Buildable buildable; - - protected PSystem pSystem; - - String patternFQN; - - /** - * @param pattern - * @param body - * @param builder - * @param buildable - */ - public EPMBodyToPSystem(Pattern pattern, PatternBody body, - IPatternMatcherContext context, - Buildable buildable) { - super(); - this.pattern = pattern; - this.body = body; - this.context = context; - this.buildable = buildable; - - patternFQN = CorePatternLanguageHelper.getFullyQualifiedName(pattern); - } - - public PSystem toPSystem() throws RetePatternBuildException { - try { - if (this.pSystem == null) { - this.pSystem = new PSystem(context, buildable, pattern); - - // TODO - // preProcessAssignments(); - preProcessParameters(); - gatherBodyConstraints(); - } - return pSystem; - } catch (RetePatternBuildException e) { - e.setPatternDescription(pattern); - throw e; - } - } - - public PVariable[] symbolicParameterArray() throws RetePatternBuildException { - toPSystem(); - - EList symParameters = pattern.getParameters(); - int arity = symParameters.size(); - PVariable[] result = new PVariable[arity]; - for (int i=0; i variables) throws RetePatternBuildException { - PVariable[] pNodeArray = getPNodeArray(variables); - return new FlatTuple(pNodeArray); - } - public PVariable[] getPNodeArray(List variables) throws RetePatternBuildException { - int k = 0; - PVariable[] pNodeArray = new PVariable[variables.size()]; - for (ValueReference varRef : variables) { - pNodeArray[k++] = getPNode(varRef); - } - return pNodeArray; - } - protected PVariable getPNode(ValueReference reference) throws RetePatternBuildException { - if (reference instanceof VariableValue) - return getPNode(((VariableValue) reference).getValue()); - else if (reference instanceof AggregatedValue) - return aggregate((AggregatedValue) reference); - else if (reference instanceof IntValue) - return pSystem.newConstantVariable(((IntValue) reference).getValue()); - else if (reference instanceof StringValue) - return pSystem.newConstantVariable(((StringValue) reference).getValue()); - else if (reference instanceof EnumValue) // EMF-specific - return pSystem.newConstantVariable(((EnumValue) reference).getLiteral().getInstance()); - else if (reference instanceof DoubleValue) { - return pSystem.newConstantVariable(((DoubleValue) reference).getValue()); - } - else if (reference instanceof BoolValue) { - Boolean b = ((BoolValue) reference).isValue(); - return pSystem.newConstantVariable(b); - } - else throw new RetePatternBuildException( - "Unsupported value reference of type {1} from EPackage {2} currently unsupported by pattern builder in pattern {3}.", - new String[]{ - reference != null? reference.eClass().getName() : "(null)", - reference != null? reference.eClass().getEPackage().getNsURI() : "(null)", - pattern.getName() - }, "Unsupported value expression", pattern); - } - - - protected PVariable newVirtual() { - return pSystem.newVirtualVariable(); - } -// protected Tuple getPNodeTuple(List references) throws RetePatternBuildException { -// PVariable[] pNodeArray = getPNodeArray(references); -// return new FlatTuple(pNodeArray); -// } -// public PVariable[] getPNodeArray(List references) throws RetePatternBuildException { -// int k = 0; -// PVariable[] pNodeArray = new PVariable[references.size()]; -// for (ValueReference varRef : references) { -// pNodeArray[k++] = getPNode(varRef); -// } -// return pNodeArray; -// } - private void preProcessParameters() { - EList parameters = pattern.getParameters(); - for (Variable variable : parameters) { - new ExportedParameter(pSystem, getPNode(variable), variable.getName()); - if (variable.getType() != null && variable.getType() instanceof ClassType) { - EClassifier classname = ((ClassType)variable.getType()).getClassname(); - PVariable pNode = getPNode(variable); - new TypeUnary(pSystem, pNode, classname); - } - } - -// final EList bodyVariables = body.getVariables(); -// for (Variable bodyVariable : bodyVariables) { -// if (bodyVariable instanceof ParameterRef) { -// final Variable referredParam = ((ParameterRef) bodyVariable).getReferredParam(); -// new Equality(pSystem, -// getPNode(referredParam), getPNode(bodyVariable)); -// } -// } - } - private void gatherBodyConstraints() throws RetePatternBuildException { - EList constraints = body.getConstraints(); - for (Constraint constraint : constraints) { - gatherConstraint(constraint); - } - } - - /** - * @param constraint - * @throws RetePatternBuildException - */ - protected void gatherConstraint(Constraint constraint) - throws RetePatternBuildException { - if (constraint instanceof EClassifierConstraint) { // EMF-specific - EClassifierConstraint constraint2 = (EClassifierConstraint) constraint; - gatherClassifierConstraint(constraint2); - } else if (constraint instanceof PatternCompositionConstraint) { - PatternCompositionConstraint constraint2 = (PatternCompositionConstraint) constraint; - gatherCompositionConstraint(constraint2); - } else if (constraint instanceof CompareConstraint) { - CompareConstraint compare = (CompareConstraint) constraint; - gatherCompareConstraint(compare); - } else if (constraint instanceof PathExpressionConstraint) { - // TODO advanced features here? - PathExpressionConstraint pathExpression = (PathExpressionConstraint) constraint; - gatherPathExpression(pathExpression); - } else if (constraint instanceof CheckConstraint) { - final CheckConstraint check = (CheckConstraint) constraint; - gatherCheckConstraint(check); - // TODO OTHER CONSTRAINT TYPES - } else { - throw new RetePatternBuildException( - "Unsupported constraint type {1} in pattern {2}.", - new String[]{constraint.eClass().getName(), patternFQN}, - "Unsupported constraint type", pattern); - } - } - - /** - * @param check - */ - protected void gatherCheckConstraint(final CheckConstraint check) { - XExpression expression = check.getExpression(); - new XBaseCheck(this, expression, pattern); - } - - /** - * @param pathExpression - * @throws RetePatternBuildException - */ - protected void gatherPathExpression(PathExpressionConstraint pathExpression) - throws RetePatternBuildException { - PathExpressionHead head = pathExpression.getHead(); - PVariable currentSrc = getPNode(head.getSrc()); - PVariable finalDst = getPNode(head.getDst()); - PathExpressionTail currentTail = head.getTail(); - - // type constraint on source - Type headType = head.getType(); - if (headType instanceof ClassType) { - EClassifier headClassname = ((ClassType)headType).getClassname(); - new TypeUnary(pSystem, currentSrc, headClassname); - } else { - throw new RetePatternBuildException( - "Unsupported path expression head type {1} in pattern {2}: {3}", - new String[]{headType.eClass().getName(), patternFQN, typeStr(headType)}, - "Unsupported navigation source", pattern); - } - - // process each segment - while (currentTail != null) { - Type currentPathSegmentType = currentTail.getType(); - currentTail = currentTail.getTail(); - - PVariable intermediate = newVirtual(); - gatherPathSegment(currentPathSegmentType, currentSrc, intermediate); - - currentSrc = intermediate; - } - // link the final step to the overall destination - new Equality(pSystem, currentSrc, finalDst); - } - - /** - * @param compare - * @throws RetePatternBuildException - */ - protected void gatherCompareConstraint(CompareConstraint compare) - throws RetePatternBuildException { - PVariable left = getPNode(compare.getLeftOperand()); - PVariable right = getPNode(compare.getRightOperand()); - switch(compare.getFeature()) { - case EQUALITY: - new Equality(pSystem, left, right); - break; - case INEQUALITY: - new Inequality(pSystem, left, right, false); - } - } - - /** - * @param constraint - * @throws RetePatternBuildException - */ - protected void gatherCompositionConstraint( - PatternCompositionConstraint constraint) - throws RetePatternBuildException { - PatternCall call = constraint.getCall(); - Pattern patternRef = call.getPatternRef(); - Tuple pNodeTuple = getPNodeTuple(call.getParameters()); - if (!call.isTransitive()) { - if (constraint.isNegative()) - new NegativePatternCall(pSystem, pNodeTuple, patternRef); - else - new PositivePatternCall(pSystem, pNodeTuple, patternRef); - } else { - if (pNodeTuple.getSize() != 2) - throw new RetePatternBuildException( - "Transitive closure of {1} in pattern {2} is unsupported because called pattern is not binary.", - new String[]{CorePatternLanguageHelper.getFullyQualifiedName(patternRef), patternFQN}, - "Transitive closure only supported for binary patterns.", - pattern); - else if (constraint.isNegative()) - throw new RetePatternBuildException( - "Unsupported negated transitive closure of {1} in pattern {2}", - new String[]{CorePatternLanguageHelper.getFullyQualifiedName(patternRef), patternFQN}, - "Unsupported negated transitive closure", pattern); - else - new BinaryTransitiveClosure(pSystem, pNodeTuple, patternRef); -// throw new RetePatternBuildException( -// "Unsupported positive transitive closure of {1} in pattern {2}", -// new String[]{CorePatternLanguageHelper.getFullyQualifiedName(patternRef), patternFQN}, -// pattern); - } - } - - /** - * @param constraint - */ - protected void gatherClassifierConstraint(EClassifierConstraint constraint) { - EClassifier classname = ((ClassType)constraint.getType()).getClassname(); - PVariable pNode = getPNode(constraint.getVar()); - new TypeUnary(pSystem, pNode, classname); - } - - protected void gatherPathSegment(Type segmentType, PVariable src, PVariable trg) throws RetePatternBuildException { - if (segmentType instanceof ReferenceType) { // EMF-specific - EStructuralFeature typeObject = ((ReferenceType) segmentType).getRefname(); - if (context.edgeInterpretation() == EdgeInterpretation.TERNARY) { - new TypeTernary(pSystem, context, newVirtual(), src, trg, typeObject); - } else { - new TypeBinary(pSystem, context, src, trg, typeObject); - } - } else throw new RetePatternBuildException( - "Unsupported path segment type {1} in pattern {2}: {3}", - new String[]{segmentType.eClass().getName(), patternFQN, typeStr(segmentType)}, - "Unsupported navigation step", pattern); - } - - - protected PVariable aggregate(AggregatedValue reference) throws RetePatternBuildException { - PVariable result = newVirtual(); - - PatternCall call = reference.getCall(); - Pattern patternRef = call.getPatternRef(); - Tuple pNodeTuple = getPNodeTuple(call.getParameters()); - - AggregatorExpression aggregator = reference.getAggregator(); - if (aggregator instanceof CountAggregator) { - new PatternMatchCounter(pSystem, pNodeTuple, patternRef, result); - } else throw new RetePatternBuildException( - "Unsupported aggregator expression type {1} in pattern {2}.", - new String[]{aggregator.eClass().getName(), patternFQN}, - "Unsupported aggregator expression", pattern); - - - return result; - } - - /** - * @return the string describing a metamodel type, for debug / exception purposes - */ - private String typeStr(Type type) { - return type.getTypename() == null ? "(null)" : type.getTypename(); - } + + protected Pattern pattern; + protected PatternBody body; + protected IPatternMatcherContext context; + protected Buildable buildable; + + protected PSystem pSystem; + + String patternFQN; + + /** + * @param pattern + * @param body + * @param builder + * @param buildable + */ + public EPMBodyToPSystem(Pattern pattern, PatternBody body, IPatternMatcherContext context, + Buildable buildable) { + super(); + this.pattern = pattern; + this.body = body; + this.context = context; + this.buildable = buildable; + + patternFQN = CorePatternLanguageHelper.getFullyQualifiedName(pattern); + } + + public PSystem toPSystem() throws RetePatternBuildException { + try { + if (this.pSystem == null) { + this.pSystem = new PSystem(context, buildable, pattern); + + // TODO + // preProcessAssignments(); + preProcessParameters(); + gatherBodyConstraints(); + } + return pSystem; + } catch (RetePatternBuildException e) { + e.setPatternDescription(pattern); + throw e; + } + } + + public PVariable[] symbolicParameterArray() throws RetePatternBuildException { + toPSystem(); + + EList symParameters = pattern.getParameters(); + int arity = symParameters.size(); + PVariable[] result = new PVariable[arity]; + for (int i = 0; i < arity; ++i) + result[i] = getPNode(symParameters.get(i)); + return result; + } + + // protected PVariable getPNode(String name) { + // return pSystem.getOrCreateVariableByName(name); + // } + + protected PVariable getPNode(Variable variable) { + if (variable instanceof ParameterRef) // handle referenced parameter variables + return getPNode(((ParameterRef) variable).getReferredParam()); // assumed to be non-null + else + return pSystem.getOrCreateVariableByName(variable); + } + + protected PVariable getPNode(VariableReference variable) { + // Warning! variable.getVar() does not differentiate between + // multiple anonymous variables ('_') + return getPNode(variable.getVariable()); + } + + protected Tuple getPNodeTuple(List variables) throws RetePatternBuildException { + PVariable[] pNodeArray = getPNodeArray(variables); + return new FlatTuple(pNodeArray); + } + + public PVariable[] getPNodeArray(List variables) throws RetePatternBuildException { + int k = 0; + PVariable[] pNodeArray = new PVariable[variables.size()]; + for (ValueReference varRef : variables) { + pNodeArray[k++] = getPNode(varRef); + } + return pNodeArray; + } + + protected PVariable getPNode(ValueReference reference) throws RetePatternBuildException { + if (reference instanceof VariableValue) + return getPNode(((VariableValue) reference).getValue()); + else if (reference instanceof AggregatedValue) + return aggregate((AggregatedValue) reference); + else if (reference instanceof IntValue) + return pSystem.newConstantVariable(((IntValue) reference).getValue()); + else if (reference instanceof StringValue) + return pSystem.newConstantVariable(((StringValue) reference).getValue()); + else if (reference instanceof EnumValue) // EMF-specific + return pSystem.newConstantVariable(((EnumValue) reference).getLiteral().getInstance()); + else if (reference instanceof DoubleValue) { + return pSystem.newConstantVariable(((DoubleValue) reference).getValue()); + } else if (reference instanceof BoolValue) { + Boolean b = ((BoolValue) reference).isValue(); + return pSystem.newConstantVariable(b); + } else + throw new RetePatternBuildException( + "Unsupported value reference of type {1} from EPackage {2} currently unsupported by pattern builder in pattern {3}.", + new String[] { reference != null ? reference.eClass().getName() : "(null)", + reference != null ? reference.eClass().getEPackage().getNsURI() : "(null)", + pattern.getName() }, "Unsupported value expression", pattern); + } + + protected PVariable newVirtual() { + return pSystem.newVirtualVariable(); + } + + // protected Tuple getPNodeTuple(List references) throws RetePatternBuildException { + // PVariable[] pNodeArray = getPNodeArray(references); + // return new FlatTuple(pNodeArray); + // } + // public PVariable[] getPNodeArray(List references) throws RetePatternBuildException { + // int k = 0; + // PVariable[] pNodeArray = new PVariable[references.size()]; + // for (ValueReference varRef : references) { + // pNodeArray[k++] = getPNode(varRef); + // } + // return pNodeArray; + // } + private void preProcessParameters() { + EList parameters = pattern.getParameters(); + for (Variable variable : parameters) { + new ExportedParameter(pSystem, getPNode(variable), variable.getName()); + if (variable.getType() != null && variable.getType() instanceof ClassType) { + EClassifier classname = ((ClassType) variable.getType()).getClassname(); + PVariable pNode = getPNode(variable); + new TypeUnary(pSystem, pNode, classname); + } + } + + // final EList bodyVariables = body.getVariables(); + // for (Variable bodyVariable : bodyVariables) { + // if (bodyVariable instanceof ParameterRef) { + // final Variable referredParam = ((ParameterRef) bodyVariable).getReferredParam(); + // new Equality(pSystem, + // getPNode(referredParam), getPNode(bodyVariable)); + // } + // } + } + + private void gatherBodyConstraints() throws RetePatternBuildException { + EList constraints = body.getConstraints(); + for (Constraint constraint : constraints) { + gatherConstraint(constraint); + } + } + + /** + * @param constraint + * @throws RetePatternBuildException + */ + protected void gatherConstraint(Constraint constraint) throws RetePatternBuildException { + if (constraint instanceof EClassifierConstraint) { // EMF-specific + EClassifierConstraint constraint2 = (EClassifierConstraint) constraint; + gatherClassifierConstraint(constraint2); + } else if (constraint instanceof PatternCompositionConstraint) { + PatternCompositionConstraint constraint2 = (PatternCompositionConstraint) constraint; + gatherCompositionConstraint(constraint2); + } else if (constraint instanceof CompareConstraint) { + CompareConstraint compare = (CompareConstraint) constraint; + gatherCompareConstraint(compare); + } else if (constraint instanceof PathExpressionConstraint) { + // TODO advanced features here? + PathExpressionConstraint pathExpression = (PathExpressionConstraint) constraint; + gatherPathExpression(pathExpression); + } else if (constraint instanceof CheckConstraint) { + final CheckConstraint check = (CheckConstraint) constraint; + gatherCheckConstraint(check); + // TODO OTHER CONSTRAINT TYPES + } else { + throw new RetePatternBuildException("Unsupported constraint type {1} in pattern {2}.", new String[] { + constraint.eClass().getName(), patternFQN }, "Unsupported constraint type", pattern); + } + } + + /** + * @param check + */ + protected void gatherCheckConstraint(final CheckConstraint check) { + XExpression expression = check.getExpression(); + new XBaseCheck(this, expression, pattern); + } + + /** + * @param pathExpression + * @throws RetePatternBuildException + */ + protected void gatherPathExpression(PathExpressionConstraint pathExpression) throws RetePatternBuildException { + PathExpressionHead head = pathExpression.getHead(); + PVariable currentSrc = getPNode(head.getSrc()); + PVariable finalDst = getPNode(head.getDst()); + PathExpressionTail currentTail = head.getTail(); + + // type constraint on source + Type headType = head.getType(); + if (headType instanceof ClassType) { + EClassifier headClassname = ((ClassType) headType).getClassname(); + new TypeUnary(pSystem, currentSrc, headClassname); + } else { + throw new RetePatternBuildException("Unsupported path expression head type {1} in pattern {2}: {3}", + new String[] { headType.eClass().getName(), patternFQN, typeStr(headType) }, + "Unsupported navigation source", pattern); + } + + // process each segment + while (currentTail != null) { + Type currentPathSegmentType = currentTail.getType(); + currentTail = currentTail.getTail(); + + PVariable intermediate = newVirtual(); + gatherPathSegment(currentPathSegmentType, currentSrc, intermediate); + + currentSrc = intermediate; + } + // link the final step to the overall destination + new Equality(pSystem, currentSrc, finalDst); + } + + /** + * @param compare + * @throws RetePatternBuildException + */ + protected void gatherCompareConstraint(CompareConstraint compare) throws RetePatternBuildException { + PVariable left = getPNode(compare.getLeftOperand()); + PVariable right = getPNode(compare.getRightOperand()); + switch (compare.getFeature()) { + case EQUALITY: + new Equality(pSystem, left, right); + break; + case INEQUALITY: + new Inequality(pSystem, left, right, false); + } + } + + /** + * @param constraint + * @throws RetePatternBuildException + */ + protected void gatherCompositionConstraint(PatternCompositionConstraint constraint) + throws RetePatternBuildException { + PatternCall call = constraint.getCall(); + Pattern patternRef = call.getPatternRef(); + Tuple pNodeTuple = getPNodeTuple(call.getParameters()); + if (!call.isTransitive()) { + if (constraint.isNegative()) + new NegativePatternCall(pSystem, pNodeTuple, patternRef); + else + new PositivePatternCall(pSystem, pNodeTuple, patternRef); + } else { + if (pNodeTuple.getSize() != 2) + throw new RetePatternBuildException( + "Transitive closure of {1} in pattern {2} is unsupported because called pattern is not binary.", + new String[] { CorePatternLanguageHelper.getFullyQualifiedName(patternRef), patternFQN }, + "Transitive closure only supported for binary patterns.", pattern); + else if (constraint.isNegative()) + throw new RetePatternBuildException("Unsupported negated transitive closure of {1} in pattern {2}", + new String[] { CorePatternLanguageHelper.getFullyQualifiedName(patternRef), patternFQN }, + "Unsupported negated transitive closure", pattern); + else + new BinaryTransitiveClosure(pSystem, pNodeTuple, patternRef); + // throw new RetePatternBuildException( + // "Unsupported positive transitive closure of {1} in pattern {2}", + // new String[]{CorePatternLanguageHelper.getFullyQualifiedName(patternRef), patternFQN}, + // pattern); + } + } + + /** + * @param constraint + */ + protected void gatherClassifierConstraint(EClassifierConstraint constraint) { + EClassifier classname = ((ClassType) constraint.getType()).getClassname(); + PVariable pNode = getPNode(constraint.getVar()); + new TypeUnary(pSystem, pNode, classname); + } + + protected void gatherPathSegment(Type segmentType, PVariable src, PVariable trg) throws RetePatternBuildException { + if (segmentType instanceof ReferenceType) { // EMF-specific + EStructuralFeature typeObject = ((ReferenceType) segmentType).getRefname(); + if (context.edgeInterpretation() == EdgeInterpretation.TERNARY) { + new TypeTernary(pSystem, context, newVirtual(), src, trg, typeObject); + } else { + new TypeBinary(pSystem, context, src, trg, typeObject); + } + } else + throw new RetePatternBuildException("Unsupported path segment type {1} in pattern {2}: {3}", new String[] { + segmentType.eClass().getName(), patternFQN, typeStr(segmentType) }, "Unsupported navigation step", + pattern); + } + + protected PVariable aggregate(AggregatedValue reference) throws RetePatternBuildException { + PVariable result = newVirtual(); + + PatternCall call = reference.getCall(); + Pattern patternRef = call.getPatternRef(); + Tuple pNodeTuple = getPNodeTuple(call.getParameters()); + + AggregatorExpression aggregator = reference.getAggregator(); + if (aggregator instanceof CountAggregator) { + new PatternMatchCounter(pSystem, pNodeTuple, patternRef, result); + } else + throw new RetePatternBuildException("Unsupported aggregator expression type {1} in pattern {2}.", + new String[] { aggregator.eClass().getName(), patternFQN }, "Unsupported aggregator expression", + pattern); + + return result; + } + + /** + * @return the string describing a metamodel type, for debug / exception purposes + */ + private String typeStr(Type type) { + return type.getTypename() == null ? "(null)" : type.getTypename(); + } } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/matcherbuilder/EPMBuildScaffold.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/matcherbuilder/EPMBuildScaffold.java index b077e780..cb7e19e6 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/matcherbuilder/EPMBuildScaffold.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/matcherbuilder/EPMBuildScaffold.java @@ -23,47 +23,46 @@ /** * @author Bergmann Gábor - * + * */ public class EPMBuildScaffold { - - protected Buildable baseBuildable; - protected IPatternMatcherContext context; - - /** - * @param baseBuildable - * @param context - */ - public EPMBuildScaffold( - Buildable baseBuildable, - IPatternMatcherContext context) { - super(); - this.baseBuildable = baseBuildable; - this.context = context; - } - public Collector construct(Pattern pattern) throws RetePatternBuildException { - Collector production = baseBuildable.putOnTab(pattern).patternCollector(pattern); - // TODO check annotations for reinterpret - - context.logDebug("EPMBuilder starts construction of: " + pattern.getName()); - for (PatternBody body : pattern.getBodies()) { - Buildable currentBuildable = - baseBuildable.getNextContainer().putOnTab(pattern); - if (Options.builderMethod == BuilderMethod.LEGACY) { - throw new UnsupportedOperationException(); - } else { - EPMBodyToPSystem converter = - new EPMBodyToPSystem(pattern, body, context, currentBuildable); - Stub bodyFinal = - Options.builderMethod.layoutStrategy().layout(converter.toPSystem()); - BuildHelper.projectIntoCollector(currentBuildable, bodyFinal, production, converter.symbolicParameterArray()); - } + protected Buildable baseBuildable; + protected IPatternMatcherContext context; + + /** + * @param baseBuildable + * @param context + */ + public EPMBuildScaffold(Buildable baseBuildable, + IPatternMatcherContext context) { + super(); + this.baseBuildable = baseBuildable; + this.context = context; + } + + public Collector construct(Pattern pattern) throws RetePatternBuildException { + Collector production = baseBuildable.putOnTab(pattern).patternCollector(pattern); + // TODO check annotations for reinterpret + + context.logDebug("EPMBuilder starts construction of: " + pattern.getName()); + for (PatternBody body : pattern.getBodies()) { + Buildable currentBuildable = baseBuildable.getNextContainer().putOnTab( + pattern); + if (Options.builderMethod == BuilderMethod.LEGACY) { + throw new UnsupportedOperationException(); + } else { + EPMBodyToPSystem converter = new EPMBodyToPSystem( + pattern, body, context, currentBuildable); + Stub bodyFinal = Options.builderMethod. layoutStrategy() + .layout(converter.toPSystem()); + BuildHelper.projectIntoCollector(currentBuildable, bodyFinal, production, + converter.symbolicParameterArray()); + } + + } + + return null; + } - } - - - return null; - } - } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/matcherbuilder/EPMBuilder.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/matcherbuilder/EPMBuilder.java index 2355cc66..4a405710 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/matcherbuilder/EPMBuilder.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/internal/matcherbuilder/EPMBuilder.java @@ -23,56 +23,51 @@ /** * @author Bergmann Gábor - * + * */ -public class EPMBuilder implements IRetePatternBuilder -{ - protected Buildable baseBuildable; - protected IPatternMatcherContext context; - - /** - * @param baseBuildable - * @param context - */ - public EPMBuilder(Buildable baseBuildable, - IPatternMatcherContext context) { - super(); - this.baseBuildable = baseBuildable; - this.context = context; - } - +public class EPMBuilder implements IRetePatternBuilder { + protected Buildable baseBuildable; + protected IPatternMatcherContext context; + /** + * @param baseBuildable + * @param context + */ + public EPMBuilder(Buildable baseBuildable, IPatternMatcherContext context) { + super(); + this.baseBuildable = baseBuildable; + this.context = context; + } - @Override - public IPatternMatcherContext getContext() { - return context; - } + @Override + public IPatternMatcherContext getContext() { + return context; + } - @Override - public void refresh() { - baseBuildable.reinitialize(); - } + @Override + public void refresh() { + baseBuildable.reinitialize(); + } - @Override - public Collector construct(Pattern pattern) throws RetePatternBuildException { - try { - EPMBuildScaffold epmBuildScaffold = - new EPMBuildScaffold(baseBuildable, context); - return epmBuildScaffold.construct(pattern); - } catch (RuntimeException ex) { - throw new RetePatternBuildException( - "Error during constructing Rete pattern matcher; please review Error Log and consult developers", new String[0], - "Error during pattern matcher construction", - pattern, ex); - } - } + @Override + public Collector construct(Pattern pattern) throws RetePatternBuildException { + try { + EPMBuildScaffold epmBuildScaffold = new EPMBuildScaffold( + baseBuildable, context); + return epmBuildScaffold.construct(pattern); + } catch (RuntimeException ex) { + throw new RetePatternBuildException( + "Error during constructing Rete pattern matcher; please review Error Log and consult developers", + new String[0], "Error during pattern matcher construction", pattern, ex); + } + } - @Override - public HashMap getPosMapping(Pattern gtPattern) { - HashMap result = new HashMap(); - EList parameters = gtPattern.getParameters(); - for (int i=0; i getPosMapping(Pattern gtPattern) { + HashMap result = new HashMap(); + EList parameters = gtPattern.getParameters(); + for (int i = 0; i < parameters.size(); ++i) + result.put(parameters.get(i), i); + return result; + } } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/util/CheckExpressionUtil.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/util/CheckExpressionUtil.java index 3bcace0e..c8095c18 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/util/CheckExpressionUtil.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/util/CheckExpressionUtil.java @@ -24,74 +24,74 @@ public class CheckExpressionUtil { - /** - * Returns a unique string name for the given xexpression + pattern combination. - * The format is FQN_(pattern body number)_(expression number). - * - * @param pattern {@link Pattern} - * @param xExpression {@link XExpression} - * @return {@link String} - */ - public static String getExpressionUniqueID(Pattern pattern, - XExpression xExpression) { - return CorePatternLanguageHelper.getFullyQualifiedName(pattern) + "_" - + getExpressionUniqueNameInPattern(pattern, xExpression); - } + /** + * Returns a unique string name for the given xexpression + pattern combination. The format is FQN_(pattern body + * number)_(expression number). + * + * @param pattern + * {@link Pattern} + * @param xExpression + * {@link XExpression} + * @return {@link String} + */ + public static String getExpressionUniqueID(Pattern pattern, XExpression xExpression) { + return CorePatternLanguageHelper.getFullyQualifiedName(pattern) + "_" + + getExpressionUniqueNameInPattern(pattern, xExpression); + } - /** - * Returns a unique string tag for the given xexpression + pattern combination. - * The format is (pattern body number)_(expression number). - * - * @param pattern {@link Pattern} - * @param xExpression {@link XExpression} - * @return {@link String} - */ - public static String getExpressionUniqueNameInPattern(Pattern pattern, - XExpression xExpression) { - int patternBodyNumber = 0; - for (PatternBody patternBody : pattern.getBodies()) { - patternBodyNumber++; - int checkConstraintNumber = 0; - for (Constraint constraint : patternBody.getConstraints()) { - if (constraint instanceof CheckConstraint) { - CheckConstraint checkConstraint = (CheckConstraint) constraint; - checkConstraintNumber++; - if (xExpression.equals(checkConstraint.getExpression())) { - return patternBodyNumber + "_" + checkConstraintNumber; - } - } - } - } - return null; - } + /** + * Returns a unique string tag for the given xexpression + pattern combination. The format is (pattern body + * number)_(expression number). + * + * @param pattern + * {@link Pattern} + * @param xExpression + * {@link XExpression} + * @return {@link String} + */ + public static String getExpressionUniqueNameInPattern(Pattern pattern, XExpression xExpression) { + int patternBodyNumber = 0; + for (PatternBody patternBody : pattern.getBodies()) { + patternBodyNumber++; + int checkConstraintNumber = 0; + for (Constraint constraint : patternBody.getConstraints()) { + if (constraint instanceof CheckConstraint) { + CheckConstraint checkConstraint = (CheckConstraint) constraint; + checkConstraintNumber++; + if (xExpression.equals(checkConstraint.getExpression())) { + return patternBodyNumber + "_" + checkConstraintNumber; + } + } + } + } + return null; + } - /** - * Returns the containing IFile, if the pattern has a valid resource. - * - * @param pattern {@link Pattern} - * @return {@link IFile} - */ - public static IFile getIFile(Pattern pattern) { - if (pattern != null) { - Resource resource = pattern.eResource(); - if (resource != null) { - URI uri = resource.getURI(); - uri = resource.getResourceSet().getURIConverter() - .normalize(uri); - String scheme = uri.scheme(); - if ("platform".equals(scheme) && uri.segmentCount() > 1 - && "resource".equals(uri.segment(0))) { - StringBuffer platformResourcePath = new StringBuffer(); - for (int j = 1, size = uri.segmentCount(); j < size; ++j) { - platformResourcePath.append('/'); - platformResourcePath.append(uri.segment(j)); - } - return ResourcesPlugin.getWorkspace().getRoot() - .getFile(new Path(platformResourcePath.toString())); - } - } - } - return null; - } + /** + * Returns the containing IFile, if the pattern has a valid resource. + * + * @param pattern + * {@link Pattern} + * @return {@link IFile} + */ + public static IFile getIFile(Pattern pattern) { + if (pattern != null) { + Resource resource = pattern.eResource(); + if (resource != null) { + URI uri = resource.getURI(); + uri = resource.getResourceSet().getURIConverter().normalize(uri); + String scheme = uri.scheme(); + if ("platform".equals(scheme) && uri.segmentCount() > 1 && "resource".equals(uri.segment(0))) { + StringBuffer platformResourcePath = new StringBuffer(); + for (int j = 1, size = uri.segmentCount(); j < size; ++j) { + platformResourcePath.append('/'); + platformResourcePath.append(uri.segment(j)); + } + return ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(platformResourcePath.toString())); + } + } + } + return null; + } } diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/util/ClassLoaderUtil.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/util/ClassLoaderUtil.java index f242a851..7c6ec752 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/util/ClassLoaderUtil.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/util/ClassLoaderUtil.java @@ -32,41 +32,37 @@ */ public class ClassLoaderUtil { - /** - * Returns a {@link ClassLoader} that is capable of loading classes defined - * in the project of the input file, or in any dependencies of that project. - * - * @param file - * @return {@link ClassLoader} - * @throws CoreException - * @throws MalformedURLException - */ - public static ClassLoader getClassLoader(IFile file) throws CoreException, - MalformedURLException { - if (file != null) { - IProject project = file.getProject(); - IJavaProject jp = JavaCore.create(project); - String[] classPathEntries = JavaRuntime - .computeDefaultRuntimeClassPath(jp); - List classURLs = getClassesAsURLs(classPathEntries); - URL[] urls = (URL[]) classURLs.toArray(new URL[classURLs.size()]); - URLClassLoader loader = URLClassLoader.newInstance(urls, jp - .getClass().getClassLoader()); - return loader; - } - return null; - } + /** + * Returns a {@link ClassLoader} that is capable of loading classes defined in the project of the input file, or in + * any dependencies of that project. + * + * @param file + * @return {@link ClassLoader} + * @throws CoreException + * @throws MalformedURLException + */ + public static ClassLoader getClassLoader(IFile file) throws CoreException, MalformedURLException { + if (file != null) { + IProject project = file.getProject(); + IJavaProject jp = JavaCore.create(project); + String[] classPathEntries = JavaRuntime.computeDefaultRuntimeClassPath(jp); + List classURLs = getClassesAsURLs(classPathEntries); + URL[] urls = (URL[]) classURLs.toArray(new URL[classURLs.size()]); + URLClassLoader loader = URLClassLoader.newInstance(urls, jp.getClass().getClassLoader()); + return loader; + } + return null; + } - private static List getClassesAsURLs(String[] classPathEntries) - throws MalformedURLException { - List urlList = new ArrayList(); - for (int i = 0; i < classPathEntries.length; i++) { - String entry = classPathEntries[i]; - IPath path = new Path(entry); - URL url = path.toFile().toURI().toURL(); - urlList.add(url); - } - return urlList; - } + private static List getClassesAsURLs(String[] classPathEntries) throws MalformedURLException { + List urlList = new ArrayList(); + for (int i = 0; i < classPathEntries.length; i++) { + String entry = classPathEntries[i]; + IPath path = new Path(entry); + URL url = path.toFile().toURI().toURL(); + urlList.add(url); + } + return urlList; + } } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/util/XmiModelUtilRunningOptionEnum.java b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/util/XmiModelUtilRunningOptionEnum.java index b65be931..c991f874 100644 --- a/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/util/XmiModelUtilRunningOptionEnum.java +++ b/plugins/org.eclipse.incquery.runtime/src/org/eclipse/incquery/runtime/util/XmiModelUtilRunningOptionEnum.java @@ -18,16 +18,17 @@ public enum XmiModelUtilRunningOptionEnum { /** * Use this if you intend to call the XmiModelUtil with workspace only URIs. */ - JUST_RESOURCE, - + JUST_RESOURCE, + /** * Use this if you intend to call the XmiModelUtil with plugin only URIs. */ - JUST_PLUGIN, - + JUST_PLUGIN, + /** - * Default choice should be this. Use this if you intend to call the XmiModelUtil with both workspace and plugin URIs. + * Default choice should be this. Use this if you intend to call the XmiModelUtil with both workspace and plugin + * URIs. */ BOTH; - + } diff --git a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/GeneratorModule.java b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/GeneratorModule.java index a82d1c9f..c62d1693 100644 --- a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/GeneratorModule.java +++ b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/GeneratorModule.java @@ -28,37 +28,37 @@ public class GeneratorModule extends EMFPatternLanguageRuntimeModule { - public Class bindIGenerationFragmentProvider() { - return ExtensionBasedGenerationFragmentProvider.class; - } + public Class bindIGenerationFragmentProvider() { + return ExtensionBasedGenerationFragmentProvider.class; + } - // contributed by org.eclipse.xtext.generator.xbase.XbaseGeneratorFragment - public Class bindIJvmModelInferrer() { - return EMFPatternLanguageJvmModelInferrer.class; - } + // contributed by org.eclipse.xtext.generator.xbase.XbaseGeneratorFragment + public Class bindIJvmModelInferrer() { + return EMFPatternLanguageJvmModelInferrer.class; + } - // contributed by org.eclipse.xtext.generator.generator.GeneratorFragment - public IWorkspaceRoot bindIWorkspaceRootToInstance() { - return ResourcesPlugin.getWorkspace().getRoot(); - } - - // contributed by org.eclipse.xtext.generator.types.TypesGeneratorFragment - @Override + // contributed by org.eclipse.xtext.generator.generator.GeneratorFragment + public IWorkspaceRoot bindIWorkspaceRootToInstance() { + return ResourcesPlugin.getWorkspace().getRoot(); + } + + // contributed by org.eclipse.xtext.generator.types.TypesGeneratorFragment + @Override public Class bindIJvmTypeProvider$Factory() { - return JdtTypeProviderFactory.class; - } - - @Override + return JdtTypeProviderFactory.class; + } + + @Override public Class bindIMetamodelProvider() { - return GenModelMetamodelProviderService.class; - } - - public Class bindIEiqGenmodelProvider() { - return GenModelMetamodelProviderService.class; - } - - @Override - public Class bindITypeProvider() { - return GenModelBasedTypeProvider.class; - } + return GenModelMetamodelProviderService.class; + } + + public Class bindIEiqGenmodelProvider() { + return GenModelMetamodelProviderService.class; + } + + @Override + public Class bindITypeProvider() { + return GenModelBasedTypeProvider.class; + } } diff --git a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/IncQueryGeneratorPlugin.java b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/IncQueryGeneratorPlugin.java index 95b493e5..36749d4d 100644 --- a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/IncQueryGeneratorPlugin.java +++ b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/IncQueryGeneratorPlugin.java @@ -20,55 +20,59 @@ public class IncQueryGeneratorPlugin implements BundleActivator { - private static BundleContext context; - private Injector injector; - public static IncQueryGeneratorPlugin INSTANCE; + private static BundleContext context; + private Injector injector; + public static IncQueryGeneratorPlugin INSTANCE; public static final String BUNDLE_ID = "org.eclipse.incquery.tooling.core"; - public static BundleContext getContext() { - return context; - } + public static BundleContext getContext() { + return context; + } - /* - * (non-Javadoc) - * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) - */ - @Override + /* + * (non-Javadoc) + * + * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + @Override public void start(BundleContext bundleContext) { - INSTANCE = this; - IncQueryGeneratorPlugin.context = bundleContext; - } + INSTANCE = this; + IncQueryGeneratorPlugin.context = bundleContext; + } - /* - * (non-Javadoc) - * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) - */ - @Override + /* + * (non-Javadoc) + * + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + @Override public void stop(BundleContext bundleContext) { - IncQueryGeneratorPlugin.context = null; - INSTANCE = null; - } + IncQueryGeneratorPlugin.context = null; + INSTANCE = null; + } - /** - * Returns injector for the EMFPatternLanguage. - * @return - */ - public Injector getInjector() { - if (injector == null) { - injector = createInjector(); - } - return injector; - } - - protected Injector createInjector() { - return Guice.createInjector(getRuntimeModule()); - } + /** + * Returns injector for the EMFPatternLanguage. + * + * @return + */ + public Injector getInjector() { + if (injector == null) { + injector = createInjector(); + } + return injector; + } - /** - * Return the runtime module for the pattern language project - * @return - */ - public EMFPatternLanguageRuntimeModule getRuntimeModule() { - return new GeneratorModule(); - } + protected Injector createInjector() { + return Guice.createInjector(getRuntimeModule()); + } + + /** + * Return the runtime module for the pattern language project + * + * @return + */ + public EMFPatternLanguageRuntimeModule getRuntimeModule() { + return new GeneratorModule(); + } } diff --git a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/builder/CleanSupport.java b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/builder/CleanSupport.java index b8c62f57..91c15e8b 100644 --- a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/builder/CleanSupport.java +++ b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/builder/CleanSupport.java @@ -9,8 +9,8 @@ * Mark Czotter - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.core.generator.builder; - +package org.eclipse.incquery.tooling.core.generator.builder; + import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -58,310 +58,314 @@ import com.google.common.collect.Maps; import com.google.inject.Inject; import com.google.inject.Injector; - -/** - * Clean phase support for BuilderParticipant. - * - * @author Mark Czotter - * - */ -public class CleanSupport { - - private final class PrepareResourceSetWithLoader implements - IResourceSetPreparer { - - private final IProject project; - - public PrepareResourceSetWithLoader(IProject project) { - this.project = project; - } - - @Override - public void prepareResourceSet(ResourceSet set) { - Map options = Maps.newHashMap(); - XMIResourceURIHandler xmiResourceURIHandler = new XMIResourceURIHandler(set); - injector.injectMembers(xmiResourceURIHandler); - options.put(XMLResource.OPTION_URI_HANDLER, xmiResourceURIHandler); - set.getLoadOptions().putAll(options); - if (set instanceof XtextResourceSet) { - ((XtextResourceSet) set).setClasspathURIContext(JavaCore.create(project)); - } - } - } - @Inject - private Injector injector; - - @Inject - private IGenerationFragmentProvider fragmentProvider; - - @Inject - private EclipseResourceSupport eclipseResourceSupport; - - @Inject - private EMFPatternLanguageJvmModelInferrerUtil jvmInferrerUtil; - - @Inject - private EnsurePluginSupport ensureSupport; - - @Inject - private IErrorFeedback errorFeedback; - - @Inject - private Logger logger; - - /** - * Performs a full clean on the currently built project and all related - * fragments. - * - * @param context - * @param monitor - */ - public void fullClean(IBuildContext context, IProgressMonitor monitor) { - try { - internalFullClean(context, monitor); - } catch (Exception e) { - logger.error("Exception during Full Clean!", e); - } finally { - monitor.worked(1); - } - } - - private void internalFullClean(IBuildContext context, IProgressMonitor monitor) throws CoreException, IncQueryException { - IProject modelProject = context.getBuiltProject(); - // clean all fragments - cleanAllFragment(modelProject); - // clean current model project - List> removableExtensions = new ArrayList>(); - removableExtensions.addAll(GenerateMatcherFactoryExtension.getRemovableExtensionIdentifiers()); - removableExtensions.addAll(GenerateXExpressionEvaluatorExtension.getRemovableExtensionIdentifiers()); - ProjectGenerationHelper.removeAllExtension(modelProject, removableExtensions); - removeExportedPackages(modelProject); - removeXmiModel(modelProject); - } - - /** - * Performs full Clean on every registered {@link IGenerationFragment}. - * @param modelProject - * @throws CoreException - */ - private void cleanAllFragment(IProject modelProject) throws CoreException { - for (IGenerationFragment fragment : fragmentProvider.getAllFragments()) { - try { - cleanFragment(modelProject, fragment); - } catch (Exception e) { - logger.error("Exception during full Clean on " + fragment.getClass().getCanonicalName(), e); - } - } - } - - private void cleanFragment(IProject modelProject, IGenerationFragment fragment) throws CoreException { - IProject fragmentProject = fragmentProvider.getFragmentProject(modelProject, fragment); - if (fragmentProject.exists()) { - fragmentProject.refreshLocal(IResource.DEPTH_INFINITE, null); - // full clean on output directories - EclipseResourceFileSystemAccess2 fsa = eclipseResourceSupport.createProjectFileSystemAccess(fragmentProject); - for (OutputConfiguration config : fsa.getOutputConfigurations().values()) { - cleanFragmentFolder(fragmentProject, config); - } - // clean all removable extensions - ProjectGenerationHelper.removeAllExtension(fragmentProject, fragment.getRemovableExtensions()); - // removing all fragment-related markers - errorFeedback.clearMarkers(fragmentProject, IErrorFeedback.FRAGMENT_ERROR_TYPE); - } - } - - private void cleanFragmentFolder(IProject fragmentProject, - OutputConfiguration config) throws CoreException { - IFolder folder = fragmentProject.getFolder(config.getOutputDirectory()); - if (folder.exists()) { - for (IResource resource : folder.members()) { - resource.delete(IResource.KEEP_HISTORY, new NullProgressMonitor()); - } - } - } - - /** - * Removes all packages, based on the Xmi Model. - * @param project - * @throws CoreException - * @throws IncQueryException - */ - private void removeExportedPackages(IProject project) throws CoreException, IncQueryException { - if (getGlobalXmiFile(project).exists()) { - ArrayList packageNames = new ArrayList(); - Resource globalXmiModel = XmiModelUtil.getGlobalXmiResource(XmiModelUtilRunningOptionEnum.JUST_RESOURCE, project.getName(), new PrepareResourceSetWithLoader(project)); - Iterator iter = globalXmiModel.getAllContents(); - while(iter.hasNext()) { - EObject obj = iter.next(); - if (obj instanceof Pattern) { - packageNames.add(jvmInferrerUtil.getPackageName((Pattern) obj)); - } - } - ProjectGenerationHelper.removePackageExports(project, packageNames); - } - } - - /** - * Deletes the Global XMI model file from the queries folder. - * @param project - * @throws CoreException - */ - private void removeXmiModel(IProject project) throws CoreException { - IFile file = project.getFile(new Path(XmiModelUtil.getGlobalXmiFilePath())); - if (file != null && file.exists()) { - file.delete(IResource.KEEP_HISTORY, new NullProgressMonitor()); - } - } - - /** - * Performs a normal Clean on the currently built project and all related - * fragments. - * - * @param context - * @param relevantDeltas - * @param monitor - */ - public void normalClean(IBuildContext context, List relevantDeltas, IProgressMonitor monitor) { - try { - internalNormalClean(context, relevantDeltas, monitor); - } catch (Exception e) { - logger.error("Exception during Normal Clean!", e); - } finally { - monitor.worked(1); - } - } - - private void internalNormalClean(IBuildContext context, List relevantDeltas, IProgressMonitor monitor) throws CoreException, IncQueryException { - IProject modelProject = context.getBuiltProject(); - if (getGlobalXmiFile(modelProject).exists()) { - Resource globalXmiModel = XmiModelUtil.getGlobalXmiResource(XmiModelUtilRunningOptionEnum.JUST_RESOURCE, modelProject.getName(), new PrepareResourceSetWithLoader(modelProject)); - for (Delta delta : relevantDeltas) { - Resource deltaResource = context.getResourceSet().getResource(delta.getUri(), true); - if (delta.getNew() != null /*&& shouldGenerate(deltaResource, context)*/) { - cleanUpDelta(modelProject, deltaResource, globalXmiModel); - } - } - } - } - - /** - * Full cleanUp for current deltaResource based on the Global XMI model saved before. - * @param project - * @param deltaResource - * @param globalXmiModel - * @throws CoreException - */ - private void cleanUpDelta(IProject project, Resource deltaResource, Resource globalXmiModel) throws CoreException { - // do the clean up based on the previous model - ArrayList packageNames = new ArrayList(); - TreeIterator it = globalXmiModel.getAllContents(); - while (it.hasNext()) { - EObject obj = it.next(); - if (obj instanceof Pattern) { - Pattern pattern = (Pattern) obj; - if (pattern.getFileName().equals( - deltaResource.getURI().toString())) { - // add package name for removal - packageNames.add(jvmInferrerUtil.getPackageName(pattern)); - // clean up code and extensions in the modelProject - executeCleanUpOnModelProject(project, pattern); - // clean up code and extensions for all fragments - executeCleanUpOnFragments(project, pattern); - } - } - } - // remove previously exported packages - ProjectGenerationHelper.removePackageExports(project, packageNames); - } - - /** - * Executes Normal Build cleanUp on the current Built Project - * (modelProject). Removes all code generated previously for the - * {@link Pattern}, and marks current {@link Pattern} related extensions for - * removal. - * - * @param modelProject - * @param pattern - * @throws CoreException - */ - private void executeCleanUpOnModelProject(IProject modelProject, Pattern pattern) throws CoreException { - EclipseResourceFileSystemAccess2 fsa = eclipseResourceSupport.createProjectFileSystemAccess(modelProject); - List classPackagePaths = getPathsForJvmInferredClasses(pattern); - String outputDir = fsa.getOutputConfigurations().get(IFileSystemAccess.DEFAULT_OUTPUT).getOutputDirectory(); - for (String classPackagePath : classPackagePaths) { - try { - fsa.deleteFile(classPackagePath); - } catch (Exception e) { - String msg = String.format("Java file cannot be deleted through IFileSystemAccess: %s", classPackagePath); - logger.warn(msg, e); - IFile classFile = modelProject.getFile(new Path(outputDir + "/" + classPackagePath)); - if (classFile != null && classFile.exists()) { - classFile.delete(IResource.KEEP_HISTORY, null); - } - } - } - // only the extension id and point name is needed for removal - String extensionId = CorePatternLanguageHelper.getFullyQualifiedName(pattern); - ensureSupport.removeExtension(modelProject, Pair.of(extensionId, IExtensions.MATCHERFACTORY_EXTENSION_POINT_ID)); - ensureSupport.removeExtension(modelProject, Pair.of(extensionId, IExtensions.XEXPRESSIONEVALUATOR_EXTENSION_POINT_ID)); - } - - private List getPathsForJvmInferredClasses(Pattern pattern) { - final String packageName = jvmInferrerUtil.getPackagePath(pattern); - List classNames = Lists.newArrayList( - jvmInferrerUtil.matchClassName(pattern), - jvmInferrerUtil.matcherClassName(pattern), - jvmInferrerUtil.matcherFactoryClassName(pattern), - jvmInferrerUtil.processorClassName(pattern)); - return Lists.transform(classNames, new Function() { - @Override - public String apply(String input) { - return String.format("%s/%s.java", packageName, input); - } - }); - } - - /** - * Executes Normal Build cleanUp on every {@link IGenerationFragment} - * registered to the current {@link Pattern}. Marks current {@link Pattern} - * related extensions for removal. If the {@link IProject} related to - * {@link IGenerationFragment} does not exist, clean up skipped for the - * fragment. - * - * @param modelProject - * @param pattern - * @throws CoreException - */ - private void executeCleanUpOnFragments(IProject modelProject, Pattern pattern) throws CoreException { - for (IGenerationFragment fragment : fragmentProvider - .getFragmentsForPattern(pattern)) { - try { - injector.injectMembers(fragment); - // clean if the project still exist - IProject targetProject = fragmentProvider.getFragmentProject(modelProject, fragment); - if (targetProject.exists()) { - targetProject.refreshLocal(IResource.DEPTH_INFINITE, null); - EclipseResourceFileSystemAccess2 fsa = eclipseResourceSupport.createProjectFileSystemAccess(targetProject); - fragment.cleanUp(pattern, fsa); - ensureSupport.removeAllExtension(targetProject, fragment.removeExtension(pattern)); - // removing all fragment-related markers - errorFeedback.clearMarkers(targetProject, IErrorFeedback.FRAGMENT_ERROR_TYPE); - } - } catch (Exception e) { - String msg = String.format("Exception when executing clean for '%s' in fragment '%s'", CorePatternLanguageHelper.getFullyQualifiedName(pattern), fragment.getClass().getCanonicalName()); - logger.error(msg, e); - } - } - } - - /** - * Returns an {@link IFile} on the path 'queries/globalEiqModel.xmi' in the project. - * @param project - * @return - */ - private IFile getGlobalXmiFile(IProject project) { - return project.getFile(new Path(XmiModelUtil.getGlobalXmiFilePath())); - } - -} +/** + * Clean phase support for BuilderParticipant. + * + * @author Mark Czotter + * + */ +public class CleanSupport { + + private final class PrepareResourceSetWithLoader implements IResourceSetPreparer { + + private final IProject project; + + public PrepareResourceSetWithLoader(IProject project) { + this.project = project; + } + + @Override + public void prepareResourceSet(ResourceSet set) { + Map options = Maps.newHashMap(); + XMIResourceURIHandler xmiResourceURIHandler = new XMIResourceURIHandler(set); + injector.injectMembers(xmiResourceURIHandler); + options.put(XMLResource.OPTION_URI_HANDLER, xmiResourceURIHandler); + set.getLoadOptions().putAll(options); + if (set instanceof XtextResourceSet) { + ((XtextResourceSet) set).setClasspathURIContext(JavaCore.create(project)); + } + } + } + + @Inject + private Injector injector; + + @Inject + private IGenerationFragmentProvider fragmentProvider; + + @Inject + private EclipseResourceSupport eclipseResourceSupport; + + @Inject + private EMFPatternLanguageJvmModelInferrerUtil jvmInferrerUtil; + + @Inject + private EnsurePluginSupport ensureSupport; + + @Inject + private IErrorFeedback errorFeedback; + + @Inject + private Logger logger; + + /** + * Performs a full clean on the currently built project and all related fragments. + * + * @param context + * @param monitor + */ + public void fullClean(IBuildContext context, IProgressMonitor monitor) { + try { + internalFullClean(context, monitor); + } catch (Exception e) { + logger.error("Exception during Full Clean!", e); + } finally { + monitor.worked(1); + } + } + + private void internalFullClean(IBuildContext context, IProgressMonitor monitor) throws CoreException, + IncQueryException { + IProject modelProject = context.getBuiltProject(); + // clean all fragments + cleanAllFragment(modelProject); + // clean current model project + List> removableExtensions = new ArrayList>(); + removableExtensions.addAll(GenerateMatcherFactoryExtension.getRemovableExtensionIdentifiers()); + removableExtensions.addAll(GenerateXExpressionEvaluatorExtension.getRemovableExtensionIdentifiers()); + ProjectGenerationHelper.removeAllExtension(modelProject, removableExtensions); + removeExportedPackages(modelProject); + removeXmiModel(modelProject); + } + + /** + * Performs full Clean on every registered {@link IGenerationFragment}. + * + * @param modelProject + * @throws CoreException + */ + private void cleanAllFragment(IProject modelProject) throws CoreException { + for (IGenerationFragment fragment : fragmentProvider.getAllFragments()) { + try { + cleanFragment(modelProject, fragment); + } catch (Exception e) { + logger.error("Exception during full Clean on " + fragment.getClass().getCanonicalName(), e); + } + } + } + + private void cleanFragment(IProject modelProject, IGenerationFragment fragment) throws CoreException { + IProject fragmentProject = fragmentProvider.getFragmentProject(modelProject, fragment); + if (fragmentProject.exists()) { + fragmentProject.refreshLocal(IResource.DEPTH_INFINITE, null); + // full clean on output directories + EclipseResourceFileSystemAccess2 fsa = eclipseResourceSupport + .createProjectFileSystemAccess(fragmentProject); + for (OutputConfiguration config : fsa.getOutputConfigurations().values()) { + cleanFragmentFolder(fragmentProject, config); + } + // clean all removable extensions + ProjectGenerationHelper.removeAllExtension(fragmentProject, fragment.getRemovableExtensions()); + // removing all fragment-related markers + errorFeedback.clearMarkers(fragmentProject, IErrorFeedback.FRAGMENT_ERROR_TYPE); + } + } + + private void cleanFragmentFolder(IProject fragmentProject, OutputConfiguration config) throws CoreException { + IFolder folder = fragmentProject.getFolder(config.getOutputDirectory()); + if (folder.exists()) { + for (IResource resource : folder.members()) { + resource.delete(IResource.KEEP_HISTORY, new NullProgressMonitor()); + } + } + } + + /** + * Removes all packages, based on the Xmi Model. + * + * @param project + * @throws CoreException + * @throws IncQueryException + */ + private void removeExportedPackages(IProject project) throws CoreException, IncQueryException { + if (getGlobalXmiFile(project).exists()) { + ArrayList packageNames = new ArrayList(); + Resource globalXmiModel = XmiModelUtil.getGlobalXmiResource(XmiModelUtilRunningOptionEnum.JUST_RESOURCE, + project.getName(), new PrepareResourceSetWithLoader(project)); + Iterator iter = globalXmiModel.getAllContents(); + while (iter.hasNext()) { + EObject obj = iter.next(); + if (obj instanceof Pattern) { + packageNames.add(jvmInferrerUtil.getPackageName((Pattern) obj)); + } + } + ProjectGenerationHelper.removePackageExports(project, packageNames); + } + } + + /** + * Deletes the Global XMI model file from the queries folder. + * + * @param project + * @throws CoreException + */ + private void removeXmiModel(IProject project) throws CoreException { + IFile file = project.getFile(new Path(XmiModelUtil.getGlobalXmiFilePath())); + if (file != null && file.exists()) { + file.delete(IResource.KEEP_HISTORY, new NullProgressMonitor()); + } + } + + /** + * Performs a normal Clean on the currently built project and all related fragments. + * + * @param context + * @param relevantDeltas + * @param monitor + */ + public void normalClean(IBuildContext context, List relevantDeltas, IProgressMonitor monitor) { + try { + internalNormalClean(context, relevantDeltas, monitor); + } catch (Exception e) { + logger.error("Exception during Normal Clean!", e); + } finally { + monitor.worked(1); + } + } + + private void internalNormalClean(IBuildContext context, List relevantDeltas, IProgressMonitor monitor) + throws CoreException, IncQueryException { + IProject modelProject = context.getBuiltProject(); + if (getGlobalXmiFile(modelProject).exists()) { + Resource globalXmiModel = XmiModelUtil.getGlobalXmiResource(XmiModelUtilRunningOptionEnum.JUST_RESOURCE, + modelProject.getName(), new PrepareResourceSetWithLoader(modelProject)); + for (Delta delta : relevantDeltas) { + Resource deltaResource = context.getResourceSet().getResource(delta.getUri(), true); + if (delta.getNew() != null /* && shouldGenerate(deltaResource, context) */) { + cleanUpDelta(modelProject, deltaResource, globalXmiModel); + } + } + } + } + + /** + * Full cleanUp for current deltaResource based on the Global XMI model saved before. + * + * @param project + * @param deltaResource + * @param globalXmiModel + * @throws CoreException + */ + private void cleanUpDelta(IProject project, Resource deltaResource, Resource globalXmiModel) throws CoreException { + // do the clean up based on the previous model + ArrayList packageNames = new ArrayList(); + TreeIterator it = globalXmiModel.getAllContents(); + while (it.hasNext()) { + EObject obj = it.next(); + if (obj instanceof Pattern) { + Pattern pattern = (Pattern) obj; + if (pattern.getFileName().equals(deltaResource.getURI().toString())) { + // add package name for removal + packageNames.add(jvmInferrerUtil.getPackageName(pattern)); + // clean up code and extensions in the modelProject + executeCleanUpOnModelProject(project, pattern); + // clean up code and extensions for all fragments + executeCleanUpOnFragments(project, pattern); + } + } + } + // remove previously exported packages + ProjectGenerationHelper.removePackageExports(project, packageNames); + } + + /** + * Executes Normal Build cleanUp on the current Built Project (modelProject). Removes all code generated previously + * for the {@link Pattern}, and marks current {@link Pattern} related extensions for removal. + * + * @param modelProject + * @param pattern + * @throws CoreException + */ + private void executeCleanUpOnModelProject(IProject modelProject, Pattern pattern) throws CoreException { + EclipseResourceFileSystemAccess2 fsa = eclipseResourceSupport.createProjectFileSystemAccess(modelProject); + List classPackagePaths = getPathsForJvmInferredClasses(pattern); + String outputDir = fsa.getOutputConfigurations().get(IFileSystemAccess.DEFAULT_OUTPUT).getOutputDirectory(); + for (String classPackagePath : classPackagePaths) { + try { + fsa.deleteFile(classPackagePath); + } catch (Exception e) { + String msg = String.format("Java file cannot be deleted through IFileSystemAccess: %s", + classPackagePath); + logger.warn(msg, e); + IFile classFile = modelProject.getFile(new Path(outputDir + "/" + classPackagePath)); + if (classFile != null && classFile.exists()) { + classFile.delete(IResource.KEEP_HISTORY, null); + } + } + } + // only the extension id and point name is needed for removal + String extensionId = CorePatternLanguageHelper.getFullyQualifiedName(pattern); + ensureSupport + .removeExtension(modelProject, Pair.of(extensionId, IExtensions.MATCHERFACTORY_EXTENSION_POINT_ID)); + ensureSupport.removeExtension(modelProject, + Pair.of(extensionId, IExtensions.XEXPRESSIONEVALUATOR_EXTENSION_POINT_ID)); + } + + private List getPathsForJvmInferredClasses(Pattern pattern) { + final String packageName = jvmInferrerUtil.getPackagePath(pattern); + List classNames = Lists.newArrayList(jvmInferrerUtil.matchClassName(pattern), + jvmInferrerUtil.matcherClassName(pattern), jvmInferrerUtil.matcherFactoryClassName(pattern), + jvmInferrerUtil.processorClassName(pattern)); + return Lists.transform(classNames, new Function() { + @Override + public String apply(String input) { + return String.format("%s/%s.java", packageName, input); + } + }); + } + + /** + * Executes Normal Build cleanUp on every {@link IGenerationFragment} registered to the current {@link Pattern}. + * Marks current {@link Pattern} related extensions for removal. If the {@link IProject} related to + * {@link IGenerationFragment} does not exist, clean up skipped for the fragment. + * + * @param modelProject + * @param pattern + * @throws CoreException + */ + private void executeCleanUpOnFragments(IProject modelProject, Pattern pattern) throws CoreException { + for (IGenerationFragment fragment : fragmentProvider.getFragmentsForPattern(pattern)) { + try { + injector.injectMembers(fragment); + // clean if the project still exist + IProject targetProject = fragmentProvider.getFragmentProject(modelProject, fragment); + if (targetProject.exists()) { + targetProject.refreshLocal(IResource.DEPTH_INFINITE, null); + EclipseResourceFileSystemAccess2 fsa = eclipseResourceSupport + .createProjectFileSystemAccess(targetProject); + fragment.cleanUp(pattern, fsa); + ensureSupport.removeAllExtension(targetProject, fragment.removeExtension(pattern)); + // removing all fragment-related markers + errorFeedback.clearMarkers(targetProject, IErrorFeedback.FRAGMENT_ERROR_TYPE); + } + } catch (Exception e) { + String msg = String.format("Exception when executing clean for '%s' in fragment '%s'", + CorePatternLanguageHelper.getFullyQualifiedName(pattern), fragment.getClass() + .getCanonicalName()); + logger.error(msg, e); + } + } + } + + /** + * Returns an {@link IFile} on the path 'queries/globalEiqModel.xmi' in the project. + * + * @param project + * @return + */ + private IFile getGlobalXmiFile(IProject project) { + return project.getFile(new Path(XmiModelUtil.getGlobalXmiFilePath())); + } + +} diff --git a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/builder/EMFPatternLanguageBuilderParticipant.java b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/builder/EMFPatternLanguageBuilderParticipant.java index 2359a986..feb7d403 100644 --- a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/builder/EMFPatternLanguageBuilderParticipant.java +++ b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/builder/EMFPatternLanguageBuilderParticipant.java @@ -66,44 +66,44 @@ */ public class EMFPatternLanguageBuilderParticipant extends BuilderParticipant { - @Inject - private Injector injector; + @Inject + private Injector injector; - @Inject - private IGenerator generator; + @Inject + private IGenerator generator; - @Inject - private IGenerationFragmentProvider fragmentProvider; + @Inject + private IGenerationFragmentProvider fragmentProvider; - @Inject - private EMFPatternLanguageJvmModelInferrerUtil util; + @Inject + private EMFPatternLanguageJvmModelInferrerUtil util; - @Inject - private XmiModelSupport xmiModelSupport; + @Inject + private XmiModelSupport xmiModelSupport; - @Inject - private EnsurePluginSupport ensureSupport; + @Inject + private EnsurePluginSupport ensureSupport; - @Inject - private CleanSupport cleanSupport; + @Inject + private CleanSupport cleanSupport; - @Inject - private EclipseResourceSupport eclipseResourceSupport; + @Inject + private EclipseResourceSupport eclipseResourceSupport; - @Inject - private GenerateMatcherFactoryExtension matcherFactoryExtensionGenerator; + @Inject + private GenerateMatcherFactoryExtension matcherFactoryExtensionGenerator; - @Inject - private GenerateXExpressionEvaluatorExtension xExpressionEvaluatorExtensionGenerator; + @Inject + private GenerateXExpressionEvaluatorExtension xExpressionEvaluatorExtensionGenerator; - @Inject - private IEiqGenmodelProvider genmodelProvider; + @Inject + private IEiqGenmodelProvider genmodelProvider; - @Inject - private Logger logger; + @Inject + private Logger logger; - @Inject - private IStorage2UriMapper storage2UriMapper; + @Inject + private IStorage2UriMapper storage2UriMapper; protected boolean isFullBuildNeeded(final IBuildContext context) { IProject project = context.getBuiltProject(); @@ -117,255 +117,217 @@ protected boolean isFullBuildNeeded(final IBuildContext context) { return false; } - @Override - public void build(final IBuildContext context, IProgressMonitor monitor) - throws CoreException { - if (!isEnabled(context)) { - return; - } - if (isFullBuildNeeded(context)) { + @Override + public void build(final IBuildContext context, IProgressMonitor monitor) throws CoreException { + if (!isEnabled(context)) { + return; + } + if (isFullBuildNeeded(context)) { context.needRebuild(); - return; - } - final List relevantDeltas = getRelevantDeltas(context); - if (relevantDeltas.isEmpty()) { - return; - } - // monitor handling - if (monitor.isCanceled()) { - throw new OperationCanceledException(); - } - SubMonitor progress = SubMonitor.convert(monitor, 5); - final IProject modelProject = context.getBuiltProject(); - modelProject.refreshLocal(IResource.DEPTH_INFINITE, - progress.newChild(1)); - if (context.getBuildType() == BuildType.CLEAN - || context.getBuildType() == BuildType.RECOVERY) { - cleanSupport.fullClean(context, progress.newChild(1)); - // invoke clean build on main project src-gen - super.build(context, progress.newChild(1)); - if (context.getBuildType() == BuildType.CLEAN) { - // work 2 unit if clean build is performed (xmi build, and - // ensure) - progress.worked(2); - return; - } - } else { - ensureSupport.clean(); - cleanSupport.normalClean(context, relevantDeltas, - progress.newChild(1)); - } - super.build(context, progress.newChild(1)); - // normal cleanUp and codegen done on every delta, do XMI Model build - xmiModelSupport.build(relevantDeltas.get(0), context, - progress.newChild(1)); - // normal code generation done, extensions, packages ready to add to the - // plug-ins - ensureSupport.ensure(modelProject, progress.newChild(1)); - } - - @Override - protected void handleChangedContents(Delta delta, IBuildContext context, - EclipseResourceFileSystemAccess2 fileSystemAccess) - throws CoreException { - // TODO: we will run out of memory here if the number of deltas is large - // enough - Resource deltaResource = context.getResourceSet().getResource( - delta.getUri(), true); - if (shouldGenerate(deltaResource, context)) { - try { - // do inferred jvm model to code transformation - generator.doGenerate(deltaResource, fileSystemAccess); - doPostGenerate(deltaResource, context); - } catch (RuntimeException e) { - if (e.getCause() instanceof CoreException) { - throw (CoreException) e.getCause(); - } - throw e; - } - } - } + return; + } + final List relevantDeltas = getRelevantDeltas(context); + if (relevantDeltas.isEmpty()) { + return; + } + // monitor handling + if (monitor.isCanceled()) { + throw new OperationCanceledException(); + } + SubMonitor progress = SubMonitor.convert(monitor, 5); + final IProject modelProject = context.getBuiltProject(); + modelProject.refreshLocal(IResource.DEPTH_INFINITE, progress.newChild(1)); + if (context.getBuildType() == BuildType.CLEAN || context.getBuildType() == BuildType.RECOVERY) { + cleanSupport.fullClean(context, progress.newChild(1)); + // invoke clean build on main project src-gen + super.build(context, progress.newChild(1)); + if (context.getBuildType() == BuildType.CLEAN) { + // work 2 unit if clean build is performed (xmi build, and + // ensure) + progress.worked(2); + return; + } + } else { + ensureSupport.clean(); + cleanSupport.normalClean(context, relevantDeltas, progress.newChild(1)); + } + super.build(context, progress.newChild(1)); + // normal cleanUp and codegen done on every delta, do XMI Model build + xmiModelSupport.build(relevantDeltas.get(0), context, progress.newChild(1)); + // normal code generation done, extensions, packages ready to add to the + // plug-ins + ensureSupport.ensure(modelProject, progress.newChild(1)); + } - /** - * From all {@link Pattern} instance in the current deltaResource, computes - * various additions to the modelProject, and executes the provided - * fragments. Various contribution: package export, MatcherFactory - * extension, validation constraint stuff. - * - * - * @param deltaResource - * @param context - * @throws CoreException - */ - private void doPostGenerate(Resource deltaResource, IBuildContext context) - throws CoreException { - final IProject project = context.getBuiltProject(); - ExtensionGenerator extGenerator = new ExtensionGenerator(); - extGenerator.setProject(project); - calculateEMFModelProjects(deltaResource, project); - TreeIterator it = deltaResource.getAllContents(); - while (it.hasNext()) { - EObject obj = it.next(); - if (obj instanceof Pattern - && !CorePatternLanguageHelper.isPrivate((Pattern) obj)) { - Pattern pattern = (Pattern) obj; + @Override + protected void handleChangedContents(Delta delta, IBuildContext context, + EclipseResourceFileSystemAccess2 fileSystemAccess) throws CoreException { + // TODO: we will run out of memory here if the number of deltas is large + // enough + Resource deltaResource = context.getResourceSet().getResource(delta.getUri(), true); + if (shouldGenerate(deltaResource, context)) { + try { + // do inferred jvm model to code transformation + generator.doGenerate(deltaResource, fileSystemAccess); + doPostGenerate(deltaResource, context); + } catch (RuntimeException e) { + if (e.getCause() instanceof CoreException) { + throw (CoreException) e.getCause(); + } + throw e; + } + } + } - Iterable matcherFactoryExtensionContribution = matcherFactoryExtensionGenerator - .extensionContribution(pattern, extGenerator); - ensureSupport.appendAllExtension(project, - matcherFactoryExtensionContribution); + /** + * From all {@link Pattern} instance in the current deltaResource, computes various additions to the modelProject, + * and executes the provided fragments. Various contribution: package export, MatcherFactory extension, validation + * constraint stuff. + * + * + * @param deltaResource + * @param context + * @throws CoreException + */ + private void doPostGenerate(Resource deltaResource, IBuildContext context) throws CoreException { + final IProject project = context.getBuiltProject(); + ExtensionGenerator extGenerator = new ExtensionGenerator(); + extGenerator.setProject(project); + calculateEMFModelProjects(deltaResource, project); + TreeIterator it = deltaResource.getAllContents(); + while (it.hasNext()) { + EObject obj = it.next(); + if (obj instanceof Pattern && !CorePatternLanguageHelper.isPrivate((Pattern) obj)) { + Pattern pattern = (Pattern) obj; + Iterable matcherFactoryExtensionContribution = matcherFactoryExtensionGenerator + .extensionContribution(pattern, extGenerator); + ensureSupport.appendAllExtension(project, matcherFactoryExtensionContribution); - for (PatternBody patternBody : pattern.getBodies()) { - for (Constraint constraint : patternBody.getConstraints()) { - if (constraint instanceof CheckConstraint) { - CheckConstraint checkConstraint = (CheckConstraint) constraint; - XExpression xExpression = checkConstraint.getExpression(); - String expressionID = CheckExpressionUtil - .getExpressionUniqueID(pattern, xExpression); - String expressionUniqueNameInPattern = CheckExpressionUtil.getExpressionUniqueNameInPattern(pattern, xExpression); - Iterable xExpressionEvaluatorExtensionContribution = xExpressionEvaluatorExtensionGenerator - .extensionContribution(pattern, expressionID, expressionUniqueNameInPattern, - extGenerator); - ensureSupport.appendAllExtension(project, - xExpressionEvaluatorExtensionContribution); - } - } - } + for (PatternBody patternBody : pattern.getBodies()) { + for (Constraint constraint : patternBody.getConstraints()) { + if (constraint instanceof CheckConstraint) { + CheckConstraint checkConstraint = (CheckConstraint) constraint; + XExpression xExpression = checkConstraint.getExpression(); + String expressionID = CheckExpressionUtil.getExpressionUniqueID(pattern, xExpression); + String expressionUniqueNameInPattern = CheckExpressionUtil + .getExpressionUniqueNameInPattern(pattern, xExpression); + Iterable xExpressionEvaluatorExtensionContribution = xExpressionEvaluatorExtensionGenerator + .extensionContribution(pattern, expressionID, expressionUniqueNameInPattern, + extGenerator); + ensureSupport.appendAllExtension(project, xExpressionEvaluatorExtensionContribution); + } + } + } - executeGeneratorFragments(context.getBuiltProject(), pattern); - ensureSupport.exportPackage(project, - util.getPackageName(pattern)); - } - } - } + executeGeneratorFragments(context.getBuiltProject(), pattern); + ensureSupport.exportPackage(project, util.getPackageName(pattern)); + } + } + } - private void calculateEMFModelProjects(Resource deltaResource, - IProject project) { - TreeIterator it = deltaResource.getAllContents(); - while (it.hasNext()) { - EObject obj = it.next(); - if (obj instanceof PatternModel) { - PatternModel patternModel = (PatternModel) obj; - for (PackageImport packageImport : patternModel - .getImportPackages()) { - GenPackage genPackage = genmodelProvider.findGenPackage( - packageImport, packageImport.getEPackage()); - if (genPackage != null) { - String modelPluginID = genPackage.getGenModel() - .getModelPluginID(); - if (modelPluginID != null && !modelPluginID.isEmpty()) { - ensureSupport.addModelBundleId(project, - modelPluginID); - } - } - } - it.prune(); - } - } - } + private void calculateEMFModelProjects(Resource deltaResource, IProject project) { + TreeIterator it = deltaResource.getAllContents(); + while (it.hasNext()) { + EObject obj = it.next(); + if (obj instanceof PatternModel) { + PatternModel patternModel = (PatternModel) obj; + for (PackageImport packageImport : patternModel.getImportPackages()) { + GenPackage genPackage = genmodelProvider.findGenPackage(packageImport, packageImport.getEPackage()); + if (genPackage != null) { + String modelPluginID = genPackage.getGenModel().getModelPluginID(); + if (modelPluginID != null && !modelPluginID.isEmpty()) { + ensureSupport.addModelBundleId(project, modelPluginID); + } + } + } + it.prune(); + } + } + } - /** - * Executes all {@link IGenerationFragment} provided for the current - * {@link Pattern}. - * - * @param modelProject - * @param pattern - * @throws CoreException - */ - private void executeGeneratorFragments(IProject modelProject, - Pattern pattern) throws CoreException { - for (IGenerationFragment fragment : fragmentProvider - .getFragmentsForPattern(pattern)) { - try { - injector.injectMembers(fragment); - executeGeneratorFragment(fragment, modelProject, pattern); - } catch (Exception e) { - String msg = String - .format("Exception when executing generation for '%s' in fragment '%s'", - CorePatternLanguageHelper - .getFullyQualifiedName(pattern), - fragment.getClass().getCanonicalName()); - logger.error(msg, e); - } - } - } + /** + * Executes all {@link IGenerationFragment} provided for the current {@link Pattern}. + * + * @param modelProject + * @param pattern + * @throws CoreException + */ + private void executeGeneratorFragments(IProject modelProject, Pattern pattern) throws CoreException { + for (IGenerationFragment fragment : fragmentProvider.getFragmentsForPattern(pattern)) { + try { + injector.injectMembers(fragment); + executeGeneratorFragment(fragment, modelProject, pattern); + } catch (Exception e) { + String msg = String.format("Exception when executing generation for '%s' in fragment '%s'", + CorePatternLanguageHelper.getFullyQualifiedName(pattern), fragment.getClass() + .getCanonicalName()); + logger.error(msg, e); + } + } + } - private void executeGeneratorFragment(IGenerationFragment fragment, - IProject modelProject, Pattern pattern) throws CoreException { - IProject targetProject = createOrGetTargetProject(modelProject, - fragment); - EclipseResourceFileSystemAccess2 fsa = eclipseResourceSupport - .createProjectFileSystemAccess(targetProject); - fragment.generateFiles(pattern, fsa); - // Generating Eclipse extensions - ExtensionGenerator exGenerator = new ExtensionGenerator(); - exGenerator.setProject(targetProject); - Iterable extensionContribution = fragment - .extensionContribution(pattern, exGenerator); - // Gathering all registered extensions together to avoid unnecessary - // plugin.xml modifications - // Both for performance and for avoiding race conditions - ensureSupport.appendAllExtension(targetProject, extensionContribution); - } + private void executeGeneratorFragment(IGenerationFragment fragment, IProject modelProject, Pattern pattern) + throws CoreException { + IProject targetProject = createOrGetTargetProject(modelProject, fragment); + EclipseResourceFileSystemAccess2 fsa = eclipseResourceSupport.createProjectFileSystemAccess(targetProject); + fragment.generateFiles(pattern, fsa); + // Generating Eclipse extensions + ExtensionGenerator exGenerator = new ExtensionGenerator(); + exGenerator.setProject(targetProject); + Iterable extensionContribution = fragment.extensionContribution(pattern, exGenerator); + // Gathering all registered extensions together to avoid unnecessary + // plugin.xml modifications + // Both for performance and for avoiding race conditions + ensureSupport.appendAllExtension(targetProject, extensionContribution); + } - /** - * Creates or finds {@link IProject} associated with the - * {@link IGenerationFragment}. If the project exist dependencies ensured - * based on the {@link IGenerationFragment} contribution. If the project not - * exist, it will be initialized. - * - * @param modelProject - * @param fragment - * @return - * @throws CoreException - */ - private IProject createOrGetTargetProject(IProject modelProject, - IGenerationFragment fragment) throws CoreException { - String postfix = fragment.getProjectPostfix(); - String modelProjectName = ProjectGenerationHelper - .getBundleSymbolicName(modelProject); - if (postfix == null || postfix.isEmpty()) { - ProjectGenerationHelper.ensureBundleDependencies(modelProject, - Lists.newArrayList(fragment.getProjectDependencies())); - return modelProject; - } else { - List dependencies = Lists.newArrayList(); - dependencies.add(modelProjectName); - dependencies.addAll(ensureSupport - .getModelBundleDependencies(modelProject)); - dependencies.addAll(Lists.newArrayList(fragment - .getProjectDependencies())); - IProject targetProject = fragmentProvider.getFragmentProject( - modelProject, fragment); - if (!targetProject.exists()) { - ProjectGenerationHelper.initializePluginProject(targetProject, - dependencies, fragment.getAdditionalBinIncludes()); - } else { - ProjectGenerationHelper.ensureBundleDependencies(targetProject, - dependencies); - } - return targetProject; - } - } + /** + * Creates or finds {@link IProject} associated with the {@link IGenerationFragment}. If the project exist + * dependencies ensured based on the {@link IGenerationFragment} contribution. If the project not exist, it will be + * initialized. + * + * @param modelProject + * @param fragment + * @return + * @throws CoreException + */ + private IProject createOrGetTargetProject(IProject modelProject, IGenerationFragment fragment) throws CoreException { + String postfix = fragment.getProjectPostfix(); + String modelProjectName = ProjectGenerationHelper.getBundleSymbolicName(modelProject); + if (postfix == null || postfix.isEmpty()) { + ProjectGenerationHelper.ensureBundleDependencies(modelProject, + Lists.newArrayList(fragment.getProjectDependencies())); + return modelProject; + } else { + List dependencies = Lists.newArrayList(); + dependencies.add(modelProjectName); + dependencies.addAll(ensureSupport.getModelBundleDependencies(modelProject)); + dependencies.addAll(Lists.newArrayList(fragment.getProjectDependencies())); + IProject targetProject = fragmentProvider.getFragmentProject(modelProject, fragment); + if (!targetProject.exists()) { + ProjectGenerationHelper.initializePluginProject(targetProject, dependencies, + fragment.getAdditionalBinIncludes()); + } else { + ProjectGenerationHelper.ensureBundleDependencies(targetProject, dependencies); + } + return targetProject; + } + } - @Override - protected boolean shouldGenerate(Resource resource, IBuildContext context) { - try { - Iterable> storages = storage2UriMapper - .getStorages(resource.getURI()); - for (Pair pair : storages) { - if (pair.getFirst() instanceof IFile - && pair.getSecond().equals(context.getBuiltProject())) { - IFile file = (IFile) pair.getFirst(); - return file.findMaxProblemSeverity( - "org.eclipse.xtext.ui.check", true, - IResource.DEPTH_INFINITE) != IMarker.SEVERITY_ERROR; - } - } - return false; - } catch (CoreException exc) { - throw new WrappedException(exc); - } - } + @Override + protected boolean shouldGenerate(Resource resource, IBuildContext context) { + try { + Iterable> storages = storage2UriMapper.getStorages(resource.getURI()); + for (Pair pair : storages) { + if (pair.getFirst() instanceof IFile && pair.getSecond().equals(context.getBuiltProject())) { + IFile file = (IFile) pair.getFirst(); + return file.findMaxProblemSeverity("org.eclipse.xtext.ui.check", true, IResource.DEPTH_INFINITE) != IMarker.SEVERITY_ERROR; + } + } + return false; + } catch (CoreException exc) { + throw new WrappedException(exc); + } + } } diff --git a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/builder/EclipseResourceSupport.java b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/builder/EclipseResourceSupport.java index fd69e679..1bcae243 100644 --- a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/builder/EclipseResourceSupport.java +++ b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/builder/EclipseResourceSupport.java @@ -9,63 +9,64 @@ * Zoltan Ujhelyi, Mark Czotter - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.core.generator.builder; - -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.xtext.builder.EclipseOutputConfigurationProvider; -import org.eclipse.xtext.builder.EclipseResourceFileSystemAccess2; -import org.eclipse.xtext.generator.OutputConfiguration; - -import com.google.inject.Inject; -import com.google.inject.Provider; - -public class EclipseResourceSupport { - - @Inject - private Provider fileSystemAccessProvider; - - @Inject - private EclipseOutputConfigurationProvider outputConfigurationProvider; - - /** - * Calculates a file system access component for the selected target project. This is required for code generation API. - * @param targetProject - * @return an initialized file system access component for the - */ - public EclipseResourceFileSystemAccess2 createProjectFileSystemAccess( - IProject targetProject) { - EclipseResourceFileSystemAccess2 fsa = fileSystemAccessProvider.get(); - fsa.setProject(targetProject); - fsa.setMonitor(new NullProgressMonitor()); - Map outputs = new HashMap(); - for (OutputConfiguration conf : outputConfigurationProvider.getOutputConfigurations(targetProject)) { - outputs.put(conf.getName(), conf); - } - fsa.setOutputConfigurations(outputs); - fsa.setPostProcessor(new EclipseResourceFileSystemAccess2.IFileCallback() { - - public boolean beforeFileDeletion(IFile file) { - return true; - } - - public void afterFileUpdate(IFile file) { - handleFileAccess(file); - } - - public void afterFileCreation(IFile file) { - handleFileAccess(file); - } - - protected void handleFileAccess(IFile file) { - } - - }); - return fsa; - } - -} +package org.eclipse.incquery.tooling.core.generator.builder; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.xtext.builder.EclipseOutputConfigurationProvider; +import org.eclipse.xtext.builder.EclipseResourceFileSystemAccess2; +import org.eclipse.xtext.generator.OutputConfiguration; + +import com.google.inject.Inject; +import com.google.inject.Provider; + +public class EclipseResourceSupport { + + @Inject + private Provider fileSystemAccessProvider; + + @Inject + private EclipseOutputConfigurationProvider outputConfigurationProvider; + + /** + * Calculates a file system access component for the selected target project. This is required for code generation + * API. + * + * @param targetProject + * @return an initialized file system access component for the + */ + public EclipseResourceFileSystemAccess2 createProjectFileSystemAccess(IProject targetProject) { + EclipseResourceFileSystemAccess2 fsa = fileSystemAccessProvider.get(); + fsa.setProject(targetProject); + fsa.setMonitor(new NullProgressMonitor()); + Map outputs = new HashMap(); + for (OutputConfiguration conf : outputConfigurationProvider.getOutputConfigurations(targetProject)) { + outputs.put(conf.getName(), conf); + } + fsa.setOutputConfigurations(outputs); + fsa.setPostProcessor(new EclipseResourceFileSystemAccess2.IFileCallback() { + + public boolean beforeFileDeletion(IFile file) { + return true; + } + + public void afterFileUpdate(IFile file) { + handleFileAccess(file); + } + + public void afterFileCreation(IFile file) { + handleFileAccess(file); + } + + protected void handleFileAccess(IFile file) { + } + + }); + return fsa; + } + +} diff --git a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/builder/EnsurePluginSupport.java b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/builder/EnsurePluginSupport.java index f68ea852..15df586a 100644 --- a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/builder/EnsurePluginSupport.java +++ b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/builder/EnsurePluginSupport.java @@ -9,8 +9,8 @@ * Mark Czotter - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.core.generator.builder; - +package org.eclipse.incquery.tooling.core.generator.builder; + import java.util.Collection; import org.apache.log4j.Logger; @@ -31,161 +31,157 @@ import com.google.common.collect.Multimap; import com.google.inject.Inject; import com.google.inject.Singleton; - -/** - * Ensure support for BuilderParticipant. - * - * @author Mark Czotter - * - */ -@Singleton -public class EnsurePluginSupport { - - @Inject - private IGenerationFragmentProvider fragmentProvider; - - @Inject - private Logger logger; - - private Multimap exportedPackageMap = ArrayListMultimap.create(); - private Multimap appendableExtensionMap = ArrayListMultimap.create(); - private Multimap> removableExtensionMap = ArrayListMultimap.create(); - private Multimap modelBundleIds = HashMultimap.create(); - - public void appendExtension(IProject project, IPluginExtension extension) { - appendableExtensionMap.put(project, extension); - } - - public void appendAllExtension(IProject project, Iterable extensions) { - appendableExtensionMap.putAll(project, extensions); - } - - public void removeExtension(IProject project, Pair extension) { - removableExtensionMap.put(project, extension); - } - - public void removeAllExtension(IProject targetProject, - Iterable> extensions) { - removableExtensionMap.putAll(targetProject, extensions); - } - - public void exportPackage(IProject project, String packageName) { - exportedPackageMap.put(project, packageName); - } - - /** - * Adds a bundle id to the projects bundle collection. The implementation - * manages multiple additions by storing only a single element for each id. - * - * @param project - * @param bundleId - */ - public void addModelBundleId(IProject project, String bundleId) { - modelBundleIds.put(project, bundleId); - } - - public void clean() { - exportedPackageMap.clear(); - appendableExtensionMap.clear(); - removableExtensionMap.clear(); - modelBundleIds.clear(); - } - - /** - * The ensure phase performs changes to the plugin.xml and MANIFEST.MF descriptors. - * @param modelProject - * @param monitor - * @throws CoreException - */ - public void ensure(IProject modelProject, IProgressMonitor monitor) { - // normal code generation done, extensions, packages ready to add to the plug-ins - try { - internalEnsure(modelProject, monitor); - } catch (Exception e) { - logger.error("Exception during Extension/Package ensure Phase", e); - } finally { - monitor.worked(1); - } - } - - public Collection getModelBundleDependencies(IProject project) { - return modelBundleIds.get(project); - } - - private void internalEnsure(IProject modelProject, IProgressMonitor monitor) throws CoreException { - // ensure exported package and extensions - ensurePackages(monitor); - ensureExtensions(monitor); - ensureSourceFolders(modelProject, monitor); - } - - private void ensurePackages(IProgressMonitor monitor) throws CoreException { - for (IProject proj : exportedPackageMap.keySet()) { - // ensure package exports per project - ProjectGenerationHelper.ensurePackageExports(proj, exportedPackageMap.get(proj)); - } - } - - private void ensureExtensions(IProgressMonitor monitor) throws CoreException { - // Loading extensions to the generated projects - // if new contributed extensions exists remove the removables from the - // contributed extensions, so the truly removed extensions remain in the removedExtensions - if (!appendableExtensionMap.isEmpty()) { - // iterate over the contributed extensions, remove the removables - for (IProject proj : appendableExtensionMap.keySet()) { - Iterable extensions = appendableExtensionMap.get(proj); - Collection> removableExtensions = removableExtensionMap.get(proj); - if (!removableExtensions.isEmpty()) { - removeSameExtensions(removableExtensions, extensions); - } - ProjectGenerationHelper.ensureExtensions(proj, extensions, - removableExtensions); - } - // iterate over the remaining removables, remove all prev. extension from the projects - for (IProject proj : removableExtensionMap.keySet()) { - if (!appendableExtensionMap.containsKey(proj)) { - Iterable> removableExtensions = removableExtensionMap.get(proj); - Iterable extensions = Lists.newArrayList(); - ProjectGenerationHelper.ensureExtensions(proj, extensions, - removableExtensions); - } - } - } else { - // if no contributed extensions (like no pattern in the eiq file) - // remove all previous extension - for (IProject proj : removableExtensionMap.keySet()) { - Iterable> removableExtensions = removableExtensionMap.get(proj); - Iterable extensions = Lists.newArrayList(); - ProjectGenerationHelper.ensureExtensions(proj, extensions, - removableExtensions); - } - } - } - - private void removeSameExtensions(Collection> removeFrom, - Iterable searchList) { - // not remove a removable if exist in the current extension map - for (final IPluginExtension ext : searchList) { - Pair found = IterableExtensions.findFirst(removeFrom, new Functions.Function1, Boolean>() { - @Override - public Boolean apply(Pair p) { - return (p.getKey().equals(ext.getId())) - && (p.getValue().equals(ext.getPoint())); - } - }); - removeFrom.remove(found); - } - } - - private void ensureSourceFolders(IProject modelProject, IProgressMonitor monitor) throws CoreException { - // ensure classpath entries on the projects - ProjectGenerationHelper.ensureSourceFolders(modelProject, monitor); - for (IGenerationFragment fragment : fragmentProvider.getAllFragments()) { - IProject fragmentProject = fragmentProvider.getFragmentProject(modelProject, fragment); - if (fragmentProject.exists()) { - ProjectGenerationHelper.ensureSourceFolders(fragmentProject, monitor); - } - } - } - -} + +/** + * Ensure support for BuilderParticipant. + * + * @author Mark Czotter + * + */ +@Singleton +public class EnsurePluginSupport { + + @Inject + private IGenerationFragmentProvider fragmentProvider; + + @Inject + private Logger logger; + + private Multimap exportedPackageMap = ArrayListMultimap.create(); + private Multimap appendableExtensionMap = ArrayListMultimap.create(); + private Multimap> removableExtensionMap = ArrayListMultimap.create(); + private Multimap modelBundleIds = HashMultimap.create(); + + public void appendExtension(IProject project, IPluginExtension extension) { + appendableExtensionMap.put(project, extension); + } + + public void appendAllExtension(IProject project, Iterable extensions) { + appendableExtensionMap.putAll(project, extensions); + } + + public void removeExtension(IProject project, Pair extension) { + removableExtensionMap.put(project, extension); + } + + public void removeAllExtension(IProject targetProject, Iterable> extensions) { + removableExtensionMap.putAll(targetProject, extensions); + } + + public void exportPackage(IProject project, String packageName) { + exportedPackageMap.put(project, packageName); + } + + /** + * Adds a bundle id to the projects bundle collection. The implementation manages multiple additions by storing only + * a single element for each id. + * + * @param project + * @param bundleId + */ + public void addModelBundleId(IProject project, String bundleId) { + modelBundleIds.put(project, bundleId); + } + + public void clean() { + exportedPackageMap.clear(); + appendableExtensionMap.clear(); + removableExtensionMap.clear(); + modelBundleIds.clear(); + } + + /** + * The ensure phase performs changes to the plugin.xml and MANIFEST.MF descriptors. + * + * @param modelProject + * @param monitor + * @throws CoreException + */ + public void ensure(IProject modelProject, IProgressMonitor monitor) { + // normal code generation done, extensions, packages ready to add to the plug-ins + try { + internalEnsure(modelProject, monitor); + } catch (Exception e) { + logger.error("Exception during Extension/Package ensure Phase", e); + } finally { + monitor.worked(1); + } + } + + public Collection getModelBundleDependencies(IProject project) { + return modelBundleIds.get(project); + } + + private void internalEnsure(IProject modelProject, IProgressMonitor monitor) throws CoreException { + // ensure exported package and extensions + ensurePackages(monitor); + ensureExtensions(monitor); + ensureSourceFolders(modelProject, monitor); + } + + private void ensurePackages(IProgressMonitor monitor) throws CoreException { + for (IProject proj : exportedPackageMap.keySet()) { + // ensure package exports per project + ProjectGenerationHelper.ensurePackageExports(proj, exportedPackageMap.get(proj)); + } + } + + private void ensureExtensions(IProgressMonitor monitor) throws CoreException { + // Loading extensions to the generated projects + // if new contributed extensions exists remove the removables from the + // contributed extensions, so the truly removed extensions remain in the removedExtensions + if (!appendableExtensionMap.isEmpty()) { + // iterate over the contributed extensions, remove the removables + for (IProject proj : appendableExtensionMap.keySet()) { + Iterable extensions = appendableExtensionMap.get(proj); + Collection> removableExtensions = removableExtensionMap.get(proj); + if (!removableExtensions.isEmpty()) { + removeSameExtensions(removableExtensions, extensions); + } + ProjectGenerationHelper.ensureExtensions(proj, extensions, removableExtensions); + } + // iterate over the remaining removables, remove all prev. extension from the projects + for (IProject proj : removableExtensionMap.keySet()) { + if (!appendableExtensionMap.containsKey(proj)) { + Iterable> removableExtensions = removableExtensionMap.get(proj); + Iterable extensions = Lists.newArrayList(); + ProjectGenerationHelper.ensureExtensions(proj, extensions, removableExtensions); + } + } + } else { + // if no contributed extensions (like no pattern in the eiq file) + // remove all previous extension + for (IProject proj : removableExtensionMap.keySet()) { + Iterable> removableExtensions = removableExtensionMap.get(proj); + Iterable extensions = Lists.newArrayList(); + ProjectGenerationHelper.ensureExtensions(proj, extensions, removableExtensions); + } + } + } + + private void removeSameExtensions(Collection> removeFrom, Iterable searchList) { + // not remove a removable if exist in the current extension map + for (final IPluginExtension ext : searchList) { + Pair found = IterableExtensions.findFirst(removeFrom, + new Functions.Function1, Boolean>() { + @Override + public Boolean apply(Pair p) { + return (p.getKey().equals(ext.getId())) && (p.getValue().equals(ext.getPoint())); + } + }); + removeFrom.remove(found); + } + } + + private void ensureSourceFolders(IProject modelProject, IProgressMonitor monitor) throws CoreException { + // ensure classpath entries on the projects + ProjectGenerationHelper.ensureSourceFolders(modelProject, monitor); + for (IGenerationFragment fragment : fragmentProvider.getAllFragments()) { + IProject fragmentProject = fragmentProvider.getFragmentProject(modelProject, fragment); + if (fragmentProject.exists()) { + ProjectGenerationHelper.ensureSourceFolders(fragmentProject, monitor); + } + } + } + +} diff --git a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/builder/GeneratorIssueCodes.java b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/builder/GeneratorIssueCodes.java index ef49ac13..e64a13e8 100644 --- a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/builder/GeneratorIssueCodes.java +++ b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/builder/GeneratorIssueCodes.java @@ -14,9 +14,10 @@ import org.eclipse.incquery.tooling.core.generator.IncQueryGeneratorPlugin; public final class GeneratorIssueCodes { - - private GeneratorIssueCodes() {} - + + private GeneratorIssueCodes() { + } + public static final String INVALID_PATTERN_MODEL_CODE = IncQueryGeneratorPlugin.BUNDLE_ID + ".invalid.patternmodel"; public static final String INVALID_TYPEREF_CODE = IncQueryGeneratorPlugin.BUNDLE_ID + ".invalid.typeref"; } diff --git a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/builder/IErrorFeedback.java b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/builder/IErrorFeedback.java index 3316efeb..d6728f8a 100644 --- a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/builder/IErrorFeedback.java +++ b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/builder/IErrorFeedback.java @@ -18,55 +18,69 @@ public interface IErrorFeedback { - /** - * An error type for use in the JvmModelInferrer. It is differentiated from {@link #FRAGMENT_ERROR_TYPE}, as the - * two builds have different lifecycles, so cleaning has to be executed at different points. - */ + /** + * An error type for use in the JvmModelInferrer. It is differentiated from {@link #FRAGMENT_ERROR_TYPE}, as the two + * builds have different lifecycles, so cleaning has to be executed at different points. + */ static final String JVMINFERENCE_ERROR_TYPE = "org.eclipse.incquery.tooling.core.generator.marker.inference"; - /** - * An error type for use in the generator fragments. It is differentiated from {@link #JVMINFERENCE_ERROR_TYPE}, as the - * two builds have different lifecycles, so cleaning has to be executed at different points. - */ + /** + * An error type for use in the generator fragments. It is differentiated from {@link #JVMINFERENCE_ERROR_TYPE}, as + * the two builds have different lifecycles, so cleaning has to be executed at different points. + */ static final String FRAGMENT_ERROR_TYPE = "org.eclipse.incquery.tooling.core.generator.marker.fragment"; - - /** - * Clears all problem markers from the resource and all its descendants. - * @param resource a file, folder or project to clean all markers from - * @param markerType {@link #JVMINFERENCE_ERROR_TYPE} and {@link #FRAGMENT_ERROR_TYPE} are supported - */ - void clearMarkers(IResource resource, String markerType); - - /** - * Reports an error in a context object. The error marker only appears if the context object is contained in a workspace resource, - * and then it is associated with the location of the context object in the textual file. - * All runtime errors related to the creation of the marker are logged. - * @param ctx - * @param message - * @param errorCode an arbitrary error code - see {@link GeneratorIssueCodes} for already defined constants - * @param severity - * @param markerType {@link #JVMINFERENCE_ERROR_TYPE} and {@link #FRAGMENT_ERROR_TYPE} are supported - */ - void reportError(EObject ctx, String message, String errorCode, Severity severity, String markerType); - /** - * Reports an error in a context object. The error marker only appears if the context object is contained in a workspace resource, - * but it is NOT associated with the location of the context object in the textual file. - * All runtime errors related to the creation of the marker are logged. - * @param ctx - * @param message - * @param errorCode an arbitrary error code - see {@link GeneratorIssueCodes} for already defined constants - * @param severity - * @param markerType {@link #JVMINFERENCE_ERROR_TYPE} and {@link #FRAGMENT_ERROR_TYPE} are supported - */ - void reportErrorNoLocation(EObject ctx, String message, String errorCode, Severity severity, String markerType); - /** - * Reports an error in a file, but is not associated to any specific line. - * All runtime errors related to the creation of the marker are logged. - * @param file - * @param message - * @param errorCode an arbitrary error code - see {@link GeneratorIssueCodes} for already defined constants - * @param severity - * @param markerType {@link #JVMINFERENCE_ERROR_TYPE} and {@link #FRAGMENT_ERROR_TYPE} are supported - */ - void reportError(IFile file, String message, String errorCode, Severity severity, String markerType); + + /** + * Clears all problem markers from the resource and all its descendants. + * + * @param resource + * a file, folder or project to clean all markers from + * @param markerType + * {@link #JVMINFERENCE_ERROR_TYPE} and {@link #FRAGMENT_ERROR_TYPE} are supported + */ + void clearMarkers(IResource resource, String markerType); + + /** + * Reports an error in a context object. The error marker only appears if the context object is contained in a + * workspace resource, and then it is associated with the location of the context object in the textual file. All + * runtime errors related to the creation of the marker are logged. + * + * @param ctx + * @param message + * @param errorCode + * an arbitrary error code - see {@link GeneratorIssueCodes} for already defined constants + * @param severity + * @param markerType + * {@link #JVMINFERENCE_ERROR_TYPE} and {@link #FRAGMENT_ERROR_TYPE} are supported + */ + void reportError(EObject ctx, String message, String errorCode, Severity severity, String markerType); + + /** + * Reports an error in a context object. The error marker only appears if the context object is contained in a + * workspace resource, but it is NOT associated with the location of the context object in the textual file. + * All runtime errors related to the creation of the marker are logged. + * + * @param ctx + * @param message + * @param errorCode + * an arbitrary error code - see {@link GeneratorIssueCodes} for already defined constants + * @param severity + * @param markerType + * {@link #JVMINFERENCE_ERROR_TYPE} and {@link #FRAGMENT_ERROR_TYPE} are supported + */ + void reportErrorNoLocation(EObject ctx, String message, String errorCode, Severity severity, String markerType); + + /** + * Reports an error in a file, but is not associated to any specific line. All runtime errors related to the + * creation of the marker are logged. + * + * @param file + * @param message + * @param errorCode + * an arbitrary error code - see {@link GeneratorIssueCodes} for already defined constants + * @param severity + * @param markerType + * {@link #JVMINFERENCE_ERROR_TYPE} and {@link #FRAGMENT_ERROR_TYPE} are supported + */ + void reportError(IFile file, String message, String errorCode, Severity severity, String markerType); } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/builder/xmi/XmiModelSupport.java b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/builder/xmi/XmiModelSupport.java index 8e04bbbb..036302a2 100644 --- a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/builder/xmi/XmiModelSupport.java +++ b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/builder/xmi/XmiModelSupport.java @@ -9,8 +9,8 @@ * Mark Czotter - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.core.generator.builder.xmi; - +package org.eclipse.incquery.tooling.core.generator.builder.xmi; + import java.util.List; import org.apache.log4j.Logger; @@ -31,81 +31,79 @@ import org.eclipse.xtext.resource.impl.ResourceDescriptionsProvider; import com.google.inject.Inject; - -/** - * Xmi Model Support for the BuilderParticipant. - * Builds an XMI model from an {@link IBuildContext}. - * Gathers all relevant resources that is accessible from the classpath. - * - * @author Mark Czotter - * - */ -public class XmiModelSupport { - - @Inject - private XmiModelBuilder xmiModelBuilder; - - @Inject - private ResourceDescriptionsProvider resourceDescriptionsProvider; - - @Inject - private IResourceServiceProvider resourceServiceProvider; - - @Inject - private IContainer.Manager containerManager; - @Inject - private Logger logger; - - /** - * Builds a global XMI model with a {@link XmiModelBuilder} builder. Before - * the actual build, finds all relevant eiq resources, so the XMI build is - * performed on all currently available {@link PatternModel}. - * - * @param baseDelta - * @param context - * @param monitor - * @throws CoreException - */ - public void build(Delta baseDelta, IBuildContext context, IProgressMonitor monitor) { - // Normal CleanUp and codegen done on every delta, do XMI Model build - try { - monitor.beginTask("Building XMI model", 1); - internalBuild(baseDelta, context, monitor); - } catch (Exception e) { - logger.error("Exception during XMI Model Building Phase", e); - } finally { - monitor.worked(1); - } - } - - private void internalBuild(Delta baseDelta, IBuildContext context, IProgressMonitor monitor) throws CoreException { - Resource deltaResource = context.getResourceSet().getResource(baseDelta.getUri(), true); - // create a resourcedescription for the input, - // this way we can find all relevant EIQ file in the context of this input. - IResourceDescriptions index = resourceDescriptionsProvider.createResourceDescriptions(); - IResourceDescription resDesc = index.getResourceDescription(deltaResource.getURI()); - List visibleContainers = containerManager.getVisibleContainers(resDesc, index); - // load all visible resource to the resourceset of the input resource - for (IContainer container : visibleContainers) { - for (IResourceDescription rd : container.getResourceDescriptions()) { - if (resourceServiceProvider.canHandle(rd.getURI())) { - context.getResourceSet().getResource(rd.getURI(), true); - } - } - } - xmiModelBuilder.build(context.getResourceSet(), getXmiModelPath(context.getBuiltProject())); - } - - private String getXmiModelPath(IProject project) throws CoreException { - IFolder folder = project.getFolder(XmiModelUtil.XMI_OUTPUT_FOLDER); - IFile file = folder.getFile(XmiModelUtil.GLOBAL_EIQ_FILENAME); - if (!folder.exists()) { - folder.create(IResource.DEPTH_INFINITE, false, null); - } - if (file.exists()) { - file.delete(true, null); - } - return file.getFullPath().toString(); - } - -} + +/** + * Xmi Model Support for the BuilderParticipant. Builds an XMI model from an {@link IBuildContext}. Gathers all relevant + * resources that is accessible from the classpath. + * + * @author Mark Czotter + * + */ +public class XmiModelSupport { + + @Inject + private XmiModelBuilder xmiModelBuilder; + + @Inject + private ResourceDescriptionsProvider resourceDescriptionsProvider; + + @Inject + private IResourceServiceProvider resourceServiceProvider; + + @Inject + private IContainer.Manager containerManager; + @Inject + private Logger logger; + + /** + * Builds a global XMI model with a {@link XmiModelBuilder} builder. Before the actual build, finds all relevant eiq + * resources, so the XMI build is performed on all currently available {@link PatternModel}. + * + * @param baseDelta + * @param context + * @param monitor + * @throws CoreException + */ + public void build(Delta baseDelta, IBuildContext context, IProgressMonitor monitor) { + // Normal CleanUp and codegen done on every delta, do XMI Model build + try { + monitor.beginTask("Building XMI model", 1); + internalBuild(baseDelta, context, monitor); + } catch (Exception e) { + logger.error("Exception during XMI Model Building Phase", e); + } finally { + monitor.worked(1); + } + } + + private void internalBuild(Delta baseDelta, IBuildContext context, IProgressMonitor monitor) throws CoreException { + Resource deltaResource = context.getResourceSet().getResource(baseDelta.getUri(), true); + // create a resourcedescription for the input, + // this way we can find all relevant EIQ file in the context of this input. + IResourceDescriptions index = resourceDescriptionsProvider.createResourceDescriptions(); + IResourceDescription resDesc = index.getResourceDescription(deltaResource.getURI()); + List visibleContainers = containerManager.getVisibleContainers(resDesc, index); + // load all visible resource to the resourceset of the input resource + for (IContainer container : visibleContainers) { + for (IResourceDescription rd : container.getResourceDescriptions()) { + if (resourceServiceProvider.canHandle(rd.getURI())) { + context.getResourceSet().getResource(rd.getURI(), true); + } + } + } + xmiModelBuilder.build(context.getResourceSet(), getXmiModelPath(context.getBuiltProject())); + } + + private String getXmiModelPath(IProject project) throws CoreException { + IFolder folder = project.getFolder(XmiModelUtil.XMI_OUTPUT_FOLDER); + IFile file = folder.getFile(XmiModelUtil.GLOBAL_EIQ_FILENAME); + if (!folder.exists()) { + folder.create(IResource.DEPTH_INFINITE, false, null); + } + if (file.exists()) { + file.delete(true, null); + } + return file.getFullPath().toString(); + } + +} diff --git a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/fragments/ExtensionBasedGenerationFragmentProvider.java b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/fragments/ExtensionBasedGenerationFragmentProvider.java index 2485d95a..a8e2eea2 100644 --- a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/fragments/ExtensionBasedGenerationFragmentProvider.java +++ b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/fragments/ExtensionBasedGenerationFragmentProvider.java @@ -29,74 +29,72 @@ import com.google.inject.Inject; /** - * A provider for {@link IGenerationFragment} classes - the fragment list is populated using the - * registered extensions for the {@value #EXTENSIONID} extension point. + * A provider for {@link IGenerationFragment} classes - the fragment list is populated using the registered extensions + * for the {@value #EXTENSIONID} extension point. + * * @author Zoltan Ujhelyi - * + * */ -public class ExtensionBasedGenerationFragmentProvider implements - IGenerationFragmentProvider { - - @Inject - private Logger logger; +public class ExtensionBasedGenerationFragmentProvider implements IGenerationFragmentProvider { + + @Inject + private Logger logger; static final String EXTENSIONID = "org.eclipse.incquery.tooling.core.generatorFragment"; - static final String GENERIC_ATTRIBUTE = ""; - private Multimap fragments; - - @Inject - private IWorkspaceRoot workspaceRoot; + static final String GENERIC_ATTRIBUTE = ""; + private Multimap fragments; + + @Inject + private IWorkspaceRoot workspaceRoot; + + protected void initializeFragments() { + fragments = ArrayListMultimap.create(); + final IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(EXTENSIONID); + for (IConfigurationElement e : config) { + final String annotationName = e.getAttribute("annotation") != null ? e.getAttribute("annotation") + : GENERIC_ATTRIBUTE; + try { + IGenerationFragment fragment = (IGenerationFragment) e.createExecutableExtension("fragment"); + fragments.put(annotationName, fragment); + } catch (CoreException e1) { + logger.warn("Cannot load generator fragment from " + e.getContributor().getName(), e1); + } + } + } + + @Override + public Iterable getFragmentsForPattern(Pattern pattern) { + if (fragments == null) { + initializeFragments(); + } + HashSet fragmentSet = new HashSet(fragments.get(GENERIC_ATTRIBUTE)); + for (Annotation annotation : pattern.getAnnotations()) { + fragmentSet.addAll(fragments.get(annotation.getName())); + } + return fragmentSet; + } - protected void initializeFragments() { - fragments = ArrayListMultimap.create(); - final IConfigurationElement[] config = Platform.getExtensionRegistry() - .getConfigurationElementsFor(EXTENSIONID); - for (IConfigurationElement e : config) { - final String annotationName = e.getAttribute("annotation") != null ? e.getAttribute("annotation") : GENERIC_ATTRIBUTE; - try { - IGenerationFragment fragment = (IGenerationFragment) e.createExecutableExtension("fragment"); - fragments.put(annotationName, fragment); - } catch (CoreException e1) { - logger.warn("Cannot load generator fragment from " + e.getContributor().getName(), e1); - } - } - } - - @Override - public Iterable getFragmentsForPattern(Pattern pattern) { - if (fragments == null) { - initializeFragments(); - } - HashSet fragmentSet = new HashSet(fragments.get(GENERIC_ATTRIBUTE)); - for (Annotation annotation : pattern.getAnnotations()) { - fragmentSet.addAll(fragments.get(annotation.getName())); - } - return fragmentSet; - } + @Override + public Iterable getAllFragments() { + if (fragments == null) { + initializeFragments(); + } + HashSet fragmentSet = new HashSet(fragments.values()); + return fragmentSet; + } - @Override - public Iterable getAllFragments() { - if (fragments == null) { - initializeFragments(); - } - HashSet fragmentSet = new HashSet(fragments.values()); - return fragmentSet; - } + @Override + public IProject getFragmentProject(IProject modelProject, IGenerationFragment fragment) { + if (StringExtensions.isNullOrEmpty(fragment.getProjectPostfix())) { + return modelProject; + } + String projectName = getFragmentProjectName(modelProject, fragment); + return workspaceRoot.getProject(projectName); + } - @Override - public IProject getFragmentProject(IProject modelProject, - IGenerationFragment fragment) { - if (StringExtensions.isNullOrEmpty(fragment.getProjectPostfix())) { - return modelProject; - } - String projectName = getFragmentProjectName(modelProject, fragment); - return workspaceRoot.getProject(projectName); - } - - private String getFragmentProjectName(IProject base, IGenerationFragment fragment) { - return String.format("%s.%s", - ProjectGenerationHelper.getBundleSymbolicName(base), - fragment.getProjectPostfix()); - } + private String getFragmentProjectName(IProject base, IGenerationFragment fragment) { + return String + .format("%s.%s", ProjectGenerationHelper.getBundleSymbolicName(base), fragment.getProjectPostfix()); + } } diff --git a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/fragments/IGenerationFragment.java b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/fragments/IGenerationFragment.java index b34aa692..a71554e7 100644 --- a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/fragments/IGenerationFragment.java +++ b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/fragments/IGenerationFragment.java @@ -20,79 +20,75 @@ import org.eclipse.xtext.xbase.lib.Pair; /** - * A code generation fragment is used by annotation processors for code - * generation. + * A code generation fragment is used by annotation processors for code generation. * * @author Zoltan Ujhelyi * */ public interface IGenerationFragment { - /** - * Returns the postfix used to define the destination project. The generated - * contents are put into the model.project.name.postfix - * project, or left in the model.project.name project if a - * null postfix is returned. - * - * @return A project postfix, or null - */ - String getProjectPostfix(); + /** + * Returns the postfix used to define the destination project. The generated contents are put into the + * model.project.name.postfix project, or left in the model.project.name project if a null + * postfix is returned. + * + * @return A project postfix, or null + */ + String getProjectPostfix(); - /** - * Returns an array of bundle id's to add to the destination project as dependency. This - * array need not to contain the model project, as it is added automatically - * to new generated projects. - * - * @return A non-null (but possibly empty) array of dependencies to add. - */ - String[] getProjectDependencies(); - - /** - * Executes code generation for a selected pattern. All resulting files - * should be placed using the file system access component. - * - * @param pattern - * @param fsa - */ - void generateFiles(Pattern pattern, IFileSystemAccess fsa); - - /** - * Cleans up the previosly generated files for the selected pattern. Delete - * the files using the file system access component. - * - * @param pattern - * @param fsa - */ - void cleanUp(Pattern pattern, IFileSystemAccess fsa); + /** + * Returns an array of bundle id's to add to the destination project as dependency. This array need not to contain + * the model project, as it is added automatically to new generated projects. + * + * @return A non-null (but possibly empty) array of dependencies to add. + */ + String[] getProjectDependencies(); + + /** + * Executes code generation for a selected pattern. All resulting files should be placed using the file system + * access component. + * + * @param pattern + * @param fsa + */ + void generateFiles(Pattern pattern, IFileSystemAccess fsa); + + /** + * Cleans up the previosly generated files for the selected pattern. Delete the files using the file system access + * component. + * + * @param pattern + * @param fsa + */ + void cleanUp(Pattern pattern, IFileSystemAccess fsa); + + // public Iterable inferFiles(Pattern pattern); + /** + * Returns a collection of extension contributions for the selected pattern. The {@link ExtensionGeneration} + * parameter provides a builder API for Xtend-based generators to have a readable generator. + * + * @param pattern + * @param exGen + * @return a collection of plugin extensions + */ + Iterable extensionContribution(Pattern pattern, ExtensionGenerator exGen); + + /** + * Returns a collections of extensions, that need to be removed from the plugin.xml. + * + * @param pattern + * @return + */ + Iterable> removeExtension(Pattern pattern); + + /** + * Returns pairs of extension id prefix and point id. All extension with one of these ids and prefixes will be + * removed from the fragments project's plugin.xml. This method only invoked during Clean Build. + * + * @return + */ + Collection> getRemovableExtensions(); + + IPath[] getAdditionalBinIncludes(); - //public Iterable inferFiles(Pattern pattern); - /** - * Returns a collection of extension contributions for the selected pattern. - * The {@link ExtensionGeneration} parameter provides a builder API for - * Xtend-based generators to have a readable generator. - * - * @param pattern - * @param exGen - * @return a collection of plugin extensions - */ - Iterable extensionContribution(Pattern pattern, ExtensionGenerator exGen); - - /** - * Returns a collections of extensions, that need to be removed from the plugin.xml. - * @param pattern - * @return - */ - Iterable> removeExtension(Pattern pattern); - - /** - * Returns pairs of extension id prefix and point id. All extension with one of these ids and prefixes will be - * removed from the fragments project's plugin.xml. This method only invoked - * during Clean Build. - * - * @return - */ - Collection> getRemovableExtensions(); - - IPath[] getAdditionalBinIncludes(); - } diff --git a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/fragments/IGenerationFragmentProvider.java b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/fragments/IGenerationFragmentProvider.java index 872a71e7..0422adfb 100644 --- a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/fragments/IGenerationFragmentProvider.java +++ b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/fragments/IGenerationFragmentProvider.java @@ -16,33 +16,35 @@ import org.eclipse.incquery.tooling.core.generator.GeneratorModule; /** - * An interface for collecting code generation fragments for specific patterns. - * The concrete value is injected using the {@link GeneratorModule}-based - * injectors. + * An interface for collecting code generation fragments for specific patterns. The concrete value is injected using the + * {@link GeneratorModule}-based injectors. * * @author Zoltan Ujhelyi * */ public interface IGenerationFragmentProvider { - /** - * Collects the generation fragments applicable for a selected pattern. - * @param pattern - * @return a non-null collection of code generation fragments. May be empty. - */ - public Iterable getFragmentsForPattern(Pattern pattern); - - /** - * Collects all {@link IGenerationFragment}. - * @return a non-null collection of code generation fragments. - */ - public Iterable getAllFragments(); - - /** - * Returns the fragment project for the {@link IGenerationFragment} based on the modelProject. - * @param modelProject - * @param fragment - * @return - */ - public IProject getFragmentProject(IProject modelProject, IGenerationFragment fragment); + /** + * Collects the generation fragments applicable for a selected pattern. + * + * @param pattern + * @return a non-null collection of code generation fragments. May be empty. + */ + public Iterable getFragmentsForPattern(Pattern pattern); + + /** + * Collects all {@link IGenerationFragment}. + * + * @return a non-null collection of code generation fragments. + */ + public Iterable getAllFragments(); + + /** + * Returns the fragment project for the {@link IGenerationFragment} based on the modelProject. + * + * @param modelProject + * @param fragment + * @return + */ + public IProject getFragmentProject(IProject modelProject, IGenerationFragment fragment); } diff --git a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/genmodel/GenModelMetamodelProviderService.java b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/genmodel/GenModelMetamodelProviderService.java index 2cdf6ddd..901cc3bb 100644 --- a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/genmodel/GenModelMetamodelProviderService.java +++ b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/genmodel/GenModelMetamodelProviderService.java @@ -84,7 +84,7 @@ public boolean apply(IEObjectDescription desc) { @Inject private IJavaProjectProvider projectProvider; - + @Inject private IQualifiedNameConverter qualifiedNameConverter; @@ -277,7 +277,7 @@ private List getAllGenPackages(GenModel genModel) { } return resultList; } - + private List getAllNestedGenPackages(GenPackage outerGenPackage) { List resultList = new ArrayList(); for (GenPackage innerGenPackage : outerGenPackage.getNestedGenPackages()) { diff --git a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/genmodel/IEiqGenmodelProvider.java b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/genmodel/IEiqGenmodelProvider.java index 961bcbd6..b2d11521 100644 --- a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/genmodel/IEiqGenmodelProvider.java +++ b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/genmodel/IEiqGenmodelProvider.java @@ -29,93 +29,82 @@ */ public interface IEiqGenmodelProvider { - /** - * Gets the generator model for a selected IncQuery-related context object - * (e.g. a {@link Pattern}). If the project of the pattern has no generator - * model specified, this method returns an empty generator model. The - * genmodel will be placed into the {@link ResourceSet} of the Pattern - * object. - * - * @param pattern - * @return the loaded generator model - * @throws IllegalArgumentException - * if the parameter pattern is not serialized into a - * {@link ResourceSet} that is not linked to an IncQuery project - */ - IncQueryGeneratorModel getGeneratorModel(EObject context); + /** + * Gets the generator model for a selected IncQuery-related context object (e.g. a {@link Pattern}). If the project + * of the pattern has no generator model specified, this method returns an empty generator model. The genmodel will + * be placed into the {@link ResourceSet} of the Pattern object. + * + * @param pattern + * @return the loaded generator model + * @throws IllegalArgumentException + * if the parameter pattern is not serialized into a {@link ResourceSet} that is not linked to an + * IncQuery project + */ + IncQueryGeneratorModel getGeneratorModel(EObject context); - /** - * Gets the generator model for a selected IncQuery project. If the project - * has no generator model specified, this method returns an empty generator - * model. The genmodel will be placed into the specified resource set - * - * @param project - * @param set - * @return the loaded generator model - */ - IncQueryGeneratorModel getGeneratorModel(IProject project, ResourceSet set); - - /** - * Saves the changes to the generator model instance in the selected - * project. The provider assumes that the genmodel was instantiated by using - * the {@link #getGeneratorModel(EObject)} or the - * {@link #getGeneratorModel(IProject, ResourceSet)} methods. - * - * @throws IOException - */ - void saveGeneratorModel(IProject project, IncQueryGeneratorModel generatorModel) throws IOException; + /** + * Gets the generator model for a selected IncQuery project. If the project has no generator model specified, this + * method returns an empty generator model. The genmodel will be placed into the specified resource set + * + * @param project + * @param set + * @return the loaded generator model + */ + IncQueryGeneratorModel getGeneratorModel(IProject project, ResourceSet set); - - /** - * Collects all EPackage objects available from a selected project, including - * the ones from the EPackage Registry. - * If the project features an eiqgen files, the packages referenced there - * are also included. - * @param project - * @return a non-null collection of packages - * @throws CoreException - */ - Collection getAllMetamodelObjects(IProject project) throws CoreException; - - /** - * Tries to find the EMF {@link GenModel} for a selected {@link EPackage}. - * The context object is used for determining the actual project. - * - * @param ePackage - * @return the corresponding {@link GenPackage} for the selected - * {@link EPackage} - */ - GenPackage findGenPackage(EObject context, EPackage ePackage); - - /** - * Tries to find the EMF {@link GenModel} for a selected {@link EPackage}. - * The resource set is expected to be the one Xtext assigns for a Java - * project. - * - * @param packageNsUri - * @return the corresponding {@link GenPackage} for the selected - * {@link EPackage} - */ - GenPackage findGenPackage(ResourceSet set, final String packageNsUri); - /** - * Tries to find the EMF {@link GenModel} for a selected {@link EPackage}. - * The resource set is expected to be the one Xtext assigns for a Java - * project. - * - * @param packageNsUri - * @return the corresponding {@link GenPackage} for the selected - * {@link EPackage} - */ - GenPackage findGenPackage(ResourceSet set, final EPackage ePackage); - - /** - * Tries to find the EMF {@link GenModel} for a selected {@link EPackage}. - * The context object is used for determining the actual project. - * - * @param packageNsUri - * @return the corresponding {@link GenPackage} for the selected - * {@link EPackage} - */ - GenPackage findGenPackage(EObject ctx, final String packageNsUri); + /** + * Saves the changes to the generator model instance in the selected project. The provider assumes that the genmodel + * was instantiated by using the {@link #getGeneratorModel(EObject)} or the + * {@link #getGeneratorModel(IProject, ResourceSet)} methods. + * + * @throws IOException + */ + void saveGeneratorModel(IProject project, IncQueryGeneratorModel generatorModel) throws IOException; + + /** + * Collects all EPackage objects available from a selected project, including the ones from the EPackage Registry. + * If the project features an eiqgen files, the packages referenced there are also included. + * + * @param project + * @return a non-null collection of packages + * @throws CoreException + */ + Collection getAllMetamodelObjects(IProject project) throws CoreException; + + /** + * Tries to find the EMF {@link GenModel} for a selected {@link EPackage}. The context object is used for + * determining the actual project. + * + * @param ePackage + * @return the corresponding {@link GenPackage} for the selected {@link EPackage} + */ + GenPackage findGenPackage(EObject context, EPackage ePackage); + + /** + * Tries to find the EMF {@link GenModel} for a selected {@link EPackage}. The resource set is expected to be the + * one Xtext assigns for a Java project. + * + * @param packageNsUri + * @return the corresponding {@link GenPackage} for the selected {@link EPackage} + */ + GenPackage findGenPackage(ResourceSet set, final String packageNsUri); + + /** + * Tries to find the EMF {@link GenModel} for a selected {@link EPackage}. The resource set is expected to be the + * one Xtext assigns for a Java project. + * + * @param packageNsUri + * @return the corresponding {@link GenPackage} for the selected {@link EPackage} + */ + GenPackage findGenPackage(ResourceSet set, final EPackage ePackage); + + /** + * Tries to find the EMF {@link GenModel} for a selected {@link EPackage}. The context object is used for + * determining the actual project. + * + * @param packageNsUri + * @return the corresponding {@link GenPackage} for the selected {@link EPackage} + */ + GenPackage findGenPackage(EObject ctx, final String packageNsUri); } diff --git a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/jvmmodel/EMFPatternJvmModelAssociator.java b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/jvmmodel/EMFPatternJvmModelAssociator.java index 8afcd8f4..66ca7ec2 100644 --- a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/jvmmodel/EMFPatternJvmModelAssociator.java +++ b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/jvmmodel/EMFPatternJvmModelAssociator.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.core.generator.jvmmodel; - +package org.eclipse.incquery.tooling.core.generator.jvmmodel; + import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; @@ -23,39 +23,37 @@ import org.eclipse.xtext.xbase.jvmmodel.JvmModelAssociator; import com.google.inject.Inject; - -/** - * This subClass is needed for local variable scoping. PatternBody not associated with any Inferred classes. - * - * @author Mark Czotter - * - */ + +/** + * This subClass is needed for local variable scoping. PatternBody not associated with any Inferred classes. + * + * @author Mark Czotter + * + */ @SuppressWarnings("restriction") -public class EMFPatternJvmModelAssociator extends JvmModelAssociator { - - @Inject - private IErrorFeedback feedback; - - @Override - public JvmIdentifiableElement getLogicalContainer(EObject object) { - if (object instanceof PatternBody) { - return null; - } - return super.getLogicalContainer(object); - } - - @Override - public void installDerivedState(DerivedStateAwareResource resource, - boolean preIndexingPhase) { - if (!resource.getURI().isEmpty() && resource.getURI().isPlatformResource()) { - IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); - IFile file = root.getFile(new Path(resource.getURI() - .toPlatformString(true))); - if (file.exists()) { - feedback.clearMarkers(file, IErrorFeedback.JVMINFERENCE_ERROR_TYPE); - } - } - super.installDerivedState(resource, preIndexingPhase); - } - -} +public class EMFPatternJvmModelAssociator extends JvmModelAssociator { + + @Inject + private IErrorFeedback feedback; + + @Override + public JvmIdentifiableElement getLogicalContainer(EObject object) { + if (object instanceof PatternBody) { + return null; + } + return super.getLogicalContainer(object); + } + + @Override + public void installDerivedState(DerivedStateAwareResource resource, boolean preIndexingPhase) { + if (!resource.getURI().isEmpty() && resource.getURI().isPlatformResource()) { + IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); + IFile file = root.getFile(new Path(resource.getURI().toPlatformString(true))); + if (file.exists()) { + feedback.clearMarkers(file, IErrorFeedback.JVMINFERENCE_ERROR_TYPE); + } + } + super.installDerivedState(resource, preIndexingPhase); + } + +} diff --git a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/types/GenModelBasedTypeProvider.java b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/types/GenModelBasedTypeProvider.java index e41d20a5..ce600e64 100644 --- a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/types/GenModelBasedTypeProvider.java +++ b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/types/GenModelBasedTypeProvider.java @@ -31,83 +31,84 @@ import com.google.inject.Singleton; /** - * An extension of the {@link EMFPatternTypeProvider}, which can use the - * genmodel informations as well, if it is present. The main logic for the type - * inference is implemented in the {@link EMFPatternTypeProvider}. + * An extension of the {@link EMFPatternTypeProvider}, which can use the genmodel informations as well, if it is + * present. The main logic for the type inference is implemented in the {@link EMFPatternTypeProvider}. */ @Singleton @SuppressWarnings("restriction") public class GenModelBasedTypeProvider extends EMFPatternTypeProvider { - @Inject - private IEiqGenmodelProvider genModelProvider; + @Inject + private IEiqGenmodelProvider genModelProvider; - @Inject - private IErrorFeedback errorFeedback; + @Inject + private IErrorFeedback errorFeedback; - @Inject - private TypeReferences typeReferences; + @Inject + private TypeReferences typeReferences; - @Inject - private Primitives primitives; + @Inject + private Primitives primitives; - @Override - protected JvmTypeReference getTypeReferenceForVariableWithEClassifier(EClassifier classifier, Variable variable) { - JvmTypeReference typeReference = super.getTypeReferenceForVariableWithEClassifier(classifier, variable); - if (typeReference == null && classifier != null) { - EPackage ePackage = classifier.getEPackage(); - if (ePackage != null) { - GenPackage genPackage = genModelProvider.findGenPackage(variable, ePackage); - if (genPackage != null) { - typeReference = resolveTypeReference(genPackage, classifier, variable); - } - } - } - return typeReference; - } + @Override + protected JvmTypeReference getTypeReferenceForVariableWithEClassifier(EClassifier classifier, Variable variable) { + JvmTypeReference typeReference = super.getTypeReferenceForVariableWithEClassifier(classifier, variable); + if (typeReference == null && classifier != null) { + EPackage ePackage = classifier.getEPackage(); + if (ePackage != null) { + GenPackage genPackage = genModelProvider.findGenPackage(variable, ePackage); + if (genPackage != null) { + typeReference = resolveTypeReference(genPackage, classifier, variable); + } + } + } + return typeReference; + } - /** - * Resolves the {@link Variable} using information from the - * {@link GenPackage}. Tries to find an appropriate {@link GenClass} for the - * {@link EClassifier}. If one is found, then returns a - * {@link JvmTypeReference} for it's qualified interface name. - * - * @param genPackage - * @param classifier - * @param variable - * @return - */ - private JvmTypeReference resolveTypeReference(GenPackage genPackage, EClassifier classifier, Variable variable) { - GenClass genClass = findGenClass(genPackage, classifier); - if (genClass != null) { - JvmTypeReference typeReference = getTypeReferenceForTypeName(genClass.getQualifiedInterfaceName(), variable); - if (typeReference == null) { - EObject context = variable; - if (variable.eContainer() instanceof PatternBody && variable.getReferences().size() > 0) { - context = variable.getReferences().get(0); - } - errorFeedback.reportError(context, String.format( - "Cannot resolve corresponding Java type for variable %s. Are the required bundle dependencies set?", - variable.getName()), GeneratorIssueCodes.INVALID_TYPEREF_CODE, Severity.WARNING, - IErrorFeedback.JVMINFERENCE_ERROR_TYPE); - } - return typeReference; - } - return null; - } + /** + * Resolves the {@link Variable} using information from the {@link GenPackage}. Tries to find an appropriate + * {@link GenClass} for the {@link EClassifier}. If one is found, then returns a {@link JvmTypeReference} for it's + * qualified interface name. + * + * @param genPackage + * @param classifier + * @param variable + * @return + */ + private JvmTypeReference resolveTypeReference(GenPackage genPackage, EClassifier classifier, Variable variable) { + GenClass genClass = findGenClass(genPackage, classifier); + if (genClass != null) { + JvmTypeReference typeReference = getTypeReferenceForTypeName(genClass.getQualifiedInterfaceName(), variable); + if (typeReference == null) { + EObject context = variable; + if (variable.eContainer() instanceof PatternBody && variable.getReferences().size() > 0) { + context = variable.getReferences().get(0); + } + errorFeedback + .reportError( + context, + String.format( + "Cannot resolve corresponding Java type for variable %s. Are the required bundle dependencies set?", + variable.getName()), GeneratorIssueCodes.INVALID_TYPEREF_CODE, + Severity.WARNING, IErrorFeedback.JVMINFERENCE_ERROR_TYPE); + } + return typeReference; + } + return null; + } - private GenClass findGenClass(GenPackage genPackage, EClassifier classifier) { - for (GenClass genClass : genPackage.getGenClasses()) { - if (classifier.equals(genClass.getEcoreClassifier())) { - return genClass; - } - } - return null; - } + private GenClass findGenClass(GenPackage genPackage, EClassifier classifier) { + for (GenClass genClass : genPackage.getGenClasses()) { + if (classifier.equals(genClass.getEcoreClassifier())) { + return genClass; + } + } + return null; + } - private JvmTypeReference getTypeReferenceForTypeName(String typeName, Variable variable) { - JvmTypeReference typeRef = typeReferences.getTypeForName(typeName, variable); - return primitives.asWrapperTypeIfPrimitive(typeRef); - } + private JvmTypeReference getTypeReferenceForTypeName(String typeName, Variable variable) { + JvmTypeReference typeRef = typeReferences.getTypeForName(typeName, variable); + return primitives.asWrapperTypeIfPrimitive(typeRef); + } } diff --git a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/util/EMFJvmTypesBuilder.java b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/util/EMFJvmTypesBuilder.java index 0453eff3..957089da 100644 --- a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/util/EMFJvmTypesBuilder.java +++ b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/util/EMFJvmTypesBuilder.java @@ -9,8 +9,8 @@ * Mark Czotter - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.core.generator.util; - +package org.eclipse.incquery.tooling.core.generator.util; + import org.apache.log4j.Logger; import org.eclipse.emf.ecore.EObject; import org.eclipse.xtext.common.types.JvmLowerBound; @@ -25,87 +25,86 @@ import com.google.common.base.Preconditions; import com.google.inject.Inject; - -/** - * Custom {@link JvmTypesBuilder} for EMFPatternLanguage. - * - * @author Mark Czotter - * - */ -@SuppressWarnings("restriction") -public class EMFJvmTypesBuilder extends JvmTypesBuilder { - - @Inject - private TypesFactory factory = TypesFactory.eINSTANCE; - - @Inject - private TypeReferences typeReferences; - @Inject - private Logger logger; - - /** - * Creates a {@link JvmWildcardTypeReference} with a {@link JvmLowerBound} - * constraint to 'clone' parameter. - * - * @param clone - * @return {@link JvmWildcardTypeReference} with a {@link JvmLowerBound} - * contraint. - */ - public JvmWildcardTypeReference wildCardSuper(JvmTypeReference clone) { - JvmWildcardTypeReference result = factory.createJvmWildcardTypeReference(); - JvmLowerBound lowerBound = factory.createJvmLowerBound(); - lowerBound.setTypeReference(clone); - result.getConstraints().add(lowerBound); - return result; - } - - /** - * Creates a JvmTypeReference, that does not have any type parameter (serialized as a raw type). - * @return - */ - public JvmTypeReference newRawTypeRef(EObject ctx, Class clazz, JvmTypeReference... typeArgs) { - Preconditions.checkNotNull(clazz, "clazz"); - - JvmType declaredType = typeReferences.findDeclaredType(clazz, ctx); - if (declaredType == null) { - return null; - } - return createTypeRef(declaredType); - } - - /** - * Creates a JvmTypeReference, that does not have any type parameter (serialized as a raw type). - * @return - */ - public JvmTypeReference newRawTypeRef(EObject ctx, String typeName, JvmTypeReference... typeArgs) { - Preconditions.checkNotNull(typeName, "typeName"); - Preconditions.checkNotNull(ctx, "context"); - - JvmType declaredType = typeReferences.findDeclaredType(typeName, ctx); - if (declaredType == null) { - return null; - } - return createTypeRef(declaredType); - } - - private JvmTypeReference createTypeRef(JvmType type) { - JvmParameterizedTypeReference reference = factory.createJvmParameterizedTypeReference(); - reference.setType(type); - return reference; - } - - /** - * Overriding parent method to replace logging - * {@inheritDoc} - */ - protected T initializeSafely(T targetElement, Procedure1 initializer) { - if(targetElement != null && initializer != null) { - try { - initializer.apply(targetElement); - } catch (Exception e) { - logger.error("Error initializing JvmElement", e); - } - } - return targetElement; - } -} + +/** + * Custom {@link JvmTypesBuilder} for EMFPatternLanguage. + * + * @author Mark Czotter + * + */ +@SuppressWarnings("restriction") +public class EMFJvmTypesBuilder extends JvmTypesBuilder { + + @Inject + private TypesFactory factory = TypesFactory.eINSTANCE; + + @Inject + private TypeReferences typeReferences; + @Inject + private Logger logger; + + /** + * Creates a {@link JvmWildcardTypeReference} with a {@link JvmLowerBound} constraint to 'clone' parameter. + * + * @param clone + * @return {@link JvmWildcardTypeReference} with a {@link JvmLowerBound} contraint. + */ + public JvmWildcardTypeReference wildCardSuper(JvmTypeReference clone) { + JvmWildcardTypeReference result = factory.createJvmWildcardTypeReference(); + JvmLowerBound lowerBound = factory.createJvmLowerBound(); + lowerBound.setTypeReference(clone); + result.getConstraints().add(lowerBound); + return result; + } + + /** + * Creates a JvmTypeReference, that does not have any type parameter (serialized as a raw type). + * + * @return + */ + public JvmTypeReference newRawTypeRef(EObject ctx, Class clazz, JvmTypeReference... typeArgs) { + Preconditions.checkNotNull(clazz, "clazz"); + + JvmType declaredType = typeReferences.findDeclaredType(clazz, ctx); + if (declaredType == null) { + return null; + } + return createTypeRef(declaredType); + } + + /** + * Creates a JvmTypeReference, that does not have any type parameter (serialized as a raw type). + * + * @return + */ + public JvmTypeReference newRawTypeRef(EObject ctx, String typeName, JvmTypeReference... typeArgs) { + Preconditions.checkNotNull(typeName, "typeName"); + Preconditions.checkNotNull(ctx, "context"); + + JvmType declaredType = typeReferences.findDeclaredType(typeName, ctx); + if (declaredType == null) { + return null; + } + return createTypeRef(declaredType); + } + + private JvmTypeReference createTypeRef(JvmType type) { + JvmParameterizedTypeReference reference = factory.createJvmParameterizedTypeReference(); + reference.setType(type); + return reference; + } + + /** + * Overriding parent method to replace logging {@inheritDoc} + */ + protected T initializeSafely(T targetElement, Procedure1 initializer) { + if (targetElement != null && initializer != null) { + try { + initializer.apply(targetElement); + } catch (Exception e) { + logger.error("Error initializing JvmElement", e); + } + } + return targetElement; + } +} diff --git a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/util/EMFPatternURIHandler.java b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/util/EMFPatternURIHandler.java index 36506276..2f25eddc 100644 --- a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/util/EMFPatternURIHandler.java +++ b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/util/EMFPatternURIHandler.java @@ -9,41 +9,41 @@ * Mark Czotter - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.core.generator.util; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.emf.common.util.URI; -import org.eclipse.emf.ecore.EPackage; -import org.eclipse.emf.ecore.xmi.impl.URIHandlerImpl; - -public class EMFPatternURIHandler extends URIHandlerImpl { - - private final Map uriToEPackageMap = new HashMap(); - - public EMFPatternURIHandler(Collection packages) { - for (EPackage e : packages) { - if (e.eResource() != null) { - uriToEPackageMap.put(e.eResource().getURI(), e); - } - } - } - - @Override - public URI deresolve(URI uri) { - if (uri.isPlatform()) { - String fragment = uri.fragment(); - URI fragmentRemoved = uri.trimFragment(); - EPackage p = uriToEPackageMap.get(fragmentRemoved); - if (p != null) { - URI newURI = URI.createURI(p.getNsURI()); - newURI = newURI.appendFragment(fragment); - return newURI; - } - } - return super.deresolve(uri); - } - -} +package org.eclipse.incquery.tooling.core.generator.util; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.xmi.impl.URIHandlerImpl; + +public class EMFPatternURIHandler extends URIHandlerImpl { + + private final Map uriToEPackageMap = new HashMap(); + + public EMFPatternURIHandler(Collection packages) { + for (EPackage e : packages) { + if (e.eResource() != null) { + uriToEPackageMap.put(e.eResource().getURI(), e); + } + } + } + + @Override + public URI deresolve(URI uri) { + if (uri.isPlatform()) { + String fragment = uri.fragment(); + URI fragmentRemoved = uri.trimFragment(); + EPackage p = uriToEPackageMap.get(fragmentRemoved); + if (p != null) { + URI newURI = URI.createURI(p.getNsURI()); + newURI = newURI.appendFragment(fragment); + return newURI; + } + } + return super.deresolve(uri); + } + +} diff --git a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/util/XMIResourceURIHandler.java b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/util/XMIResourceURIHandler.java index eabed058..cbfe5ecb 100644 --- a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/util/XMIResourceURIHandler.java +++ b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/generator/util/XMIResourceURIHandler.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.core.generator.util; - +package org.eclipse.incquery.tooling.core.generator.util; + import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.resource.ResourceSet; @@ -18,33 +18,33 @@ import org.eclipse.incquery.patternlanguage.emf.scoping.IMetamodelProvider; import com.google.inject.Inject; - + /** - * Helper class for loading XMI resources using information available in - * + * Helper class for loading XMI resources using information available in + * */ -public class XMIResourceURIHandler extends URIHandlerImpl { - - @Inject - IMetamodelProvider metamodelProvider; - private ResourceSet set; - - public XMIResourceURIHandler(ResourceSet set) { - this.set = set; - } - - @Override - public URI resolve(URI uri) { - if (uri.isRelative()) { - return super.resolve(uri); - } - if(!uri.isPlatform()) { - EPackage epackage = metamodelProvider.loadEPackage(uri.trimFragment().toString(), set); - if (epackage != null) { - return epackage.eResource().getURI().appendFragment(uri.fragment()); - } - } - return super.resolve(uri); - } - -} +public class XMIResourceURIHandler extends URIHandlerImpl { + + @Inject + IMetamodelProvider metamodelProvider; + private ResourceSet set; + + public XMIResourceURIHandler(ResourceSet set) { + this.set = set; + } + + @Override + public URI resolve(URI uri) { + if (uri.isRelative()) { + return super.resolve(uri); + } + if (!uri.isPlatform()) { + EPackage epackage = metamodelProvider.loadEPackage(uri.trimFragment().toString(), set); + if (epackage != null) { + return epackage.eResource().getURI().appendFragment(uri.fragment()); + } + } + return super.resolve(uri); + } + +} diff --git a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/project/CollectDeletedElement.java b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/project/CollectDeletedElement.java index a72f8673..58bccfb2 100644 --- a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/project/CollectDeletedElement.java +++ b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/project/CollectDeletedElement.java @@ -19,15 +19,14 @@ import org.eclipse.core.runtime.CoreException; class CollectDeletedElement implements IResourceVisitor { - List toDelete = new ArrayList(); - @Override - public boolean visit(IResource resource) throws CoreException { - if (resource instanceof IFile - && "java".equalsIgnoreCase(((IFile) resource) - .getFileExtension())) { - toDelete.add(resource); - return false; - } - return true; - } + List toDelete = new ArrayList(); + + @Override + public boolean visit(IResource resource) throws CoreException { + if (resource instanceof IFile && "java".equalsIgnoreCase(((IFile) resource).getFileExtension())) { + toDelete.add(resource); + return false; + } + return true; + } } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/project/IncQueryNature.java b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/project/IncQueryNature.java index de6b6f44..5ffdb542 100644 --- a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/project/IncQueryNature.java +++ b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/project/IncQueryNature.java @@ -22,41 +22,38 @@ */ public class IncQueryNature implements IProjectNature { - /** - * The project nature identifier used for defining the project nature of an - * IncQuery project. - */ + /** + * The project nature identifier used for defining the project nature of an IncQuery project. + */ public static final String NATURE_ID = "org.eclipse.incquery.projectnature"; //$NON-NLS-1$ public static final String BUNDLE_ID = "org.eclipse.incquery.tooling.core"; //$NON-NLS-1$ public static final String BUILDER_ID = BUNDLE_ID + ".projectbuilder";//$NON-NLS-1$ - public static final String SRCGEN_DIR = "src-gen/"; //$NON-NLS-1$ - public static final String SRC_DIR = "src/"; //$NON-NLS-1$ - public static final String EXECUTION_ENVIRONMENT = "JavaSE-1.6"; //$NON_NLS-1$ - public static final String IQGENMODEL = "generator.eiqgen"; - - private IProject project; + public static final String SRCGEN_DIR = "src-gen/"; //$NON-NLS-1$ + public static final String SRC_DIR = "src/"; //$NON-NLS-1$ + public static final String EXECUTION_ENVIRONMENT = "JavaSE-1.6"; // $NON_NLS-1$ + public static final String IQGENMODEL = "generator.eiqgen"; - /* - * (non-Javadoc) - * - * @see org.eclipse.core.resources.IProjectNature#getProject() - */ - public IProject getProject() { - return project; - } + private IProject project; - /* - * (non-Javadoc) - * - * @see - * org.eclipse.core.resources.IProjectNature#setProject(org.eclipse.core - * .resources.IProject) - */ - public void setProject(IProject project) { - this.project = project; - } + /* + * (non-Javadoc) + * + * @see org.eclipse.core.resources.IProjectNature#getProject() + */ + public IProject getProject() { + return project; + } - public void configure() throws CoreException { + /* + * (non-Javadoc) + * + * @see org.eclipse.core.resources.IProjectNature#setProject(org.eclipse.core .resources.IProject) + */ + public void setProject(IProject project) { + this.project = project; + } + + public void configure() throws CoreException { IProjectDescription desc = project.getDescription(); ICommand[] commands = desc.getBuildSpec(); for (int i = 0; i < commands.length; i++) { @@ -72,9 +69,9 @@ public void configure() throws CoreException { newCommandList[commands.length] = command; desc.setBuildSpec(newCommandList); project.setDescription(desc, null); - } + } - public void deconfigure() throws CoreException { + public void deconfigure() throws CoreException { IProjectDescription desc = project.getDescription(); ICommand[] commands = desc.getBuildSpec(); int index = 0; @@ -94,6 +91,6 @@ public void deconfigure() throws CoreException { newCommandList[commands.length] = command; desc.setBuildSpec(newCommandList); project.setDescription(desc, null); - } + } } diff --git a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/project/ProjectGenerationHelper.java b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/project/ProjectGenerationHelper.java index e6dae36a..88b8a372 100644 --- a/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/project/ProjectGenerationHelper.java +++ b/plugins/org.eclipse.incquery.tooling.core/src/org/eclipse/incquery/tooling/core/project/ProjectGenerationHelper.java @@ -72,753 +72,703 @@ @SuppressWarnings("restriction") public abstract class ProjectGenerationHelper { - private static final String INVALID_PROJECT_MESSAGE = "Only existing, open plug-in projects are supported by the generator."; - - private static final class IDToRequireBundleTransformer implements - Function { - private final IBundleProjectService service; - - private IDToRequireBundleTransformer(IBundleProjectService service) { - this.service = service; - } - - @Override - public IRequiredBundleDescription apply(String input) { - return service.newRequiredBundle(input, null, false, false); - } - } - - /** - * Two source folders: src to be manually written and src-gen to contain - * generated code - */ - public static final List SOURCEFOLDERS = ImmutableList.of( - IncQueryNature.SRC_DIR, IncQueryNature.SRCGEN_DIR); - /** - * A single source folder named src - */ - public static final List SINGLESOURCEFOLDER = ImmutableList.of( "src" ); - - /** - * Creates a new IncQuery project: a plug-in project with src and src-gen - * folders and specific dependencies. - * - * @param description - * @param proj - * @param monitor - * @throws CoreException - * @throws OperationCanceledException - */ - public static void createProject(IProjectDescription description, - IProject proj, List additionalDependencies, IProgressMonitor monitor) throws CoreException { - List dependencies = Lists.newArrayList("org.eclipse.pde.core", "org.eclipse.emf.ecore", - "org.eclipse.emf.transaction", IncQueryRuntimePlugin.PLUGIN_ID, - "org.eclipse.xtext.xbase.lib"); - if (additionalDependencies != null) { - dependencies.addAll(additionalDependencies); - } - BundleContext context = null; - ServiceReference ref = null; - - try { - - monitor.beginTask("", 2000); - /* Creating plug-in information */ - context = IncQueryGeneratorPlugin.getContext(); - ref = context.getServiceReference(IBundleProjectService.class); - final IBundleProjectService service = context.getService(ref); - IBundleProjectDescription bundleDesc = service.getDescription(proj); - IPath[] additionalBinIncludes = new IPath[] { - new Path("plugin.xml"), new Path("queries/") }; - ProjectGenerationHelper.fillProjectMetadata(proj, dependencies, - service, bundleDesc, additionalBinIncludes); - bundleDesc.apply(monitor); - // Adding IncQuery-specific natures - ProjectGenerationHelper.addNatures(proj, new String[] { - IncQueryNature.NATURE_ID, - "org.eclipse.xtext.ui.shared.xtextNature" }, monitor); - } finally { - monitor.done(); - if (context != null && ref != null) { - context.ungetService(ref); - } - } - } - - /** - * Adds a collection of natures to the project - * - * @param proj - * @param natures - * @param monitor - * @return - * @throws CoreException - */ - public static IProjectDescription addNatures(IProject proj, - String[] natures, IProgressMonitor monitor) throws CoreException { - IProjectDescription desc = proj.getDescription(); - List newNatures = new ArrayList(); - newNatures.addAll(Arrays.asList(desc.getNatureIds())); - newNatures.addAll(Arrays.asList(natures)); - desc.setNatureIds(newNatures.toArray(new String[newNatures.size()])); - proj.setDescription(desc, monitor); - return desc; - } - - /** - * Adds a file to a container. - * - * @param container - * the container to add the file to - * @param path - * the path of the newly created file - * @param contentStream - * the file will be filled with this stream's contents - * @param monitor - * @throws CoreException - */ - public static void addFileToProject(IContainer container, Path path, - InputStream contentStream, IProgressMonitor monitor) - throws CoreException { - final IFile file = container.getFile(path); - - if (file.exists()) { - file.setContents(contentStream, true, true, monitor); - } else { - file.create(contentStream, true, monitor); - } - - } - - /** - * @param folder - * @param monitor - * @throws CoreException - */ - public static void deleteJavaFiles(IFolder folder, - final IProgressMonitor monitor) throws CoreException { - folder.refreshLocal(IResource.DEPTH_INFINITE, monitor); - CollectDeletedElement visitor = new CollectDeletedElement(); - folder.accept(visitor); - for (IResource res : visitor.toDelete) { - res.delete(false, new SubProgressMonitor(monitor, 1)); - } - } - - public static void initializePluginProject(IProject project, - final List dependencies, final IPath[] additionalBinIncludes) throws CoreException { - initializePluginProject(project, dependencies, additionalBinIncludes, - new NullProgressMonitor()); - } - - public static void initializePluginProject(IProject project, - final List dependencies, final IPath[] additionalBinIncludes, IProgressMonitor monitor) - throws CoreException { - BundleContext context = null; - ServiceReference ref = null; - try { - context = IncQueryGeneratorPlugin.getContext(); - ref = context.getServiceReference(IBundleProjectService.class); - final IBundleProjectService service = context.getService(ref); - IBundleProjectDescription bundleDesc = service - .getDescription(project); - fillProjectMetadata(project, dependencies, service, bundleDesc, additionalBinIncludes); - bundleDesc.apply(monitor); - } finally { - if (context != null && ref != null) { - context.ungetService(ref); - } - } - } - - /** - * Initializes the plug-in metadata of a newly created project. - * - * @param project - * the plug-in project to create the metadata for. The plug-in id - * will be the same as the project name - * @param dependencies - * a list of required bundles to add - * @param service - * @param bundleDesc - */ - public static void fillProjectMetadata(IProject project, - final List dependencies, - final IBundleProjectService service, - IBundleProjectDescription bundleDesc, - final IPath[] additionalBinIncludes) { - bundleDesc.setBundleName(project.getName()); - bundleDesc.setBundleVersion(new Version(0, 0, 1, "qualifier")); - bundleDesc.setSingleton(true); - bundleDesc.setTargetVersion(IBundleProjectDescription.VERSION_3_6); - bundleDesc.setSymbolicName(project.getName()); - bundleDesc.setExtensionRegistry(true); - bundleDesc.setBinIncludes(additionalBinIncludes); - - bundleDesc.setBundleClasspath(getUpdatedBundleClasspathEntries(new IBundleClasspathEntry[0], service)); - bundleDesc - .setExecutionEnvironments(new String[] { IncQueryNature.EXECUTION_ENVIRONMENT }); - // Adding dependencies - IRequiredBundleDescription[] reqBundles = Lists.transform(dependencies, - new IDToRequireBundleTransformer(service)).toArray( - new IRequiredBundleDescription[dependencies.size()]); - bundleDesc.setRequiredBundles(reqBundles); - } - - /** - * Checks whether the project depends on a selected bundle ID - * @param project an existing, open plug-in project to check - * @param dependency bundle identifier - * @return true, if the project depends on the given bundle - * @throws CoreException - */ - public static boolean checkBundleDependency(IProject project, String dependency) throws CoreException { - Preconditions.checkArgument(project.exists() && project.isOpen() && (PDE.hasPluginNature(project)), - INVALID_PROJECT_MESSAGE); - BundleContext context = null; - ServiceReference ref = null; - try { - context = IncQueryGeneratorPlugin.getContext(); - ref = context.getServiceReference(IBundleProjectService.class); - final IBundleProjectService service = context.getService(ref); - IBundleProjectDescription bundleDesc = service - .getDescription(project); - for (IRequiredBundleDescription require : bundleDesc.getRequiredBundles()) { - if (dependency.equals(require.getName())) { - return true; - } - } - return false; - } finally { - if (context != null && ref != null) { - context.ungetService(ref); - } - } - } - - /** - * Updates project manifest to ensure the selected bundle dependencies are - * set. Does not change existing dependencies. - * - * @param project - * @param dependencies - * @throws CoreException - */ - public static void ensureBundleDependencies(IProject project, - final List dependencies) throws CoreException { - ensureBundleDependencies(project, dependencies, - new NullProgressMonitor()); - } - - /** - * Updates project manifest to ensure the selected bundle dependencies are - * set. Does not change existing dependencies. - * - * @param project an existing, open PDE plug-in project - * @param dependencies - * @param monitor - * @throws CoreException - */ - public static void ensureBundleDependencies(IProject project, - final List dependencies, IProgressMonitor monitor) - throws CoreException { - Preconditions.checkArgument(project.exists() && project.isOpen() && (PDE.hasPluginNature(project)), - INVALID_PROJECT_MESSAGE); - if (dependencies.isEmpty()) { - return; - } - BundleContext context = null; - ServiceReference ref = null; - try { - context = IncQueryGeneratorPlugin.getContext(); - ref = context.getServiceReference(IBundleProjectService.class); - final IBundleProjectService service = context.getService(ref); - IBundleProjectDescription bundleDesc = service - .getDescription(project); - ensureBundleDependencies(service, bundleDesc, dependencies); - bundleDesc.apply(monitor); - } finally { - if (context != null && ref != null) { - context.ungetService(ref); - } - } - } - - /** - * Updates project manifest to ensure the selected bundle dependencies are - * set. Does not change existing dependencies. - * @param service - * @param bundleDesc - * @param dependencies - */ - static void ensureBundleDependencies(IBundleProjectService service, - IBundleProjectDescription bundleDesc, - final List dependencies) { - IRequiredBundleDescription[] requiredBundles = bundleDesc - .getRequiredBundles(); - List missingDependencies = new ArrayList(dependencies); - if (requiredBundles != null) { - for (IRequiredBundleDescription bundle : requiredBundles) { - if (missingDependencies.contains(bundle.getName())) { - missingDependencies.remove(bundle.getName()); - } - } - } - bundleDesc.setRequiredBundles(Lists.transform(missingDependencies, - new IDToRequireBundleTransformer(service)).toArray( - new IRequiredBundleDescription[missingDependencies.size()])); - } - - /** - * Updates project manifest to ensure the selected packages are exported. - * Does not change existing exports. - * - * @param project - * @param dependencies - * @throws CoreException - */ - public static void ensurePackageExports(IProject project, - final Collection dependencies) throws CoreException { - ensurePackageExports(project, dependencies, new NullProgressMonitor()); - } - - /** - * Updates project manifest to ensure the selected packages are exported. - * Does not change existing exports. - * - * @param project an existing, open PDE plug-in project - * @param exports a non-empty list of package exports - * @param monitor - * @throws CoreException - */ - public static void ensurePackageExports(IProject project, - final Collection exports, IProgressMonitor monitor) - throws CoreException { - Preconditions.checkArgument(project.exists() && project.isOpen() && (PDE.hasPluginNature(project)), - INVALID_PROJECT_MESSAGE); - if (exports.isEmpty()) { - return; - } - - BundleContext context = null; - ServiceReference ref = null; - try { - context = IncQueryGeneratorPlugin.getContext(); - ref = context.getServiceReference(IBundleProjectService.class); - final IBundleProjectService service = context.getService(ref); - IBundleProjectDescription bundleDesc = service - .getDescription(project); - ensurePackageExports(service, bundleDesc, exports); - bundleDesc.apply(monitor); - } finally { - if (context != null && ref != null) { - context.ungetService(ref); - } - } - } - - /** - * Updates project manifest to ensure the selected packages are removed. - * Does not change existing exports. - * - * @param project an existing, open plug-in project - * @param dependencies - * @param monitor - * @throws CoreException - */ - public static void removePackageExports(IProject project, - final List dependencies, IProgressMonitor monitor) - throws CoreException { - Preconditions.checkArgument(project.exists() && project.isOpen() && (PDE.hasPluginNature(project)), - INVALID_PROJECT_MESSAGE); - if (dependencies.isEmpty()) { - return; - } - - BundleContext context = null; - ServiceReference ref = null; - try { - context = IncQueryGeneratorPlugin.getContext(); - ref = context.getServiceReference(IBundleProjectService.class); - final IBundleProjectService service = context.getService(ref); - IBundleProjectDescription bundleDesc = service - .getDescription(project); - removePackageExports(service, bundleDesc, dependencies); - bundleDesc.apply(monitor); - } finally { - if (context != null && ref != null) { - context.ungetService(ref); - } - } - } - - /** - * Updates project manifest to ensure the selected packages are exported. - * Does not change existing exports. - * - * @param service - * @param bundleDesc - * @param exports - */ - static void ensurePackageExports( - final IBundleProjectService service, - IBundleProjectDescription bundleDesc, final Collection exports) { - IPackageExportDescription[] packageExports = bundleDesc - .getPackageExports(); - List missingExports = new ArrayList(exports); - List exportList = new ArrayList(); - if (packageExports != null) { - for (IPackageExportDescription export : packageExports) { - if (!missingExports.contains(export.getName())) { - missingExports.remove(export.getName()); - } - exportList.add(export); - } - } - exportList.addAll(Lists.transform(missingExports, - new Function() { - - @Override - public IPackageExportDescription apply(String input) { - return service - .newPackageExport(input, null, true, null); - } - })); - - bundleDesc.setPackageExports(exportList - .toArray(new IPackageExportDescription[exportList.size()])); - } - - /** - * Updates project manifest to ensure the selected packages are removed. - * Does not change existing exports. - * - * @param service - * @param bundleDesc - * @param exports - */ - static void removePackageExports( - final IBundleProjectService service, - IBundleProjectDescription bundleDesc, final List exports) { - IPackageExportDescription[] packageExports = bundleDesc - .getPackageExports(); - List exportList = new ArrayList(); - if (packageExports != null) { - for (IPackageExportDescription export : packageExports) { - if (!exports.contains(export.getName())) { - exportList.add(export); - } - } - } - bundleDesc.setPackageExports(exportList - .toArray(new IPackageExportDescription[exportList.size()])); - } - - /** - * Updates the selected project to contain the selected extension. The - * extensions are identified using an identifier and extension point - * together; old extensions are replaced with the new ones, other extensions - * are kept intact. - * - * @param project - * @param contributedExtensions - * @throws CoreException - */ - public static void ensureExtensions(IProject project, - Iterable contributedExtensions, Iterable> removedExtensions) - throws CoreException { - ensureExtensions(project, contributedExtensions, removedExtensions, - new NullProgressMonitor()); - } - - /** - * Updates the selected project to contain the selected extension. The - * extensions are identified using an identifier and extension point - * together; old extensions are replaced with the new ones, other extensions - * are kept intact. An extension will be ignored, if exist in the removedExtensions list. - * - * @param project an existing, open PDE plug-in project - * @param contributedExtensions - * @param removedExtensions - * @param monitor - * @throws CoreException - */ - public static void ensureExtensions(IProject project, - Iterable contributedExtensions, Iterable> removedExtensions, - IProgressMonitor monitor) throws CoreException { - Preconditions.checkArgument(project.exists() && project.isOpen() && (PDE.hasPluginNature(project)), - INVALID_PROJECT_MESSAGE); - - if (StringExtensions.isNullOrEmpty(project.getName())) { - return; - } - Multimap extensionMap = ArrayListMultimap - .create(); - for (IPluginExtension extension : contributedExtensions) { - extensionMap.put(extension.getId(), extension); - } - // XXX Using two APIs to extension generation: one to read and one to - // write - IFile pluginXml = PDEProject.getPluginXml(project); - IPluginModel plugin = (IPluginModel) PDECore.getDefault() - .getModelManager().findModel(project); - WorkspacePluginModel fModel = new WorkspacePluginModel(pluginXml, false); - fModel.setEditable(true); - fModel.load(); - // Storing a write-only plugin.xml model - IExtensions extensions = fModel.getExtensions(); - // Storing a read-only plugin.xml model - if (plugin != null) { - IExtensions readExtension = plugin.getExtensions(); - nextExtension: for (final IPluginExtension extension : readExtension - .getExtensions()) { - String id = getExtensionId(extension, project); - boolean extensionToCreateFound = isExtensionInMap(extensionMap, - extension, extension.getId()); - if (!extensionToCreateFound) { - extensionToCreateFound = isExtensionInMap(extensionMap, - extension, id); - } - if (extensionToCreateFound) { - continue nextExtension; - } - // remove if contained in the removables - final String extensionId = id; - Pair removable = Iterables.find(removedExtensions, new Predicate>() { - @Override - public boolean apply(Pair p) { - return p.getKey().equals(extensionId) && - p.getValue().equals(extension.getPoint()); - } - }, null); - - if (removable == null) { - // XXX cloning extensions to remove project name prefixes - IPluginExtension cloneExtension = fModel.createExtension(); - cloneExtension.setId(id); - String name = extension.getName(); - if (name != null && !name.isEmpty()) { - cloneExtension.setName(name); - } - cloneExtension.setPoint(extension.getPoint()); - for (IPluginObject obj : extension.getChildren()) { - cloneExtension.add(obj); - } - cloneExtension.setInTheModel(true); - extensions.add(cloneExtension); - } - } - for (IPluginExtensionPoint point : readExtension - .getExtensionPoints()) { - extensions.add(point); - } - } - for (IPluginExtension contribExtension : contributedExtensions) { - extensions.add(contribExtension); - contribExtension.setInTheModel(true); - } - fModel.save(); - } - - /** - * @param extensionMap - * @param extension - * @param id - * @return - */ - private static boolean isExtensionInMap( - Multimap extensionMap, - final IPluginExtension extension, String id) { - boolean extensionToCreateFound = false; - if (extensionMap.containsKey(id)) { - extensionToCreateFound = Iterables.any(extensionMap.get(id), - new Predicate() { - @Override - public boolean apply(IPluginExtension ex) { - return ex.getPoint().equals(extension.getPoint()); - } - }); - } - return extensionToCreateFound; - } - - /** - * Updates project manifest to ensure the selected packages are removed. - * Does not change existing exports. - * - * @param project - * @param dependencies - * @throws CoreException - */ - public static void removePackageExports(IProject project, - List dependencies) throws CoreException { - removePackageExports(project, dependencies, new NullProgressMonitor()); - } - - - /** - * Removes all extensions from the project, if the extension's pointId - * equals to one of the given pointId. - * - * @param project an existing, open PDE project - * @param removableExtensionIdentifiers - * - contains both the extension id prefix (key), and the - * extension point id (value) - * @throws CoreException - */ - public static void removeAllExtension(IProject project, Collection> removableExtensionIdentifiers) throws CoreException { - Preconditions.checkArgument(project.exists() && project.isOpen() && (PDE.hasPluginNature(project))); - - if (StringExtensions.isNullOrEmpty(project.getName())) { - return; - } - IFile pluginXml = PDEProject.getPluginXml(project); - IPluginModel plugin = (IPluginModel) PDECore.getDefault() - .getModelManager().findModel(project); - WorkspacePluginModel fModel = new WorkspacePluginModel(pluginXml, false); - fModel.setEditable(true); - fModel.load(); - // Storing a write-only plugin.xml model - IExtensions extensions = fModel.getExtensions(); - if (plugin != null) { - // Storing a read-only plugin.xml model - IExtensions readExtension = plugin.getExtensions(); - for (final IPluginExtension extension : readExtension.getExtensions()) { - String id = getExtensionId(extension, project); - if (!isRemovableExtension(id, extension.getPoint(), removableExtensionIdentifiers)) { - // XXX cloning extensions to remove project name prefixes - IPluginExtension cloneExtension = fModel.createExtension(); - cloneExtension.setId(id); - cloneExtension.setName(extension.getName()); - cloneExtension.setPoint(extension.getPoint()); - for (IPluginObject obj : extension.getChildren()) { - cloneExtension.add(obj); - } - cloneExtension.setInTheModel(true); - extensions.add(cloneExtension); - } - } - // add extension points - for (IPluginExtensionPoint point : readExtension - .getExtensionPoints()) { - extensions.add(point); - } - } - fModel.save(); - } - - /** - * Returns true if the extension is removable from the plugin.xml. If the - * extension id is prefixed with one of the identifier prefix and the - * pointId is equals with the extension's point id, then the extension will - * be removed. If the prefix is null or empty, only the pointId equality is - * necessary for the removal. - * - * @param extensionId - * @param pointId - * @param removableExtensionIdentifiers - * @return - */ - private static boolean isRemovableExtension(final String extensionId, final String pointId, - Collection> removableExtensionIdentifiers) { - Pair foundOne = IterableExtensions.findFirst(removableExtensionIdentifiers, new Functions.Function1, Boolean>() { - @Override - public Boolean apply(Pair p) { - if (StringExtensions.isNullOrEmpty(p.getKey())) { - return pointId.equals(p.getValue()); - } - return extensionId.startsWith(p.getKey()) && pointId.equals(p.getValue()); - } - }); - return foundOne != null; - } - - /** - * Returns the extension Id. Removes the plug-in name if the extension id prefixed with it. - * @param extension - * @param project - * @return - */ - private static String getExtensionId(IPluginExtension extension, IProject project) { - String id = extension.getId(); - if (id != null && id.startsWith(project.getName())) { - int beginIndex = project.getName().length() + 1; - if (beginIndex >= 0) { - id = id.substring(beginIndex); - } - } - return id; - } - - /** - * Ensures that the project contains the src and src-gen folders as source folders. - * @param project an existing, open plug-in project - * @param monitor - * @throws CoreException - */ - public static void ensureSourceFolders(IProject project, IProgressMonitor monitor) throws CoreException { - Preconditions.checkArgument(project.exists() && project.isOpen() && (PDE.hasPluginNature(project)), - INVALID_PROJECT_MESSAGE); - BundleContext context = null; - ServiceReference ref = null; - try { - context = IncQueryGeneratorPlugin.getContext(); - ref = context.getServiceReference(IBundleProjectService.class); - final IBundleProjectService service = context.getService(ref); - IBundleProjectDescription bundleDesc = service - .getDescription(project); - bundleDesc.setBundleClasspath(getUpdatedBundleClasspathEntries(bundleDesc.getBundleClasspath(), service)); - bundleDesc.apply(monitor); - } finally { - if (context != null && ref != null) { - context.ungetService(ref); - } - } - } - - /** - * Returns an updated the classpath entries of a project by ensuring all required source folders are present. - * - * @param service - * @return - */ - private static IBundleClasspathEntry[] getUpdatedBundleClasspathEntries(final IBundleClasspathEntry[] oldClasspath, final IBundleProjectService service) { - Collection classPathSourceList = Collections2.filter(Lists.newArrayList(oldClasspath), new Predicate() { - @Override - public boolean apply(IBundleClasspathEntry entry) { - return entry.getSourcePath() != null && !entry.getSourcePath().isEmpty(); - } - }); - final Collection existingSourceEntries = Collections2.transform(classPathSourceList, new Function() { - @Override - public String apply(IBundleClasspathEntry entry) { - return entry.getSourcePath().toString(); - } - }); - Collection missingSourceFolders = Collections2.filter(SOURCEFOLDERS, new Predicate() { - @Override - public boolean apply(String entry) { - return !existingSourceEntries.contains(entry); - } - }); - Collection newClasspathEntries= Collections2.transform( - missingSourceFolders, new Function() { - @Override - public IBundleClasspathEntry apply(String input) { - return service.newBundleClasspathEntry(new Path(input), - null, null); - } - }); - - List modifiedClasspathEntries = Lists.newArrayList(oldClasspath); - modifiedClasspathEntries.addAll(newClasspathEntries); - return modifiedClasspathEntries.toArray(new IBundleClasspathEntry[modifiedClasspathEntries.size()]); - } - - public static String getBundleSymbolicName(IProject project) { - IPluginModel plugin = (IPluginModel) PDECore.getDefault() - .getModelManager().findModel(project); - return plugin.getBundleDescription().getSymbolicName(); - } - + private static final String INVALID_PROJECT_MESSAGE = "Only existing, open plug-in projects are supported by the generator."; + + private static final class IDToRequireBundleTransformer implements Function { + private final IBundleProjectService service; + + private IDToRequireBundleTransformer(IBundleProjectService service) { + this.service = service; + } + + @Override + public IRequiredBundleDescription apply(String input) { + return service.newRequiredBundle(input, null, false, false); + } + } + + /** + * Two source folders: src to be manually written and src-gen to contain generated code + */ + public static final List SOURCEFOLDERS = ImmutableList + .of(IncQueryNature.SRC_DIR, IncQueryNature.SRCGEN_DIR); + /** + * A single source folder named src + */ + public static final List SINGLESOURCEFOLDER = ImmutableList.of("src"); + + /** + * Creates a new IncQuery project: a plug-in project with src and src-gen folders and specific dependencies. + * + * @param description + * @param proj + * @param monitor + * @throws CoreException + * @throws OperationCanceledException + */ + public static void createProject(IProjectDescription description, IProject proj, + List additionalDependencies, IProgressMonitor monitor) throws CoreException { + List dependencies = Lists.newArrayList("org.eclipse.pde.core", "org.eclipse.emf.ecore", + "org.eclipse.emf.transaction", IncQueryRuntimePlugin.PLUGIN_ID, "org.eclipse.xtext.xbase.lib"); + if (additionalDependencies != null) { + dependencies.addAll(additionalDependencies); + } + BundleContext context = null; + ServiceReference ref = null; + + try { + + monitor.beginTask("", 2000); + /* Creating plug-in information */ + context = IncQueryGeneratorPlugin.getContext(); + ref = context.getServiceReference(IBundleProjectService.class); + final IBundleProjectService service = context.getService(ref); + IBundleProjectDescription bundleDesc = service.getDescription(proj); + IPath[] additionalBinIncludes = new IPath[] { new Path("plugin.xml"), new Path("queries/") }; + ProjectGenerationHelper.fillProjectMetadata(proj, dependencies, service, bundleDesc, additionalBinIncludes); + bundleDesc.apply(monitor); + // Adding IncQuery-specific natures + ProjectGenerationHelper.addNatures(proj, new String[] { IncQueryNature.NATURE_ID, + "org.eclipse.xtext.ui.shared.xtextNature" }, monitor); + } finally { + monitor.done(); + if (context != null && ref != null) { + context.ungetService(ref); + } + } + } + + /** + * Adds a collection of natures to the project + * + * @param proj + * @param natures + * @param monitor + * @return + * @throws CoreException + */ + public static IProjectDescription addNatures(IProject proj, String[] natures, IProgressMonitor monitor) + throws CoreException { + IProjectDescription desc = proj.getDescription(); + List newNatures = new ArrayList(); + newNatures.addAll(Arrays.asList(desc.getNatureIds())); + newNatures.addAll(Arrays.asList(natures)); + desc.setNatureIds(newNatures.toArray(new String[newNatures.size()])); + proj.setDescription(desc, monitor); + return desc; + } + + /** + * Adds a file to a container. + * + * @param container + * the container to add the file to + * @param path + * the path of the newly created file + * @param contentStream + * the file will be filled with this stream's contents + * @param monitor + * @throws CoreException + */ + public static void addFileToProject(IContainer container, Path path, InputStream contentStream, + IProgressMonitor monitor) throws CoreException { + final IFile file = container.getFile(path); + + if (file.exists()) { + file.setContents(contentStream, true, true, monitor); + } else { + file.create(contentStream, true, monitor); + } + + } + + /** + * @param folder + * @param monitor + * @throws CoreException + */ + public static void deleteJavaFiles(IFolder folder, final IProgressMonitor monitor) throws CoreException { + folder.refreshLocal(IResource.DEPTH_INFINITE, monitor); + CollectDeletedElement visitor = new CollectDeletedElement(); + folder.accept(visitor); + for (IResource res : visitor.toDelete) { + res.delete(false, new SubProgressMonitor(monitor, 1)); + } + } + + public static void initializePluginProject(IProject project, final List dependencies, + final IPath[] additionalBinIncludes) throws CoreException { + initializePluginProject(project, dependencies, additionalBinIncludes, new NullProgressMonitor()); + } + + public static void initializePluginProject(IProject project, final List dependencies, + final IPath[] additionalBinIncludes, IProgressMonitor monitor) throws CoreException { + BundleContext context = null; + ServiceReference ref = null; + try { + context = IncQueryGeneratorPlugin.getContext(); + ref = context.getServiceReference(IBundleProjectService.class); + final IBundleProjectService service = context.getService(ref); + IBundleProjectDescription bundleDesc = service.getDescription(project); + fillProjectMetadata(project, dependencies, service, bundleDesc, additionalBinIncludes); + bundleDesc.apply(monitor); + } finally { + if (context != null && ref != null) { + context.ungetService(ref); + } + } + } + + /** + * Initializes the plug-in metadata of a newly created project. + * + * @param project + * the plug-in project to create the metadata for. The plug-in id will be the same as the project name + * @param dependencies + * a list of required bundles to add + * @param service + * @param bundleDesc + */ + public static void fillProjectMetadata(IProject project, final List dependencies, + final IBundleProjectService service, IBundleProjectDescription bundleDesc, + final IPath[] additionalBinIncludes) { + bundleDesc.setBundleName(project.getName()); + bundleDesc.setBundleVersion(new Version(0, 0, 1, "qualifier")); + bundleDesc.setSingleton(true); + bundleDesc.setTargetVersion(IBundleProjectDescription.VERSION_3_6); + bundleDesc.setSymbolicName(project.getName()); + bundleDesc.setExtensionRegistry(true); + bundleDesc.setBinIncludes(additionalBinIncludes); + + bundleDesc.setBundleClasspath(getUpdatedBundleClasspathEntries(new IBundleClasspathEntry[0], service)); + bundleDesc.setExecutionEnvironments(new String[] { IncQueryNature.EXECUTION_ENVIRONMENT }); + // Adding dependencies + IRequiredBundleDescription[] reqBundles = Lists.transform(dependencies, + new IDToRequireBundleTransformer(service)).toArray(new IRequiredBundleDescription[dependencies.size()]); + bundleDesc.setRequiredBundles(reqBundles); + } + + /** + * Checks whether the project depends on a selected bundle ID + * + * @param project + * an existing, open plug-in project to check + * @param dependency + * bundle identifier + * @return true, if the project depends on the given bundle + * @throws CoreException + */ + public static boolean checkBundleDependency(IProject project, String dependency) throws CoreException { + Preconditions.checkArgument(project.exists() && project.isOpen() && (PDE.hasPluginNature(project)), + INVALID_PROJECT_MESSAGE); + BundleContext context = null; + ServiceReference ref = null; + try { + context = IncQueryGeneratorPlugin.getContext(); + ref = context.getServiceReference(IBundleProjectService.class); + final IBundleProjectService service = context.getService(ref); + IBundleProjectDescription bundleDesc = service.getDescription(project); + for (IRequiredBundleDescription require : bundleDesc.getRequiredBundles()) { + if (dependency.equals(require.getName())) { + return true; + } + } + return false; + } finally { + if (context != null && ref != null) { + context.ungetService(ref); + } + } + } + + /** + * Updates project manifest to ensure the selected bundle dependencies are set. Does not change existing + * dependencies. + * + * @param project + * @param dependencies + * @throws CoreException + */ + public static void ensureBundleDependencies(IProject project, final List dependencies) throws CoreException { + ensureBundleDependencies(project, dependencies, new NullProgressMonitor()); + } + + /** + * Updates project manifest to ensure the selected bundle dependencies are set. Does not change existing + * dependencies. + * + * @param project + * an existing, open PDE plug-in project + * @param dependencies + * @param monitor + * @throws CoreException + */ + public static void ensureBundleDependencies(IProject project, final List dependencies, + IProgressMonitor monitor) throws CoreException { + Preconditions.checkArgument(project.exists() && project.isOpen() && (PDE.hasPluginNature(project)), + INVALID_PROJECT_MESSAGE); + if (dependencies.isEmpty()) { + return; + } + BundleContext context = null; + ServiceReference ref = null; + try { + context = IncQueryGeneratorPlugin.getContext(); + ref = context.getServiceReference(IBundleProjectService.class); + final IBundleProjectService service = context.getService(ref); + IBundleProjectDescription bundleDesc = service.getDescription(project); + ensureBundleDependencies(service, bundleDesc, dependencies); + bundleDesc.apply(monitor); + } finally { + if (context != null && ref != null) { + context.ungetService(ref); + } + } + } + + /** + * Updates project manifest to ensure the selected bundle dependencies are set. Does not change existing + * dependencies. + * + * @param service + * @param bundleDesc + * @param dependencies + */ + static void ensureBundleDependencies(IBundleProjectService service, IBundleProjectDescription bundleDesc, + final List dependencies) { + IRequiredBundleDescription[] requiredBundles = bundleDesc.getRequiredBundles(); + List missingDependencies = new ArrayList(dependencies); + if (requiredBundles != null) { + for (IRequiredBundleDescription bundle : requiredBundles) { + if (missingDependencies.contains(bundle.getName())) { + missingDependencies.remove(bundle.getName()); + } + } + } + bundleDesc.setRequiredBundles(Lists.transform(missingDependencies, new IDToRequireBundleTransformer(service)) + .toArray(new IRequiredBundleDescription[missingDependencies.size()])); + } + + /** + * Updates project manifest to ensure the selected packages are exported. Does not change existing exports. + * + * @param project + * @param dependencies + * @throws CoreException + */ + public static void ensurePackageExports(IProject project, final Collection dependencies) + throws CoreException { + ensurePackageExports(project, dependencies, new NullProgressMonitor()); + } + + /** + * Updates project manifest to ensure the selected packages are exported. Does not change existing exports. + * + * @param project + * an existing, open PDE plug-in project + * @param exports + * a non-empty list of package exports + * @param monitor + * @throws CoreException + */ + public static void ensurePackageExports(IProject project, final Collection exports, IProgressMonitor monitor) + throws CoreException { + Preconditions.checkArgument(project.exists() && project.isOpen() && (PDE.hasPluginNature(project)), + INVALID_PROJECT_MESSAGE); + if (exports.isEmpty()) { + return; + } + + BundleContext context = null; + ServiceReference ref = null; + try { + context = IncQueryGeneratorPlugin.getContext(); + ref = context.getServiceReference(IBundleProjectService.class); + final IBundleProjectService service = context.getService(ref); + IBundleProjectDescription bundleDesc = service.getDescription(project); + ensurePackageExports(service, bundleDesc, exports); + bundleDesc.apply(monitor); + } finally { + if (context != null && ref != null) { + context.ungetService(ref); + } + } + } + + /** + * Updates project manifest to ensure the selected packages are removed. Does not change existing exports. + * + * @param project + * an existing, open plug-in project + * @param dependencies + * @param monitor + * @throws CoreException + */ + public static void removePackageExports(IProject project, final List dependencies, IProgressMonitor monitor) + throws CoreException { + Preconditions.checkArgument(project.exists() && project.isOpen() && (PDE.hasPluginNature(project)), + INVALID_PROJECT_MESSAGE); + if (dependencies.isEmpty()) { + return; + } + + BundleContext context = null; + ServiceReference ref = null; + try { + context = IncQueryGeneratorPlugin.getContext(); + ref = context.getServiceReference(IBundleProjectService.class); + final IBundleProjectService service = context.getService(ref); + IBundleProjectDescription bundleDesc = service.getDescription(project); + removePackageExports(service, bundleDesc, dependencies); + bundleDesc.apply(monitor); + } finally { + if (context != null && ref != null) { + context.ungetService(ref); + } + } + } + + /** + * Updates project manifest to ensure the selected packages are exported. Does not change existing exports. + * + * @param service + * @param bundleDesc + * @param exports + */ + static void ensurePackageExports(final IBundleProjectService service, IBundleProjectDescription bundleDesc, + final Collection exports) { + IPackageExportDescription[] packageExports = bundleDesc.getPackageExports(); + List missingExports = new ArrayList(exports); + List exportList = new ArrayList(); + if (packageExports != null) { + for (IPackageExportDescription export : packageExports) { + if (!missingExports.contains(export.getName())) { + missingExports.remove(export.getName()); + } + exportList.add(export); + } + } + exportList.addAll(Lists.transform(missingExports, new Function() { + + @Override + public IPackageExportDescription apply(String input) { + return service.newPackageExport(input, null, true, null); + } + })); + + bundleDesc.setPackageExports(exportList.toArray(new IPackageExportDescription[exportList.size()])); + } + + /** + * Updates project manifest to ensure the selected packages are removed. Does not change existing exports. + * + * @param service + * @param bundleDesc + * @param exports + */ + static void removePackageExports(final IBundleProjectService service, IBundleProjectDescription bundleDesc, + final List exports) { + IPackageExportDescription[] packageExports = bundleDesc.getPackageExports(); + List exportList = new ArrayList(); + if (packageExports != null) { + for (IPackageExportDescription export : packageExports) { + if (!exports.contains(export.getName())) { + exportList.add(export); + } + } + } + bundleDesc.setPackageExports(exportList.toArray(new IPackageExportDescription[exportList.size()])); + } + + /** + * Updates the selected project to contain the selected extension. The extensions are identified using an identifier + * and extension point together; old extensions are replaced with the new ones, other extensions are kept intact. + * + * @param project + * @param contributedExtensions + * @throws CoreException + */ + public static void ensureExtensions(IProject project, Iterable contributedExtensions, + Iterable> removedExtensions) throws CoreException { + ensureExtensions(project, contributedExtensions, removedExtensions, new NullProgressMonitor()); + } + + /** + * Updates the selected project to contain the selected extension. The extensions are identified using an identifier + * and extension point together; old extensions are replaced with the new ones, other extensions are kept intact. An + * extension will be ignored, if exist in the removedExtensions list. + * + * @param project + * an existing, open PDE plug-in project + * @param contributedExtensions + * @param removedExtensions + * @param monitor + * @throws CoreException + */ + public static void ensureExtensions(IProject project, Iterable contributedExtensions, + Iterable> removedExtensions, IProgressMonitor monitor) throws CoreException { + Preconditions.checkArgument(project.exists() && project.isOpen() && (PDE.hasPluginNature(project)), + INVALID_PROJECT_MESSAGE); + + if (StringExtensions.isNullOrEmpty(project.getName())) { + return; + } + Multimap extensionMap = ArrayListMultimap.create(); + for (IPluginExtension extension : contributedExtensions) { + extensionMap.put(extension.getId(), extension); + } + // XXX Using two APIs to extension generation: one to read and one to + // write + IFile pluginXml = PDEProject.getPluginXml(project); + IPluginModel plugin = (IPluginModel) PDECore.getDefault().getModelManager().findModel(project); + WorkspacePluginModel fModel = new WorkspacePluginModel(pluginXml, false); + fModel.setEditable(true); + fModel.load(); + // Storing a write-only plugin.xml model + IExtensions extensions = fModel.getExtensions(); + // Storing a read-only plugin.xml model + if (plugin != null) { + IExtensions readExtension = plugin.getExtensions(); + nextExtension: for (final IPluginExtension extension : readExtension.getExtensions()) { + String id = getExtensionId(extension, project); + boolean extensionToCreateFound = isExtensionInMap(extensionMap, extension, extension.getId()); + if (!extensionToCreateFound) { + extensionToCreateFound = isExtensionInMap(extensionMap, extension, id); + } + if (extensionToCreateFound) { + continue nextExtension; + } + // remove if contained in the removables + final String extensionId = id; + Pair removable = Iterables.find(removedExtensions, + new Predicate>() { + @Override + public boolean apply(Pair p) { + return p.getKey().equals(extensionId) && p.getValue().equals(extension.getPoint()); + } + }, null); + + if (removable == null) { + // XXX cloning extensions to remove project name prefixes + IPluginExtension cloneExtension = fModel.createExtension(); + cloneExtension.setId(id); + String name = extension.getName(); + if (name != null && !name.isEmpty()) { + cloneExtension.setName(name); + } + cloneExtension.setPoint(extension.getPoint()); + for (IPluginObject obj : extension.getChildren()) { + cloneExtension.add(obj); + } + cloneExtension.setInTheModel(true); + extensions.add(cloneExtension); + } + } + for (IPluginExtensionPoint point : readExtension.getExtensionPoints()) { + extensions.add(point); + } + } + for (IPluginExtension contribExtension : contributedExtensions) { + extensions.add(contribExtension); + contribExtension.setInTheModel(true); + } + fModel.save(); + } + + /** + * @param extensionMap + * @param extension + * @param id + * @return + */ + private static boolean isExtensionInMap(Multimap extensionMap, + final IPluginExtension extension, String id) { + boolean extensionToCreateFound = false; + if (extensionMap.containsKey(id)) { + extensionToCreateFound = Iterables.any(extensionMap.get(id), new Predicate() { + @Override + public boolean apply(IPluginExtension ex) { + return ex.getPoint().equals(extension.getPoint()); + } + }); + } + return extensionToCreateFound; + } + + /** + * Updates project manifest to ensure the selected packages are removed. Does not change existing exports. + * + * @param project + * @param dependencies + * @throws CoreException + */ + public static void removePackageExports(IProject project, List dependencies) throws CoreException { + removePackageExports(project, dependencies, new NullProgressMonitor()); + } + + /** + * Removes all extensions from the project, if the extension's pointId equals to one of the given pointId. + * + * @param project + * an existing, open PDE project + * @param removableExtensionIdentifiers + * - contains both the extension id prefix (key), and the extension point id (value) + * @throws CoreException + */ + public static void removeAllExtension(IProject project, + Collection> removableExtensionIdentifiers) throws CoreException { + Preconditions.checkArgument(project.exists() && project.isOpen() && (PDE.hasPluginNature(project))); + + if (StringExtensions.isNullOrEmpty(project.getName())) { + return; + } + IFile pluginXml = PDEProject.getPluginXml(project); + IPluginModel plugin = (IPluginModel) PDECore.getDefault().getModelManager().findModel(project); + WorkspacePluginModel fModel = new WorkspacePluginModel(pluginXml, false); + fModel.setEditable(true); + fModel.load(); + // Storing a write-only plugin.xml model + IExtensions extensions = fModel.getExtensions(); + if (plugin != null) { + // Storing a read-only plugin.xml model + IExtensions readExtension = plugin.getExtensions(); + for (final IPluginExtension extension : readExtension.getExtensions()) { + String id = getExtensionId(extension, project); + if (!isRemovableExtension(id, extension.getPoint(), removableExtensionIdentifiers)) { + // XXX cloning extensions to remove project name prefixes + IPluginExtension cloneExtension = fModel.createExtension(); + cloneExtension.setId(id); + cloneExtension.setName(extension.getName()); + cloneExtension.setPoint(extension.getPoint()); + for (IPluginObject obj : extension.getChildren()) { + cloneExtension.add(obj); + } + cloneExtension.setInTheModel(true); + extensions.add(cloneExtension); + } + } + // add extension points + for (IPluginExtensionPoint point : readExtension.getExtensionPoints()) { + extensions.add(point); + } + } + fModel.save(); + } + + /** + * Returns true if the extension is removable from the plugin.xml. If the extension id is prefixed with one of the + * identifier prefix and the pointId is equals with the extension's point id, then the extension will be removed. If + * the prefix is null or empty, only the pointId equality is necessary for the removal. + * + * @param extensionId + * @param pointId + * @param removableExtensionIdentifiers + * @return + */ + private static boolean isRemovableExtension(final String extensionId, final String pointId, + Collection> removableExtensionIdentifiers) { + Pair foundOne = IterableExtensions.findFirst(removableExtensionIdentifiers, + new Functions.Function1, Boolean>() { + @Override + public Boolean apply(Pair p) { + if (StringExtensions.isNullOrEmpty(p.getKey())) { + return pointId.equals(p.getValue()); + } + return extensionId.startsWith(p.getKey()) && pointId.equals(p.getValue()); + } + }); + return foundOne != null; + } + + /** + * Returns the extension Id. Removes the plug-in name if the extension id prefixed with it. + * + * @param extension + * @param project + * @return + */ + private static String getExtensionId(IPluginExtension extension, IProject project) { + String id = extension.getId(); + if (id != null && id.startsWith(project.getName())) { + int beginIndex = project.getName().length() + 1; + if (beginIndex >= 0) { + id = id.substring(beginIndex); + } + } + return id; + } + + /** + * Ensures that the project contains the src and src-gen folders as source folders. + * + * @param project + * an existing, open plug-in project + * @param monitor + * @throws CoreException + */ + public static void ensureSourceFolders(IProject project, IProgressMonitor monitor) throws CoreException { + Preconditions.checkArgument(project.exists() && project.isOpen() && (PDE.hasPluginNature(project)), + INVALID_PROJECT_MESSAGE); + BundleContext context = null; + ServiceReference ref = null; + try { + context = IncQueryGeneratorPlugin.getContext(); + ref = context.getServiceReference(IBundleProjectService.class); + final IBundleProjectService service = context.getService(ref); + IBundleProjectDescription bundleDesc = service.getDescription(project); + bundleDesc.setBundleClasspath(getUpdatedBundleClasspathEntries(bundleDesc.getBundleClasspath(), service)); + bundleDesc.apply(monitor); + } finally { + if (context != null && ref != null) { + context.ungetService(ref); + } + } + } + + /** + * Returns an updated the classpath entries of a project by ensuring all required source folders are present. + * + * @param service + * @return + */ + private static IBundleClasspathEntry[] getUpdatedBundleClasspathEntries(final IBundleClasspathEntry[] oldClasspath, + final IBundleProjectService service) { + Collection classPathSourceList = Collections2.filter(Lists.newArrayList(oldClasspath), + new Predicate() { + @Override + public boolean apply(IBundleClasspathEntry entry) { + return entry.getSourcePath() != null && !entry.getSourcePath().isEmpty(); + } + }); + final Collection existingSourceEntries = Collections2.transform(classPathSourceList, + new Function() { + @Override + public String apply(IBundleClasspathEntry entry) { + return entry.getSourcePath().toString(); + } + }); + Collection missingSourceFolders = Collections2.filter(SOURCEFOLDERS, new Predicate() { + @Override + public boolean apply(String entry) { + return !existingSourceEntries.contains(entry); + } + }); + Collection newClasspathEntries = Collections2.transform(missingSourceFolders, + new Function() { + @Override + public IBundleClasspathEntry apply(String input) { + return service.newBundleClasspathEntry(new Path(input), null, null); + } + }); + + List modifiedClasspathEntries = Lists.newArrayList(oldClasspath); + modifiedClasspathEntries.addAll(newClasspathEntries); + return modifiedClasspathEntries.toArray(new IBundleClasspathEntry[modifiedClasspathEntries.size()]); + } + + public static String getBundleSymbolicName(IProject project) { + IPluginModel plugin = (IPluginModel) PDECore.getDefault().getModelManager().findModel(project); + return plugin.getBundleDescription().getSymbolicName(); + } + } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.tooling.generator.model.ui/src/org/eclipse/incquery/tooling/generator/model/ui/GeneratorModelUiModule.java b/plugins/org.eclipse.incquery.tooling.generator.model.ui/src/org/eclipse/incquery/tooling/generator/model/ui/GeneratorModelUiModule.java index 88603977..fdf2d4fd 100644 --- a/plugins/org.eclipse.incquery.tooling.generator.model.ui/src/org/eclipse/incquery/tooling/generator/model/ui/GeneratorModelUiModule.java +++ b/plugins/org.eclipse.incquery.tooling.generator.model.ui/src/org/eclipse/incquery/tooling/generator/model/ui/GeneratorModelUiModule.java @@ -22,20 +22,20 @@ * Use this class to register components to be used within the IDE. */ public class GeneratorModelUiModule extends AbstractGeneratorModelUiModule { - public GeneratorModelUiModule(AbstractUIPlugin plugin) { - super(plugin); - } + public GeneratorModelUiModule(AbstractUIPlugin plugin) { + super(plugin); + } private static final String loggerRoot = "org.eclipse.incquery"; - @Provides - @Singleton - Logger provideLoggerImplementation() { - return Logger.getLogger(loggerRoot); - } + @Provides + @Singleton + Logger provideLoggerImplementation() { + return Logger.getLogger(loggerRoot); + } - @SingletonBinding(eager = true) - public Class bindGeneratorModelJavaValidator() { - return GenmodelProjectBasedValidation.class; - } + @SingletonBinding(eager = true) + public Class bindGeneratorModelJavaValidator() { + return GenmodelProjectBasedValidation.class; + } } diff --git a/plugins/org.eclipse.incquery.tooling.generator.model.ui/src/org/eclipse/incquery/tooling/generator/model/ui/contentassist/GeneratorModelProposalProvider.java b/plugins/org.eclipse.incquery.tooling.generator.model.ui/src/org/eclipse/incquery/tooling/generator/model/ui/contentassist/GeneratorModelProposalProvider.java index ba59dfc9..135a7e1b 100644 --- a/plugins/org.eclipse.incquery.tooling.generator.model.ui/src/org/eclipse/incquery/tooling/generator/model/ui/contentassist/GeneratorModelProposalProvider.java +++ b/plugins/org.eclipse.incquery.tooling.generator.model.ui/src/org/eclipse/incquery/tooling/generator/model/ui/contentassist/GeneratorModelProposalProvider.java @@ -1,9 +1,10 @@ /* -* generated by Xtext -*/ + * generated by Xtext + */ package org.eclipse.incquery.tooling.generator.model.ui.contentassist; import org.eclipse.incquery.tooling.generator.model.ui.contentassist.AbstractGeneratorModelProposalProvider; + /** * see http://www.eclipse.org/Xtext/documentation/latest/xtext.html#contentAssist on how to customize content assistant */ diff --git a/plugins/org.eclipse.incquery.tooling.generator.model.ui/src/org/eclipse/incquery/tooling/generator/model/ui/labeling/GeneratorModelDescriptionLabelProvider.java b/plugins/org.eclipse.incquery.tooling.generator.model.ui/src/org/eclipse/incquery/tooling/generator/model/ui/labeling/GeneratorModelDescriptionLabelProvider.java index bb5d186c..50ae8881 100644 --- a/plugins/org.eclipse.incquery.tooling.generator.model.ui/src/org/eclipse/incquery/tooling/generator/model/ui/labeling/GeneratorModelDescriptionLabelProvider.java +++ b/plugins/org.eclipse.incquery.tooling.generator.model.ui/src/org/eclipse/incquery/tooling/generator/model/ui/labeling/GeneratorModelDescriptionLabelProvider.java @@ -1,6 +1,6 @@ /* -* generated by Xtext -*/ + * generated by Xtext + */ package org.eclipse.incquery.tooling.generator.model.ui.labeling; import org.eclipse.xtext.ui.label.DefaultDescriptionLabelProvider; @@ -12,16 +12,12 @@ */ public class GeneratorModelDescriptionLabelProvider extends DefaultDescriptionLabelProvider { -/* - //Labels and icons can be computed like this: - - String text(IEObjectDescription ele) { - return "my "+ele.getName(); - } - - String image(IEObjectDescription ele) { - return ele.getEClass().getName() + ".gif"; - } -*/ + /* + * //Labels and icons can be computed like this: + * + * String text(IEObjectDescription ele) { return "my "+ele.getName(); } + * + * String image(IEObjectDescription ele) { return ele.getEClass().getName() + ".gif"; } + */ } diff --git a/plugins/org.eclipse.incquery.tooling.generator.model.ui/src/org/eclipse/incquery/tooling/generator/model/ui/labeling/GeneratorModelLabelProvider.java b/plugins/org.eclipse.incquery.tooling.generator.model.ui/src/org/eclipse/incquery/tooling/generator/model/ui/labeling/GeneratorModelLabelProvider.java index 35ed998f..763c1817 100644 --- a/plugins/org.eclipse.incquery.tooling.generator.model.ui/src/org/eclipse/incquery/tooling/generator/model/ui/labeling/GeneratorModelLabelProvider.java +++ b/plugins/org.eclipse.incquery.tooling.generator.model.ui/src/org/eclipse/incquery/tooling/generator/model/ui/labeling/GeneratorModelLabelProvider.java @@ -1,11 +1,11 @@ /* -* generated by Xtext -*/ + * generated by Xtext + */ package org.eclipse.incquery.tooling.generator.model.ui.labeling; import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider; -import org.eclipse.xtext.ui.label.DefaultEObjectLabelProvider; - +import org.eclipse.xtext.ui.label.DefaultEObjectLabelProvider; + import com.google.inject.Inject; /** @@ -15,20 +15,16 @@ */ public class GeneratorModelLabelProvider extends DefaultEObjectLabelProvider { - @Inject - public GeneratorModelLabelProvider(AdapterFactoryLabelProvider delegate) { - super(delegate); - } - -/* - //Labels and icons can be computed like this: - - String text(MyModel ele) { - return "my "+ele.getName(); - } - - String image(MyModel ele) { - return "MyModel.gif"; + @Inject + public GeneratorModelLabelProvider(AdapterFactoryLabelProvider delegate) { + super(delegate); } -*/ + + /* + * //Labels and icons can be computed like this: + * + * String text(MyModel ele) { return "my "+ele.getName(); } + * + * String image(MyModel ele) { return "MyModel.gif"; } + */ } diff --git a/plugins/org.eclipse.incquery.tooling.generator.model.ui/src/org/eclipse/incquery/tooling/generator/model/ui/outline/GeneratorModelOutlineTreeProvider.java b/plugins/org.eclipse.incquery.tooling.generator.model.ui/src/org/eclipse/incquery/tooling/generator/model/ui/outline/GeneratorModelOutlineTreeProvider.java index e3088a1e..424ab9c4 100644 --- a/plugins/org.eclipse.incquery.tooling.generator.model.ui/src/org/eclipse/incquery/tooling/generator/model/ui/outline/GeneratorModelOutlineTreeProvider.java +++ b/plugins/org.eclipse.incquery.tooling.generator.model.ui/src/org/eclipse/incquery/tooling/generator/model/ui/outline/GeneratorModelOutlineTreeProvider.java @@ -1,6 +1,6 @@ /* -* generated by Xtext -*/ + * generated by Xtext + */ package org.eclipse.incquery.tooling.generator.model.ui.outline; import org.eclipse.xtext.ui.editor.outline.impl.DefaultOutlineTreeProvider; @@ -10,5 +10,5 @@ * */ public class GeneratorModelOutlineTreeProvider extends DefaultOutlineTreeProvider { - + } diff --git a/plugins/org.eclipse.incquery.tooling.generator.model.ui/src/org/eclipse/incquery/tooling/generator/model/ui/quickfix/GeneratorModelQuickfixProvider.java b/plugins/org.eclipse.incquery.tooling.generator.model.ui/src/org/eclipse/incquery/tooling/generator/model/ui/quickfix/GeneratorModelQuickfixProvider.java index 90a66dce..2d05593a 100644 --- a/plugins/org.eclipse.incquery.tooling.generator.model.ui/src/org/eclipse/incquery/tooling/generator/model/ui/quickfix/GeneratorModelQuickfixProvider.java +++ b/plugins/org.eclipse.incquery.tooling.generator.model.ui/src/org/eclipse/incquery/tooling/generator/model/ui/quickfix/GeneratorModelQuickfixProvider.java @@ -1,19 +1,18 @@ - package org.eclipse.incquery.tooling.generator.model.ui.quickfix; import org.eclipse.xtext.ui.editor.quickfix.DefaultQuickfixProvider; public class GeneratorModelQuickfixProvider extends DefaultQuickfixProvider { -// @Fix(MyJavaValidator.INVALID_NAME) -// public void capitalizeName(final Issue issue, IssueResolutionAcceptor acceptor) { -// acceptor.accept(issue, "Capitalize name", "Capitalize the name.", "upcase.png", new IModification() { -// public void apply(IModificationContext context) throws BadLocationException { -// IXtextDocument xtextDocument = context.getXtextDocument(); -// String firstLetter = xtextDocument.get(issue.getOffset(), 1); -// xtextDocument.replace(issue.getOffset(), 1, firstLetter.toUpperCase()); -// } -// }); -// } + // @Fix(MyJavaValidator.INVALID_NAME) + // public void capitalizeName(final Issue issue, IssueResolutionAcceptor acceptor) { + // acceptor.accept(issue, "Capitalize name", "Capitalize the name.", "upcase.png", new IModification() { + // public void apply(IModificationContext context) throws BadLocationException { + // IXtextDocument xtextDocument = context.getXtextDocument(); + // String firstLetter = xtextDocument.get(issue.getOffset(), 1); + // xtextDocument.replace(issue.getOffset(), 1, firstLetter.toUpperCase()); + // } + // }); + // } } diff --git a/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/GeneratorModelRuntimeModule.java b/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/GeneratorModelRuntimeModule.java index 21179a3c..7d15b171 100644 --- a/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/GeneratorModelRuntimeModule.java +++ b/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/GeneratorModelRuntimeModule.java @@ -20,12 +20,12 @@ */ public class GeneratorModelRuntimeModule extends AbstractGeneratorModelRuntimeModule { - @Override - public Class bindILinkingService() { - return GeneratorModelLinkingService.class; - } + @Override + public Class bindILinkingService() { + return GeneratorModelLinkingService.class; + } - public Class bindICrossReferenceSerializer() { - return GeneratorModelCrossRefSerializer.class; - } + public Class bindICrossReferenceSerializer() { + return GeneratorModelCrossRefSerializer.class; + } } diff --git a/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/GeneratorModelStandaloneSetup.java b/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/GeneratorModelStandaloneSetup.java index 642cf15a..fd57eba2 100644 --- a/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/GeneratorModelStandaloneSetup.java +++ b/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/GeneratorModelStandaloneSetup.java @@ -10,15 +10,12 @@ *******************************************************************************/ package org.eclipse.incquery.tooling.generator.model; - /** - * Initialization support for running Xtext languages - * without equinox extension registry + * Initialization support for running Xtext languages without equinox extension registry */ -public class GeneratorModelStandaloneSetup extends GeneratorModelStandaloneSetupGenerated{ +public class GeneratorModelStandaloneSetup extends GeneratorModelStandaloneSetupGenerated { - public static void doSetup() { - new GeneratorModelStandaloneSetup().createInjectorAndDoEMFRegistration(); - } + public static void doSetup() { + new GeneratorModelStandaloneSetup().createInjectorAndDoEMFRegistration(); + } } - diff --git a/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/formatting/GeneratorModelFormatter.java b/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/formatting/GeneratorModelFormatter.java index 9cea3c19..a918ada9 100644 --- a/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/formatting/GeneratorModelFormatter.java +++ b/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/formatting/GeneratorModelFormatter.java @@ -16,19 +16,18 @@ /** * This class contains custom formatting description. * - * see : http://www.eclipse.org/Xtext/documentation/latest/xtext.html#formatting - * on how and when to use it + * see : http://www.eclipse.org/Xtext/documentation/latest/xtext.html#formatting on how and when to use it * * Also see {@link org.eclipse.xtext.xtext.XtextFormattingTokenSerializer} as an example */ public class GeneratorModelFormatter extends AbstractDeclarativeFormatter { - - @Override - protected void configureFormatting(FormattingConfig c) { -// It's usually a good idea to activate the following three statements. -// They will add and preserve newlines around comments -// c.setLinewrap(0, 1, 2).before(getGrammarAccess().getSL_COMMENTRule()); -// c.setLinewrap(0, 1, 2).before(getGrammarAccess().getML_COMMENTRule()); -// c.setLinewrap(0, 1, 1).after(getGrammarAccess().getML_COMMENTRule()); - } + + @Override + protected void configureFormatting(FormattingConfig c) { + // It's usually a good idea to activate the following three statements. + // They will add and preserve newlines around comments + // c.setLinewrap(0, 1, 2).before(getGrammarAccess().getSL_COMMENTRule()); + // c.setLinewrap(0, 1, 2).before(getGrammarAccess().getML_COMMENTRule()); + // c.setLinewrap(0, 1, 1).after(getGrammarAccess().getML_COMMENTRule()); + } } diff --git a/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/scoping/GeneratorModelCrossRefSerializer.java b/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/scoping/GeneratorModelCrossRefSerializer.java index 7876c64c..f498ee00 100644 --- a/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/scoping/GeneratorModelCrossRefSerializer.java +++ b/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/scoping/GeneratorModelCrossRefSerializer.java @@ -19,15 +19,13 @@ public class GeneratorModelCrossRefSerializer extends CrossReferenceSerializer { - @Override - public String serializeCrossRef(EObject semanticObject, - CrossReference crossref, EObject target, INode node, Acceptor errors) { - if (target instanceof GenModel && target.eResource() != null) { - return String.format("\"%s\"", target.eResource().getURI() - .toString()); - } - return super.serializeCrossRef(semanticObject, crossref, target, node, - errors); - } + @Override + public String serializeCrossRef(EObject semanticObject, CrossReference crossref, EObject target, INode node, + Acceptor errors) { + if (target instanceof GenModel && target.eResource() != null) { + return String.format("\"%s\"", target.eResource().getURI().toString()); + } + return super.serializeCrossRef(semanticObject, crossref, target, node, errors); + } } diff --git a/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/scoping/GeneratorModelLinkingService.java b/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/scoping/GeneratorModelLinkingService.java index 181cc9d3..a3d2a85f 100644 --- a/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/scoping/GeneratorModelLinkingService.java +++ b/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/scoping/GeneratorModelLinkingService.java @@ -32,21 +32,19 @@ public class GeneratorModelLinkingService extends DefaultLinkingService { private static final Logger LOG = Logger.getLogger(GeneratorModelLinkingService.class); - + @Inject private IValueConverterService valueConverterService; - + @Override public List getLinkedObjects(EObject context, EReference ref, INode node) { - if (ref == GeneratorModelPackage.eINSTANCE - .getGeneratorModelReference_Genmodel() - && context instanceof GeneratorModelReference - && node instanceof ILeafNode) { + if (ref == GeneratorModelPackage.eINSTANCE.getGeneratorModelReference_Genmodel() + && context instanceof GeneratorModelReference && node instanceof ILeafNode) { return getGenModel((GeneratorModelReference) context, (ILeafNode) node); - } + } return super.getLinkedObjects(context, ref, node); } - + private List getGenModel(GeneratorModelReference context, ILeafNode text) { String nsUri = getMetamodelNsURI(text); if (nsUri == null) { @@ -54,21 +52,21 @@ private List getGenModel(GeneratorModelReference context, ILeafNode tex } GenModel pack = loadGenmodel(nsUri, context.eResource().getResourceSet()); if (pack != null) { - return Collections.singletonList(pack); + return Collections. singletonList(pack); } return Collections.emptyList(); } private String getMetamodelNsURI(ILeafNode text) { try { - return (String) valueConverterService.toValue(text.getText(), getLinkingHelper().getRuleNameFrom(text - .getGrammarElement()), text); + return (String) valueConverterService.toValue(text.getText(), + getLinkingHelper().getRuleNameFrom(text.getGrammarElement()), text); } catch (ValueConverterException e) { LOG.debug("Exception on leaf '" + text.getText() + "'", e); return null; } } - + private GenModel loadGenmodel(String resourceOrNsURI, ResourceSet resourceSet) { URI uri = null; try { @@ -81,7 +79,7 @@ private GenModel loadGenmodel(String resourceOrNsURI, ResourceSet resourceSet) { } catch (IllegalArgumentException ex) { LOG.trace("Invalid package URI: '" + resourceOrNsURI + "'", ex); return null; - } catch(RuntimeException ex) { + } catch (RuntimeException ex) { if (uri != null && uri.isPlatformResource()) { String platformString = uri.toPlatformString(true); URI platformPluginURI = URI.createPlatformPluginURI(platformString, true); diff --git a/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/scoping/GeneratorModelScopeProvider.java b/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/scoping/GeneratorModelScopeProvider.java index 7992ecc4..f7a07247 100644 --- a/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/scoping/GeneratorModelScopeProvider.java +++ b/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/scoping/GeneratorModelScopeProvider.java @@ -15,9 +15,8 @@ /** * This class contains custom scoping description. * - * see : http://www.eclipse.org/Xtext/documentation/latest/xtext.html#scoping - * on how and when to use it - * + * see : http://www.eclipse.org/Xtext/documentation/latest/xtext.html#scoping on how and when to use it + * */ public class GeneratorModelScopeProvider extends AbstractDeclarativeScopeProvider { diff --git a/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/validation/GeneratorModelIssueCodes.java b/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/validation/GeneratorModelIssueCodes.java index df3fee9a..522700ca 100644 --- a/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/validation/GeneratorModelIssueCodes.java +++ b/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/validation/GeneratorModelIssueCodes.java @@ -12,12 +12,11 @@ /** * @author Zoltan Ujhelyi - * + * */ public class GeneratorModelIssueCodes { - private final static String GENERATOR_MODEL_PREFIX = "eiqgen."; + private final static String GENERATOR_MODEL_PREFIX = "eiqgen."; - public final static String PACKAGE_OVERRIDE_CODE = GENERATOR_MODEL_PREFIX - + "package_override"; + public final static String PACKAGE_OVERRIDE_CODE = GENERATOR_MODEL_PREFIX + "package_override"; } diff --git a/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/validation/GeneratorModelJavaValidator.java b/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/validation/GeneratorModelJavaValidator.java index 3f428e28..e6dbf8e5 100644 --- a/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/validation/GeneratorModelJavaValidator.java +++ b/plugins/org.eclipse.incquery.tooling.generator.model/src/org/eclipse/incquery/tooling/generator/model/validation/GeneratorModelJavaValidator.java @@ -15,28 +15,26 @@ import org.eclipse.incquery.tooling.generator.model.generatorModel.GeneratorModelPackage; import org.eclipse.incquery.tooling.generator.model.generatorModel.GeneratorModelReference; import org.eclipse.xtext.validation.Check; - public class GeneratorModelJavaValidator extends AbstractGeneratorModelJavaValidator { - private static final String OVERRIDE_MESSAGE = "The genmodel import overrides the EPackage %s from the EMF EPackage registry. Be careful as this might cause issues with the interpretative tooling."; + private static final String OVERRIDE_MESSAGE = "The genmodel import overrides the EPackage %s from the EMF EPackage registry. Be careful as this might cause issues with the interpretative tooling."; - @Check - public void checkPackageOverride(GeneratorModelReference reference) { - if (reference.getGenmodel() == null - || reference.getGenmodel().getGenPackages().isEmpty()) { - return; - } - org.eclipse.emf.ecore.EPackage.Registry registry = EPackage.Registry.INSTANCE; - for (GenPackage genPackage : reference.getGenmodel().getGenPackages()) { - EPackage ePackage = genPackage.getEcorePackage(); - String nsURI = ePackage.getNsURI(); - if (registry.containsKey(nsURI)) { + @Check + public void checkPackageOverride(GeneratorModelReference reference) { + if (reference.getGenmodel() == null || reference.getGenmodel().getGenPackages().isEmpty()) { + return; + } + org.eclipse.emf.ecore.EPackage.Registry registry = EPackage.Registry.INSTANCE; + for (GenPackage genPackage : reference.getGenmodel().getGenPackages()) { + EPackage ePackage = genPackage.getEcorePackage(); + String nsURI = ePackage.getNsURI(); + if (registry.containsKey(nsURI)) { error(String.format(OVERRIDE_MESSAGE, nsURI), - GeneratorModelPackage.Literals.GENERATOR_MODEL_REFERENCE__GENMODEL, - GeneratorModelIssueCodes.PACKAGE_OVERRIDE_CODE); - } - } + GeneratorModelPackage.Literals.GENERATOR_MODEL_REFERENCE__GENMODEL, + GeneratorModelIssueCodes.PACKAGE_OVERRIDE_CODE); + } + } - } + } } diff --git a/plugins/org.eclipse.incquery.tooling.ui.retevis/src/org/eclipse/incquery/tooling/ui/retevis/Activator.java b/plugins/org.eclipse.incquery.tooling.ui.retevis/src/org/eclipse/incquery/tooling/ui/retevis/Activator.java index 17345b71..a117ccaf 100644 --- a/plugins/org.eclipse.incquery.tooling.ui.retevis/src/org/eclipse/incquery/tooling/ui/retevis/Activator.java +++ b/plugins/org.eclipse.incquery.tooling.ui.retevis/src/org/eclipse/incquery/tooling/ui/retevis/Activator.java @@ -9,55 +9,57 @@ */ public class Activator extends AbstractUIPlugin { - // The plug-in ID - public static final String PLUGIN_ID = "org.eclipse.incquery.tooling.ui.retevis"; //$NON-NLS-1$ - - // The shared instance - private static Activator plugin; - - /** - * The constructor - */ - public Activator() { - } - - /* - * (non-Javadoc) - * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) - */ - @Override + // The plug-in ID + public static final String PLUGIN_ID = "org.eclipse.incquery.tooling.ui.retevis"; //$NON-NLS-1$ + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() { + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + @Override public void start(BundleContext context) throws Exception { - super.start(context); - plugin = this; - } - - /* - * (non-Javadoc) - * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) - */ - @Override + super.start(context); + plugin = this; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + @Override public void stop(BundleContext context) throws Exception { - plugin = null; - super.stop(context); - } - - /** - * Returns the shared instance - * - * @return the shared instance - */ - public static Activator getDefault() { - return plugin; - } - - /** - * Returns an image descriptor for the image file at the given - * plug-in relative path - * - * @param path the path - * @return the image descriptor - */ - public static ImageDescriptor getImageDescriptor(String path) { - return imageDescriptorFromPlugin(PLUGIN_ID, path); - } + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + + /** + * Returns an image descriptor for the image file at the given plug-in relative path + * + * @param path + * the path + * @return the image descriptor + */ + public static ImageDescriptor getImageDescriptor(String path) { + return imageDescriptorFromPlugin(PLUGIN_ID, path); + } } diff --git a/plugins/org.eclipse.incquery.tooling.ui.retevis/src/org/eclipse/incquery/tooling/ui/retevis/views/ReteVisView.java b/plugins/org.eclipse.incquery.tooling.ui.retevis/src/org/eclipse/incquery/tooling/ui/retevis/views/ReteVisView.java index 56d5e3f6..2e881846 100644 --- a/plugins/org.eclipse.incquery.tooling.ui.retevis/src/org/eclipse/incquery/tooling/ui/retevis/views/ReteVisView.java +++ b/plugins/org.eclipse.incquery.tooling.ui.retevis/src/org/eclipse/incquery/tooling/ui/retevis/views/ReteVisView.java @@ -1,6 +1,5 @@ package org.eclipse.incquery.tooling.ui.retevis.views; - import org.eclipse.gef4.zest.core.viewers.AbstractZoomableViewer; import org.eclipse.gef4.zest.core.viewers.GraphViewer; import org.eclipse.gef4.zest.core.viewers.IZoomableWorkbenchPart; @@ -27,90 +26,90 @@ /** * * @author istvanrath - * + * */ public class ReteVisView extends ViewPart implements IZoomableWorkbenchPart { - /** - * The ID of the view as specified by the extension. - */ - public static final String ID = "org.eclipse.incquery.tooling.ui.retevis.views.ReteVisView"; + /** + * The ID of the view as specified by the extension. + */ + public static final String ID = "org.eclipse.incquery.tooling.ui.retevis.views.ReteVisView"; - private GraphViewer graphViewer; + private GraphViewer graphViewer; private ColorTheme theme; - @Override - public AbstractZoomableViewer getZoomableViewer() { - return graphViewer; - } - - /** - * The constructor. - */ - public ReteVisView() { } + @Override + public AbstractZoomableViewer getZoomableViewer() { + return graphViewer; + } + + /** + * The constructor. + */ + public ReteVisView() { + } - /** - * This is a callback that will allow us - * to create the viewer and initialize it. - */ - @Override + /** + * This is a callback that will allow us to create the viewer and initialize it. + */ + @Override public void createPartControl(Composite parent) { - // initialize Zest viewer - graphViewer = new GraphViewer(parent, SWT.BORDER); + // initialize Zest viewer + graphViewer = new GraphViewer(parent, SWT.BORDER); graphViewer.setConnectionStyle(ZestStyles.CONNECTIONS_DIRECTED); - graphViewer.setContentProvider(new ZestReteContentProvider()); - ZestReteLabelProvider labelProvider = new ZestReteLabelProvider(); + graphViewer.setContentProvider(new ZestReteContentProvider()); + ZestReteLabelProvider labelProvider = new ZestReteLabelProvider(); Display display = parent.getDisplay(); theme = new ColorTheme(display); labelProvider.setColors(theme); - graphViewer.setLabelProvider(labelProvider); - } + graphViewer.setLabelProvider(labelProvider); + } + + @Override + public void init(IViewSite site) throws PartInitException { + super.init(site); + site.getPage().addSelectionListener(new ISelectionListener() { - @Override - public void init(IViewSite site) throws PartInitException { - super.init(site); - site.getPage().addSelectionListener(new ISelectionListener() { - - @Override - public void selectionChanged(IWorkbenchPart part, ISelection selection) { - if (selection instanceof IStructuredSelection) { - IStructuredSelection sel = (IStructuredSelection) selection; - Object o = sel.getFirstElement(); - if (o!=null && o instanceof ObservablePatternMatcher) { - ObservablePatternMatcher pm = (ObservablePatternMatcher) o; - //String patternFqn = pl.getFullPatternNamePrefix()+"."+pl.getPatternNameFragment(); - try { - ReteBoundary rb = pm.getMatcher().getEngine().getReteEngine().getBoundary(); - ((ZestReteLabelProvider)graphViewer.getLabelProvider()).setRb( rb ); - //graphViewer.setInput( pm.getMatcher().getEngine().getReteEngine().getBoundary() ); + @Override + public void selectionChanged(IWorkbenchPart part, ISelection selection) { + if (selection instanceof IStructuredSelection) { + IStructuredSelection sel = (IStructuredSelection) selection; + Object o = sel.getFirstElement(); + if (o != null && o instanceof ObservablePatternMatcher) { + ObservablePatternMatcher pm = (ObservablePatternMatcher) o; + // String patternFqn = pl.getFullPatternNamePrefix()+"."+pl.getPatternNameFragment(); + try { + ReteBoundary rb = pm.getMatcher().getEngine().getReteEngine().getBoundary(); + ((ZestReteLabelProvider) graphViewer.getLabelProvider()).setRb(rb); + // graphViewer.setInput( pm.getMatcher().getEngine().getReteEngine().getBoundary() ); SugiyamaLayoutAlgorithm sugiyamaAlgorithm = new SugiyamaLayoutAlgorithm(); HorizontalShiftAlgorithm shiftAlgorithm = new HorizontalShiftAlgorithm(); graphViewer.setLayoutAlgorithm(new CompositeLayoutAlgorithm(new LayoutAlgorithm[] { sugiyamaAlgorithm, shiftAlgorithm })); // graphViewer.setLayoutAlgorithm(new TreeLayoutAlgorithm()); - //graphViewer.setLayoutAlgorithm(new SpringLayoutAlgorithm()); - //graphViewer.setLayoutAlgorithm(new RadialLayoutAlgorithm()); - //graphViewer.setLayoutAlgorithm(new SpaceTreeLayoutAlgorithm()); + // graphViewer.setLayoutAlgorithm(new SpringLayoutAlgorithm()); + // graphViewer.setLayoutAlgorithm(new RadialLayoutAlgorithm()); + // graphViewer.setLayoutAlgorithm(new SpaceTreeLayoutAlgorithm()); graphViewer.setInput(rb.getHeadContainer()); // graphViewer.applyLayout(); // graphViewer.refresh(); - } catch (IncQueryException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - } - } - }); - } - - /** - * Passing the focus request to the viewer's control. - */ - @Override - public void setFocus() { - // treeViewer.getControl().setFocus(); - } + } catch (IncQueryException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + } + }); + } + + /** + * Passing the focus request to the viewer's control. + */ + @Override + public void setFocus() { + // treeViewer.getControl().setFocus(); + } /* * (non-Javadoc) @@ -124,7 +123,5 @@ public void dispose() { } super.dispose(); } - - - + } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.tooling.ui.retevis/src/org/eclipse/incquery/tooling/ui/retevis/views/ZestReteContentProvider.java b/plugins/org.eclipse.incquery.tooling.ui.retevis/src/org/eclipse/incquery/tooling/ui/retevis/views/ZestReteContentProvider.java index 587909ad..23d3e752 100644 --- a/plugins/org.eclipse.incquery.tooling.ui.retevis/src/org/eclipse/incquery/tooling/ui/retevis/views/ZestReteContentProvider.java +++ b/plugins/org.eclipse.incquery.tooling.ui.retevis/src/org/eclipse/incquery/tooling/ui/retevis/views/ZestReteContentProvider.java @@ -14,34 +14,32 @@ import org.eclipse.incquery.runtime.rete.remote.Address; import org.eclipse.jface.viewers.ArrayContentProvider; -public class ZestReteContentProvider extends ArrayContentProvider implements - IGraphEntityContentProvider { +public class ZestReteContentProvider extends ArrayContentProvider implements IGraphEntityContentProvider { - @Override - public Object[] getElements(Object inputElement) { - if (inputElement instanceof ReteContainer) { - return super.getElements(((ReteContainer)inputElement).getAllNodes()); - } - else if (inputElement instanceof ReteBoundary) { - ReteBoundary rb = (ReteBoundary) inputElement; - Vector r = new Vector(); - for (Object a : rb.getAllUnaryRoots()) { - r.add(rb.getHeadContainer().resolveLocal( (Address)a )); // access all unary constraints - } - for (Object a : rb.getAllTernaryEdgeRoots()) { - r.add(rb.getHeadContainer().resolveLocal( (Address)a )); // access all ternary constraints - } - return r.toArray(); - } - return super.getElements(inputElement); - } + @Override + public Object[] getElements(Object inputElement) { + if (inputElement instanceof ReteContainer) { + return super.getElements(((ReteContainer) inputElement).getAllNodes()); + } else if (inputElement instanceof ReteBoundary) { + ReteBoundary rb = (ReteBoundary) inputElement; + Vector r = new Vector(); + for (Object a : rb.getAllUnaryRoots()) { + r.add(rb.getHeadContainer().resolveLocal((Address) a)); // access all unary constraints + } + for (Object a : rb.getAllTernaryEdgeRoots()) { + r.add(rb.getHeadContainer().resolveLocal((Address) a)); // access all ternary constraints + } + return r.toArray(); + } + return super.getElements(inputElement); + } - @Override - public Object[] getConnectedTo(Object entity) { - if (entity instanceof Node) { - Vector r = new Vector(); + @Override + public Object[] getConnectedTo(Object entity) { + if (entity instanceof Node) { + Vector r = new Vector(); if (entity instanceof Supplier) { - r.addAll( ((Supplier)entity).getReceivers() ); + r.addAll(((Supplier) entity).getReceivers()); try { Field field = entity.getClass().getDeclaredField("memoryNullIndexer"); field.setAccessible(true); @@ -74,18 +72,17 @@ public Object[] getConnectedTo(Object entity) { // r.add(node.getNullIndexer()); // // } - } - if (entity instanceof Indexer) { - if (entity instanceof StandardIndexer) { - for (IndexerListener il : ((StandardIndexer)entity).getListeners()){ - r.add(il.getOwner()); - } - } - } - return r.toArray(); - } - return null; - } - - + } + if (entity instanceof Indexer) { + if (entity instanceof StandardIndexer) { + for (IndexerListener il : ((StandardIndexer) entity).getListeners()) { + r.add(il.getOwner()); + } + } + } + return r.toArray(); + } + return null; + } + } diff --git a/plugins/org.eclipse.incquery.tooling.ui.retevis/src/org/eclipse/incquery/tooling/ui/retevis/views/ZestReteLabelProvider.java b/plugins/org.eclipse.incquery.tooling.ui.retevis/src/org/eclipse/incquery/tooling/ui/retevis/views/ZestReteLabelProvider.java index d9728362..b7cbe7ea 100644 --- a/plugins/org.eclipse.incquery.tooling.ui.retevis/src/org/eclipse/incquery/tooling/ui/retevis/views/ZestReteLabelProvider.java +++ b/plugins/org.eclipse.incquery.tooling.ui.retevis/src/org/eclipse/incquery/tooling/ui/retevis/views/ZestReteLabelProvider.java @@ -37,8 +37,8 @@ public class ZestReteLabelProvider extends LabelProvider implements IEntityStyle private final int INDEXER_ID = 0; private final int RETEMATCHER_ID = 1; private final int INPUT_ID = 2; - - private ReteBoundary rb; + + private ReteBoundary rb; private ColorTheme theme; /** @@ -51,29 +51,27 @@ public void setColors(ColorTheme theme) { this.theme = theme; } - - - public ReteBoundary getRb() { - return rb; - } - - public void setRb(ReteBoundary rb) { - this.rb = rb; - // initialize reverse traceability information - resetReverseMap(); - for (Object _o : rb.getAllProductionNodes()) { - Node productionNode = rb.getHeadContainer().resolveLocal((Address)_o); - if (productionNode!=null && productionNode instanceof Production) { - initalizeReverseMap((Production)productionNode); - } - } - } - - - @Override - public String getText(Object element) { - if (element instanceof Node) { - Node n = (Node) element; + + public ReteBoundary getRb() { + return rb; + } + + public void setRb(ReteBoundary rb) { + this.rb = rb; + // initialize reverse traceability information + resetReverseMap(); + for (Object _o : rb.getAllProductionNodes()) { + Node productionNode = rb.getHeadContainer().resolveLocal((Address) _o); + if (productionNode != null && productionNode instanceof Production) { + initalizeReverseMap((Production) productionNode); + } + } + } + + @Override + public String getText(Object element) { + if (element instanceof Node) { + Node n = (Node) element; Class namedClass = n.getClass(); String simpleName; do { @@ -81,8 +79,8 @@ public String getText(Object element) { namedClass = namedClass.getSuperclass(); } while (simpleName == null || simpleName.isEmpty()); String s = "" + simpleName; - if (n instanceof UniquenessEnforcerNode) { - // print tuplememory statistics + if (n instanceof UniquenessEnforcerNode) { + // print tuplememory statistics UniquenessEnforcerNode un = (UniquenessEnforcerNode) n; if (un.getParents().isEmpty() && un.getTag() instanceof ENamedElement) { @@ -91,10 +89,10 @@ public String getText(Object element) { } s += " [" + (un).getMemory().size() + "]"; - } - if (n instanceof IndexerWithMemory) { - s+="["+((IndexerWithMemory)n).getMemory().getSize()+"]"; - } + } + if (n instanceof IndexerWithMemory) { + s += "[" + ((IndexerWithMemory) n).getMemory().getSize() + "]"; + } if (!(n instanceof UniquenessEnforcerNode || n instanceof ConstantNode)) { StringBuilder sb = new StringBuilder(); sb.append("\n"); @@ -114,33 +112,33 @@ public String getText(Object element) { s += sb.toString(); } } - return s; - } - return "!"; -// return s+super.getText(element); - } - + return s; + } + return "!"; + // return s+super.getText(element); + } + @Override - public IFigure getTooltip(Object entity) { + public IFigure getTooltip(Object entity) { if (entity instanceof Node) { - Node n = (Node)entity; - String s=""; - - for (Stub st : getStubsForNode(n)) { - s+=getEnforcedConstraints(st); - } - - FlowPage fp = new FlowPage(); - - TextFlow nameTf = new TextFlow(); -// nameTf.setFont(fontRegistry.get("default")); - TextFlow infoTf = new TextFlow(); -// infoTf.setFont(fontRegistry.get("code")); - + Node n = (Node) entity; + String s = ""; + + for (Stub st : getStubsForNode(n)) { + s += getEnforcedConstraints(st); + } + + FlowPage fp = new FlowPage(); + + TextFlow nameTf = new TextFlow(); + // nameTf.setFont(fontRegistry.get("default")); + TextFlow infoTf = new TextFlow(); + // infoTf.setFont(fontRegistry.get("code")); + nameTf.setText(n.toString()); - String info="";//"\n"; - info+="Stubs:\n"+s;//+"\n"; - infoTf.setText(info); + String info = "";// "\n"; + info += "Stubs:\n" + s;// +"\n"; + infoTf.setText(info); if (entity instanceof RetePatternMatcher) { if (((Node) entity).getTag() instanceof Pattern) { Pattern pattern = (Pattern) ((Node) entity).getTag(); @@ -158,91 +156,94 @@ public IFigure getTooltip(Object entity) { nameTf.setText(sb.toString()); fp.add(nameTf); } - fp.add(infoTf); - return fp; + fp.add(infoTf); + return fp; + } + return null; + } + + // useful only for production nodes + private static String getEnforcedConstraints(Stub st) { + String s = ""; + for (Object _pc : st.getAllEnforcedConstraints()) { + PConstraint pc = (PConstraint) _pc; + s += "\t[" + pc.getClass().getSimpleName() + "]:"; + for (Object _v : pc.getAffectedVariables()) { + PVariable v = (PVariable) _v; + s += "{" + v.getName() + "}"; + } + s += "\n"; } - return null; - } - - // useful only for production nodes - private static String getEnforcedConstraints(Stub st) { - String s=""; - for (Object _pc : st.getAllEnforcedConstraints()) { - PConstraint pc = (PConstraint) _pc; - s+="\t["+pc.getClass().getSimpleName()+"]:"; - for (Object _v : pc.getAffectedVariables()) { - PVariable v = (PVariable) _v; - s+="{"+v.getName()+"}"; - } - s+="\n"; - } - return s; - } - - private Collection>> getStubsForNode(Node n) { - Collection>> r = reverseMap.get(n); - if (r!=null) return r; - else return Collections.EMPTY_SET; - } - - Map>>> reverseMap;// = new HashMap>>>(); - - private void resetReverseMap() { - reverseMap = new HashMap>>>(); - } - - private void initalizeReverseMap(Production prod) { - for (Object _stubOfProd : rb.getParentStubsOfReceiver(new Address(prod))) { - Stub stubOfProd = (Stub) _stubOfProd; - for (Stub> s : getAllParentStubs(stubOfProd)) { - Address address = (Address) s.getHandle(); - Node n = rb.getHeadContainer().resolveLocal(address); - Collection>> t = reverseMap.get(n); - if (t==null) { - t=new HashSet>>(); - } - t.add(s); - reverseMap.put(n, t); - } - } - } - - private static Collection>> getAllParentStubs(Stub> st) { - if (st!=null) { - Vector>> v = new Vector>>(); - v.add(st); - v.addAll(getAllParentStubs( st.getPrimaryParentStub() ) ); - v.addAll(getAllParentStubs( st.getSecondaryParentStub() ) ); - return v; - } else return Collections.EMPTY_LIST; - } - - @Override - public Color getNodeHighlightColor(Object entity) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Color getBorderColor(Object entity) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Color getBorderHighlightColor(Object entity) { - // TODO Auto-generated method stub - return null; - } - - @Override - public int getBorderWidth(Object entity) { - // TODO Auto-generated method stub - return 0; - } - - @Override - public Color getBackgroundColour(Object entity) { + return s; + } + + private Collection>> getStubsForNode(Node n) { + Collection>> r = reverseMap.get(n); + if (r != null) + return r; + else + return Collections.EMPTY_SET; + } + + Map>>> reverseMap;// = new HashMap>>>(); + + private void resetReverseMap() { + reverseMap = new HashMap>>>(); + } + + private void initalizeReverseMap(Production prod) { + for (Object _stubOfProd : rb.getParentStubsOfReceiver(new Address(prod))) { + Stub stubOfProd = (Stub) _stubOfProd; + for (Stub> s : getAllParentStubs(stubOfProd)) { + Address address = (Address) s.getHandle(); + Node n = rb.getHeadContainer().resolveLocal(address); + Collection>> t = reverseMap.get(n); + if (t == null) { + t = new HashSet>>(); + } + t.add(s); + reverseMap.put(n, t); + } + } + } + + private static Collection>> getAllParentStubs(Stub> st) { + if (st != null) { + Vector>> v = new Vector>>(); + v.add(st); + v.addAll(getAllParentStubs(st.getPrimaryParentStub())); + v.addAll(getAllParentStubs(st.getSecondaryParentStub())); + return v; + } else + return Collections.EMPTY_LIST; + } + + @Override + public Color getNodeHighlightColor(Object entity) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Color getBorderColor(Object entity) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Color getBorderHighlightColor(Object entity) { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getBorderWidth(Object entity) { + // TODO Auto-generated method stub + return 0; + } + + @Override + public Color getBackgroundColour(Object entity) { if (entity instanceof Indexer) { return theme.getNodeColor(INDEXER_ID); } else if (entity instanceof RetePatternMatcher) { @@ -253,11 +254,11 @@ public Color getBackgroundColour(Object entity) { return theme.getNodeColor(INPUT_ID); } } - return null; - } + return null; + } - @Override - public Color getForegroundColour(Object entity) { + @Override + public Color getForegroundColour(Object entity) { if (entity instanceof Indexer) { return theme.getTextColor(INDEXER_ID); } else if (entity instanceof RetePatternMatcher) { @@ -268,13 +269,13 @@ public Color getForegroundColour(Object entity) { return theme.getTextColor(INPUT_ID); } } - return null; - } + return null; + } - @Override - public boolean fisheyeNode(Object entity) { - // TODO Auto-generated method stub + @Override + public boolean fisheyeNode(Object entity) { + // TODO Auto-generated method stub return true; - } + } } diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/IncQueryGUIPlugin.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/IncQueryGUIPlugin.java index 26cb4019..638892fb 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/IncQueryGUIPlugin.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/IncQueryGUIPlugin.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui; - +package org.eclipse.incquery.tooling.ui; + import org.eclipse.core.runtime.ILog; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; @@ -19,81 +19,83 @@ import org.eclipse.ui.plugin.AbstractUIPlugin; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; - -/** - * The activator class controls the plug-in life cycle - */ -public class IncQueryGUIPlugin extends AbstractUIPlugin { - - /** - * The plug-in ID - */ - public static final String PLUGIN_ID = "org.eclipse.incquery.tooling.ui"; - - public static final String ICON_ROOT = "navigator_root"; - public static final String ICON_MATCHER = "matcher"; - public static final String ICON_MATCH = "match"; - public static final String ICON_ERROR = "error"; - public static final String ICON_ARROW_RIGHT = "arrow_right"; - public static final String ICON_ARROW_LEFT = "arrow_left"; - public static final String ICON_PIN = "pin"; - public static final String ICON_ARROW_TOP = "arrow_top"; - public static final String ICON_ARROW_BOTTOM = "arrow_bottom"; - public static final String ICON_EPACKAGE = "epackage"; - public static final String ICON_EIQ = "eiq"; - - // The shared instance - private static IncQueryGUIPlugin plugin; - - /* - * (non-Javadoc) - * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext) - */ - @Override - public void start(BundleContext context) throws Exception { - super.start(context); - plugin = this; - } - - /* - * (non-Javadoc) - * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) - */ - @Override - public void stop(BundleContext context) throws Exception { - plugin = null; - super.stop(context); - } - - /** - * Returns the shared instance - * - * @return the shared instance - */ - public static IncQueryGUIPlugin getDefault() { - return plugin; - } - - @Override - protected void initializeImageRegistry(ImageRegistry reg) { - super.initializeImageRegistry(reg); - @SuppressWarnings("unused") - Bundle bundle = Platform.getBundle(PLUGIN_ID); - reg.put(ICON_ROOT, imageDescriptorFromPlugin(PLUGIN_ID, "icons/root.gif")); - reg.put(ICON_MATCHER, imageDescriptorFromPlugin(PLUGIN_ID, "icons/matcher.gif")); - reg.put(ICON_MATCH, imageDescriptorFromPlugin(PLUGIN_ID, "icons/match.gif")); - reg.put(ICON_ERROR, imageDescriptorFromPlugin(PLUGIN_ID, "icons/error.gif")); - reg.put(ICON_PIN, imageDescriptorFromPlugin(PLUGIN_ID, "icons/pin.gif")); - reg.put(ICON_ARROW_RIGHT, imageDescriptorFromPlugin(PLUGIN_ID, "icons/arrow_right.gif")); - reg.put(ICON_ARROW_LEFT, imageDescriptorFromPlugin(PLUGIN_ID, "icons/arrow_left.gif")); - reg.put(ICON_ARROW_TOP, imageDescriptorFromPlugin(PLUGIN_ID, "icons/arrow_top.gif")); - reg.put(ICON_ARROW_BOTTOM, imageDescriptorFromPlugin(PLUGIN_ID, "icons/arrow_bottom.gif")); - reg.put(ICON_EPACKAGE, imageDescriptorFromPlugin(PLUGIN_ID, "icons/epackage.gif")); - reg.put(ICON_EIQ, imageDescriptorFromPlugin(PLUGIN_ID, "icons/logo2.png")); - } - - public void logException(String message, Throwable exception) { - ILog logger = getLog(); - logger.log(new Status(IStatus.ERROR, PLUGIN_ID, message, exception)); - } -} + +/** + * The activator class controls the plug-in life cycle + */ +public class IncQueryGUIPlugin extends AbstractUIPlugin { + + /** + * The plug-in ID + */ + public static final String PLUGIN_ID = "org.eclipse.incquery.tooling.ui"; + + public static final String ICON_ROOT = "navigator_root"; + public static final String ICON_MATCHER = "matcher"; + public static final String ICON_MATCH = "match"; + public static final String ICON_ERROR = "error"; + public static final String ICON_ARROW_RIGHT = "arrow_right"; + public static final String ICON_ARROW_LEFT = "arrow_left"; + public static final String ICON_PIN = "pin"; + public static final String ICON_ARROW_TOP = "arrow_top"; + public static final String ICON_ARROW_BOTTOM = "arrow_bottom"; + public static final String ICON_EPACKAGE = "epackage"; + public static final String ICON_EIQ = "eiq"; + + // The shared instance + private static IncQueryGUIPlugin plugin; + + /* + * (non-Javadoc) + * + * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext) + */ + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) + */ + @Override + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static IncQueryGUIPlugin getDefault() { + return plugin; + } + + @Override + protected void initializeImageRegistry(ImageRegistry reg) { + super.initializeImageRegistry(reg); + @SuppressWarnings("unused") + Bundle bundle = Platform.getBundle(PLUGIN_ID); + reg.put(ICON_ROOT, imageDescriptorFromPlugin(PLUGIN_ID, "icons/root.gif")); + reg.put(ICON_MATCHER, imageDescriptorFromPlugin(PLUGIN_ID, "icons/matcher.gif")); + reg.put(ICON_MATCH, imageDescriptorFromPlugin(PLUGIN_ID, "icons/match.gif")); + reg.put(ICON_ERROR, imageDescriptorFromPlugin(PLUGIN_ID, "icons/error.gif")); + reg.put(ICON_PIN, imageDescriptorFromPlugin(PLUGIN_ID, "icons/pin.gif")); + reg.put(ICON_ARROW_RIGHT, imageDescriptorFromPlugin(PLUGIN_ID, "icons/arrow_right.gif")); + reg.put(ICON_ARROW_LEFT, imageDescriptorFromPlugin(PLUGIN_ID, "icons/arrow_left.gif")); + reg.put(ICON_ARROW_TOP, imageDescriptorFromPlugin(PLUGIN_ID, "icons/arrow_top.gif")); + reg.put(ICON_ARROW_BOTTOM, imageDescriptorFromPlugin(PLUGIN_ID, "icons/arrow_bottom.gif")); + reg.put(ICON_EPACKAGE, imageDescriptorFromPlugin(PLUGIN_ID, "icons/epackage.gif")); + reg.put(ICON_EIQ, imageDescriptorFromPlugin(PLUGIN_ID, "icons/logo2.png")); + } + + public void logException(String message, Throwable exception) { + ILog logger = getLog(); + logger.log(new Status(IStatus.ERROR, PLUGIN_ID, message, exception)); + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/IncQueryLanguageExecutableExtensionFactory.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/IncQueryLanguageExecutableExtensionFactory.java index 5b7436ab..6129942f 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/IncQueryLanguageExecutableExtensionFactory.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/IncQueryLanguageExecutableExtensionFactory.java @@ -14,12 +14,11 @@ import org.eclipse.incquery.patternlanguage.emf.ui.EMFPatternLanguageExecutableExtensionFactory; import org.osgi.framework.Bundle; -public class IncQueryLanguageExecutableExtensionFactory extends - EMFPatternLanguageExecutableExtensionFactory { +public class IncQueryLanguageExecutableExtensionFactory extends EMFPatternLanguageExecutableExtensionFactory { - @Override - protected Bundle getBundle() { - return IncQueryGUIPlugin.getDefault().getBundle(); - } + @Override + protected Bundle getBundle() { + return IncQueryGUIPlugin.getDefault().getBundle(); + } } diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/content/QueryFolderFilter.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/content/QueryFolderFilter.java index 82e2db7c..1ebe965b 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/content/QueryFolderFilter.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/content/QueryFolderFilter.java @@ -21,25 +21,25 @@ public class QueryFolderFilter extends ViewerFilter { - @Override - public boolean select(Viewer viewer, Object parentElement, Object element) { - try { - //Filter only active on IncQuery projects - if (parentElement instanceof IProject) { - IProject project = (IProject) parentElement; - if (project.hasNature(IncQueryNature.NATURE_ID)) - return true; - } - if (element instanceof IFolder) { - IFolder folder = (IFolder) element; - if (XmiModelUtil.XMI_OUTPUT_FOLDER.equals(folder.getName())) { - return false; - } - } - } catch (CoreException e) { - //If exception is thrown, simply ignore it, and filter nothing - } - return true; - } + @Override + public boolean select(Viewer viewer, Object parentElement, Object element) { + try { + // Filter only active on IncQuery projects + if (parentElement instanceof IProject) { + IProject project = (IProject) parentElement; + if (project.hasNature(IncQueryNature.NATURE_ID)) + return true; + } + if (element instanceof IFolder) { + IFolder folder = (IFolder) element; + if (XmiModelUtil.XMI_OUTPUT_FOLDER.equals(folder.getName())) { + return false; + } + } + } catch (CoreException e) { + // If exception is thrown, simply ignore it, and filter nothing + } + return true; + } } diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/dialog/PatternMatchDialogContentProvider.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/dialog/PatternMatchDialogContentProvider.java index ca1867f1..cce39307 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/dialog/PatternMatchDialogContentProvider.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/dialog/PatternMatchDialogContentProvider.java @@ -19,82 +19,94 @@ /** * @author Mark Czotter - * + * */ public class PatternMatchDialogContentProvider implements ITreeContentProvider { - private IncQueryMatcher matcher; - private Collection matches; - - public PatternMatchDialogContentProvider( - IncQueryMatcher matcher, - Collection matches) { - this.matcher = matcher; - this.matches = matches; - } + private IncQueryMatcher matcher; + private Collection matches; + + public PatternMatchDialogContentProvider(IncQueryMatcher matcher, + Collection matches) { + this.matcher = matcher; + this.matches = matches; + } - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.IContentProvider#dispose() - */ - @Override - public void dispose() { - this.matcher = null; - this.matches = null; - } + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + @Override + public void dispose() { + this.matcher = null; + this.matches = null; + } - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) - */ - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - if (newInput != null && newInput instanceof IncQueryMatcher && newInput != oldInput) { - this.matcher = (IncQueryMatcher) newInput; - this.matches = matcher.getAllMatches(); - } - } + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, + * java.lang.Object) + */ + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + if (newInput != null && newInput instanceof IncQueryMatcher && newInput != oldInput) { + this.matcher = (IncQueryMatcher) newInput; + this.matches = matcher.getAllMatches(); + } + } - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.ITreeContentProvider#getElements(java.lang.Object) - */ - @Override - public Object[] getElements(Object inputElement) { - if (inputElement instanceof IncQueryMatcher) { - return matches.toArray(); - } - return null; - } + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ITreeContentProvider#getElements(java.lang.Object) + */ + @Override + public Object[] getElements(Object inputElement) { + if (inputElement instanceof IncQueryMatcher) { + return matches.toArray(); + } + return null; + } - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) - */ - @Override - public Object[] getChildren(Object parentElement) { - if (parentElement instanceof IncQueryMatcher) { - return matches.toArray(); - } - return null; - } + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) + */ + @Override + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof IncQueryMatcher) { + return matches.toArray(); + } + return null; + } - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) - */ - @Override - public Object getParent(Object element) { - if (element instanceof IPatternMatch) { - return matcher; - } - return null; - } + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) + */ + @Override + public Object getParent(Object element) { + if (element instanceof IPatternMatch) { + return matcher; + } + return null; + } - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object) - */ - @Override - public boolean hasChildren(Object element) { - if (element instanceof IncQueryMatcher) { - return !matches.isEmpty(); - } - return false; - } + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object) + */ + @Override + public boolean hasChildren(Object element) { + if (element instanceof IncQueryMatcher) { + return !matches.isEmpty(); + } + return false; + } } diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/dialog/PatternMatchDialogLabelProvider.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/dialog/PatternMatchDialogLabelProvider.java index ff610ca1..74c91357 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/dialog/PatternMatchDialogLabelProvider.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/dialog/PatternMatchDialogLabelProvider.java @@ -21,65 +21,78 @@ /** * @author Mark Czotter - * + * */ public class PatternMatchDialogLabelProvider implements ILabelProvider { - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener) - */ - @Override - public void addListener(ILabelProviderListener listener) { - } + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener) + */ + @Override + public void addListener(ILabelProviderListener listener) { + } - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose() - */ - @Override - public void dispose() { - } + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose() + */ + @Override + public void dispose() { + } - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object, java.lang.String) - */ - @Override - public boolean isLabelProperty(Object element, String property) { - return false; - } + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object, java.lang.String) + */ + @Override + public boolean isLabelProperty(Object element, String property) { + return false; + } - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener) - */ - @Override - public void removeListener(ILabelProviderListener listener) { - } + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener) + */ + @Override + public void removeListener(ILabelProviderListener listener) { + } - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object) - */ - @Override - public Image getImage(Object element) { - ImageRegistry imageRegistry = IncQueryGUIPlugin.getDefault().getImageRegistry(); - if (element instanceof IPatternMatch) { - return imageRegistry.get(IncQueryGUIPlugin.ICON_MATCH); - } - return null; - } + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object) + */ + @Override + public Image getImage(Object element) { + ImageRegistry imageRegistry = IncQueryGUIPlugin.getDefault().getImageRegistry(); + if (element instanceof IPatternMatch) { + return imageRegistry.get(IncQueryGUIPlugin.ICON_MATCH); + } + return null; + } - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object) - */ - @Override - public String getText(Object element) { - if (element instanceof IPatternMatch) { - String message = DatabindingUtil.getMessage((IPatternMatch) element, true); - if (message != null) { - return DatabindingAdapterUtil.getMessage((IPatternMatch) element, message); - } else { - return element.toString(); - } - } - return null; - } + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object) + */ + @Override + public String getText(Object element) { + if (element instanceof IPatternMatch) { + String message = DatabindingUtil.getMessage((IPatternMatch) element, true); + if (message != null) { + return DatabindingAdapterUtil.getMessage((IPatternMatch) element, message); + } else { + return element.toString(); + } + } + return null; + } } diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/dialog/SampleUIDialogCreator.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/dialog/SampleUIDialogCreator.java index 88be666e..9ec8158b 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/dialog/SampleUIDialogCreator.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/dialog/SampleUIDialogCreator.java @@ -22,27 +22,29 @@ /** * @author Mark Czotter - * + * */ public class SampleUIDialogCreator { - /** - * Creates a dialog that shows the current matches of the matcher. - * @param parent - * @return - */ - public static final Dialog createDialog(IncQueryMatcher matcher) { - final String patternFqn = matcher.getPatternName(); - final Collection matches = matcher.getAllMatches(); - final Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); - final ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(shell, new PatternMatchDialogLabelProvider(), new PatternMatchDialogContentProvider(matcher, matches)); - dialog.setTitle(String.format("Matchset of the pattern %s", patternFqn)); - dialog.setMessage(DatabindingUtil.getMessage(matcher, matches.size(), patternFqn)); - dialog.setEmptyListMessage("No matches!"); - dialog.setAllowMultiple(false); - dialog.setDoubleClickSelects(false); - dialog.setInput(matcher); - return dialog; - } - + /** + * Creates a dialog that shows the current matches of the matcher. + * + * @param parent + * @return + */ + public static final Dialog createDialog(IncQueryMatcher matcher) { + final String patternFqn = matcher.getPatternName(); + final Collection matches = matcher.getAllMatches(); + final Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); + final ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(shell, + new PatternMatchDialogLabelProvider(), new PatternMatchDialogContentProvider(matcher, matches)); + dialog.setTitle(String.format("Matchset of the pattern %s", patternFqn)); + dialog.setMessage(DatabindingUtil.getMessage(matcher, matches.size(), patternFqn)); + dialog.setEmptyListMessage("No matches!"); + dialog.setAllowMultiple(false); + dialog.setDoubleClickSelects(false); + dialog.setInput(matcher); + return dialog; + } + } diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/QueryExplorer.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/QueryExplorer.java index 9b2af5b4..f79e0d1c 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/QueryExplorer.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/QueryExplorer.java @@ -74,307 +74,307 @@ import com.google.inject.Injector; /** - * Query Explorer view implementation. + * Query Explorer view implementation. * * @author Tamas Szabo - * + * */ public class QueryExplorer extends ViewPart { - private static final String PACKAGE_PRESENTATION_STATE = "packagePresentationState"; - private static final String PATTERNS_VIEWER_FLYOUT_STATE = "patternsViewerFlyoutState"; - private static final String DETAILS_VIEW_FLYOUT_STATE = "detailsViewFlyoutState"; + private static final String PACKAGE_PRESENTATION_STATE = "packagePresentationState"; + private static final String PATTERNS_VIEWER_FLYOUT_STATE = "patternsViewerFlyoutState"; + private static final String DETAILS_VIEW_FLYOUT_STATE = "detailsViewFlyoutState"; public static final String ID = "org.eclipse.incquery.queryexplorer.QueryExplorer"; - - private final Map modelConnectorMap = new HashMap(); - - private TableViewer detailsTableViewer; - private CheckboxTreeViewer patternsTreeViewer; - private TreeViewer matcherTreeViewer; - - private final MatcherContentProvider matcherContentProvider; - private final MatcherLabelProvider matcherLabelProvider; - private final MatcherTreeViewerRoot matcherTreeViewerRoot; - - public static PatternsViewerInput patternsViewerInput = new PatternsViewerInput(); - - private FlyoutControlComposite patternsViewerFlyout; - private FlyoutControlComposite detailsViewerFlyout; - - private IFlyoutPreferences detailsViewerFlyoutPreferences; - private IFlyoutPreferences patternsViewerFlyoutPreferences; - - private final PatternsViewerFlatContentProvider flatCP; - private final PatternsViewerFlatLabelProvider flatLP; - private final PatternsViewerHierarchicalContentProvider hierarchicalCP; - private final PatternsViewerHierarchicalLabelProvider hierarchicalLP; - - @Inject - private Injector injector; - - @Inject - private TableViewerUtil tableViewerUtil; - - private String mementoPackagePresentation = "flat"; - - public QueryExplorer() { - matcherContentProvider = new MatcherContentProvider(); - matcherLabelProvider = new MatcherLabelProvider(); - matcherTreeViewerRoot = new MatcherTreeViewerRoot(); - flatCP = new PatternsViewerFlatContentProvider(); - hierarchicalCP = new PatternsViewerHierarchicalContentProvider(); - hierarchicalLP = new PatternsViewerHierarchicalLabelProvider(patternsViewerInput); - flatLP = new PatternsViewerFlatLabelProvider(patternsViewerInput); - } - - public MatcherTreeViewerRoot getMatcherTreeViewerRoot() { - return matcherTreeViewerRoot; - } - - public Map getModelConnectorMap() { - return modelConnectorMap; - } - - public static QueryExplorer getInstance() { - //In Juno activeWorkbenchWindow will be null when Eclipse is closing - IWorkbenchWindow activeWorkbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (activeWorkbenchWindow != null && activeWorkbenchWindow.getActivePage() != null) { - return (QueryExplorer) activeWorkbenchWindow.getActivePage().findView(ID); - } - return null; - } - - public TreeViewer getMatcherTreeViewer() { - return matcherTreeViewer; - } - - public PatternsViewerFlatContentProvider getFlatContentProvider() { - return flatCP; - } - - public PatternsViewerFlatLabelProvider getFlatLabelProvider() { - return flatLP; - } - - public PatternsViewerHierarchicalContentProvider getHierarchicalContentProvider() { - return hierarchicalCP; - } - - public PatternsViewerHierarchicalLabelProvider getHierarchicalLabelProvider() { - return hierarchicalLP; - } - - @Override - public void init(IViewSite site, IMemento memento) throws PartInitException { - super.init(site, memento); - int detailsState = IFlyoutPreferences.STATE_OPEN; - int patternsState = IFlyoutPreferences.STATE_COLLAPSED; - if (memento != null) { - if (memento.getInteger(DETAILS_VIEW_FLYOUT_STATE) != null) { - detailsState = memento.getInteger(DETAILS_VIEW_FLYOUT_STATE); - } - if (memento.getInteger(PATTERNS_VIEWER_FLYOUT_STATE) != null) { - patternsState = memento.getInteger(DETAILS_VIEW_FLYOUT_STATE); - } - if (memento.getString(PACKAGE_PRESENTATION_STATE) != null) { - mementoPackagePresentation = memento.getString(PACKAGE_PRESENTATION_STATE); - } - } - detailsViewerFlyoutPreferences = new FlyoutPreferences(IFlyoutPreferences.DOCK_EAST, detailsState, 300); - patternsViewerFlyoutPreferences = new FlyoutPreferences(IFlyoutPreferences.DOCK_WEST, patternsState, 100); - - IncQueryGUIPlugin.getDefault().getPreferenceStore().setDefault(PreferenceConstants.WILDCARD_MODE, true); - } - - public void clearTableViewer() { - if (detailsTableViewer.getContentProvider() != null) { - detailsTableViewer.setInput(null); - } - } - - @Override + + private final Map modelConnectorMap = new HashMap(); + + private TableViewer detailsTableViewer; + private CheckboxTreeViewer patternsTreeViewer; + private TreeViewer matcherTreeViewer; + + private final MatcherContentProvider matcherContentProvider; + private final MatcherLabelProvider matcherLabelProvider; + private final MatcherTreeViewerRoot matcherTreeViewerRoot; + + public static PatternsViewerInput patternsViewerInput = new PatternsViewerInput(); + + private FlyoutControlComposite patternsViewerFlyout; + private FlyoutControlComposite detailsViewerFlyout; + + private IFlyoutPreferences detailsViewerFlyoutPreferences; + private IFlyoutPreferences patternsViewerFlyoutPreferences; + + private final PatternsViewerFlatContentProvider flatCP; + private final PatternsViewerFlatLabelProvider flatLP; + private final PatternsViewerHierarchicalContentProvider hierarchicalCP; + private final PatternsViewerHierarchicalLabelProvider hierarchicalLP; + + @Inject + private Injector injector; + + @Inject + private TableViewerUtil tableViewerUtil; + + private String mementoPackagePresentation = "flat"; + + public QueryExplorer() { + matcherContentProvider = new MatcherContentProvider(); + matcherLabelProvider = new MatcherLabelProvider(); + matcherTreeViewerRoot = new MatcherTreeViewerRoot(); + flatCP = new PatternsViewerFlatContentProvider(); + hierarchicalCP = new PatternsViewerHierarchicalContentProvider(); + hierarchicalLP = new PatternsViewerHierarchicalLabelProvider(patternsViewerInput); + flatLP = new PatternsViewerFlatLabelProvider(patternsViewerInput); + } + + public MatcherTreeViewerRoot getMatcherTreeViewerRoot() { + return matcherTreeViewerRoot; + } + + public Map getModelConnectorMap() { + return modelConnectorMap; + } + + public static QueryExplorer getInstance() { + // In Juno activeWorkbenchWindow will be null when Eclipse is closing + IWorkbenchWindow activeWorkbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (activeWorkbenchWindow != null && activeWorkbenchWindow.getActivePage() != null) { + return (QueryExplorer) activeWorkbenchWindow.getActivePage().findView(ID); + } + return null; + } + + public TreeViewer getMatcherTreeViewer() { + return matcherTreeViewer; + } + + public PatternsViewerFlatContentProvider getFlatContentProvider() { + return flatCP; + } + + public PatternsViewerFlatLabelProvider getFlatLabelProvider() { + return flatLP; + } + + public PatternsViewerHierarchicalContentProvider getHierarchicalContentProvider() { + return hierarchicalCP; + } + + public PatternsViewerHierarchicalLabelProvider getHierarchicalLabelProvider() { + return hierarchicalLP; + } + + @Override + public void init(IViewSite site, IMemento memento) throws PartInitException { + super.init(site, memento); + int detailsState = IFlyoutPreferences.STATE_OPEN; + int patternsState = IFlyoutPreferences.STATE_COLLAPSED; + if (memento != null) { + if (memento.getInteger(DETAILS_VIEW_FLYOUT_STATE) != null) { + detailsState = memento.getInteger(DETAILS_VIEW_FLYOUT_STATE); + } + if (memento.getInteger(PATTERNS_VIEWER_FLYOUT_STATE) != null) { + patternsState = memento.getInteger(DETAILS_VIEW_FLYOUT_STATE); + } + if (memento.getString(PACKAGE_PRESENTATION_STATE) != null) { + mementoPackagePresentation = memento.getString(PACKAGE_PRESENTATION_STATE); + } + } + detailsViewerFlyoutPreferences = new FlyoutPreferences(IFlyoutPreferences.DOCK_EAST, detailsState, 300); + patternsViewerFlyoutPreferences = new FlyoutPreferences(IFlyoutPreferences.DOCK_WEST, patternsState, 100); + + IncQueryGUIPlugin.getDefault().getPreferenceStore().setDefault(PreferenceConstants.WILDCARD_MODE, true); + } + + public void clearTableViewer() { + if (detailsTableViewer.getContentProvider() != null) { + detailsTableViewer.setInput(null); + } + } + + @Override public void createPartControl(Composite parent) { - detailsViewerFlyout = new FlyoutControlComposite(parent, SWT.NONE, detailsViewerFlyoutPreferences); - detailsViewerFlyout.setTitleText("Details / Filters"); - detailsViewerFlyout.setValidDockLocations(IFlyoutPreferences.DOCK_EAST); - - patternsViewerFlyout = new FlyoutControlComposite(detailsViewerFlyout.getClientParent(), SWT.NONE, patternsViewerFlyoutPreferences); - patternsViewerFlyout.setTitleText("Pattern registry"); - patternsViewerFlyout.setValidDockLocations(IFlyoutPreferences.DOCK_WEST); - - matcherTreeViewer = new TreeViewer(patternsViewerFlyout.getClientParent()); - detailsTableViewer = new TableViewer(detailsViewerFlyout.getFlyoutParent(), SWT.FULL_SELECTION); - - //matcherTreeViewer configuration - matcherTreeViewer.setContentProvider(matcherContentProvider); - matcherTreeViewer.setLabelProvider(matcherLabelProvider); - matcherTreeViewer.setInput(matcherTreeViewerRoot); - matcherTreeViewer.setComparator(null); - IObservableValue selection = ViewersObservables.observeSingleSelection(matcherTreeViewer); - selection.addValueChangeListener(new MatcherTreeViewerSelectionChangeListener()); - DoubleClickListener listener = new DoubleClickListener(); - injector.injectMembers(listener); - matcherTreeViewer.addDoubleClickListener(listener); - - //patternsViewer configuration - patternsTreeViewer = new CheckboxTreeViewer(patternsViewerFlyout.getFlyoutParent(), SWT.CHECK | SWT.BORDER | SWT.MULTI); - patternsTreeViewer.addCheckStateListener(new CheckStateListener()); -// patternsTreeViewer.setContentProvider(flatCP); -// patternsTreeViewer.setLabelProvider(flatLP); - setPackagePresentation(mementoPackagePresentation, false); - patternsTreeViewer.setInput(patternsViewerInput); - - // Create menu manager. + detailsViewerFlyout = new FlyoutControlComposite(parent, SWT.NONE, detailsViewerFlyoutPreferences); + detailsViewerFlyout.setTitleText("Details / Filters"); + detailsViewerFlyout.setValidDockLocations(IFlyoutPreferences.DOCK_EAST); + + patternsViewerFlyout = new FlyoutControlComposite(detailsViewerFlyout.getClientParent(), SWT.NONE, + patternsViewerFlyoutPreferences); + patternsViewerFlyout.setTitleText("Pattern registry"); + patternsViewerFlyout.setValidDockLocations(IFlyoutPreferences.DOCK_WEST); + + matcherTreeViewer = new TreeViewer(patternsViewerFlyout.getClientParent()); + detailsTableViewer = new TableViewer(detailsViewerFlyout.getFlyoutParent(), SWT.FULL_SELECTION); + + // matcherTreeViewer configuration + matcherTreeViewer.setContentProvider(matcherContentProvider); + matcherTreeViewer.setLabelProvider(matcherLabelProvider); + matcherTreeViewer.setInput(matcherTreeViewerRoot); + matcherTreeViewer.setComparator(null); + IObservableValue selection = ViewersObservables.observeSingleSelection(matcherTreeViewer); + selection.addValueChangeListener(new MatcherTreeViewerSelectionChangeListener()); + DoubleClickListener listener = new DoubleClickListener(); + injector.injectMembers(listener); + matcherTreeViewer.addDoubleClickListener(listener); + + // patternsViewer configuration + patternsTreeViewer = new CheckboxTreeViewer(patternsViewerFlyout.getFlyoutParent(), SWT.CHECK | SWT.BORDER + | SWT.MULTI); + patternsTreeViewer.addCheckStateListener(new CheckStateListener()); + // patternsTreeViewer.setContentProvider(flatCP); + // patternsTreeViewer.setLabelProvider(flatLP); + setPackagePresentation(mementoPackagePresentation, false); + patternsTreeViewer.setInput(patternsViewerInput); + + // Create menu manager. MenuManager matcherTreeViewerMenuManager = new MenuManager(); matcherTreeViewerMenuManager.setRemoveAllWhenShown(true); matcherTreeViewerMenuManager.addMenuListener(new IMenuListener() { - @Override + @Override public void menuAboutToShow(IMenuManager mgr) { - fillContextMenu(mgr); + fillContextMenu(mgr); } - }); + }); // Create menu for tree viewer Menu matcherTreeViewerMenu = matcherTreeViewerMenuManager.createContextMenu(matcherTreeViewer.getControl()); - matcherTreeViewer.getControl().setMenu(matcherTreeViewerMenu); + matcherTreeViewer.getControl().setMenu(matcherTreeViewerMenu); getSite().registerContextMenu("org.eclipse.incquery.queryexplorer.QueryExplorer.treeViewerMenu", matcherTreeViewerMenuManager, matcherTreeViewer); - + MenuManager patternsViewerMenuManager = new MenuManager(); patternsViewerMenuManager.setRemoveAllWhenShown(true); patternsViewerMenuManager.addMenuListener(new IMenuListener() { - @Override + @Override public void menuAboutToShow(IMenuManager mgr) { - fillContextMenu(mgr); + fillContextMenu(mgr); } }); - // Create menu for patterns viewer - Menu patternsViewerMenu = patternsViewerMenuManager.createContextMenu(patternsTreeViewer.getControl()); - patternsTreeViewer.getControl().setMenu(patternsViewerMenu); + // Create menu for patterns viewer + Menu patternsViewerMenu = patternsViewerMenuManager.createContextMenu(patternsTreeViewer.getControl()); + patternsTreeViewer.getControl().setMenu(patternsViewerMenu); getSite().registerContextMenu("org.eclipse.incquery.queryexplorer.QueryExplorer.patternsViewerMenu", patternsViewerMenuManager, patternsTreeViewer); - - //tableView configuration - Table table = detailsTableViewer.getTable(); - table.setHeaderVisible(true); - table.setLinesVisible(true); - - //tableViewer.setContentProvider(new ObservableListContentProvider()); - GridData gridData = new GridData(); - gridData.verticalAlignment = GridData.FILL; - gridData.horizontalSpan = 2; - gridData.grabExcessHorizontalSpace = true; - gridData.grabExcessVerticalSpace = true; - gridData.horizontalAlignment = GridData.FILL; - detailsTableViewer.getControl().setLayoutData(gridData); - - //Focus listening and selection providing - getSite().setSelectionProvider(matcherTreeViewer); - - initFileListener(); - initPatternsViewerWithGeneratedPatterns(); - } - - private void fillContextMenu(IMenuManager mgr) { + + // tableView configuration + Table table = detailsTableViewer.getTable(); + table.setHeaderVisible(true); + table.setLinesVisible(true); + + // tableViewer.setContentProvider(new ObservableListContentProvider()); + GridData gridData = new GridData(); + gridData.verticalAlignment = GridData.FILL; + gridData.horizontalSpan = 2; + gridData.grabExcessHorizontalSpace = true; + gridData.grabExcessVerticalSpace = true; + gridData.horizontalAlignment = GridData.FILL; + detailsTableViewer.getControl().setLayoutData(gridData); + + // Focus listening and selection providing + getSite().setSelectionProvider(matcherTreeViewer); + + initFileListener(); + initPatternsViewerWithGeneratedPatterns(); + } + + private void fillContextMenu(IMenuManager mgr) { mgr.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS)); - } + } - @Override + @Override public void setFocus() { - matcherTreeViewer.getControl().setFocus(); - } - - private class MatcherTreeViewerSelectionChangeListener implements IValueChangeListener { - - @Override - public void handleValueChange(ValueChangeEvent event) { - Object value = event.getObservableValue().getValue(); - - tableViewerUtil.clearTableViewerColumns(detailsTableViewer); - clearTableViewer(); - - if (value instanceof ObservablePatternMatcher) { - ObservablePatternMatcher observableMatcher = (ObservablePatternMatcher) value; - if (observableMatcher.getMatcher() != null) { - tableViewerUtil.prepareTableViewerForMatcherConfiguration(observableMatcher, detailsTableViewer); - String patternFqn = CorePatternLanguageHelper.getFullyQualifiedName(observableMatcher.getMatcher().getPattern()); - Pattern pattern = PatternRegistry.getInstance().getPatternByFqn(patternFqn); - List components = null; - if (PatternRegistry.getInstance().isGenerated(pattern)) { - components = patternsViewerInput.getGeneratedPatternsRoot().find(patternFqn); - components.add(0, patternsViewerInput.getGeneratedPatternsRoot()); - } - else { - components = patternsViewerInput.getGenericPatternsRoot().find(patternFqn); - components.add(0, patternsViewerInput.getGenericPatternsRoot()); - } - - if (components != null) { - patternsTreeViewer.setSelection(new TreeSelection(new TreePath(components.toArray()))); - } - } - else { - clearTableViewer(); - } - } - else if (value instanceof ObservablePatternMatch) { - ObservablePatternMatch match = (ObservablePatternMatch) value; - tableViewerUtil.prepareTableViewerForObservableInput(match, detailsTableViewer); - } - } - } - - private void initPatternsViewerWithGeneratedPatterns() { - for (Pattern pattern : DatabindingUtil.getGeneratedPatterns()) { - String patternFqn = CorePatternLanguageHelper.getFullyQualifiedName(pattern); - PatternRegistry.getInstance().addGeneratedPattern(pattern, patternFqn); - PatternRegistry.getInstance().addActivePattern(pattern); - patternsViewerInput.getGeneratedPatternsRoot().addComponent(patternFqn); - } - - patternsTreeViewer.refresh(); - patternsViewerInput.getGeneratedPatternsRoot().updateSelection(patternsTreeViewer); - } - - private void initFileListener() { - IResourceChangeListener listener = new ResourceChangeListener(injector); - ResourcesPlugin.getWorkspace().addResourceChangeListener(listener, IResourceChangeEvent.PRE_BUILD); - } - - public PatternsViewerInput getPatternsViewerInput() { - return patternsViewerInput; - } - - public CheckboxTreeViewer getPatternsViewer() { - return patternsTreeViewer; - } - - public FlyoutControlComposite getPatternsViewerFlyout() { - return patternsViewerFlyout; - } - - @Override - public void saveState(IMemento memento) { - super.saveState(memento); - memento.putInteger(DETAILS_VIEW_FLYOUT_STATE, detailsViewerFlyout.getPreferences().getState()); - memento.putInteger(PATTERNS_VIEWER_FLYOUT_STATE, patternsViewerFlyout.getPreferences().getState()); - memento.putString(PACKAGE_PRESENTATION_STATE, (patternsTreeViewer.getContentProvider() == flatCP) ? "flat" : "hierarchical"); - } - - public void setPackagePresentation(String command, boolean update) { - - if (command.contains("flat")) { - patternsTreeViewer.setContentProvider(flatCP); - patternsTreeViewer.setLabelProvider(flatLP); - } - else { - patternsTreeViewer.setContentProvider(hierarchicalCP); - patternsTreeViewer.setLabelProvider(hierarchicalLP); - } - - if (update) { - patternsViewerInput.getGeneratedPatternsRoot().updateSelection(patternsTreeViewer); - patternsViewerInput.getGenericPatternsRoot().updateSelection(patternsTreeViewer); - } - } + matcherTreeViewer.getControl().setFocus(); + } + + private class MatcherTreeViewerSelectionChangeListener implements IValueChangeListener { + + @Override + public void handleValueChange(ValueChangeEvent event) { + Object value = event.getObservableValue().getValue(); + + tableViewerUtil.clearTableViewerColumns(detailsTableViewer); + clearTableViewer(); + + if (value instanceof ObservablePatternMatcher) { + ObservablePatternMatcher observableMatcher = (ObservablePatternMatcher) value; + if (observableMatcher.getMatcher() != null) { + tableViewerUtil.prepareTableViewerForMatcherConfiguration(observableMatcher, detailsTableViewer); + String patternFqn = CorePatternLanguageHelper.getFullyQualifiedName(observableMatcher.getMatcher() + .getPattern()); + Pattern pattern = PatternRegistry.getInstance().getPatternByFqn(patternFqn); + List components = null; + if (PatternRegistry.getInstance().isGenerated(pattern)) { + components = patternsViewerInput.getGeneratedPatternsRoot().find(patternFqn); + components.add(0, patternsViewerInput.getGeneratedPatternsRoot()); + } else { + components = patternsViewerInput.getGenericPatternsRoot().find(patternFqn); + components.add(0, patternsViewerInput.getGenericPatternsRoot()); + } + + if (components != null) { + patternsTreeViewer.setSelection(new TreeSelection(new TreePath(components.toArray()))); + } + } else { + clearTableViewer(); + } + } else if (value instanceof ObservablePatternMatch) { + ObservablePatternMatch match = (ObservablePatternMatch) value; + tableViewerUtil.prepareTableViewerForObservableInput(match, detailsTableViewer); + } + } + } + + private void initPatternsViewerWithGeneratedPatterns() { + for (Pattern pattern : DatabindingUtil.getGeneratedPatterns()) { + String patternFqn = CorePatternLanguageHelper.getFullyQualifiedName(pattern); + PatternRegistry.getInstance().addGeneratedPattern(pattern, patternFqn); + PatternRegistry.getInstance().addActivePattern(pattern); + patternsViewerInput.getGeneratedPatternsRoot().addComponent(patternFqn); + } + + patternsTreeViewer.refresh(); + patternsViewerInput.getGeneratedPatternsRoot().updateSelection(patternsTreeViewer); + } + + private void initFileListener() { + IResourceChangeListener listener = new ResourceChangeListener(injector); + ResourcesPlugin.getWorkspace().addResourceChangeListener(listener, IResourceChangeEvent.PRE_BUILD); + } + + public PatternsViewerInput getPatternsViewerInput() { + return patternsViewerInput; + } + + public CheckboxTreeViewer getPatternsViewer() { + return patternsTreeViewer; + } + + public FlyoutControlComposite getPatternsViewerFlyout() { + return patternsViewerFlyout; + } + + @Override + public void saveState(IMemento memento) { + super.saveState(memento); + memento.putInteger(DETAILS_VIEW_FLYOUT_STATE, detailsViewerFlyout.getPreferences().getState()); + memento.putInteger(PATTERNS_VIEWER_FLYOUT_STATE, patternsViewerFlyout.getPreferences().getState()); + memento.putString(PACKAGE_PRESENTATION_STATE, (patternsTreeViewer.getContentProvider() == flatCP) ? "flat" + : "hierarchical"); + } + + public void setPackagePresentation(String command, boolean update) { + + if (command.contains("flat")) { + patternsTreeViewer.setContentProvider(flatCP); + patternsTreeViewer.setLabelProvider(flatLP); + } else { + patternsTreeViewer.setContentProvider(hierarchicalCP); + patternsTreeViewer.setLabelProvider(hierarchicalLP); + } + + if (update) { + patternsViewerInput.getGeneratedPatternsRoot().updateSelection(patternsTreeViewer); + patternsViewerInput.getGenericPatternsRoot().updateSelection(patternsTreeViewer); + } + } } diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/DetailElement.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/DetailElement.java index 5bb678f0..dcad46fc 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/DetailElement.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/DetailElement.java @@ -9,45 +9,44 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.content.detail; - -/** - * This class represents a single row in the table viewer and is associated to a single - * ObservableValue and it's value. - * - * @author Tamas Szabo - * - */ -public class DetailElement { - - private String key; - private String value; - - public DetailElement(String key, String value) { - super(); - this.key = key; - this.value = value; - } - - public String getKey() { - return key; - } - - public void setKey(String key) { - this.key = key; - } - - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } - - //Used by ViewerComparator too - @Override - public String toString() { - return key; - } -} +package org.eclipse.incquery.tooling.ui.queryexplorer.content.detail; + +/** + * This class represents a single row in the table viewer and is associated to a single ObservableValue and it's value. + * + * @author Tamas Szabo + * + */ +public class DetailElement { + + private String key; + private String value; + + public DetailElement(String key, String value) { + super(); + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + // Used by ViewerComparator too + @Override + public String toString() { + return key; + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/DetailElementCellModifier.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/DetailElementCellModifier.java index 9398c906..869d5133 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/DetailElementCellModifier.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/DetailElementCellModifier.java @@ -9,31 +9,31 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.content.detail; - -import org.eclipse.jface.viewers.ICellModifier; - -/** - * This is a basic implementation of the ICellModifier interface used for pattern matches. - * Note that this class is necessary because of the 'two-sided' table viewer used in the Details/Filters view. - * - * @author Tamas Szabo - * - */ -public class DetailElementCellModifier implements ICellModifier { - - @Override - public boolean canModify(Object element, String property) { - return false; - } - - @Override - public Object getValue(Object element, String property) { - return null; - } - - @Override - public void modify(Object element, String property, Object value) { - - } -} +package org.eclipse.incquery.tooling.ui.queryexplorer.content.detail; + +import org.eclipse.jface.viewers.ICellModifier; + +/** + * This is a basic implementation of the ICellModifier interface used for pattern matches. Note that this class is + * necessary because of the 'two-sided' table viewer used in the Details/Filters view. + * + * @author Tamas Szabo + * + */ +public class DetailElementCellModifier implements ICellModifier { + + @Override + public boolean canModify(Object element, String property) { + return false; + } + + @Override + public Object getValue(Object element, String property) { + return null; + } + + @Override + public void modify(Object element, String property, Object value) { + + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/DetailElementLabelProvider.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/DetailElementLabelProvider.java index b33c50c3..96080e30 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/DetailElementLabelProvider.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/DetailElementLabelProvider.java @@ -9,29 +9,29 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.content.detail; - -import org.eclipse.jface.viewers.ITableLabelProvider; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.swt.graphics.Image; - -public final class DetailElementLabelProvider extends LabelProvider implements ITableLabelProvider { - - public Image getColumnImage(Object element, int columnIndex) { - return null; - } - - @Override - public String getColumnText(Object element, int columnIndex) { - DetailElement de = (DetailElement) element; - switch (columnIndex) { - case 0: - return de.getKey(); - case 1: - return de.getValue(); - default: - return ""; - } - } - +package org.eclipse.incquery.tooling.ui.queryexplorer.content.detail; + +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.graphics.Image; + +public final class DetailElementLabelProvider extends LabelProvider implements ITableLabelProvider { + + public Image getColumnImage(Object element, int columnIndex) { + return null; + } + + @Override + public String getColumnText(Object element, int columnIndex) { + DetailElement de = (DetailElement) element; + switch (columnIndex) { + case 0: + return de.getKey(); + case 1: + return de.getValue(); + default: + return ""; + } + } + } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/DetailObserver.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/DetailObserver.java index e678d23b..480f245c 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/DetailObserver.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/DetailObserver.java @@ -9,19 +9,19 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.content.detail; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.databinding.observable.Diffs; -import org.eclipse.core.databinding.observable.list.AbstractObservableList; -import org.eclipse.core.databinding.observable.value.IObservableValue; -import org.eclipse.core.databinding.observable.value.IValueChangeListener; -import org.eclipse.core.databinding.observable.value.ValueChangeEvent; +package org.eclipse.incquery.tooling.ui.queryexplorer.content.detail; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.databinding.observable.Diffs; +import org.eclipse.core.databinding.observable.list.AbstractObservableList; +import org.eclipse.core.databinding.observable.value.IObservableValue; +import org.eclipse.core.databinding.observable.value.IValueChangeListener; +import org.eclipse.core.databinding.observable.value.ValueChangeEvent; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider; @@ -29,142 +29,138 @@ import org.eclipse.incquery.runtime.api.IPatternMatch; import org.eclipse.incquery.tooling.ui.queryexplorer.content.matcher.ObservablePatternMatch; import org.eclipse.incquery.tooling.ui.queryexplorer.util.DatabindingUtil; - -/** - * The class is used to provide input for the tableviewer for a given PatternMatch. - * All of the declared ObservableValues will be present in the table for the match. - * The generated DatabindableMatcher class is used to get IObservableValues for the given parameters. - * - * @author Tamas Szabo - * - */ -public class DetailObserver extends AbstractObservableList { - - private ObservablePatternMatch patternMatch; - private List details; - private ValueChangeListener listener; - private Map valueMap; - - public DetailObserver(DatabindingAdapter databindableMatcher, ObservablePatternMatch pm) { - this.patternMatch = pm; - this.details = new ArrayList(); - this.valueMap = new HashMap(); - this.listener = new ValueChangeListener(); - for (String param : databindableMatcher.getParameterNames()) { - IObservableValue oval = databindableMatcher.getObservableParameter(patternMatch.getPatternMatch(), param); - - if (oval != null) { - oval.addValueChangeListener(listener); - DetailElement de = new DetailElement(param, createValueRepresentation(oval.getValue())); - addDetail(oval, de, -1); - } - else { - Object value = patternMatch.getPatternMatch().get(param); - this.details.add(new DetailElement(param, createValueRepresentation(value))); - } - } - } - - private String createValueRepresentation(Object value) { - if (value == null) { - return null; - } - else if (value instanceof EObject) { - EObject obj = (EObject) value; - URI uri = obj.eClass().eResource().getURI(); - AdapterFactoryLabelProvider labelProvider = DatabindingUtil.getAdapterFactoryLabelProvider(uri); - if (labelProvider != null) { - return labelProvider.getText(obj); - } - } - else if (value instanceof Collection) { - return "Collection ["+((Collection) value).size()+"]"; - } - - return value.toString(); - } - - private void addDetail(IObservableValue ov, DetailElement de, int index) { - if (index == -1) { - this.details.add(de); - this.valueMap.put(ov, de); - fireListChange(Diffs.createListDiff(Diffs.createListDiffEntry(this.details.size(), true, de))); - } - else { - this.details.add(index, de); - this.valueMap.put(ov, de); - fireListChange(Diffs.createListDiff(Diffs.createListDiffEntry(index, true, de))); - } - } - - private void removeDetail(IObservableValue ov, DetailElement de, int index) { - this.details.remove(index); - this.valueMap.remove(ov); - fireListChange(Diffs.createListDiff(Diffs.createListDiffEntry(index, false, de))); - } - - @Override - public Object getElementType() { - return DetailElement.class; - } - - @Override - protected int doGetSize() { - return this.details.size(); - } - - @Override - public Object get(int index) { - return this.details.get(index); - } - - /** - * Used to observ changes in the observed values. - * - * @author Tamas Szabo - * - */ - private class ValueChangeListener implements IValueChangeListener { - - @Override - public void handleValueChange(ValueChangeEvent event) { - IObservableValue ov = event.getObservableValue(); - Object value = ov.getValue(); - DetailElement de = valueMap.get(ov); - int index = findElement(de); - removeDetail(ov, de, index); - DetailElement newDe = null; - - String data = ""; - if (value == null) { - data = null; - } - else if (value instanceof Collection) { - data = "Collection ["+((Collection) value).size()+"]"; - } - else { - data = value.toString(); - } - - newDe = new DetailElement(de.getKey(), data); - - addDetail(ov, newDe, index); - } - - } - - /** - * Find a given element is the details list. - * - * @param de element to be found - * @return the index of the element if it is present in the detials list, or -1 if not - */ - private int findElement(DetailElement de) { - int i = 0; - for (DetailElement e : details) { - if (e.equals(de)) return i; - i ++; - } - return -1; - } -} + +/** + * The class is used to provide input for the tableviewer for a given PatternMatch. All of the declared ObservableValues + * will be present in the table for the match. The generated DatabindableMatcher class is used to get IObservableValues + * for the given parameters. + * + * @author Tamas Szabo + * + */ +public class DetailObserver extends AbstractObservableList { + + private ObservablePatternMatch patternMatch; + private List details; + private ValueChangeListener listener; + private Map valueMap; + + public DetailObserver(DatabindingAdapter databindableMatcher, ObservablePatternMatch pm) { + this.patternMatch = pm; + this.details = new ArrayList(); + this.valueMap = new HashMap(); + this.listener = new ValueChangeListener(); + for (String param : databindableMatcher.getParameterNames()) { + IObservableValue oval = databindableMatcher.getObservableParameter(patternMatch.getPatternMatch(), param); + + if (oval != null) { + oval.addValueChangeListener(listener); + DetailElement de = new DetailElement(param, createValueRepresentation(oval.getValue())); + addDetail(oval, de, -1); + } else { + Object value = patternMatch.getPatternMatch().get(param); + this.details.add(new DetailElement(param, createValueRepresentation(value))); + } + } + } + + private String createValueRepresentation(Object value) { + if (value == null) { + return null; + } else if (value instanceof EObject) { + EObject obj = (EObject) value; + URI uri = obj.eClass().eResource().getURI(); + AdapterFactoryLabelProvider labelProvider = DatabindingUtil.getAdapterFactoryLabelProvider(uri); + if (labelProvider != null) { + return labelProvider.getText(obj); + } + } else if (value instanceof Collection) { + return "Collection [" + ((Collection) value).size() + "]"; + } + + return value.toString(); + } + + private void addDetail(IObservableValue ov, DetailElement de, int index) { + if (index == -1) { + this.details.add(de); + this.valueMap.put(ov, de); + fireListChange(Diffs.createListDiff(Diffs.createListDiffEntry(this.details.size(), true, de))); + } else { + this.details.add(index, de); + this.valueMap.put(ov, de); + fireListChange(Diffs.createListDiff(Diffs.createListDiffEntry(index, true, de))); + } + } + + private void removeDetail(IObservableValue ov, DetailElement de, int index) { + this.details.remove(index); + this.valueMap.remove(ov); + fireListChange(Diffs.createListDiff(Diffs.createListDiffEntry(index, false, de))); + } + + @Override + public Object getElementType() { + return DetailElement.class; + } + + @Override + protected int doGetSize() { + return this.details.size(); + } + + @Override + public Object get(int index) { + return this.details.get(index); + } + + /** + * Used to observ changes in the observed values. + * + * @author Tamas Szabo + * + */ + private class ValueChangeListener implements IValueChangeListener { + + @Override + public void handleValueChange(ValueChangeEvent event) { + IObservableValue ov = event.getObservableValue(); + Object value = ov.getValue(); + DetailElement de = valueMap.get(ov); + int index = findElement(de); + removeDetail(ov, de, index); + DetailElement newDe = null; + + String data = ""; + if (value == null) { + data = null; + } else if (value instanceof Collection) { + data = "Collection [" + ((Collection) value).size() + "]"; + } else { + data = value.toString(); + } + + newDe = new DetailElement(de.getKey(), data); + + addDetail(ov, newDe, index); + } + + } + + /** + * Find a given element is the details list. + * + * @param de + * element to be found + * @return the index of the element if it is present in the detials list, or -1 if not + */ + private int findElement(DetailElement de) { + int i = 0; + for (DetailElement e : details) { + if (e.equals(de)) + return i; + i++; + } + return -1; + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/MatcherConfiguration.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/MatcherConfiguration.java index bd20a97d..85625a05 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/MatcherConfiguration.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/MatcherConfiguration.java @@ -9,48 +9,48 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.content.detail; - -public class MatcherConfiguration { - - private String parameterName; - private String clazz; - private Object filter; - - public MatcherConfiguration(String parameterName, String clazz, Object filter) { - super(); - this.parameterName = parameterName; - this.clazz = clazz; - this.filter = filter; - } - - public String getParameterName() { - return parameterName; - } - - public void setParameterName(String parameterName) { - this.parameterName = parameterName; - } - - public String getClazz() { - return clazz; - } - - public void setClazz(String clazz) { - this.clazz = clazz; - } - - public Object getFilter() { - return filter; - } - - public void setFilter(Object filter) { - this.filter = filter; - } - - //Used by ViewerComparator too - @Override - public String toString() { - return parameterName; - } -} +package org.eclipse.incquery.tooling.ui.queryexplorer.content.detail; + +public class MatcherConfiguration { + + private String parameterName; + private String clazz; + private Object filter; + + public MatcherConfiguration(String parameterName, String clazz, Object filter) { + super(); + this.parameterName = parameterName; + this.clazz = clazz; + this.filter = filter; + } + + public String getParameterName() { + return parameterName; + } + + public void setParameterName(String parameterName) { + this.parameterName = parameterName; + } + + public String getClazz() { + return clazz; + } + + public void setClazz(String clazz) { + this.clazz = clazz; + } + + public Object getFilter() { + return filter; + } + + public void setFilter(Object filter) { + this.filter = filter; + } + + // Used by ViewerComparator too + @Override + public String toString() { + return parameterName; + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/MatcherConfigurationCellModifier.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/MatcherConfigurationCellModifier.java index 074ea911..5a6bc50e 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/MatcherConfigurationCellModifier.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/MatcherConfigurationCellModifier.java @@ -9,68 +9,65 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.content.detail; - -import org.eclipse.emf.common.util.URI; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider; +package org.eclipse.incquery.tooling.ui.queryexplorer.content.detail; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider; import org.eclipse.incquery.tooling.ui.queryexplorer.util.DatabindingUtil; -import org.eclipse.jface.viewers.ICellModifier; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.swt.widgets.Item; - -public class MatcherConfigurationCellModifier implements ICellModifier { - - private TableViewer viewer; - - public MatcherConfigurationCellModifier(TableViewer viewer) { - this.viewer = viewer; - } - - @Override - public boolean canModify(Object element, String property) { - if (property.equalsIgnoreCase("filter")) { - return true; - } - else { - return false; - } - } - - @Override - public Object getValue(Object element, String property) { - MatcherConfiguration conf = (MatcherConfiguration) element; - if (property.equalsIgnoreCase("filter")) { - if (conf.getFilter() instanceof EObject) { - EObject eObj = (EObject) conf.getFilter(); - URI uri = eObj.eClass().eResource().getURI(); - AdapterFactoryLabelProvider lp = DatabindingUtil.getAdapterFactoryLabelProvider(uri); - if (lp != null) { - return lp.getText(eObj); - } - } - return conf.getFilter(); - } - else if (property.equalsIgnoreCase("class")) { - return conf.getClazz(); - } - else if (property.equalsIgnoreCase("parameter")) { - return conf.getParameterName(); - } - return ""; - } - - @Override - public void modify(Object element, String property, Object value) { - if (element instanceof Item) { - element = ((Item) element).getData(); - } - MatcherConfiguration conf = (MatcherConfiguration) element; - - if (conf != null && property.equalsIgnoreCase("filter")) { - conf.setFilter(value); - viewer.update(conf, null); - } - } - -} +import org.eclipse.jface.viewers.ICellModifier; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.swt.widgets.Item; + +public class MatcherConfigurationCellModifier implements ICellModifier { + + private TableViewer viewer; + + public MatcherConfigurationCellModifier(TableViewer viewer) { + this.viewer = viewer; + } + + @Override + public boolean canModify(Object element, String property) { + if (property.equalsIgnoreCase("filter")) { + return true; + } else { + return false; + } + } + + @Override + public Object getValue(Object element, String property) { + MatcherConfiguration conf = (MatcherConfiguration) element; + if (property.equalsIgnoreCase("filter")) { + if (conf.getFilter() instanceof EObject) { + EObject eObj = (EObject) conf.getFilter(); + URI uri = eObj.eClass().eResource().getURI(); + AdapterFactoryLabelProvider lp = DatabindingUtil.getAdapterFactoryLabelProvider(uri); + if (lp != null) { + return lp.getText(eObj); + } + } + return conf.getFilter(); + } else if (property.equalsIgnoreCase("class")) { + return conf.getClazz(); + } else if (property.equalsIgnoreCase("parameter")) { + return conf.getParameterName(); + } + return ""; + } + + @Override + public void modify(Object element, String property, Object value) { + if (element instanceof Item) { + element = ((Item) element).getData(); + } + MatcherConfiguration conf = (MatcherConfiguration) element; + + if (conf != null && property.equalsIgnoreCase("filter")) { + conf.setFilter(value); + viewer.update(conf, null); + } + } + +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/MatcherConfigurationContentProvider.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/MatcherConfigurationContentProvider.java index 5fcb2c72..822fe57c 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/MatcherConfigurationContentProvider.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/MatcherConfigurationContentProvider.java @@ -9,30 +9,30 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.content.detail; - -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.Viewer; - -public class MatcherConfigurationContentProvider implements IStructuredContentProvider { - - private MatcherConfiguration[] input; - - @Override - public void dispose() { - - } - - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - if (newInput != null && newInput instanceof MatcherConfiguration[]) { - input = (MatcherConfiguration[]) newInput; - } - } - - @Override - public Object[] getElements(Object inputElement) { - return input; - } - -} +package org.eclipse.incquery.tooling.ui.queryexplorer.content.detail; + +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.Viewer; + +public class MatcherConfigurationContentProvider implements IStructuredContentProvider { + + private MatcherConfiguration[] input; + + @Override + public void dispose() { + + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + if (newInput != null && newInput instanceof MatcherConfiguration[]) { + input = (MatcherConfiguration[]) newInput; + } + } + + @Override + public Object[] getElements(Object inputElement) { + return input; + } + +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/MatcherConfigurationLabelProvider.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/MatcherConfigurationLabelProvider.java index cc3177c0..2399d1cf 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/MatcherConfigurationLabelProvider.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/MatcherConfigurationLabelProvider.java @@ -9,48 +9,46 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.content.detail; - -import org.eclipse.emf.common.util.URI; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider; +package org.eclipse.incquery.tooling.ui.queryexplorer.content.detail; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider; import org.eclipse.incquery.tooling.ui.queryexplorer.util.DatabindingUtil; -import org.eclipse.jface.viewers.ITableLabelProvider; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.swt.graphics.Image; - -public final class MatcherConfigurationLabelProvider extends LabelProvider implements ITableLabelProvider { - - public Image getColumnImage(Object element, int columnIndex) { - return null; - } - - @Override - public String getColumnText(Object element, int columnIndex) { - MatcherConfiguration mc = (MatcherConfiguration) element; - switch (columnIndex) { - case 0: - return mc.getParameterName(); - case 1: - if (mc.getFilter() == null) { - return ""; - } - else if (mc.getFilter() instanceof EObject) { - EObject eObj = (EObject) mc.getFilter(); - URI uri = eObj.eClass().eResource().getURI(); - AdapterFactoryLabelProvider lp = DatabindingUtil.getAdapterFactoryLabelProvider(uri); - if (lp != null) { - return lp.getText(eObj); - } - } - else { - return mc.getFilter().toString(); - } - case 2: - return mc.getClazz(); - default: - return ""; - } - } - +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.graphics.Image; + +public final class MatcherConfigurationLabelProvider extends LabelProvider implements ITableLabelProvider { + + public Image getColumnImage(Object element, int columnIndex) { + return null; + } + + @Override + public String getColumnText(Object element, int columnIndex) { + MatcherConfiguration mc = (MatcherConfiguration) element; + switch (columnIndex) { + case 0: + return mc.getParameterName(); + case 1: + if (mc.getFilter() == null) { + return ""; + } else if (mc.getFilter() instanceof EObject) { + EObject eObj = (EObject) mc.getFilter(); + URI uri = eObj.eClass().eResource().getURI(); + AdapterFactoryLabelProvider lp = DatabindingUtil.getAdapterFactoryLabelProvider(uri); + if (lp != null) { + return lp.getText(eObj); + } + } else { + return mc.getFilter().toString(); + } + case 2: + return mc.getClazz(); + default: + return ""; + } + } + } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/ModelElementCellEditor.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/ModelElementCellEditor.java index 32f2ec1b..13bbef7f 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/ModelElementCellEditor.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/ModelElementCellEditor.java @@ -52,15 +52,15 @@ public class ModelElementCellEditor extends CellEditor { private Text inputText; private Button dialogButton; private Button clearButton; - private KeyListener keyListener; + private KeyListener keyListener; private Object value = null; private Notifier root; private Table table; private ObservablePatternMatcher observableMatcher; - + @Inject TableViewerUtil tableViewerUtil; - + public ModelElementCellEditor(Table table, ObservablePatternMatcher observableMatcher) { super(table, SWT.NONE); this.root = observableMatcher.getParent().getNotifier(); @@ -69,23 +69,24 @@ public ModelElementCellEditor(Table table, ObservablePatternMatcher observableMa } private class DialogCellLayout extends Layout { - + public void layout(Composite editor, boolean force) { Rectangle bounds = editor.getClientArea(); Point dialogButtonSize = dialogButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, force); Point clearButtonSize = clearButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, force); if (contents != null) { - contents.setBounds(0, 0, bounds.width - dialogButtonSize.x - clearButtonSize.x, bounds.height); - } - - clearButton.setBounds(bounds.width - dialogButtonSize.x - clearButtonSize.x, 0, clearButtonSize.x, bounds.height); + contents.setBounds(0, 0, bounds.width - dialogButtonSize.x - clearButtonSize.x, bounds.height); + } + + clearButton.setBounds(bounds.width - dialogButtonSize.x - clearButtonSize.x, 0, clearButtonSize.x, + bounds.height); dialogButton.setBounds(bounds.width - dialogButtonSize.x, 0, dialogButtonSize.x, bounds.height); } public Point computeSize(Composite editor, int wHint, int hHint, boolean force) { if (wHint != SWT.DEFAULT && hHint != SWT.DEFAULT) { - return new Point(wHint, hHint); - } + return new Point(wHint, hHint); + } Point contentsSize = contents.computeSize(SWT.DEFAULT, SWT.DEFAULT, force); Point buttonSize = dialogButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, force); // Just return the button width to ensure the button is not clipped @@ -101,9 +102,9 @@ private Button createDialogButton(Composite parent) { result.setText("..."); return result; } - + private Button createClearButton(Composite parent) { - Button result = new Button(parent, SWT.DOWN); + Button result = new Button(parent, SWT.DOWN); result.setText("X"); return result; } @@ -131,7 +132,7 @@ protected Control createControl(Composite parent) { clearButton = createClearButton(editor); clearButton.setFont(font); - + dialogButton = createDialogButton(editor); dialogButton.setFont(font); @@ -142,18 +143,20 @@ public void keyReleased(KeyEvent e) { } } }); - + dialogButton.addSelectionListener(new SelectionAdapter() { - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) */ public void widgetSelected(SelectionEvent event) { - TableItem selection = table.getSelection()[0]; - MatcherConfiguration conf = (MatcherConfiguration) selection.getData(); - if (!tableViewerUtil.isPrimitiveType(conf.getClazz())) { - Object newValue = openDialogBox(editor, conf.getClazz()); + TableItem selection = table.getSelection()[0]; + MatcherConfiguration conf = (MatcherConfiguration) selection.getData(); + if (!tableViewerUtil.isPrimitiveType(conf.getClazz())) { + Object newValue = openDialogBox(editor, conf.getClazz()); - if (newValue != null) { + if (newValue != null) { boolean newValidState = isCorrect(newValue); if (newValidState) { markDirty(); @@ -167,21 +170,21 @@ public void widgetSelected(SelectionEvent event) { } fireApplyEditorValue(); } - } + } } }); - + clearButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - TableItem selection = table.getSelection()[0]; - MatcherConfiguration conf = (MatcherConfiguration) selection.getData(); - inputText.setText(""); - value = ""; - conf.setFilter(""); - observableMatcher.setFilter(getFilter(table)); - } - }); + @Override + public void widgetSelected(SelectionEvent e) { + TableItem selection = table.getSelection()[0]; + MatcherConfiguration conf = (MatcherConfiguration) selection.getData(); + inputText.setText(""); + value = ""; + conf.setFilter(""); + observableMatcher.setFilter(getFilter(table)); + } + }); setValueValid(true); @@ -189,65 +192,63 @@ public void widgetSelected(SelectionEvent e) { } public void deactivate() { - if (inputText != null && !inputText.isDisposed()) { - inputText.removeKeyListener(getTextKeyListener()); - } - - super.deactivate(); - } + if (inputText != null && !inputText.isDisposed()) { + inputText.removeKeyListener(getTextKeyListener()); + } + + super.deactivate(); + } protected Object doGetValue() { return value; } protected void doSetFocus() { - TableItem selection = table.getSelection()[0]; - MatcherConfiguration conf = (MatcherConfiguration) selection.getData(); - - if (!tableViewerUtil.isPrimitiveType(conf.getClazz())) { - inputText.setEditable(false); - } - else { - inputText.setEditable(true); - } - + TableItem selection = table.getSelection()[0]; + MatcherConfiguration conf = (MatcherConfiguration) selection.getData(); + + if (!tableViewerUtil.isPrimitiveType(conf.getClazz())) { + inputText.setEditable(false); + } else { + inputText.setEditable(true); + } + inputText.setFocus(); inputText.addKeyListener(getTextKeyListener()); inputText.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE)); } private KeyListener getTextKeyListener() { - if (keyListener == null) { - keyListener = new KeyListener() { - - @Override - public void keyReleased(KeyEvent e) { - - String newValue = inputText.getText(); - TableItem ti = table.getSelection()[0]; - MatcherConfiguration conf = (MatcherConfiguration) ti.getData(); - - if (tableViewerUtil.isValidValue(conf.getClazz(), newValue)) { - inputText.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE)); - conf.setFilter(inputText.getText()); - value = inputText.getText(); - //set restriction for observable matcher - observableMatcher.setFilter(getFilter(table)); - } - else { - inputText.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_RED)); - } - } - - @Override - public void keyPressed(KeyEvent e) { - - } - }; - } - - return keyListener; - } + if (keyListener == null) { + keyListener = new KeyListener() { + + @Override + public void keyReleased(KeyEvent e) { + + String newValue = inputText.getText(); + TableItem ti = table.getSelection()[0]; + MatcherConfiguration conf = (MatcherConfiguration) ti.getData(); + + if (tableViewerUtil.isValidValue(conf.getClazz(), newValue)) { + inputText.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE)); + conf.setFilter(inputText.getText()); + value = inputText.getText(); + // set restriction for observable matcher + observableMatcher.setFilter(getFilter(table)); + } else { + inputText.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_RED)); + } + } + + @Override + public void keyPressed(KeyEvent e) { + + } + }; + } + + return keyListener; + } protected void doSetValue(Object value) { this.value = value; @@ -259,112 +260,107 @@ protected Text getDefaultText() { } protected Object openDialogBox(Control cellEditorWindow, String restriction) { - ElementListSelectionDialog listDialog = - new ElementListSelectionDialog( - PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), - new ModelElementListDialogLabelProvider() - ); - listDialog.setTitle("Model element selection"); - listDialog.setMessage("Select a model element (* = any string, ? = any char):"); - Object[] input = getElements(this.root, restriction); - listDialog.setElements(input); - listDialog.open(); - Object[] result = listDialog.getResult(); - if (result != null && result.length > 0) { - return result[0]; - } + ElementListSelectionDialog listDialog = new ElementListSelectionDialog(PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getShell(), new ModelElementListDialogLabelProvider()); + listDialog.setTitle("Model element selection"); + listDialog.setMessage("Select a model element (* = any string, ? = any char):"); + Object[] input = getElements(this.root, restriction); + listDialog.setElements(input); + listDialog.open(); + Object[] result = listDialog.getResult(); + if (result != null && result.length > 0) { + return result[0]; + } return null; } protected void updateContents(Object value) { if (inputText == null) { - return; - } + return; + } String text = "";//$NON-NLS-1$ if (value != null) { - text = value.toString(); - } + text = value.toString(); + } inputText.setText(text); } - + private Object[] getFilter(Table table) { - Object[] result = new Object[table.getItems().length]; - - int i = 0; - for (String parameterName : observableMatcher.getMatcher().getParameterNames()) { - result[i++] = getParameterFilter(table, parameterName); - } - - return result; + Object[] result = new Object[table.getItems().length]; + + int i = 0; + for (String parameterName : observableMatcher.getMatcher().getParameterNames()) { + result[i++] = getParameterFilter(table, parameterName); + } + + return result; } - + private Object getParameterFilter(Table table, String parameterName) { - for (int i = 0;i result = new ArrayList(); - TreeIterator iterator = null; - EObject obj = null; - - if (root instanceof EObject) { - iterator = ((EObject) root).eAllContents(); - - while (iterator.hasNext()) { - obj = iterator.next(); - if (isOfType(obj.getClass(), restrictionFqn)) { - result.add(obj); - } - } - } - else if (root instanceof Resource) { - iterator = ((Resource) root).getAllContents(); - - while (iterator.hasNext()) { - obj = iterator.next(); - if (isOfType(obj.getClass(), restrictionFqn)) { - result.add(obj); - } - } - } - else if (root instanceof ResourceSet) { - for (Resource res : ((ResourceSet) root).getResources()) { - iterator = res.getAllContents(); - while (iterator.hasNext()) { - obj = iterator.next(); - if (isOfType(obj.getClass(), restrictionFqn)) { - result.add(obj); - } - } - } - } - - return result.toArray(); + List result = new ArrayList(); + TreeIterator iterator = null; + EObject obj = null; + + if (root instanceof EObject) { + iterator = ((EObject) root).eAllContents(); + + while (iterator.hasNext()) { + obj = iterator.next(); + if (isOfType(obj.getClass(), restrictionFqn)) { + result.add(obj); + } + } + } else if (root instanceof Resource) { + iterator = ((Resource) root).getAllContents(); + + while (iterator.hasNext()) { + obj = iterator.next(); + if (isOfType(obj.getClass(), restrictionFqn)) { + result.add(obj); + } + } + } else if (root instanceof ResourceSet) { + for (Resource res : ((ResourceSet) root).getResources()) { + iterator = res.getAllContents(); + while (iterator.hasNext()) { + obj = iterator.next(); + if (isOfType(obj.getClass(), restrictionFqn)) { + result.add(obj); + } + } + } + } + + return result.toArray(); } - - private boolean isOfType(Class clazz, String restrictionFqn) { - List classes = collectAllInterfaces(clazz); - classes.add("java.lang.Object"); - return classes.contains(restrictionFqn); + + private boolean isOfType(Class clazz, String restrictionFqn) { + List classes = collectAllInterfaces(clazz); + classes.add("java.lang.Object"); + return classes.contains(restrictionFqn); } - + @SuppressWarnings("rawtypes") - private List collectAllInterfaces(Class clazz) { - List result = new ArrayList(); - Class[] interfaces = clazz.getInterfaces(); - - for (Class i : interfaces) { - result.add(i.getName()); - result.addAll(collectAllInterfaces(i)); - } - - return result; + private List collectAllInterfaces(Class clazz) { + List result = new ArrayList(); + Class[] interfaces = clazz.getInterfaces(); + + for (Class i : interfaces) { + result.add(i.getName()); + result.addAll(collectAllInterfaces(i)); + } + + return result; } } diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/ModelElementListDialogLabelProvider.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/ModelElementListDialogLabelProvider.java index 582c34c5..9f400c00 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/ModelElementListDialogLabelProvider.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/ModelElementListDialogLabelProvider.java @@ -9,62 +9,62 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.content.detail; - -import org.eclipse.emf.common.util.URI; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider; +package org.eclipse.incquery.tooling.ui.queryexplorer.content.detail; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider; import org.eclipse.incquery.tooling.ui.queryexplorer.util.DatabindingUtil; -import org.eclipse.jface.viewers.ILabelProvider; -import org.eclipse.jface.viewers.ILabelProviderListener; -import org.eclipse.swt.graphics.Image; - -public class ModelElementListDialogLabelProvider implements ILabelProvider { - - @Override - public void addListener(ILabelProviderListener listener) { - - } - - @Override - public void dispose() { - - } - - @Override - public boolean isLabelProperty(Object element, String property) { - return false; - } - - @Override - public void removeListener(ILabelProviderListener listener) { - - } - - @Override - public Image getImage(Object element) { - if (element instanceof EObject) { - EObject eObj = (EObject) element; - URI uri = eObj.eClass().eResource().getURI(); - AdapterFactoryLabelProvider al = DatabindingUtil.getAdapterFactoryLabelProvider(uri); - if (al != null) { - return al.getImage(element); - } - } - return null; - } - - @Override - public String getText(Object element) { - if (element instanceof EObject) { - EObject eObj = (EObject) element; - URI uri = eObj.eClass().eResource().getURI(); - AdapterFactoryLabelProvider al = DatabindingUtil.getAdapterFactoryLabelProvider(uri); - if (al != null) { - return al.getText(element); - } - } - return element.toString(); - } - -} +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.swt.graphics.Image; + +public class ModelElementListDialogLabelProvider implements ILabelProvider { + + @Override + public void addListener(ILabelProviderListener listener) { + + } + + @Override + public void dispose() { + + } + + @Override + public boolean isLabelProperty(Object element, String property) { + return false; + } + + @Override + public void removeListener(ILabelProviderListener listener) { + + } + + @Override + public Image getImage(Object element) { + if (element instanceof EObject) { + EObject eObj = (EObject) element; + URI uri = eObj.eClass().eResource().getURI(); + AdapterFactoryLabelProvider al = DatabindingUtil.getAdapterFactoryLabelProvider(uri); + if (al != null) { + return al.getImage(element); + } + } + return null; + } + + @Override + public String getText(Object element) { + if (element instanceof EObject) { + EObject eObj = (EObject) element; + URI uri = eObj.eClass().eResource().getURI(); + AdapterFactoryLabelProvider al = DatabindingUtil.getAdapterFactoryLabelProvider(uri); + if (al != null) { + return al.getText(element); + } + } + return element.toString(); + } + +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/TableViewerUtil.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/TableViewerUtil.java index e919f6dd..1addca1c 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/TableViewerUtil.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/detail/TableViewerUtil.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.content.detail; - +package org.eclipse.incquery.tooling.ui.queryexplorer.content.detail; + import java.util.HashSet; import java.util.Set; @@ -37,198 +37,181 @@ import com.google.inject.Inject; import com.google.inject.Injector; import com.google.inject.Singleton; - -@SuppressWarnings("restriction") -@Singleton -public class TableViewerUtil { - - @Inject - private ITypeProvider typeProvider; - - @Inject - private Injector injector; - - private final Set primitiveTypes; - - protected TableViewerUtil() { - primitiveTypes = new HashSet(); - primitiveTypes.add(Boolean.class.getName()); - primitiveTypes.add(Character.class.getName()); - primitiveTypes.add(Byte.class.getName()); - primitiveTypes.add(Short.class.getName()); - primitiveTypes.add(Integer.class.getName()); - primitiveTypes.add(Long.class.getName()); - primitiveTypes.add(Float.class.getName()); - primitiveTypes.add(Double.class.getName()); - primitiveTypes.add(Void.class.getName()); - primitiveTypes.add(String.class.getName()); - } - - public boolean isPrimitiveType(String fqn) { - return primitiveTypes.contains(fqn); - } - - public void prepareTableViewerForObservableInput(final ObservablePatternMatch match, TableViewer viewer) { - clearTableViewerColumns(viewer); - String[] titles = { "Parameter", "Value" }; - createColumns(viewer, titles); - viewer.setUseHashlookup(true); - viewer.setColumnProperties(titles); - viewer.setContentProvider(new ObservableListContentProvider()); - viewer.setLabelProvider(new DetailElementLabelProvider()); - viewer.setCellModifier(new DetailElementCellModifier()); - viewer.setComparator(new ViewerComparator(new DetailComparator(match.getPatternMatch().parameterNames()))); - - DatabindingAdapter databindableMatcher = - DatabindingUtil.getDatabindingAdapter(match.getPatternMatch().patternName(), match.getParent().isGenerated()); - - if (databindableMatcher == null) { - viewer.setInput(null); - } - else { - DetailObserver observer = new DetailObserver(databindableMatcher, match); - viewer.setInput(observer); - } - } - - public void prepareTableViewerForMatcherConfiguration(ObservablePatternMatcher observableMatcher, TableViewer viewer) { - clearTableViewerColumns(viewer); - String[] titles = { "Parameter", "Filter", "Class" }; - createColumns(viewer, titles); - viewer.setUseHashlookup(true); - viewer.setColumnProperties(titles); - viewer.setContentProvider(new MatcherConfigurationContentProvider()); - viewer.setLabelProvider(new MatcherConfigurationLabelProvider()); - viewer.setCellModifier(new MatcherConfigurationCellModifier(viewer)); - viewer.setComparator(new ViewerComparator(new DetailComparator(observableMatcher.getMatcher().getParameterNames()))); - - Table table = viewer.getTable(); - CellEditor[] editors = new CellEditor[titles.length]; - - editors[0] = new TextCellEditor(table); - ModelElementCellEditor cellEditor = new ModelElementCellEditor(table, observableMatcher); - injector.injectMembers(cellEditor); - editors[1] = cellEditor; - editors[2] = new TextCellEditor(table); - - viewer.setCellEditors(editors); - - Pattern pattern = PatternRegistry.getInstance().getPatternByFqn(observableMatcher.getPatternName()); - Object[] filter = observableMatcher.getFilter(); - MatcherConfiguration[] input = new MatcherConfiguration[pattern.getParameters().size()]; - if (filter != null) { - for (int i = 0;i 0 ) { - viewer.getTable().getColumns()[0].dispose(); - } - - viewer.refresh(); - } - - private void createColumns(TableViewer viewer, String[] titles) { - for (int i = 0;i primitiveTypes; + + protected TableViewerUtil() { + primitiveTypes = new HashSet(); + primitiveTypes.add(Boolean.class.getName()); + primitiveTypes.add(Character.class.getName()); + primitiveTypes.add(Byte.class.getName()); + primitiveTypes.add(Short.class.getName()); + primitiveTypes.add(Integer.class.getName()); + primitiveTypes.add(Long.class.getName()); + primitiveTypes.add(Float.class.getName()); + primitiveTypes.add(Double.class.getName()); + primitiveTypes.add(Void.class.getName()); + primitiveTypes.add(String.class.getName()); + } + + public boolean isPrimitiveType(String fqn) { + return primitiveTypes.contains(fqn); + } + + public void prepareTableViewerForObservableInput(final ObservablePatternMatch match, TableViewer viewer) { + clearTableViewerColumns(viewer); + String[] titles = { "Parameter", "Value" }; + createColumns(viewer, titles); + viewer.setUseHashlookup(true); + viewer.setColumnProperties(titles); + viewer.setContentProvider(new ObservableListContentProvider()); + viewer.setLabelProvider(new DetailElementLabelProvider()); + viewer.setCellModifier(new DetailElementCellModifier()); + viewer.setComparator(new ViewerComparator(new DetailComparator(match.getPatternMatch().parameterNames()))); + + DatabindingAdapter databindableMatcher = DatabindingUtil.getDatabindingAdapter(match + .getPatternMatch().patternName(), match.getParent().isGenerated()); + + if (databindableMatcher == null) { + viewer.setInput(null); + } else { + DetailObserver observer = new DetailObserver(databindableMatcher, match); + viewer.setInput(observer); + } + } + + public void prepareTableViewerForMatcherConfiguration(ObservablePatternMatcher observableMatcher, TableViewer viewer) { + clearTableViewerColumns(viewer); + String[] titles = { "Parameter", "Filter", "Class" }; + createColumns(viewer, titles); + viewer.setUseHashlookup(true); + viewer.setColumnProperties(titles); + viewer.setContentProvider(new MatcherConfigurationContentProvider()); + viewer.setLabelProvider(new MatcherConfigurationLabelProvider()); + viewer.setCellModifier(new MatcherConfigurationCellModifier(viewer)); + viewer.setComparator(new ViewerComparator(new DetailComparator(observableMatcher.getMatcher() + .getParameterNames()))); + + Table table = viewer.getTable(); + CellEditor[] editors = new CellEditor[titles.length]; + + editors[0] = new TextCellEditor(table); + ModelElementCellEditor cellEditor = new ModelElementCellEditor(table, observableMatcher); + injector.injectMembers(cellEditor); + editors[1] = cellEditor; + editors[2] = new TextCellEditor(table); + + viewer.setCellEditors(editors); + + Pattern pattern = PatternRegistry.getInstance().getPatternByFqn(observableMatcher.getPatternName()); + Object[] filter = observableMatcher.getFilter(); + MatcherConfiguration[] input = new MatcherConfiguration[pattern.getParameters().size()]; + if (filter != null) { + for (int i = 0; i < pattern.getParameters().size(); i++) { + Variable var = pattern.getParameters().get(i); + String name = var.getName(); + JvmTypeReference ref = typeProvider.getTypeForIdentifiable(var); + String clazz = (ref == null) ? "" : ref.getType().getQualifiedName(); + input[i] = new MatcherConfiguration(name, clazz, filter[i]); + } + viewer.setInput(input); + } + } + + public void clearTableViewerColumns(TableViewer viewer) { + + if (viewer.getContentProvider() != null) { + viewer.setInput(null); + } + while (viewer.getTable().getColumnCount() > 0) { + viewer.getTable().getColumns()[0].dispose(); + } + + viewer.refresh(); + } + + private void createColumns(TableViewer viewer, String[] titles) { + for (int i = 0; i < titles.length; i++) { + createTableViewerColumn(viewer, titles[i], i); + } + } + + private TableViewerColumn createTableViewerColumn(TableViewer viewer, String title, int index) { + final TableViewerColumn viewerColumn = new TableViewerColumn(viewer, SWT.NONE, index); + final TableColumn column = viewerColumn.getColumn(); + column.setText(title); + column.setResizable(true); + column.setMoveable(true); + column.setWidth(150); + return viewerColumn; + } + + public Object createValue(String classFqn, Object value) { + if (!(value instanceof String)) { + return value; + } else { + classFqn = classFqn.toLowerCase(); + String strValue = value.toString(); + + if (strValue.matches("")) { + return null; + } else if (Boolean.class.getName().toLowerCase().matches(classFqn)) { + return Boolean.valueOf(strValue.toLowerCase()); + } else if (Character.class.getName().toLowerCase().matches(classFqn)) { + return Character.valueOf(strValue.charAt(0)); + } else if (Byte.class.getName().toLowerCase().matches(classFqn)) { + return Byte.valueOf(strValue); + } else if (Short.class.getName().toLowerCase().matches(classFqn)) { + return Short.valueOf(strValue); + } else if (Integer.class.getName().toLowerCase().matches(classFqn)) { + return Integer.valueOf(strValue); + } else if (Long.class.getName().toLowerCase().matches(classFqn)) { + return Long.valueOf(strValue); + } else if (Float.class.getName().toLowerCase().matches(classFqn)) { + return Float.valueOf(strValue); + } else if (Double.class.getName().toLowerCase().matches(classFqn)) { + return Double.valueOf(strValue); + } else if (String.class.getName().toLowerCase().matches(classFqn)) { + return value; + } else { + return null; + } + } + } + + public boolean isValidValue(String classFqn, String value) { + classFqn = classFqn.toLowerCase(); + + if (Boolean.class.getName().toLowerCase().matches(classFqn)) { + if (value.toLowerCase().matches("true") || value.toLowerCase().matches("false")) { + return true; + } else { + return false; + } + } else if (Character.class.getName().toLowerCase().matches(classFqn)) { + return true; + } else if (Byte.class.getName().toLowerCase().matches(classFqn) + || Short.class.getName().toLowerCase().matches(classFqn) + || Integer.class.getName().toLowerCase().matches(classFqn) + || Long.class.getName().toLowerCase().matches(classFqn)) { + return value.matches("[0-9]*"); + } else if (Float.class.getName().toLowerCase().matches(classFqn) + || Double.class.getName().toLowerCase().matches(classFqn)) { + return value.matches("[0-9]*\\.?[0-9]*"); + } else if (String.class.getName().toLowerCase().matches(classFqn)) { + return true; + } else { + return true; + } + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/DockAction.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/DockAction.java index 4f06538f..5aca01de 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/DockAction.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/DockAction.java @@ -14,22 +14,22 @@ import org.eclipse.jface.action.Action; public class DockAction extends Action { - private final int location; - private FlyoutControlComposite flyoutControl; + private final int location; + private FlyoutControlComposite flyoutControl; - public DockAction(FlyoutControlComposite flyoutControl, String text, int location) { - super(text, AS_RADIO_BUTTON); - this.flyoutControl = flyoutControl; - this.location = location; - } + public DockAction(FlyoutControlComposite flyoutControl, String text, int location) { + super(text, AS_RADIO_BUTTON); + this.flyoutControl = flyoutControl; + this.location = location; + } - @Override - public boolean isChecked() { - return flyoutControl.getDockLocation() == location; - } + @Override + public boolean isChecked() { + return flyoutControl.getDockLocation() == location; + } - @Override - public void run() { - flyoutControl.setDockLocation(location); - } + @Override + public void run() { + flyoutControl.setDockLocation(location); + } } diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/DrawUtils.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/DrawUtils.java index 9e174c77..e41d8d22 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/DrawUtils.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/DrawUtils.java @@ -20,87 +20,78 @@ import org.eclipse.swt.widgets.Display; public class DrawUtils { - - public static void drawImageCHCV(GC gc, Image image, int x, int y, - int width, int height) { - if (image != null) { - Rectangle imageBounds = image.getBounds(); - int centerX = (width - imageBounds.width) / 2; - int centerY = y + (height - imageBounds.height) / 2; - gc.drawImage(image, x + centerX, centerY); - } - } - public static void drawHighlightRectangle(GC gc, int x, int y, int width, - int height) { - int right = x + width - 1; - int bottom = y + height - 1; - - Color oldForeground = gc.getForeground(); - try { - gc.setForeground(FlyoutConstants.buttonLightest); - gc.drawLine(x, y, right, y); - gc.drawLine(x, y, x, bottom); - - gc.setForeground(FlyoutConstants.buttonDarker); - gc.drawLine(right, y, right, bottom); - gc.drawLine(x, bottom, right, bottom); - } finally { - gc.setForeground(oldForeground); - } - } + public static void drawImageCHCV(GC gc, Image image, int x, int y, int width, int height) { + if (image != null) { + Rectangle imageBounds = image.getBounds(); + int centerX = (width - imageBounds.width) / 2; + int centerY = y + (height - imageBounds.height) / 2; + gc.drawImage(image, x + centerX, centerY); + } + } - public static Image createRotatedImage(Image srcImage) { - // prepare Display - Display display = Display.getCurrent(); - if (display == null) { - SWT.error(SWT.ERROR_THREAD_INVALID_ACCESS); - } - // rotate ImageData - ImageData destData; - { - ImageData srcData = srcImage.getImageData(); - if (srcData.depth < 8) { - destData = rotatePixelByPixel(srcData); - } else { - destData = rotateOptimized(srcData); - } - } - // create new image - return new Image(display, destData); - } + public static void drawHighlightRectangle(GC gc, int x, int y, int width, int height) { + int right = x + width - 1; + int bottom = y + height - 1; - private static ImageData rotatePixelByPixel(ImageData srcData) { - ImageData destData = new ImageData(srcData.height, srcData.width, - srcData.depth, srcData.palette); - for (int y = 0; y < srcData.height; y++) { - for (int x = 0; x < srcData.width; x++) { - destData.setPixel(y, srcData.width - x - 1, - srcData.getPixel(x, y)); - } - } - return destData; - } + Color oldForeground = gc.getForeground(); + try { + gc.setForeground(FlyoutConstants.buttonLightest); + gc.drawLine(x, y, right, y); + gc.drawLine(x, y, x, bottom); - private static ImageData rotateOptimized(ImageData srcData) { - int bytesPerPixel = Math.max(1, srcData.depth / 8); - int destBytesPerLine = ((srcData.height * bytesPerPixel - 1) - / srcData.scanlinePad + 1) - * srcData.scanlinePad; - byte[] newData = new byte[destBytesPerLine * srcData.width]; - for (int srcY = 0; srcY < srcData.height; srcY++) { - for (int srcX = 0; srcX < srcData.width; srcX++) { - int destX = srcY; - int destY = srcData.width - srcX - 1; - int destIndex = destY * destBytesPerLine + destX - * bytesPerPixel; - int srcIndex = srcY * srcData.bytesPerLine + srcX - * bytesPerPixel; - System.arraycopy(srcData.data, srcIndex, newData, destIndex, - bytesPerPixel); - } - } - return new ImageData(srcData.height, srcData.width, srcData.depth, - srcData.palette, srcData.scanlinePad, newData); - } + gc.setForeground(FlyoutConstants.buttonDarker); + gc.drawLine(right, y, right, bottom); + gc.drawLine(x, bottom, right, bottom); + } finally { + gc.setForeground(oldForeground); + } + } + + public static Image createRotatedImage(Image srcImage) { + // prepare Display + Display display = Display.getCurrent(); + if (display == null) { + SWT.error(SWT.ERROR_THREAD_INVALID_ACCESS); + } + // rotate ImageData + ImageData destData; + { + ImageData srcData = srcImage.getImageData(); + if (srcData.depth < 8) { + destData = rotatePixelByPixel(srcData); + } else { + destData = rotateOptimized(srcData); + } + } + // create new image + return new Image(display, destData); + } + + private static ImageData rotatePixelByPixel(ImageData srcData) { + ImageData destData = new ImageData(srcData.height, srcData.width, srcData.depth, srcData.palette); + for (int y = 0; y < srcData.height; y++) { + for (int x = 0; x < srcData.width; x++) { + destData.setPixel(y, srcData.width - x - 1, srcData.getPixel(x, y)); + } + } + return destData; + } + + private static ImageData rotateOptimized(ImageData srcData) { + int bytesPerPixel = Math.max(1, srcData.depth / 8); + int destBytesPerLine = ((srcData.height * bytesPerPixel - 1) / srcData.scanlinePad + 1) * srcData.scanlinePad; + byte[] newData = new byte[destBytesPerLine * srcData.width]; + for (int srcY = 0; srcY < srcData.height; srcY++) { + for (int srcX = 0; srcX < srcData.width; srcX++) { + int destX = srcY; + int destY = srcData.width - srcX - 1; + int destIndex = destY * destBytesPerLine + destX * bytesPerPixel; + int srcIndex = srcY * srcData.bytesPerLine + srcX * bytesPerPixel; + System.arraycopy(srcData.data, srcIndex, newData, destIndex, bytesPerPixel); + } + } + return new ImageData(srcData.height, srcData.width, srcData.depth, srcData.palette, srcData.scanlinePad, + newData); + } } diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/FlyoutConstants.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/FlyoutConstants.java index b5397660..3af762af 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/FlyoutConstants.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/FlyoutConstants.java @@ -17,44 +17,44 @@ public interface FlyoutConstants { - public static final int LEFT = 1; - public static final int CENTER = 2; - public static final int RIGHT = 4; - public static final int LEFT_CENTER_RIGHT = LEFT | CENTER | RIGHT; - public static final int TOP = 8; - public static final int MIDDLE = 16; - public static final int BOTTOM = 32; - public static final int BASELINE = 64; - public static final int TOP_MIDDLE_BOTTOM = TOP | MIDDLE | BOTTOM; - - int NONE = 0; - int NORTH = 1 << 0; - int SOUTH = 1 << 2; - int WEST = 1 << 3; - int EAST = 1 << 4; - int NORTH_EAST = NORTH | EAST; - int NORTH_WEST = NORTH | WEST; - int SOUTH_EAST = SOUTH | EAST; - int SOUTH_WEST = SOUTH | WEST; - int NORTH_SOUTH = NORTH | SOUTH; - int EAST_WEST = EAST | WEST; + public static final int LEFT = 1; + public static final int CENTER = 2; + public static final int RIGHT = 4; + public static final int LEFT_CENTER_RIGHT = LEFT | CENTER | RIGHT; + public static final int TOP = 8; + public static final int MIDDLE = 16; + public static final int BOTTOM = 32; + public static final int BASELINE = 64; + public static final int TOP_MIDDLE_BOTTOM = TOP | MIDDLE | BOTTOM; - public static Color buttonLightest = Utils.getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW); - public static Color button = Utils.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND); - public static Color buttonDarker = Utils.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW); - public static Color BLACK = new Color(null, 0, 0, 0); - - static class Utils { + int NONE = 0; + int NORTH = 1 << 0; + int SOUTH = 1 << 2; + int WEST = 1 << 3; + int EAST = 1 << 4; + int NORTH_EAST = NORTH | EAST; + int NORTH_WEST = NORTH | WEST; + int SOUTH_EAST = SOUTH | EAST; + int SOUTH_WEST = SOUTH | WEST; + int NORTH_SOUTH = NORTH | SOUTH; + int EAST_WEST = EAST | WEST; - private static Color getSystemColor(final int id) { - final Color[] color = new Color[1]; - final Display display = Display.getDefault(); - display.syncExec(new Runnable() { - public void run() { - color[0] = display.getSystemColor(id); - } - }); - return color[0]; - } - } + public static Color buttonLightest = Utils.getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW); + public static Color button = Utils.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND); + public static Color buttonDarker = Utils.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW); + public static Color BLACK = new Color(null, 0, 0, 0); + + static class Utils { + + private static Color getSystemColor(final int id) { + final Color[] color = new Color[1]; + final Display display = Display.getDefault(); + display.syncExec(new Runnable() { + public void run() { + color[0] = display.getSystemColor(id); + } + }); + return color[0]; + } + } } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/FlyoutContainer.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/FlyoutContainer.java index 75a1d0a5..e8bc5727 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/FlyoutContainer.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/FlyoutContainer.java @@ -31,512 +31,487 @@ import org.eclipse.swt.widgets.Tracker; public class FlyoutContainer extends Composite { - private static final int RESIZE_WIDTH = 5; - private static final int TITLE_LINES = 30; - private static final int TITLE_MARGIN = 5; - private static final Font TITLE_FONT = JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT); - private static final Image PIN = loadImage(IncQueryGUIPlugin.ICON_PIN); - private static final Image ARROW_LEFT = loadImage(IncQueryGUIPlugin.ICON_ARROW_LEFT); - private static final Image ARROW_RIGHT = loadImage(IncQueryGUIPlugin.ICON_ARROW_RIGHT); - private static final Image ARROW_TOP = loadImage(IncQueryGUIPlugin.ICON_ARROW_TOP); - private static final Image ARROW_BOTTOM = loadImage(IncQueryGUIPlugin.ICON_ARROW_BOTTOM); + private static final int RESIZE_WIDTH = 5; + private static final int TITLE_LINES = 30; + private static final int TITLE_MARGIN = 5; + private static final Font TITLE_FONT = JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT); + private static final Image PIN = loadImage(IncQueryGUIPlugin.ICON_PIN); + private static final Image ARROW_LEFT = loadImage(IncQueryGUIPlugin.ICON_ARROW_LEFT); + private static final Image ARROW_RIGHT = loadImage(IncQueryGUIPlugin.ICON_ARROW_RIGHT); + private static final Image ARROW_TOP = loadImage(IncQueryGUIPlugin.ICON_ARROW_TOP); + private static final Image ARROW_BOTTOM = loadImage(IncQueryGUIPlugin.ICON_ARROW_BOTTOM); - private FlyoutControlComposite flyoutControl; - private int titleWidth; - private int titleHeight; - private Image titleImage; - private Image titleImageRotated; - private boolean isResizable; - private boolean stateHover; - private Image backImage; - - private static Image loadImage(String key) { - ImageRegistry registry = IncQueryGUIPlugin.getDefault().getImageRegistry(); - Image image = registry.get(key); - return image; - } - - public FlyoutContainer(FlyoutControlComposite flyoutControl, int style) { - super(flyoutControl, style); - this.flyoutControl = flyoutControl; - configureMenu(); - updateTitleImage("title"); - // add listeners - addListener(SWT.Dispose, new Listener() { - public void handleEvent(Event event) { - if (titleImage != null) { - titleImage.dispose(); - titleImageRotated.dispose(); - titleImage = null; - titleImageRotated = null; - } - if (backImage != null) { - backImage.dispose(); - backImage = null; - } - } - }); - { - Listener listener = new Listener() { - public void handleEvent(Event event) { - layout(); - } - }; - addListener(SWT.Move, listener); - addListener(SWT.Resize, listener); - } - addListener(SWT.Paint, new Listener() { - public void handleEvent(Event event) { - handlePaint(event.gc); - } - }); - // mouse listeners - addMouseListener(new MouseAdapter() { - @Override - public void mouseDown(MouseEvent event) { - if (event.button == 1) { - handle_mouseDown(event); - } - } + private FlyoutControlComposite flyoutControl; + private int titleWidth; + private int titleHeight; + private Image titleImage; + private Image titleImageRotated; + private boolean isResizable; + private boolean stateHover; + private Image backImage; - @Override - public void mouseUp(MouseEvent event) { - if (event.button == 1) { - handle_mouseUp(event); - } - } - }); - addMouseTrackListener(new MouseTrackAdapter() { - @Override - public void mouseExit(MouseEvent e) { - stateHover = false; - redraw(); - setCursor(null); - } + private static Image loadImage(String key) { + ImageRegistry registry = IncQueryGUIPlugin.getDefault().getImageRegistry(); + Image image = registry.get(key); + return image; + } - @Override - public void mouseHover(MouseEvent e) { - handle_mouseHover(); - } - }); - addMouseMoveListener(new MouseMoveListener() { - public void mouseMove(MouseEvent event) { - handle_mouseMove(event); - } - }); - } + public FlyoutContainer(FlyoutControlComposite flyoutControl, int style) { + super(flyoutControl, style); + this.flyoutControl = flyoutControl; + configureMenu(); + updateTitleImage("title"); + // add listeners + addListener(SWT.Dispose, new Listener() { + public void handleEvent(Event event) { + if (titleImage != null) { + titleImage.dispose(); + titleImageRotated.dispose(); + titleImage = null; + titleImageRotated = null; + } + if (backImage != null) { + backImage.dispose(); + backImage = null; + } + } + }); + { + Listener listener = new Listener() { + public void handleEvent(Event event) { + layout(); + } + }; + addListener(SWT.Move, listener); + addListener(SWT.Resize, listener); + } + addListener(SWT.Paint, new Listener() { + public void handleEvent(Event event) { + handlePaint(event.gc); + } + }); + // mouse listeners + addMouseListener(new MouseAdapter() { + @Override + public void mouseDown(MouseEvent event) { + if (event.button == 1) { + handle_mouseDown(event); + } + } - private void handle_mouseDown(MouseEvent event) { - if (stateHover) { - int state = flyoutControl.getPreferences().getState(); - if (state == IFlyoutPreferences.STATE_OPEN) { - state = IFlyoutPreferences.STATE_COLLAPSED; - } else { - state = IFlyoutPreferences.STATE_OPEN; - } - flyoutControl.getPreferences().setState(state); - redraw(); - flyoutControl.layout(); - } else if (getCursor() == ICursorConstants.SIZEWE - || getCursor() == ICursorConstants.SIZENS) { - isResizable = true; - } else if (getCursor() == ICursorConstants.SIZEALL) { - handleDocking(); - } - } + @Override + public void mouseUp(MouseEvent event) { + if (event.button == 1) { + handle_mouseUp(event); + } + } + }); + addMouseTrackListener(new MouseTrackAdapter() { + @Override + public void mouseExit(MouseEvent e) { + stateHover = false; + redraw(); + setCursor(null); + } - private void handle_mouseUp(MouseEvent event) { - if (isResizable) { - isResizable = false; - handle_mouseMove(event); - } - } + @Override + public void mouseHover(MouseEvent e) { + handle_mouseHover(); + } + }); + addMouseMoveListener(new MouseMoveListener() { + public void mouseMove(MouseEvent event) { + handle_mouseMove(event); + } + }); + } - private void handle_mouseMove(MouseEvent event) { - if (isResizable) { - // prepare width - int width; - if (flyoutControl.isHorizontal()) { - width = getSize().x; - } else { - width = getSize().y; - } - // prepare new width - int newWidth = width; - if (flyoutControl.isWest()) { - newWidth = event.x + RESIZE_WIDTH / 2; - } else if (flyoutControl.isEast()) { - newWidth = width - event.x + RESIZE_WIDTH / 2; - } else if (flyoutControl.isNorth()) { - newWidth = event.y + RESIZE_WIDTH / 2; - } else if (flyoutControl.isSouth()) { - newWidth = width - event.y + RESIZE_WIDTH / 2; - } - // update width - if (newWidth != width) { - flyoutControl.getPreferences().setWidth(newWidth); - redraw(); - flyoutControl.layout(); - } - } else { - Rectangle clientArea = getClientArea(); - boolean inside = clientArea.contains(event.x, event.y); - int x = event.x; - int y = event.y; - if (inside) { - // check for state - { - boolean oldStateHover = stateHover; - if (flyoutControl.isEast()) { - stateHover = x > clientArea.width - titleHeight - && y < titleHeight; - } else { - stateHover = x < titleHeight - && y < titleHeight; - } - if (stateHover != oldStateHover) { - redraw(); - } - if (stateHover) { - setCursor(null); - return; - } - } - // check for resize band - if (isOpenExpanded()) { - if (flyoutControl.isWest() && x >= clientArea.width - RESIZE_WIDTH) { - setCursor(ICursorConstants.SIZEWE); - } else if (flyoutControl.isEast() && x <= RESIZE_WIDTH) { - setCursor(ICursorConstants.SIZEWE); - } else if (flyoutControl.isNorth() - && y >= clientArea.height - RESIZE_WIDTH) { - setCursor(ICursorConstants.SIZENS); - } else if (flyoutControl.isSouth() && y <= RESIZE_WIDTH) { - setCursor(ICursorConstants.SIZENS); - } else { - setCursor(null); - } - } - // check for docking - if (getCursor() == null) { - setCursor(ICursorConstants.SIZEALL); - } - } else { - setCursor(null); - } - } - } + private void handle_mouseDown(MouseEvent event) { + if (stateHover) { + int state = flyoutControl.getPreferences().getState(); + if (state == IFlyoutPreferences.STATE_OPEN) { + state = IFlyoutPreferences.STATE_COLLAPSED; + } else { + state = IFlyoutPreferences.STATE_OPEN; + } + flyoutControl.getPreferences().setState(state); + redraw(); + flyoutControl.layout(); + } else if (getCursor() == ICursorConstants.SIZEWE || getCursor() == ICursorConstants.SIZENS) { + isResizable = true; + } else if (getCursor() == ICursorConstants.SIZEALL) { + handleDocking(); + } + } - private void handle_mouseHover() { - if (flyoutControl.getPreferences().getState() == IFlyoutPreferences.STATE_COLLAPSED && !stateHover) { - flyoutControl.getPreferences().setState(IFlyoutPreferences.STATE_EXPANDED); - - flyoutControl.layout(); - // add listeners - Listener listener = new Listener() { - public void handleEvent(Event event) { - if (event.type == SWT.Dispose) { - getDisplay().removeFilter(SWT.MouseMove, this); - } else { - Point p = ((Control) event.widget).toDisplay( - event.x, event.y); - // during resize mouse can be temporary outside of - // flyout - ignore - if (isResizable) { - return; - } - // mouse in in flyout container - ignore - if (getClientArea().contains(toControl(p.x, p.y))) { - return; - } - // mouse is in full container - collapse - if (flyoutControl.getClientArea().contains( - flyoutControl.toControl(p.x, p.y))) { - getDisplay().removeFilter(SWT.MouseMove, this); - // it is possible, that user restored (OPEN) - // flyout, so collapse only if we still in - // expand state - if (flyoutControl.getPreferences().getState() == IFlyoutPreferences.STATE_EXPANDED) { - flyoutControl.getPreferences().setState(IFlyoutPreferences.STATE_COLLAPSED); - flyoutControl.layout(); - } - } - } - } - }; - addListener(SWT.Dispose, listener); - getDisplay().addFilter(SWT.MouseMove, listener); - } - } + private void handle_mouseUp(MouseEvent event) { + if (isResizable) { + isResizable = false; + handle_mouseMove(event); + } + } - private void handleDocking() { - final int width = flyoutControl.getPreferences().getWidth(); - final int oldDockLocation = flyoutControl.getDockLocation(); - final int[] newDockLocation = new int[] { oldDockLocation }; - final Tracker dockingTracker = new Tracker(flyoutControl, SWT.NONE); - dockingTracker.setRectangles(new Rectangle[] { getBounds() }); - dockingTracker.setStippled(true); - dockingTracker.addListener(SWT.Move, new Listener() { - public void handleEvent(Event event2) { - Rectangle clientArea = flyoutControl.getClientArea(); - Point location = flyoutControl.toControl(event2.x, event2.y); - int h3 = clientArea.height / 3; - // check locations - if (location.y < h3 - && flyoutControl.isValidDockLocation(IFlyoutPreferences.DOCK_NORTH)) { - dockingTracker - .setRectangles(new Rectangle[] { new Rectangle( - 0, 0, clientArea.width, width) }); - newDockLocation[0] = IFlyoutPreferences.DOCK_NORTH; - } else if (location.y > 2 * h3 - && flyoutControl.isValidDockLocation(IFlyoutPreferences.DOCK_SOUTH)) { - dockingTracker - .setRectangles(new Rectangle[] { new Rectangle( - 0, clientArea.height - width, - clientArea.width, width) }); - newDockLocation[0] = IFlyoutPreferences.DOCK_SOUTH; - } else if (location.x < clientArea.width / 2 - && flyoutControl.isValidDockLocation(IFlyoutPreferences.DOCK_WEST)) { - dockingTracker - .setRectangles(new Rectangle[] { new Rectangle( - 0, 0, width, clientArea.height) }); - newDockLocation[0] = IFlyoutPreferences.DOCK_WEST; - } else if (flyoutControl.isValidDockLocation(IFlyoutPreferences.DOCK_EAST)) { - dockingTracker - .setRectangles(new Rectangle[] { new Rectangle( - clientArea.width - width, 0, width, - clientArea.height) }); - newDockLocation[0] = IFlyoutPreferences.DOCK_EAST; - } else { - dockingTracker - .setRectangles(new Rectangle[] { getBounds() }); - newDockLocation[0] = oldDockLocation; - } - } - }); - // start tracking - if (dockingTracker.open()) { - flyoutControl.setDockLocation(newDockLocation[0]); - } - // dispose tracker - dockingTracker.dispose(); - } + private void handle_mouseMove(MouseEvent event) { + if (isResizable) { + // prepare width + int width; + if (flyoutControl.isHorizontal()) { + width = getSize().x; + } else { + width = getSize().y; + } + // prepare new width + int newWidth = width; + if (flyoutControl.isWest()) { + newWidth = event.x + RESIZE_WIDTH / 2; + } else if (flyoutControl.isEast()) { + newWidth = width - event.x + RESIZE_WIDTH / 2; + } else if (flyoutControl.isNorth()) { + newWidth = event.y + RESIZE_WIDTH / 2; + } else if (flyoutControl.isSouth()) { + newWidth = width - event.y + RESIZE_WIDTH / 2; + } + // update width + if (newWidth != width) { + flyoutControl.getPreferences().setWidth(newWidth); + redraw(); + flyoutControl.layout(); + } + } else { + Rectangle clientArea = getClientArea(); + boolean inside = clientArea.contains(event.x, event.y); + int x = event.x; + int y = event.y; + if (inside) { + // check for state + { + boolean oldStateHover = stateHover; + if (flyoutControl.isEast()) { + stateHover = x > clientArea.width - titleHeight && y < titleHeight; + } else { + stateHover = x < titleHeight && y < titleHeight; + } + if (stateHover != oldStateHover) { + redraw(); + } + if (stateHover) { + setCursor(null); + return; + } + } + // check for resize band + if (isOpenExpanded()) { + if (flyoutControl.isWest() && x >= clientArea.width - RESIZE_WIDTH) { + setCursor(ICursorConstants.SIZEWE); + } else if (flyoutControl.isEast() && x <= RESIZE_WIDTH) { + setCursor(ICursorConstants.SIZEWE); + } else if (flyoutControl.isNorth() && y >= clientArea.height - RESIZE_WIDTH) { + setCursor(ICursorConstants.SIZENS); + } else if (flyoutControl.isSouth() && y <= RESIZE_WIDTH) { + setCursor(ICursorConstants.SIZENS); + } else { + setCursor(null); + } + } + // check for docking + if (getCursor() == null) { + setCursor(ICursorConstants.SIZEALL); + } + } else { + setCursor(null); + } + } + } - public Control getControl() { - Control[] children = getChildren(); - return children.length == 1 ? children[0] : null; - } + private void handle_mouseHover() { + if (flyoutControl.getPreferences().getState() == IFlyoutPreferences.STATE_COLLAPSED && !stateHover) { + flyoutControl.getPreferences().setState(IFlyoutPreferences.STATE_EXPANDED); - public void setTitleText(String text) { - updateTitleImage(text); - } + flyoutControl.layout(); + // add listeners + Listener listener = new Listener() { + public void handleEvent(Event event) { + if (event.type == SWT.Dispose) { + getDisplay().removeFilter(SWT.MouseMove, this); + } else { + Point p = ((Control) event.widget).toDisplay(event.x, event.y); + // during resize mouse can be temporary outside of + // flyout - ignore + if (isResizable) { + return; + } + // mouse in in flyout container - ignore + if (getClientArea().contains(toControl(p.x, p.y))) { + return; + } + // mouse is in full container - collapse + if (flyoutControl.getClientArea().contains(flyoutControl.toControl(p.x, p.y))) { + getDisplay().removeFilter(SWT.MouseMove, this); + // it is possible, that user restored (OPEN) + // flyout, so collapse only if we still in + // expand state + if (flyoutControl.getPreferences().getState() == IFlyoutPreferences.STATE_EXPANDED) { + flyoutControl.getPreferences().setState(IFlyoutPreferences.STATE_COLLAPSED); + flyoutControl.layout(); + } + } + } + } + }; + addListener(SWT.Dispose, listener); + getDisplay().addFilter(SWT.MouseMove, listener); + } + } - @Override - public void layout() { - Control control = getControl(); - if (control == null) { - return; - } - - Rectangle clientArea = getClientArea(); - if (isOpenExpanded()) { - if (flyoutControl.isWest()) { - int y = titleHeight; - control.setBounds(0, y, clientArea.width - RESIZE_WIDTH, - clientArea.height - y); - } else if (flyoutControl.isEast()) { - int y = titleHeight; - control.setBounds(RESIZE_WIDTH, y, clientArea.width - - RESIZE_WIDTH, clientArea.height - y); - } else if (flyoutControl.isNorth()) { - int y = titleHeight; - control.setBounds(0, y, clientArea.width, clientArea.height - - y - RESIZE_WIDTH); - } else if (flyoutControl.isSouth()) { - int y = RESIZE_WIDTH + titleHeight; - control.setBounds(0, y, clientArea.width, clientArea.height - - y); - } - } else { - control.setBounds(0, 0, 0, 0); - } - } + private void handleDocking() { + final int width = flyoutControl.getPreferences().getWidth(); + final int oldDockLocation = flyoutControl.getDockLocation(); + final int[] newDockLocation = new int[] { oldDockLocation }; + final Tracker dockingTracker = new Tracker(flyoutControl, SWT.NONE); + dockingTracker.setRectangles(new Rectangle[] { getBounds() }); + dockingTracker.setStippled(true); + dockingTracker.addListener(SWT.Move, new Listener() { + public void handleEvent(Event event2) { + Rectangle clientArea = flyoutControl.getClientArea(); + Point location = flyoutControl.toControl(event2.x, event2.y); + int h3 = clientArea.height / 3; + // check locations + if (location.y < h3 && flyoutControl.isValidDockLocation(IFlyoutPreferences.DOCK_NORTH)) { + dockingTracker.setRectangles(new Rectangle[] { new Rectangle(0, 0, clientArea.width, width) }); + newDockLocation[0] = IFlyoutPreferences.DOCK_NORTH; + } else if (location.y > 2 * h3 && flyoutControl.isValidDockLocation(IFlyoutPreferences.DOCK_SOUTH)) { + dockingTracker.setRectangles(new Rectangle[] { new Rectangle(0, clientArea.height - width, + clientArea.width, width) }); + newDockLocation[0] = IFlyoutPreferences.DOCK_SOUTH; + } else if (location.x < clientArea.width / 2 + && flyoutControl.isValidDockLocation(IFlyoutPreferences.DOCK_WEST)) { + dockingTracker.setRectangles(new Rectangle[] { new Rectangle(0, 0, width, clientArea.height) }); + newDockLocation[0] = IFlyoutPreferences.DOCK_WEST; + } else if (flyoutControl.isValidDockLocation(IFlyoutPreferences.DOCK_EAST)) { + dockingTracker.setRectangles(new Rectangle[] { new Rectangle(clientArea.width - width, 0, width, + clientArea.height) }); + newDockLocation[0] = IFlyoutPreferences.DOCK_EAST; + } else { + dockingTracker.setRectangles(new Rectangle[] { getBounds() }); + newDockLocation[0] = oldDockLocation; + } + } + }); + // start tracking + if (dockingTracker.open()) { + flyoutControl.setDockLocation(newDockLocation[0]); + } + // dispose tracker + dockingTracker.dispose(); + } - private void handlePaint(GC paintGC) { - Rectangle clientArea = getClientArea(); - // prepare back image - GC gc; - { - if (backImage == null - || !backImage.getBounds().equals(clientArea)) { - if (backImage != null) { - backImage.dispose(); - } - backImage = new Image(getDisplay(), clientArea.width, - clientArea.height); - } - // prepare GC - gc = new GC(backImage); - gc.setBackground(paintGC.getBackground()); - gc.setForeground(paintGC.getForeground()); - gc.fillRectangle(clientArea); - } - // - if (isOpenExpanded()) { - // draw header - { - // draw title - if (flyoutControl.isWest()) { - drawStateImage(gc, 0, 0); - gc.drawImage(titleImage, titleHeight, 0); - } else if (flyoutControl.isEast()) { - int x = clientArea.width - titleHeight; - drawStateImage(gc, x, 0); - gc.drawImage(titleImage, x - titleWidth, 0); - } else if (flyoutControl.isNorth()) { - drawStateImage(gc, 0, 0); - gc.drawImage(titleImage, titleHeight, 0); - } else if (flyoutControl.isSouth()) { - int y = RESIZE_WIDTH; - drawStateImage(gc, 0, y); - gc.drawImage(titleImage, titleHeight, y); - } - } - // draw resize band - drawResizeBand(gc); - } else { - if (flyoutControl.isHorizontal()) { - drawStateImage(gc, 0, 0); - gc.drawImage(titleImageRotated, 0, titleHeight); - } else { - drawStateImage(gc, 0, 0); - gc.drawImage(titleImage, titleHeight, 0); - } - DrawUtils.drawHighlightRectangle(gc, 0, 0, clientArea.width, - clientArea.height); - } - // flush back image - { - gc.dispose(); - paintGC.drawImage(backImage, 0, 0); - } - } + public Control getControl() { + Control[] children = getChildren(); + return children.length == 1 ? children[0] : null; + } - private void drawStateImage(GC gc, int x, int y) { - DrawUtils.drawImageCHCV(gc, getStateImage(), x, y, titleHeight, - titleHeight); - if (stateHover) { - DrawUtils.drawHighlightRectangle(gc, x, y, titleHeight, - titleHeight); - } - } + public void setTitleText(String text) { + updateTitleImage(text); + } - private Image getStateImage() { - int location = flyoutControl.getDockLocation(); - int state = flyoutControl.getPreferences().getState(); - if (state == IFlyoutPreferences.STATE_OPEN) { - switch (location) { - case IFlyoutPreferences.DOCK_WEST: - return ARROW_LEFT; - case IFlyoutPreferences.DOCK_EAST: - return ARROW_RIGHT; - case IFlyoutPreferences.DOCK_NORTH: - return ARROW_TOP; - case IFlyoutPreferences.DOCK_SOUTH: - return ARROW_BOTTOM; - } - } else if (state == IFlyoutPreferences.STATE_EXPANDED) { - return PIN; - } else { - switch (location) { - case IFlyoutPreferences.DOCK_WEST: - return ARROW_RIGHT; - case IFlyoutPreferences.DOCK_EAST: - return ARROW_LEFT; - case IFlyoutPreferences.DOCK_NORTH: - return ARROW_BOTTOM; - case IFlyoutPreferences.DOCK_SOUTH: - return ARROW_TOP; - } - } - - return null; - } + @Override + public void layout() { + Control control = getControl(); + if (control == null) { + return; + } - private void drawResizeBand(GC gc) { - Rectangle clientArea = getClientArea(); - // prepare locations - int x, y, width, height; - if (flyoutControl.isHorizontal()) { - if (flyoutControl.isWest()) { - x = clientArea.width - RESIZE_WIDTH; - } else { - x = 0; - } - y = 0; - width = RESIZE_WIDTH; - height = clientArea.height; - } else { - x = 0; - if (flyoutControl.isNorth()) { - y = clientArea.height - RESIZE_WIDTH; - } else { - y = 0; - } - width = clientArea.width; - height = RESIZE_WIDTH; - } - // draw band - DrawUtils.drawHighlightRectangle(gc, x, y, width, height); - } + Rectangle clientArea = getClientArea(); + if (isOpenExpanded()) { + if (flyoutControl.isWest()) { + int y = titleHeight; + control.setBounds(0, y, clientArea.width - RESIZE_WIDTH, clientArea.height - y); + } else if (flyoutControl.isEast()) { + int y = titleHeight; + control.setBounds(RESIZE_WIDTH, y, clientArea.width - RESIZE_WIDTH, clientArea.height - y); + } else if (flyoutControl.isNorth()) { + int y = titleHeight; + control.setBounds(0, y, clientArea.width, clientArea.height - y - RESIZE_WIDTH); + } else if (flyoutControl.isSouth()) { + int y = RESIZE_WIDTH + titleHeight; + control.setBounds(0, y, clientArea.width, clientArea.height - y); + } + } else { + control.setBounds(0, 0, 0, 0); + } + } - private boolean isOpenExpanded() { - int state = flyoutControl.getPreferences().getState(); - return state == IFlyoutPreferences.STATE_OPEN || state == IFlyoutPreferences.STATE_EXPANDED; - } + private void handlePaint(GC paintGC) { + Rectangle clientArea = getClientArea(); + // prepare back image + GC gc; + { + if (backImage == null || !backImage.getBounds().equals(clientArea)) { + if (backImage != null) { + backImage.dispose(); + } + backImage = new Image(getDisplay(), clientArea.width, clientArea.height); + } + // prepare GC + gc = new GC(backImage); + gc.setBackground(paintGC.getBackground()); + gc.setForeground(paintGC.getForeground()); + gc.fillRectangle(clientArea); + } + // + if (isOpenExpanded()) { + // draw header + { + // draw title + if (flyoutControl.isWest()) { + drawStateImage(gc, 0, 0); + gc.drawImage(titleImage, titleHeight, 0); + } else if (flyoutControl.isEast()) { + int x = clientArea.width - titleHeight; + drawStateImage(gc, x, 0); + gc.drawImage(titleImage, x - titleWidth, 0); + } else if (flyoutControl.isNorth()) { + drawStateImage(gc, 0, 0); + gc.drawImage(titleImage, titleHeight, 0); + } else if (flyoutControl.isSouth()) { + int y = RESIZE_WIDTH; + drawStateImage(gc, 0, y); + gc.drawImage(titleImage, titleHeight, y); + } + } + // draw resize band + drawResizeBand(gc); + } else { + if (flyoutControl.isHorizontal()) { + drawStateImage(gc, 0, 0); + gc.drawImage(titleImageRotated, 0, titleHeight); + } else { + drawStateImage(gc, 0, 0); + gc.drawImage(titleImage, titleHeight, 0); + } + DrawUtils.drawHighlightRectangle(gc, 0, 0, clientArea.width, clientArea.height); + } + // flush back image + { + gc.dispose(); + paintGC.drawImage(backImage, 0, 0); + } + } - private void updateTitleImage(String text) { - // prepare size of text - Point textSize; - { - GC gc = new GC(this); - gc.setFont(TITLE_FONT); - textSize = gc.textExtent(text); - gc.dispose(); - } - // dispose existing image - if (titleImage != null) { - titleImage.dispose(); - titleImageRotated.dispose(); - } - // prepare new image - { - titleWidth = textSize.x + 2 * TITLE_LINES + 4 * TITLE_MARGIN; - titleHeight = textSize.y; - titleImage = new Image(getDisplay(), titleWidth, titleHeight); - GC gc = new GC(titleImage); - try { - gc.setBackground(getBackground()); - gc.fillRectangle(0, 0, titleWidth, titleHeight); - gc.setForeground(FlyoutConstants.BLACK); - gc.setFont(TITLE_FONT); - gc.drawText(text, 0, 0); - - } finally { - gc.dispose(); - } - } - // prepare rotated image - titleImageRotated = DrawUtils.createRotatedImage(titleImage); - } + private void drawStateImage(GC gc, int x, int y) { + DrawUtils.drawImageCHCV(gc, getStateImage(), x, y, titleHeight, titleHeight); + if (stateHover) { + DrawUtils.drawHighlightRectangle(gc, x, y, titleHeight, titleHeight); + } + } - private void configureMenu() {} - - public int getTitleHeight() { - return titleHeight; - } - - public int getTitleWidth() { - return titleWidth; - } + private Image getStateImage() { + int location = flyoutControl.getDockLocation(); + int state = flyoutControl.getPreferences().getState(); + if (state == IFlyoutPreferences.STATE_OPEN) { + switch (location) { + case IFlyoutPreferences.DOCK_WEST: + return ARROW_LEFT; + case IFlyoutPreferences.DOCK_EAST: + return ARROW_RIGHT; + case IFlyoutPreferences.DOCK_NORTH: + return ARROW_TOP; + case IFlyoutPreferences.DOCK_SOUTH: + return ARROW_BOTTOM; + } + } else if (state == IFlyoutPreferences.STATE_EXPANDED) { + return PIN; + } else { + switch (location) { + case IFlyoutPreferences.DOCK_WEST: + return ARROW_RIGHT; + case IFlyoutPreferences.DOCK_EAST: + return ARROW_LEFT; + case IFlyoutPreferences.DOCK_NORTH: + return ARROW_BOTTOM; + case IFlyoutPreferences.DOCK_SOUTH: + return ARROW_TOP; + } + } + + return null; + } + + private void drawResizeBand(GC gc) { + Rectangle clientArea = getClientArea(); + // prepare locations + int x, y, width, height; + if (flyoutControl.isHorizontal()) { + if (flyoutControl.isWest()) { + x = clientArea.width - RESIZE_WIDTH; + } else { + x = 0; + } + y = 0; + width = RESIZE_WIDTH; + height = clientArea.height; + } else { + x = 0; + if (flyoutControl.isNorth()) { + y = clientArea.height - RESIZE_WIDTH; + } else { + y = 0; + } + width = clientArea.width; + height = RESIZE_WIDTH; + } + // draw band + DrawUtils.drawHighlightRectangle(gc, x, y, width, height); + } + + private boolean isOpenExpanded() { + int state = flyoutControl.getPreferences().getState(); + return state == IFlyoutPreferences.STATE_OPEN || state == IFlyoutPreferences.STATE_EXPANDED; + } + + private void updateTitleImage(String text) { + // prepare size of text + Point textSize; + { + GC gc = new GC(this); + gc.setFont(TITLE_FONT); + textSize = gc.textExtent(text); + gc.dispose(); + } + // dispose existing image + if (titleImage != null) { + titleImage.dispose(); + titleImageRotated.dispose(); + } + // prepare new image + { + titleWidth = textSize.x + 2 * TITLE_LINES + 4 * TITLE_MARGIN; + titleHeight = textSize.y; + titleImage = new Image(getDisplay(), titleWidth, titleHeight); + GC gc = new GC(titleImage); + try { + gc.setBackground(getBackground()); + gc.fillRectangle(0, 0, titleWidth, titleHeight); + gc.setForeground(FlyoutConstants.BLACK); + gc.setFont(TITLE_FONT); + gc.drawText(text, 0, 0); + + } finally { + gc.dispose(); + } + } + // prepare rotated image + titleImageRotated = DrawUtils.createRotatedImage(titleImage); + } + + private void configureMenu() { + } + + public int getTitleHeight() { + return titleHeight; + } + + public int getTitleWidth() { + return titleWidth; + } } diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/FlyoutControlComposite.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/FlyoutControlComposite.java index 1922ba42..8a2538ed 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/FlyoutControlComposite.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/FlyoutControlComposite.java @@ -20,151 +20,143 @@ public final class FlyoutControlComposite extends Composite { - private final IFlyoutPreferences preferences; - private final FlyoutContainer flyoutContainer; - private int minWidth = 100; - private int validDockLocations = -1; - - public FlyoutControlComposite(Composite parent, int style, - IFlyoutPreferences preferences) { - super(parent, style); - this.preferences = preferences; - - addListener(SWT.Resize, new Listener() { - public void handleEvent(Event event) { - if (getShell().getMinimized()) { - return; - } - layout(); - } - }); - - flyoutContainer = new FlyoutContainer(this, SWT.NO_BACKGROUND); - } - - public Composite getFlyoutParent() { - return flyoutContainer; - } - - public Composite getClientParent() { - return this; - } - - public void setValidDockLocations(int validDockLocations) { - this.validDockLocations = validDockLocations; - } - - public void setMinWidth(int minWidth) { - this.minWidth = minWidth; - } - - public void setTitleText(String text) { - flyoutContainer.setTitleText(text); - } - - @Override - public void layout() { - Rectangle clientArea = getClientArea(); - int state = preferences.getState(); - Control client = getChildren()[1]; - - if (clientArea.width == 0 || clientArea.height == 0) { - return; - } - - if (flyoutContainer.getControl() == null) { - flyoutContainer.setBounds(0, 0, 0, 0); - client.setBounds(clientArea); - return; - } - // prepare width to display - int width; - int offset; - if (state == IFlyoutPreferences.STATE_OPEN) { - width = preferences.getWidth(); - // limit maximum value - if (isHorizontal()) { - width = Math.min(clientArea.width / 2, width); - } else { - width = Math.min(clientArea.height / 2, width); - } - // limit minimum value - width = Math.max(width, minWidth); - width = Math.max(width, 2 * flyoutContainer.getTitleHeight() - + flyoutContainer.getTitleWidth()); - // remember actual width - preferences.setWidth(width); - // - offset = width; - } else if (state == IFlyoutPreferences.STATE_EXPANDED) { - offset = flyoutContainer.getTitleHeight(); - width = preferences.getWidth(); - } else { - width = flyoutContainer.getTitleHeight(); - offset = width; - } - // change bounds for flyout container and client control - { - if (isWest()) { - flyoutContainer.setBounds(0, 0, width, clientArea.height); - client.setBounds(offset, 0, clientArea.width - offset, - clientArea.height); - } else if (isEast()) { - flyoutContainer.setBounds(clientArea.width - width, 0, width, - clientArea.height); - client.setBounds(0, 0, clientArea.width - offset, - clientArea.height); - } else if (isNorth()) { - flyoutContainer.setBounds(0, 0, clientArea.width, width); - client.setBounds(0, offset, clientArea.width, clientArea.height - - offset); - } else if (isSouth()) { - flyoutContainer.setBounds(0, clientArea.height - width, - clientArea.width, width); - client.setBounds(0, 0, clientArea.width, clientArea.height - - offset); - } - } - } - - public boolean isHorizontal() { - return isWest() || isEast(); - } - - public boolean isWest() { - return getDockLocation() == IFlyoutPreferences.DOCK_WEST; - } - - public boolean isEast() { - return getDockLocation() == IFlyoutPreferences.DOCK_EAST; - } - - public boolean isNorth() { - return getDockLocation() == IFlyoutPreferences.DOCK_NORTH; - } - - public boolean isSouth() { - return getDockLocation() == IFlyoutPreferences.DOCK_SOUTH; - } - - public boolean isValidDockLocation(int location) { - return (location & validDockLocations) == location; - } - - public int getDockLocation() { - return preferences.getDockLocation(); - } - - public int getValidDockLocations() { - return validDockLocations; - } - - public void setDockLocation(int dockLocation) { - preferences.setDockLocation(dockLocation); - layout(); - } - - public IFlyoutPreferences getPreferences() { - return preferences; - } + private final IFlyoutPreferences preferences; + private final FlyoutContainer flyoutContainer; + private int minWidth = 100; + private int validDockLocations = -1; + + public FlyoutControlComposite(Composite parent, int style, IFlyoutPreferences preferences) { + super(parent, style); + this.preferences = preferences; + + addListener(SWT.Resize, new Listener() { + public void handleEvent(Event event) { + if (getShell().getMinimized()) { + return; + } + layout(); + } + }); + + flyoutContainer = new FlyoutContainer(this, SWT.NO_BACKGROUND); + } + + public Composite getFlyoutParent() { + return flyoutContainer; + } + + public Composite getClientParent() { + return this; + } + + public void setValidDockLocations(int validDockLocations) { + this.validDockLocations = validDockLocations; + } + + public void setMinWidth(int minWidth) { + this.minWidth = minWidth; + } + + public void setTitleText(String text) { + flyoutContainer.setTitleText(text); + } + + @Override + public void layout() { + Rectangle clientArea = getClientArea(); + int state = preferences.getState(); + Control client = getChildren()[1]; + + if (clientArea.width == 0 || clientArea.height == 0) { + return; + } + + if (flyoutContainer.getControl() == null) { + flyoutContainer.setBounds(0, 0, 0, 0); + client.setBounds(clientArea); + return; + } + // prepare width to display + int width; + int offset; + if (state == IFlyoutPreferences.STATE_OPEN) { + width = preferences.getWidth(); + // limit maximum value + if (isHorizontal()) { + width = Math.min(clientArea.width / 2, width); + } else { + width = Math.min(clientArea.height / 2, width); + } + // limit minimum value + width = Math.max(width, minWidth); + width = Math.max(width, 2 * flyoutContainer.getTitleHeight() + flyoutContainer.getTitleWidth()); + // remember actual width + preferences.setWidth(width); + // + offset = width; + } else if (state == IFlyoutPreferences.STATE_EXPANDED) { + offset = flyoutContainer.getTitleHeight(); + width = preferences.getWidth(); + } else { + width = flyoutContainer.getTitleHeight(); + offset = width; + } + // change bounds for flyout container and client control + { + if (isWest()) { + flyoutContainer.setBounds(0, 0, width, clientArea.height); + client.setBounds(offset, 0, clientArea.width - offset, clientArea.height); + } else if (isEast()) { + flyoutContainer.setBounds(clientArea.width - width, 0, width, clientArea.height); + client.setBounds(0, 0, clientArea.width - offset, clientArea.height); + } else if (isNorth()) { + flyoutContainer.setBounds(0, 0, clientArea.width, width); + client.setBounds(0, offset, clientArea.width, clientArea.height - offset); + } else if (isSouth()) { + flyoutContainer.setBounds(0, clientArea.height - width, clientArea.width, width); + client.setBounds(0, 0, clientArea.width, clientArea.height - offset); + } + } + } + + public boolean isHorizontal() { + return isWest() || isEast(); + } + + public boolean isWest() { + return getDockLocation() == IFlyoutPreferences.DOCK_WEST; + } + + public boolean isEast() { + return getDockLocation() == IFlyoutPreferences.DOCK_EAST; + } + + public boolean isNorth() { + return getDockLocation() == IFlyoutPreferences.DOCK_NORTH; + } + + public boolean isSouth() { + return getDockLocation() == IFlyoutPreferences.DOCK_SOUTH; + } + + public boolean isValidDockLocation(int location) { + return (location & validDockLocations) == location; + } + + public int getDockLocation() { + return preferences.getDockLocation(); + } + + public int getValidDockLocations() { + return validDockLocations; + } + + public void setDockLocation(int dockLocation) { + preferences.setDockLocation(dockLocation); + layout(); + } + + public IFlyoutPreferences getPreferences() { + return preferences; + } } diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/FlyoutPreferences.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/FlyoutPreferences.java index 6468346f..abaadd0e 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/FlyoutPreferences.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/FlyoutPreferences.java @@ -9,42 +9,42 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.content.flyout; - -public final class FlyoutPreferences implements IFlyoutPreferences { - private int dockLocation; - private int state; - private int width; - - public FlyoutPreferences(int dockLocation, int state, int width) { - super(); - this.dockLocation = dockLocation; - this.state = state; - this.width = width; - } - - public int getDockLocation() { - return dockLocation; - } - - public void setDockLocation(int dockLocation) { - this.dockLocation = dockLocation; - } - - public int getState() { - return state; - } - - public void setState(int state) { - this.state = state; - } - - public int getWidth() { - return width; - } - - public void setWidth(int width) { - this.width = width; - } - -} +package org.eclipse.incquery.tooling.ui.queryexplorer.content.flyout; + +public final class FlyoutPreferences implements IFlyoutPreferences { + private int dockLocation; + private int state; + private int width; + + public FlyoutPreferences(int dockLocation, int state, int width) { + super(); + this.dockLocation = dockLocation; + this.state = state; + this.width = width; + } + + public int getDockLocation() { + return dockLocation; + } + + public void setDockLocation(int dockLocation) { + this.dockLocation = dockLocation; + } + + public int getState() { + return state; + } + + public void setState(int state) { + this.state = state; + } + + public int getWidth() { + return width; + } + + public void setWidth(int width) { + this.width = width; + } + +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/ICursorConstants.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/ICursorConstants.java index 7e1b8095..a90dd36e 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/ICursorConstants.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/ICursorConstants.java @@ -15,121 +15,121 @@ import org.eclipse.swt.graphics.Cursor; public interface ICursorConstants { - /** - * System arrow cursor. - */ - Cursor ARROW = new Cursor(null, SWT.CURSOR_ARROW); - /** - * System resize north cursor. - */ - Cursor SIZEN = new Cursor(null, SWT.CURSOR_SIZEN); - /** - * System resize north-east cursor. - */ - Cursor SIZENE = new Cursor(null, SWT.CURSOR_SIZENE); - /** - * System resize east cursor. - */ - Cursor SIZEE = new Cursor(null, SWT.CURSOR_SIZEE); - /** - * System resize south-east cursor. - */ - Cursor SIZESE = new Cursor(null, SWT.CURSOR_SIZESE); - /** - * System resize south cursor. - */ - Cursor SIZES = new Cursor(null, SWT.CURSOR_SIZES); - /** - * System resize south-west cursor. - */ - Cursor SIZESW = new Cursor(null, SWT.CURSOR_SIZESW); - /** - * System resize west cursor. - */ - Cursor SIZEW = new Cursor(null, SWT.CURSOR_SIZEW); - /** - * System resize north-west cursor. - */ - Cursor SIZENW = new Cursor(null, SWT.CURSOR_SIZENW); - /** - * System resize north-south cursor - */ - Cursor SIZENS = new Cursor(null, SWT.CURSOR_SIZENS); - /** - * System resize west-east cursor - */ - Cursor SIZEWE = new Cursor(null, SWT.CURSOR_SIZEWE); - /** - * System app startup cursor. - */ - Cursor APPSTARTING = new Cursor(null, SWT.CURSOR_APPSTARTING); - /** - * System cross hair cursor. - */ - Cursor CROSS = new Cursor(null, SWT.CURSOR_CROSS); - /** - * System hand cursor. - */ - Cursor HAND = new Cursor(null, SWT.CURSOR_HAND); - /** - * System help cursor. - */ - Cursor HELP = new Cursor(null, SWT.CURSOR_HELP); - /** - * System i-beam cursor. - */ - Cursor IBEAM = new Cursor(null, SWT.CURSOR_IBEAM); - /** - * System "not allowed" cursor. - */ - Cursor NO = new Cursor(null, SWT.CURSOR_NO); - /** - * System resize all directions cursor. - */ - Cursor SIZEALL = new Cursor(null, SWT.CURSOR_SIZEALL); - /** - * System resize north-east-south-west cursor. - */ - Cursor SIZENESW = new Cursor(null, SWT.CURSOR_SIZENESW); - /** - * System resize north-west-south-east cursor. - */ - Cursor SIZENWSE = new Cursor(null, SWT.CURSOR_SIZENWSE); - /** - * System up arrow cursor. - */ - Cursor UPARROW = new Cursor(null, SWT.CURSOR_UPARROW); - /** - * System wait cursor. - */ - Cursor WAIT = new Cursor(null, SWT.CURSOR_WAIT); + /** + * System arrow cursor. + */ + Cursor ARROW = new Cursor(null, SWT.CURSOR_ARROW); + /** + * System resize north cursor. + */ + Cursor SIZEN = new Cursor(null, SWT.CURSOR_SIZEN); + /** + * System resize north-east cursor. + */ + Cursor SIZENE = new Cursor(null, SWT.CURSOR_SIZENE); + /** + * System resize east cursor. + */ + Cursor SIZEE = new Cursor(null, SWT.CURSOR_SIZEE); + /** + * System resize south-east cursor. + */ + Cursor SIZESE = new Cursor(null, SWT.CURSOR_SIZESE); + /** + * System resize south cursor. + */ + Cursor SIZES = new Cursor(null, SWT.CURSOR_SIZES); + /** + * System resize south-west cursor. + */ + Cursor SIZESW = new Cursor(null, SWT.CURSOR_SIZESW); + /** + * System resize west cursor. + */ + Cursor SIZEW = new Cursor(null, SWT.CURSOR_SIZEW); + /** + * System resize north-west cursor. + */ + Cursor SIZENW = new Cursor(null, SWT.CURSOR_SIZENW); + /** + * System resize north-south cursor + */ + Cursor SIZENS = new Cursor(null, SWT.CURSOR_SIZENS); + /** + * System resize west-east cursor + */ + Cursor SIZEWE = new Cursor(null, SWT.CURSOR_SIZEWE); + /** + * System app startup cursor. + */ + Cursor APPSTARTING = new Cursor(null, SWT.CURSOR_APPSTARTING); + /** + * System cross hair cursor. + */ + Cursor CROSS = new Cursor(null, SWT.CURSOR_CROSS); + /** + * System hand cursor. + */ + Cursor HAND = new Cursor(null, SWT.CURSOR_HAND); + /** + * System help cursor. + */ + Cursor HELP = new Cursor(null, SWT.CURSOR_HELP); + /** + * System i-beam cursor. + */ + Cursor IBEAM = new Cursor(null, SWT.CURSOR_IBEAM); + /** + * System "not allowed" cursor. + */ + Cursor NO = new Cursor(null, SWT.CURSOR_NO); + /** + * System resize all directions cursor. + */ + Cursor SIZEALL = new Cursor(null, SWT.CURSOR_SIZEALL); + /** + * System resize north-east-south-west cursor. + */ + Cursor SIZENESW = new Cursor(null, SWT.CURSOR_SIZENESW); + /** + * System resize north-west-south-east cursor. + */ + Cursor SIZENWSE = new Cursor(null, SWT.CURSOR_SIZENWSE); + /** + * System up arrow cursor. + */ + Cursor UPARROW = new Cursor(null, SWT.CURSOR_UPARROW); + /** + * System wait cursor. + */ + Cursor WAIT = new Cursor(null, SWT.CURSOR_WAIT); - /** - * Returns the cursor corresponding to the given direction. - */ - class Directional implements FlyoutConstants { - public static final Cursor getCursor(int direction) { - switch (direction) { - case NORTH : - return SIZEN; - case SOUTH : - return SIZES; - case EAST : - return SIZEE; - case WEST : - return SIZEW; - case SOUTH_EAST : - return SIZESE; - case SOUTH_WEST : - return SIZESW; - case NORTH_EAST : - return SIZENE; - case NORTH_WEST : - return SIZENW; - default : - break; - } - return null; + /** + * Returns the cursor corresponding to the given direction. + */ + class Directional implements FlyoutConstants { + public static final Cursor getCursor(int direction) { + switch (direction) { + case NORTH: + return SIZEN; + case SOUTH: + return SIZES; + case EAST: + return SIZEE; + case WEST: + return SIZEW; + case SOUTH_EAST: + return SIZESE; + case SOUTH_WEST: + return SIZESW; + case NORTH_EAST: + return SIZENE; + case NORTH_WEST: + return SIZENW; + default: + break; + } + return null; + } } - } } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/IFlyoutPreferences.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/IFlyoutPreferences.java index 62bb6c55..01bf8c3d 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/IFlyoutPreferences.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/flyout/IFlyoutPreferences.java @@ -13,24 +13,24 @@ public interface IFlyoutPreferences { - int DOCK_WEST = 1; - int DOCK_EAST = 2; - int DOCK_NORTH = 4; - int DOCK_SOUTH = 8; + int DOCK_WEST = 1; + int DOCK_EAST = 2; + int DOCK_NORTH = 4; + int DOCK_SOUTH = 8; - int STATE_OPEN = 0; - int STATE_COLLAPSED = 1; - int STATE_EXPANDED = 2; + int STATE_OPEN = 0; + int STATE_COLLAPSED = 1; + int STATE_EXPANDED = 2; - int getDockLocation(); + int getDockLocation(); - int getState(); + int getState(); - int getWidth(); + int getWidth(); - void setDockLocation(int location); + void setDockLocation(int location); - void setState(int state); + void setState(int state); - void setWidth(int width); + void setWidth(int width); } diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/MatcherContentProvider.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/MatcherContentProvider.java index a132e53a..aa99c732 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/MatcherContentProvider.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/MatcherContentProvider.java @@ -9,82 +9,75 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.content.matcher; - -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.Viewer; - -public class MatcherContentProvider implements ITreeContentProvider { - - private MatcherTreeViewerRoot input; - - public MatcherContentProvider() { - - } - - @Override - public void dispose() { - input = null; - } - - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - if (newInput != null && newInput instanceof MatcherTreeViewerRoot) { - input = (MatcherTreeViewerRoot) newInput; - } - } - - @Override - public Object[] getElements(Object inputElement) { - if (inputElement instanceof MatcherTreeViewerRoot) { - return input.getRoots().toArray(); - } - return null; - } - - @Override - public Object[] getChildren(Object parentElement) { - if (parentElement instanceof MatcherTreeViewerRoot) { - return input.getRoots().toArray(); - } - else if (parentElement instanceof ObservablePatternMatcherRoot) { - return ((ObservablePatternMatcherRoot) parentElement).getMatchers().toArray(); - } - else if (parentElement instanceof ObservablePatternMatcher) { - return ((ObservablePatternMatcher) parentElement).getMatches().toArray(); - } - return null; - } - - @Override - public Object getParent(Object element) { - if (element instanceof ObservablePatternMatcherRoot) { - return input; - } - else if (element instanceof ObservablePatternMatcher) { - return ((ObservablePatternMatcher) element).getParent(); - } - else if (element instanceof ObservablePatternMatch) { - return ((ObservablePatternMatch) element).getParent(); - } - return null; - } - - @Override - public boolean hasChildren(Object element) { - if (element != null) { - if (element instanceof MatcherTreeViewerRoot) { - return (!input.getRoots().isEmpty()); - } - else if (element instanceof ObservablePatternMatcherRoot) { - return (!((ObservablePatternMatcherRoot) element).getMatchers().isEmpty()); - } - else if (element instanceof ObservablePatternMatcher) { - return (!(((ObservablePatternMatcher) element).getMatches().isEmpty())); - } - } - return false; - } - - -} +package org.eclipse.incquery.tooling.ui.queryexplorer.content.matcher; + +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + +public class MatcherContentProvider implements ITreeContentProvider { + + private MatcherTreeViewerRoot input; + + public MatcherContentProvider() { + + } + + @Override + public void dispose() { + input = null; + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + if (newInput != null && newInput instanceof MatcherTreeViewerRoot) { + input = (MatcherTreeViewerRoot) newInput; + } + } + + @Override + public Object[] getElements(Object inputElement) { + if (inputElement instanceof MatcherTreeViewerRoot) { + return input.getRoots().toArray(); + } + return null; + } + + @Override + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof MatcherTreeViewerRoot) { + return input.getRoots().toArray(); + } else if (parentElement instanceof ObservablePatternMatcherRoot) { + return ((ObservablePatternMatcherRoot) parentElement).getMatchers().toArray(); + } else if (parentElement instanceof ObservablePatternMatcher) { + return ((ObservablePatternMatcher) parentElement).getMatches().toArray(); + } + return null; + } + + @Override + public Object getParent(Object element) { + if (element instanceof ObservablePatternMatcherRoot) { + return input; + } else if (element instanceof ObservablePatternMatcher) { + return ((ObservablePatternMatcher) element).getParent(); + } else if (element instanceof ObservablePatternMatch) { + return ((ObservablePatternMatch) element).getParent(); + } + return null; + } + + @Override + public boolean hasChildren(Object element) { + if (element != null) { + if (element instanceof MatcherTreeViewerRoot) { + return (!input.getRoots().isEmpty()); + } else if (element instanceof ObservablePatternMatcherRoot) { + return (!((ObservablePatternMatcherRoot) element).getMatchers().isEmpty()); + } else if (element instanceof ObservablePatternMatcher) { + return (!(((ObservablePatternMatcher) element).getMatches().isEmpty())); + } + } + return false; + } + +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/MatcherLabelProvider.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/MatcherLabelProvider.java index b75d389b..9c940351 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/MatcherLabelProvider.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/MatcherLabelProvider.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.content.matcher; - +package org.eclipse.incquery.tooling.ui.queryexplorer.content.matcher; + import java.util.ArrayList; import java.util.List; @@ -22,93 +22,86 @@ import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Display; - -public class MatcherLabelProvider extends ColumnLabelProvider { - - private List listeners; - - public MatcherLabelProvider() { - listeners = new ArrayList(); - } - - @Override - public void dispose() { - - } - - @Override - public boolean isLabelProperty(Object element, String property) { - if (property.matches("text")) { - return true; - } - return false; - } - - @Override - public void removeListener(ILabelProviderListener listener) { - this.listeners.remove(listener); - } - - @Override - public void addListener(ILabelProviderListener listener) { - this.listeners.add(listener); - } - - @Override - public Image getImage(Object element) { - ImageRegistry imageRegistry = IncQueryGUIPlugin.getDefault().getImageRegistry(); - - if (element instanceof ObservablePatternMatcherRoot) { - ObservablePatternMatcherRoot root = (ObservablePatternMatcherRoot) element; - if (root.isTainted()) { - return imageRegistry.get(IncQueryGUIPlugin.ICON_ERROR); - } - else { - return imageRegistry.get(IncQueryGUIPlugin.ICON_ROOT); - } - } - else if (element instanceof ObservablePatternMatcher) { - if (((ObservablePatternMatcher) element).isCreated()) { - return imageRegistry.get(IncQueryGUIPlugin.ICON_MATCHER); - } - else { - return imageRegistry.get(IncQueryGUIPlugin.ICON_ERROR); - } - } - else if (element instanceof ObservablePatternMatch) { - return imageRegistry.get(IncQueryGUIPlugin.ICON_MATCH); - } - else { - return null; - } - } - - @Override - public String getText(Object element) { - if (element instanceof ObservablePatternMatcherRoot) { - return ((ObservablePatternMatcherRoot) element).getText(); - } - else if (element instanceof ObservablePatternMatcher) { - return ((ObservablePatternMatcher) element).getText(); - } - else if (element instanceof ObservablePatternMatch) { - return ((ObservablePatternMatch) element).getText(); - } - return null; - } - - @Override - public Color getForeground(Object element) { - Display display = Display.getCurrent(); - if (element instanceof ObservablePatternMatcher) { - ObservablePatternMatcher matcher = (ObservablePatternMatcher) element; -// if (((ObservablePatternMatcher) element).getMatches().size() == 0) { -// return display.getSystemColor(SWT.COLOR_GRAY); -// } - if (matcher.isGenerated()) { - return display.getSystemColor(SWT.COLOR_DARK_GRAY); - } - } - return display.getSystemColor(SWT.COLOR_BLACK); - } -} + +public class MatcherLabelProvider extends ColumnLabelProvider { + + private List listeners; + + public MatcherLabelProvider() { + listeners = new ArrayList(); + } + + @Override + public void dispose() { + + } + + @Override + public boolean isLabelProperty(Object element, String property) { + if (property.matches("text")) { + return true; + } + return false; + } + + @Override + public void removeListener(ILabelProviderListener listener) { + this.listeners.remove(listener); + } + + @Override + public void addListener(ILabelProviderListener listener) { + this.listeners.add(listener); + } + + @Override + public Image getImage(Object element) { + ImageRegistry imageRegistry = IncQueryGUIPlugin.getDefault().getImageRegistry(); + + if (element instanceof ObservablePatternMatcherRoot) { + ObservablePatternMatcherRoot root = (ObservablePatternMatcherRoot) element; + if (root.isTainted()) { + return imageRegistry.get(IncQueryGUIPlugin.ICON_ERROR); + } else { + return imageRegistry.get(IncQueryGUIPlugin.ICON_ROOT); + } + } else if (element instanceof ObservablePatternMatcher) { + if (((ObservablePatternMatcher) element).isCreated()) { + return imageRegistry.get(IncQueryGUIPlugin.ICON_MATCHER); + } else { + return imageRegistry.get(IncQueryGUIPlugin.ICON_ERROR); + } + } else if (element instanceof ObservablePatternMatch) { + return imageRegistry.get(IncQueryGUIPlugin.ICON_MATCH); + } else { + return null; + } + } + + @Override + public String getText(Object element) { + if (element instanceof ObservablePatternMatcherRoot) { + return ((ObservablePatternMatcherRoot) element).getText(); + } else if (element instanceof ObservablePatternMatcher) { + return ((ObservablePatternMatcher) element).getText(); + } else if (element instanceof ObservablePatternMatch) { + return ((ObservablePatternMatch) element).getText(); + } + return null; + } + + @Override + public Color getForeground(Object element) { + Display display = Display.getCurrent(); + if (element instanceof ObservablePatternMatcher) { + ObservablePatternMatcher matcher = (ObservablePatternMatcher) element; + // if (((ObservablePatternMatcher) element).getMatches().size() == 0) { + // return display.getSystemColor(SWT.COLOR_GRAY); + // } + if (matcher.isGenerated()) { + return display.getSystemColor(SWT.COLOR_DARK_GRAY); + } + } + return display.getSystemColor(SWT.COLOR_BLACK); + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/MatcherTreeViewerRoot.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/MatcherTreeViewerRoot.java index b8d2407a..54b317fa 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/MatcherTreeViewerRoot.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/MatcherTreeViewerRoot.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.content.matcher; - +package org.eclipse.incquery.tooling.ui.queryexplorer.content.matcher; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -22,57 +22,57 @@ import org.eclipse.incquery.tooling.ui.queryexplorer.QueryExplorer; import org.eclipse.incquery.tooling.ui.queryexplorer.util.DatabindingUtil; import org.eclipse.ui.IEditorPart; - -public class MatcherTreeViewerRoot { -private Map roots; - - public MatcherTreeViewerRoot() { - roots = new HashMap(); - } - - public void addPatternMatcherRoot(IEditorPart editorPart, Notifier notifier) { - MatcherTreeViewerRootKey key = new MatcherTreeViewerRootKey(editorPart, notifier); - addPatternMatcherRoot(key); - } - - public void addPatternMatcherRoot(MatcherTreeViewerRootKey key) { - if (!roots.containsKey(key)) { - ObservablePatternMatcherRoot root = DatabindingUtil.createPatternMatcherRoot(key); - this.roots.put(key, root); - if (QueryExplorer.getInstance() != null) { - QueryExplorer.getInstance().getMatcherTreeViewer().refresh(this); - } - } - } - - public void removePatternMatcherRoot(IEditorPart editorPart, ResourceSet res) { - MatcherTreeViewerRootKey key = new MatcherTreeViewerRootKey(editorPart, res); - removePatternMatcherRoot(key); - } - - public void removePatternMatcherRoot(MatcherTreeViewerRootKey key) { - if (roots.containsKey(key)) { - //Notifier notifier = key.getNotifier(); - //disposing IncQueryEngine instance associated to the given Notifier - //EngineManager.getInstance().disposeEngine(notifier); - ObservablePatternMatcherRoot root = this.roots.get(key); - IncQueryEngine engine = root.getKey().getEngine(); - if(engine != null) { - engine.dispose(); - } - root.dispose(); - this.roots.remove(key); - if (QueryExplorer.getInstance() != null) { - QueryExplorer.getInstance().getMatcherTreeViewer().refresh(this); - } - } - } - - public Map getRootsMap() { - return roots; - } - - public List getRoots() { - return new ArrayList(roots.values()); - } -} + +public class MatcherTreeViewerRoot { + private Map roots; + + public MatcherTreeViewerRoot() { + roots = new HashMap(); + } + + public void addPatternMatcherRoot(IEditorPart editorPart, Notifier notifier) { + MatcherTreeViewerRootKey key = new MatcherTreeViewerRootKey(editorPart, notifier); + addPatternMatcherRoot(key); + } + + public void addPatternMatcherRoot(MatcherTreeViewerRootKey key) { + if (!roots.containsKey(key)) { + ObservablePatternMatcherRoot root = DatabindingUtil.createPatternMatcherRoot(key); + this.roots.put(key, root); + if (QueryExplorer.getInstance() != null) { + QueryExplorer.getInstance().getMatcherTreeViewer().refresh(this); + } + } + } + + public void removePatternMatcherRoot(IEditorPart editorPart, ResourceSet res) { + MatcherTreeViewerRootKey key = new MatcherTreeViewerRootKey(editorPart, res); + removePatternMatcherRoot(key); + } + + public void removePatternMatcherRoot(MatcherTreeViewerRootKey key) { + if (roots.containsKey(key)) { + // Notifier notifier = key.getNotifier(); + // disposing IncQueryEngine instance associated to the given Notifier + // EngineManager.getInstance().disposeEngine(notifier); + ObservablePatternMatcherRoot root = this.roots.get(key); + IncQueryEngine engine = root.getKey().getEngine(); + if (engine != null) { + engine.dispose(); + } + root.dispose(); + this.roots.remove(key); + if (QueryExplorer.getInstance() != null) { + QueryExplorer.getInstance().getMatcherTreeViewer().refresh(this); + } + } + } + + public Map getRootsMap() { + return roots; + } + + public List getRoots() { + return new ArrayList(roots.values()); + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/MatcherTreeViewerRootKey.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/MatcherTreeViewerRootKey.java index 20e5d71e..544212e6 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/MatcherTreeViewerRootKey.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/MatcherTreeViewerRootKey.java @@ -9,119 +9,115 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.content.matcher; - +package org.eclipse.incquery.tooling.ui.queryexplorer.content.matcher; + import org.eclipse.emf.common.notify.Notifier; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.incquery.runtime.api.IncQueryEngine; import org.eclipse.ui.IEditorPart; - -/** - * the class is used to join an IEditorPart instance and a ResourceSet instance. - * Such a key will be used to map the PatternMatcherRoot elements in the ViewerRoot. - * - * @author Tamas Szabo - * - */ -public class MatcherTreeViewerRootKey { - - private IEditorPart editorPart; - private Notifier notifier; - private IncQueryEngine engine; - - public MatcherTreeViewerRootKey(IEditorPart editor, Notifier notifier) { - super(); - this.editorPart = editor; - this.notifier = notifier; - } - - public IEditorPart getEditorPart() { - return editorPart; - } - - public void setEditorPart(IEditorPart editor) { - this.editorPart = editor; - } - - public Notifier getNotifier() { - return notifier; - } - - public void setNotifier(Notifier notifier) { - this.notifier = notifier; - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - else if (obj == null || obj.getClass() != this.getClass()) { - return false; - } - else { - MatcherTreeViewerRootKey key = (MatcherTreeViewerRootKey) obj; - if (key.getEditorPart().equals(editorPart) && key.getNotifier().equals(notifier)) { - return true; - } - else { - return false; - } - } - } - - @Override - public int hashCode() { - int hash = 1; + +/** + * the class is used to join an IEditorPart instance and a ResourceSet instance. Such a key will be used to map the + * PatternMatcherRoot elements in the ViewerRoot. + * + * @author Tamas Szabo + * + */ +public class MatcherTreeViewerRootKey { + + private IEditorPart editorPart; + private Notifier notifier; + private IncQueryEngine engine; + + public MatcherTreeViewerRootKey(IEditorPart editor, Notifier notifier) { + super(); + this.editorPart = editor; + this.notifier = notifier; + } + + public IEditorPart getEditorPart() { + return editorPart; + } + + public void setEditorPart(IEditorPart editor) { + this.editorPart = editor; + } + + public Notifier getNotifier() { + return notifier; + } + + public void setNotifier(Notifier notifier) { + this.notifier = notifier; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } else if (obj == null || obj.getClass() != this.getClass()) { + return false; + } else { + MatcherTreeViewerRootKey key = (MatcherTreeViewerRootKey) obj; + if (key.getEditorPart().equals(editorPart) && key.getNotifier().equals(notifier)) { + return true; + } else { + return false; + } + } + } + + @Override + public int hashCode() { + int hash = 1; hash = hash * 17 + editorPart.hashCode(); hash = hash * 17 + notifier.hashCode(); - return hash; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("["); - - int i = 0; - - if (notifier instanceof ResourceSet) { - ResourceSet rs = (ResourceSet) notifier; - - for (Resource r : rs.getResources()) { - sb.append(r.getURI().toString()); - if (i != rs.getResources().size()-1) { - sb.append(", "); - } - } - } - else if (notifier instanceof Resource) { - sb.append(((Resource) notifier).getURI().toString()); - } - else { - sb.append(notifier.toString()); - } - - sb.append("]"); - sb.append("["); - sb.append(editorPart.getEditorSite().getId()); - sb.append("]"); - return sb.toString(); - } - - /** - * @return the engine - */ - public IncQueryEngine getEngine() { - return engine; - } - - /** - * @param engine the engine to set - */ - public void setEngine(IncQueryEngine engine) { - this.engine = engine; - } - -} + return hash; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("["); + + int i = 0; + + if (notifier instanceof ResourceSet) { + ResourceSet rs = (ResourceSet) notifier; + + for (Resource r : rs.getResources()) { + sb.append(r.getURI().toString()); + if (i != rs.getResources().size() - 1) { + sb.append(", "); + } + } + } else if (notifier instanceof Resource) { + sb.append(((Resource) notifier).getURI().toString()); + } else { + sb.append(notifier.toString()); + } + + sb.append("]"); + sb.append("["); + sb.append(editorPart.getEditorSite().getId()); + sb.append("]"); + return sb.toString(); + } + + /** + * @return the engine + */ + public IncQueryEngine getEngine() { + return engine; + } + + /** + * @param engine + * the engine to set + */ + public void setEngine(IncQueryEngine engine) { + this.engine = engine; + } + +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/ObservablePatternMatch.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/ObservablePatternMatch.java index 3e93fbaa..7bca5bec 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/ObservablePatternMatch.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/ObservablePatternMatch.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.content.matcher; - +package org.eclipse.incquery.tooling.ui.queryexplorer.content.matcher; + import java.util.List; import org.eclipse.core.databinding.observable.value.IObservableValue; @@ -21,73 +21,71 @@ import org.eclipse.incquery.runtime.api.IPatternMatch; import org.eclipse.incquery.tooling.ui.queryexplorer.QueryExplorer; import org.eclipse.incquery.tooling.ui.queryexplorer.util.DatabindingUtil; - -/** - * A PatternMatch is associated to every match of a matcher. - * It is the lowest level element is the treeviewer. - * - * @author Tamas Szabo - * - */ -public class ObservablePatternMatch { - - private String text; - private IPatternMatch match; - private ObservablePatternMatcher parent; - private String message; - private ParameterValueChangedListener listener; - private List affectedValues; - - public ObservablePatternMatch(ObservablePatternMatcher parent, IPatternMatch match) { - this.parent = parent; - this.match = match; - this.message = DatabindingUtil.getMessage(match, parent.isGenerated()); - this.listener = new ParameterValueChangedListener(); - if (message != null) { - setText(DatabindingAdapterUtil.getMessage(match, message)); - affectedValues = IncQueryObservables.observeFeatures(match, listener, message); - } - else { - this.text = match.toString(); - } - } - - public void dispose() { - if (affectedValues != null) { - for (IObservableValue val : affectedValues) { - val.removeValueChangeListener(listener); - } - } - } - - public void setText(String text) { - this.text = text; - String[] properties = new String[] {"text"}; - if (QueryExplorer.getInstance() != null) { - QueryExplorer.getInstance().getMatcherTreeViewer().update(this, properties); - } - } - - public String getText() { - return text; - } - - public ObservablePatternMatcher getParent() { - return parent; - } - - private class ParameterValueChangedListener implements IValueChangeListener { - @Override - public void handleValueChange(ValueChangeEvent event) { - setText(DatabindingAdapterUtil.getMessage(match, message)); - } - } - - public IPatternMatch getPatternMatch() { - return match; - } - - public Object[] getLocationObjects() { - return this.match.toArray(); - } -} + +/** + * A PatternMatch is associated to every match of a matcher. It is the lowest level element is the treeviewer. + * + * @author Tamas Szabo + * + */ +public class ObservablePatternMatch { + + private String text; + private IPatternMatch match; + private ObservablePatternMatcher parent; + private String message; + private ParameterValueChangedListener listener; + private List affectedValues; + + public ObservablePatternMatch(ObservablePatternMatcher parent, IPatternMatch match) { + this.parent = parent; + this.match = match; + this.message = DatabindingUtil.getMessage(match, parent.isGenerated()); + this.listener = new ParameterValueChangedListener(); + if (message != null) { + setText(DatabindingAdapterUtil.getMessage(match, message)); + affectedValues = IncQueryObservables.observeFeatures(match, listener, message); + } else { + this.text = match.toString(); + } + } + + public void dispose() { + if (affectedValues != null) { + for (IObservableValue val : affectedValues) { + val.removeValueChangeListener(listener); + } + } + } + + public void setText(String text) { + this.text = text; + String[] properties = new String[] { "text" }; + if (QueryExplorer.getInstance() != null) { + QueryExplorer.getInstance().getMatcherTreeViewer().update(this, properties); + } + } + + public String getText() { + return text; + } + + public ObservablePatternMatcher getParent() { + return parent; + } + + private class ParameterValueChangedListener implements IValueChangeListener { + @Override + public void handleValueChange(ValueChangeEvent event) { + setText(DatabindingAdapterUtil.getMessage(match, message)); + } + } + + public IPatternMatch getPatternMatch() { + return match; + } + + public Object[] getLocationObjects() { + return this.match.toArray(); + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/ObservablePatternMatcher.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/ObservablePatternMatcher.java index 1c07b711..92634abb 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/ObservablePatternMatcher.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/ObservablePatternMatcher.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.content.matcher; - +package org.eclipse.incquery.tooling.ui.queryexplorer.content.matcher; + import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -32,309 +32,309 @@ import org.eclipse.incquery.tooling.ui.queryexplorer.QueryExplorer; import org.eclipse.incquery.tooling.ui.queryexplorer.util.DatabindingUtil; import org.eclipse.swt.widgets.Display; - -/** - * A PatternMatcher is associated to every IncQueryMatcher which is annotated with PatternUI annotation. - * These elements will be the children of the top level elements in the treeviewer. - * - * @author Tamas Szabo - * - */ -public class ObservablePatternMatcher { - - private static final String KEY_ATTRIBUTE_COMPARABLE_INTERFACE = "The key attribute does not implement the Comparable interface!"; - private static final String KEY_ATTRIBUTE_OF_ORDER_BY_ANNOTATION = "The key attribute of OrderBy annotation must look like \"ClassName.AttributeName\"!"; - private final List matches; - private final IncQueryMatcher matcher; - private DeltaMonitor deltaMonitor; - private Runnable processMatchesRunnable; - private Map sigMap; - private final ObservablePatternMatcherRoot parent; - private final boolean generated; - private final String patternFqn; - private IPatternMatch filter; - private Object[] parameterFilter; - private String orderParameter; - private boolean descendingOrder; - private final String exceptionMessage; - - public ObservablePatternMatcher( - ObservablePatternMatcherRoot parent, - IncQueryMatcher matcher, - String patternFqn, - boolean generated, - String exceptionMessage) { - this.parent = parent; - this.patternFqn = patternFqn; - this.matches = new ArrayList(); - this.matcher = matcher; - this.generated = generated; - this.orderParameter = null; - this.exceptionMessage = exceptionMessage; - - DatabindingUtil.removeOrderByPatternWarning(patternFqn); - - if (matcher != null) { - initOrdering(); - initFilter(); - this.sigMap = new HashMap(); - this.deltaMonitor = this.matcher.newFilteredDeltaMonitor(true, filter); - this.processMatchesRunnable = new Runnable() { - @Override - public void run() { - if(deltaMonitor.matchFoundEvents.size() > 0 || deltaMonitor.matchLostEvents.size() > 0) { - // this is required as both QueryExplorer.getInstance() and Realm.getDefault() work only in a UI thread - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - processNewMatches(deltaMonitor.matchFoundEvents); - processLostMatches(deltaMonitor.matchLostEvents); - deltaMonitor.clear(); - } - }); - } - } - }; - - this.matcher.addCallbackAfterUpdates(processMatchesRunnable); - this.processMatchesRunnable.run(); - } - } - - /** - * Initializes the matcher for ordering if the annotation is present. - */ - private void initOrdering() { - Annotation annotation = CorePatternLanguageHelper.getFirstAnnotationByName(matcher.getPattern(), DatabindingUtil.ORDERBY_ANNOTATION); - if (annotation != null) { - for (AnnotationParameter ap : annotation.getParameters()) { - if (ap.getName().matches("key")) { - orderParameter = ((StringValueImpl) ap.getValue()).getValue(); - } - if (ap.getName().matches("direction")) { - String direction = ((StringValueImpl) ap.getValue()).getValue(); - if (direction.matches("desc")) { - descendingOrder = true; - } - else { - descendingOrder = false; - } - } - } - } - } - - /** - * Call this method to remove the callback handler from the delta monitor of the matcher. - */ - public void dispose() { - if (matcher != null) { - for (ObservablePatternMatch pm : matches) { - pm.dispose(); - } - this.matcher.removeCallbackAfterUpdates(processMatchesRunnable); - processMatchesRunnable = null; - } - } - - /** - * Returns the index of the new match in the list based on the ordering set on the matcher. - * - * @param match the match that will be inserted - * @return -1 if the match should be inserted at the end of the list, else the actual index - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) - private int placeOfMatch(IPatternMatch match) { - if (orderParameter != null) { - String[] tokens = orderParameter.split("\\."); - - if (tokens.length == 2) { - String orderParameterClass = tokens[0]; - String orderParameterAttribute = tokens[1]; - - EObject obj = (EObject) match.get(orderParameterClass); - EStructuralFeature feature = DatabindingAdapterUtil.getFeature(obj, orderParameterAttribute); - Object value = obj.eGet(feature); - if (value instanceof Comparable) { - - for (int i = 0;i= 0) { - return i; - } - } - } - } - else { - DatabindingUtil.addOrderByPatternWarning( - CorePatternLanguageHelper.getFullyQualifiedName(this.matcher.getPattern()), - KEY_ATTRIBUTE_COMPARABLE_INTERFACE); - } - } - else { - DatabindingUtil.addOrderByPatternWarning( - CorePatternLanguageHelper.getFullyQualifiedName(this.matcher.getPattern()), - KEY_ATTRIBUTE_OF_ORDER_BY_ANNOTATION); - } - } - return -1; - } - - private void processNewMatches(Collection matches) { - for (IPatternMatch s : matches) { - addMatch(s); - } - } - - private void processLostMatches(Collection matches) { - for (IPatternMatch s : matches) { - removeMatch(s); - } - } - - private void addMatch(IPatternMatch match) { - ObservablePatternMatch pm = new ObservablePatternMatch(this, match); - this.sigMap.put(match, pm); - int index = placeOfMatch(match); - - if (index == -1) { - this.matches.add(pm); - } - else { - this.matches.add(index, pm); - } - if (QueryExplorer.getInstance() != null) { - QueryExplorer.getInstance().getMatcherTreeViewer().refresh(this); - } - } - - private void removeMatch(IPatternMatch match) { - //null checks - eclipse closing - issue 162 - ObservablePatternMatch observableMatch = this.sigMap.remove(match); - if (observableMatch != null) { - this.matches.remove(observableMatch); - observableMatch.dispose(); - } - if (QueryExplorer.getInstance() != null) { - QueryExplorer.getInstance().getMatcherTreeViewer().refresh(this); - } - } - - public ObservablePatternMatcherRoot getParent() { - return parent; - } - - public IncQueryMatcher getMatcher() { - return matcher; - } - - public String getPatternName() { - return patternFqn; - } - - private void initFilter() { - if (matcher != null) { - parameterFilter = new Object[this.matcher.getParameterNames().length]; - - for (int i = 0;i tmp = new HashSet(sigMap.keySet()); - - for (IPatternMatch match : tmp) { - removeMatch(match); - } - - if (QueryExplorer.getInstance() != null) { - QueryExplorer.getInstance().getMatcherTreeViewer().refresh(this); - } - this.deltaMonitor = this.matcher.newFilteredDeltaMonitor(true, filter); - this.processMatchesRunnable.run(); - } - - private boolean isFiltered() { - if (matcher != null) { - for (int i = 0;i getMatches() { - return matches; - } - - /** - * Returns true if the matcher is generated, false if it is generic. - * - * @return true for generated, false for generic matcher - */ - public boolean isGenerated() { - return generated; - } - - /** - * Returns true if the RETE matcher was created for this observable matcher, false otherwise. - * - * @return true if matcher could be created - */ - public boolean isCreated() { - return matcher != null; - } - - /** - * If the engine becomes tainted stop monitoring the matcher. - * This way the previoud match set will remain stable and the user - */ - public void stopMonitoring() { - this.matcher.removeCallbackAfterUpdates(processMatchesRunnable); - } -} + +/** + * A PatternMatcher is associated to every IncQueryMatcher which is annotated with PatternUI annotation. These elements + * will be the children of the top level elements in the treeviewer. + * + * @author Tamas Szabo + * + */ +public class ObservablePatternMatcher { + + private static final String KEY_ATTRIBUTE_COMPARABLE_INTERFACE = "The key attribute does not implement the Comparable interface!"; + private static final String KEY_ATTRIBUTE_OF_ORDER_BY_ANNOTATION = "The key attribute of OrderBy annotation must look like \"ClassName.AttributeName\"!"; + private final List matches; + private final IncQueryMatcher matcher; + private DeltaMonitor deltaMonitor; + private Runnable processMatchesRunnable; + private Map sigMap; + private final ObservablePatternMatcherRoot parent; + private final boolean generated; + private final String patternFqn; + private IPatternMatch filter; + private Object[] parameterFilter; + private String orderParameter; + private boolean descendingOrder; + private final String exceptionMessage; + + public ObservablePatternMatcher(ObservablePatternMatcherRoot parent, IncQueryMatcher matcher, + String patternFqn, boolean generated, String exceptionMessage) { + this.parent = parent; + this.patternFqn = patternFqn; + this.matches = new ArrayList(); + this.matcher = matcher; + this.generated = generated; + this.orderParameter = null; + this.exceptionMessage = exceptionMessage; + + DatabindingUtil.removeOrderByPatternWarning(patternFqn); + + if (matcher != null) { + initOrdering(); + initFilter(); + this.sigMap = new HashMap(); + this.deltaMonitor = this.matcher.newFilteredDeltaMonitor(true, filter); + this.processMatchesRunnable = new Runnable() { + @Override + public void run() { + if (deltaMonitor.matchFoundEvents.size() > 0 || deltaMonitor.matchLostEvents.size() > 0) { + // this is required as both QueryExplorer.getInstance() and Realm.getDefault() work only in a UI + // thread + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + processNewMatches(deltaMonitor.matchFoundEvents); + processLostMatches(deltaMonitor.matchLostEvents); + deltaMonitor.clear(); + } + }); + } + } + }; + + this.matcher.addCallbackAfterUpdates(processMatchesRunnable); + this.processMatchesRunnable.run(); + } + } + + /** + * Initializes the matcher for ordering if the annotation is present. + */ + private void initOrdering() { + Annotation annotation = CorePatternLanguageHelper.getFirstAnnotationByName(matcher.getPattern(), + DatabindingUtil.ORDERBY_ANNOTATION); + if (annotation != null) { + for (AnnotationParameter ap : annotation.getParameters()) { + if (ap.getName().matches("key")) { + orderParameter = ((StringValueImpl) ap.getValue()).getValue(); + } + if (ap.getName().matches("direction")) { + String direction = ((StringValueImpl) ap.getValue()).getValue(); + if (direction.matches("desc")) { + descendingOrder = true; + } else { + descendingOrder = false; + } + } + } + } + } + + /** + * Call this method to remove the callback handler from the delta monitor of the matcher. + */ + public void dispose() { + if (matcher != null) { + for (ObservablePatternMatch pm : matches) { + pm.dispose(); + } + this.matcher.removeCallbackAfterUpdates(processMatchesRunnable); + processMatchesRunnable = null; + } + } + + /** + * Returns the index of the new match in the list based on the ordering set on the matcher. + * + * @param match + * the match that will be inserted + * @return -1 if the match should be inserted at the end of the list, else the actual index + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + private int placeOfMatch(IPatternMatch match) { + if (orderParameter != null) { + String[] tokens = orderParameter.split("\\."); + + if (tokens.length == 2) { + String orderParameterClass = tokens[0]; + String orderParameterAttribute = tokens[1]; + + EObject obj = (EObject) match.get(orderParameterClass); + EStructuralFeature feature = DatabindingAdapterUtil.getFeature(obj, orderParameterAttribute); + Object value = obj.eGet(feature); + if (value instanceof Comparable) { + + for (int i = 0; i < matches.size(); i++) { + IPatternMatch compMatch = matches.get(i).getPatternMatch(); + EObject compObj = (EObject) compMatch.get(orderParameterClass); + EStructuralFeature compFeature = DatabindingAdapterUtil.getFeature(compObj, + orderParameterAttribute); + Comparable compValue = (Comparable) compObj.eGet(compFeature); + // descending order, the new position is the index where the current match param is greater than + // the actual element + if (descendingOrder) { + if (compValue.compareTo(value) <= 0) { + return i; + } + } + // ascending order, the new position is the index where the current match param is smaller than + // the actual element + else { + if (compValue.compareTo(value) >= 0) { + return i; + } + } + } + } else { + DatabindingUtil.addOrderByPatternWarning( + CorePatternLanguageHelper.getFullyQualifiedName(this.matcher.getPattern()), + KEY_ATTRIBUTE_COMPARABLE_INTERFACE); + } + } else { + DatabindingUtil.addOrderByPatternWarning( + CorePatternLanguageHelper.getFullyQualifiedName(this.matcher.getPattern()), + KEY_ATTRIBUTE_OF_ORDER_BY_ANNOTATION); + } + } + return -1; + } + + private void processNewMatches(Collection matches) { + for (IPatternMatch s : matches) { + addMatch(s); + } + } + + private void processLostMatches(Collection matches) { + for (IPatternMatch s : matches) { + removeMatch(s); + } + } + + private void addMatch(IPatternMatch match) { + ObservablePatternMatch pm = new ObservablePatternMatch(this, match); + this.sigMap.put(match, pm); + int index = placeOfMatch(match); + + if (index == -1) { + this.matches.add(pm); + } else { + this.matches.add(index, pm); + } + if (QueryExplorer.getInstance() != null) { + QueryExplorer.getInstance().getMatcherTreeViewer().refresh(this); + } + } + + private void removeMatch(IPatternMatch match) { + // null checks - eclipse closing - issue 162 + ObservablePatternMatch observableMatch = this.sigMap.remove(match); + if (observableMatch != null) { + this.matches.remove(observableMatch); + observableMatch.dispose(); + } + if (QueryExplorer.getInstance() != null) { + QueryExplorer.getInstance().getMatcherTreeViewer().refresh(this); + } + } + + public ObservablePatternMatcherRoot getParent() { + return parent; + } + + public IncQueryMatcher getMatcher() { + return matcher; + } + + public String getPatternName() { + return patternFqn; + } + + private void initFilter() { + if (matcher != null) { + parameterFilter = new Object[this.matcher.getParameterNames().length]; + + for (int i = 0; i < this.matcher.getParameterNames().length; i++) { + parameterFilter[i] = null; + } + + this.filter = this.matcher.arrayToMatch(parameterFilter); + } + } + + public void setFilter(Object[] parameterFilter) { + this.parameterFilter = parameterFilter.clone(); + this.filter = this.matcher.arrayToMatch(this.parameterFilter); + + Set tmp = new HashSet(sigMap.keySet()); + + for (IPatternMatch match : tmp) { + removeMatch(match); + } + + if (QueryExplorer.getInstance() != null) { + QueryExplorer.getInstance().getMatcherTreeViewer().refresh(this); + } + this.deltaMonitor = this.matcher.newFilteredDeltaMonitor(true, filter); + this.processMatchesRunnable.run(); + } + + private boolean isFiltered() { + if (matcher != null) { + for (int i = 0; i < this.matcher.getParameterNames().length; i++) { + if (parameterFilter[i] != null) { + return true; + } + } + } + + return false; + } + + /** + * Returns the current filter used on the corresponding matcher. + * + * @return the filter as an array of objects + */ + public Object[] getFilter() { + return parameterFilter; + } + + /** + * Returns the label for the observable pattern matcher that will be used in the {@link QueryExplorer}. + * + * @return the label + */ + public String getText() { + return DatabindingUtil.getMessage(matcher, matches.size(), patternFqn, isGenerated(), isFiltered(), + exceptionMessage); + } + + public static final String MATCHES_ID = "matches"; + + /** + * Returns the list of observable pattern matches under this matcher. + * + * @return the list of matches + */ + public List getMatches() { + return matches; + } + + /** + * Returns true if the matcher is generated, false if it is generic. + * + * @return true for generated, false for generic matcher + */ + public boolean isGenerated() { + return generated; + } + + /** + * Returns true if the RETE matcher was created for this observable matcher, false otherwise. + * + * @return true if matcher could be created + */ + public boolean isCreated() { + return matcher != null; + } + + /** + * If the engine becomes tainted stop monitoring the matcher. This way the previoud match set will remain stable and + * the user + */ + public void stopMonitoring() { + this.matcher.removeCallbackAfterUpdates(processMatchesRunnable); + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/ObservablePatternMatcherRoot.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/ObservablePatternMatcherRoot.java index cb8b8ed3..75070796 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/ObservablePatternMatcherRoot.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/ObservablePatternMatcherRoot.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.content.matcher; - +package org.eclipse.incquery.tooling.ui.queryexplorer.content.matcher; + import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.LinkedList; @@ -37,186 +37,185 @@ import org.eclipse.incquery.tooling.ui.queryexplorer.util.DatabindingUtil; import org.eclipse.incquery.tooling.ui.queryexplorer.util.PatternRegistry; import org.eclipse.ui.IEditorPart; - -/** - * Each IEditingDomainProvider will be associated a PatternMatcherRoot element in the tree viewer. - * PatterMatcherRoots are indexed with a ViewerRootKey. - * - * It's children element will be PatterMatchers. - * - * @author Tamas Szabo - * - */ -public class ObservablePatternMatcherRoot extends EngineTaintListener { - - private final Map matchers; - private final List sortedMatchers; - private final MatcherTreeViewerRootKey key; - - private final ILog logger = IncQueryGUIPlugin.getDefault().getLog(); - - public ObservablePatternMatcherRoot(MatcherTreeViewerRootKey key) { - matchers = new HashMap(); - sortedMatchers = new LinkedList(); - this.key = key; - - IncQueryEngine engine = key.getEngine(); - if(engine == null) { - key.setEngine(createEngine()); - } - if (engine != null) { - engine.getLogger().addAppender(this); - } - } - - private IncQueryEngine createEngine() { - try { - IncQueryEngine engine = EngineManager.getInstance().createUnmanagedIncQueryEngine(key.getNotifier()); - return engine; - } catch (IncQueryException e) { - logger.log(new Status(IStatus.ERROR, IncQueryGUIPlugin.PLUGIN_ID, "Could not retrieve IncQueryEngine for "+key.getNotifier(), e)); - return null; - } - } - - public void addMatcher(IncQueryMatcher matcher, String patternFqn, boolean generated, String exceptionMessage) { - //This cast could not be avoided because later the filtered delta monitor will need the base IPatternMatch - @SuppressWarnings("unchecked") - ObservablePatternMatcher pm = new ObservablePatternMatcher(this, (IncQueryMatcher) matcher, patternFqn, generated, exceptionMessage); - this.matchers.put(patternFqn, pm); - - //generated matchers are inserted in front of the list - if (generated) { - this.sortedMatchers.add(0, pm); - } - //generic matchers are inserted in the list according to the order in the eiq file - else { - this.sortedMatchers.add(pm); - } - if (QueryExplorer.getInstance() != null) { - QueryExplorer.getInstance().getMatcherTreeViewer().refresh(this); - } - } - - public void removeMatcher(String patternFqn) { - //if the pattern is first deactivated then removed, than the matcher corresponding matcher is disposed - ObservablePatternMatcher matcher = this.matchers.get(patternFqn); - if (matcher != null) { - this.sortedMatchers.remove(matcher); - matcher.dispose(); - this.matchers.remove(patternFqn); - if (QueryExplorer.getInstance() != null) { - QueryExplorer.getInstance().getMatcherTreeViewer().refresh(this); - } - } - } - - public static final String MATCHERS_ID = "matchers"; - - public List getMatchers() { - return sortedMatchers; - } - - public String getText() { - return key.toString(); - } - - public void dispose() { - for (ObservablePatternMatcher pm : this.matchers.values()) { - pm.dispose(); - } - IncQueryEngine engine = key.getEngine();//createEngine(); - if (engine != null) { - engine.getLogger().removeAppender(this); - } - } - - public boolean isTainted() { - IncQueryEngine engine = key.getEngine();//createEngine(); - return (engine == null) ? true : engine.isTainted(); - } - - public MatcherTreeViewerRootKey getKey() { - return key; - } - - public IEditorPart getEditorPart() { - return this.key.getEditorPart(); - } - - public Notifier getNotifier() { - return this.key.getNotifier(); - } - - @Override - public void engineBecameTainted() { - for (ObservablePatternMatcher matcher : this.matchers.values()) { - matcher.stopMonitoring(); - } - } - - public void registerPattern(final Pattern... patterns) { - boolean wildcardMode = IncQueryGUIPlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.WILDCARD_MODE); - IncQueryEngine engine; - try { - //engine = EngineManager.getInstance().getIncQueryEngine(getNotifier()); - engine = key.getEngine(); - try { - engine.setWildcardMode(wildcardMode); - } catch (IllegalStateException ex) { - // could not set wildcard mode - } - - if (engine.getBaseIndex().isInWildcardMode()) { - addMatchersForPatterns(patterns); - } else { - engine.getBaseIndex().coalesceTraversals(new Callable() { - @Override - public Void call() throws Exception { - addMatchersForPatterns(patterns); - return null; - } - }); - } - - } catch (IncQueryException ex) { - logger.log(new Status(IStatus.ERROR, - IncQueryGUIPlugin.PLUGIN_ID, - "Cannot initialize pattern matcher engine.", ex)); - } catch (InvocationTargetException e) { - logger.log(new Status(IStatus.ERROR, - IncQueryGUIPlugin.PLUGIN_ID, - "Error during pattern matcher construction: " + e.getCause().getMessage(), e.getCause())); - } - } - - private void addMatchersForPatterns(Pattern... patterns) { - for (Pattern pattern : patterns) { - IncQueryMatcher matcher = null; - boolean isGenerated = PatternRegistry.getInstance().isGenerated(pattern); - String message = null; - try { - if (isGenerated) { - matcher = DatabindingUtil.getMatcherFactoryForGeneratedPattern(pattern).getMatcher(key.getEngine()); - } - else { - matcher = new GenericPatternMatcher(pattern, key.getEngine()); - } - } catch (Exception e) { - logger.log(new Status(IStatus.ERROR, - IncQueryGUIPlugin.PLUGIN_ID, - "Cannot initialize pattern matcher for pattern " - + CorePatternLanguageHelper.getFullyQualifiedName(pattern), e)); - matcher = null; - message = (e instanceof IncQueryException) ? - ((IncQueryException)e).getShortMessage() : e.getMessage(); - } - - addMatcher(matcher, CorePatternLanguageHelper.getFullyQualifiedName(pattern), isGenerated, message); - } - } - - public void unregisterPattern(Pattern pattern) { - removeMatcher(CorePatternLanguageHelper.getFullyQualifiedName(pattern)); - } -} + +/** + * Each IEditingDomainProvider will be associated a PatternMatcherRoot element in the tree viewer. PatterMatcherRoots + * are indexed with a ViewerRootKey. + * + * It's children element will be PatterMatchers. + * + * @author Tamas Szabo + * + */ +public class ObservablePatternMatcherRoot extends EngineTaintListener { + + private final Map matchers; + private final List sortedMatchers; + private final MatcherTreeViewerRootKey key; + + private final ILog logger = IncQueryGUIPlugin.getDefault().getLog(); + + public ObservablePatternMatcherRoot(MatcherTreeViewerRootKey key) { + matchers = new HashMap(); + sortedMatchers = new LinkedList(); + this.key = key; + + IncQueryEngine engine = key.getEngine(); + if (engine == null) { + key.setEngine(createEngine()); + } + if (engine != null) { + engine.getLogger().addAppender(this); + } + } + + private IncQueryEngine createEngine() { + try { + IncQueryEngine engine = EngineManager.getInstance().createUnmanagedIncQueryEngine(key.getNotifier()); + return engine; + } catch (IncQueryException e) { + logger.log(new Status(IStatus.ERROR, IncQueryGUIPlugin.PLUGIN_ID, "Could not retrieve IncQueryEngine for " + + key.getNotifier(), e)); + return null; + } + } + + public void addMatcher(IncQueryMatcher matcher, String patternFqn, boolean generated, + String exceptionMessage) { + // This cast could not be avoided because later the filtered delta monitor will need the base IPatternMatch + @SuppressWarnings("unchecked") + ObservablePatternMatcher pm = new ObservablePatternMatcher(this, (IncQueryMatcher) matcher, + patternFqn, generated, exceptionMessage); + this.matchers.put(patternFqn, pm); + + // generated matchers are inserted in front of the list + if (generated) { + this.sortedMatchers.add(0, pm); + } + // generic matchers are inserted in the list according to the order in the eiq file + else { + this.sortedMatchers.add(pm); + } + if (QueryExplorer.getInstance() != null) { + QueryExplorer.getInstance().getMatcherTreeViewer().refresh(this); + } + } + + public void removeMatcher(String patternFqn) { + // if the pattern is first deactivated then removed, than the matcher corresponding matcher is disposed + ObservablePatternMatcher matcher = this.matchers.get(patternFqn); + if (matcher != null) { + this.sortedMatchers.remove(matcher); + matcher.dispose(); + this.matchers.remove(patternFqn); + if (QueryExplorer.getInstance() != null) { + QueryExplorer.getInstance().getMatcherTreeViewer().refresh(this); + } + } + } + + public static final String MATCHERS_ID = "matchers"; + + public List getMatchers() { + return sortedMatchers; + } + + public String getText() { + return key.toString(); + } + + public void dispose() { + for (ObservablePatternMatcher pm : this.matchers.values()) { + pm.dispose(); + } + IncQueryEngine engine = key.getEngine();// createEngine(); + if (engine != null) { + engine.getLogger().removeAppender(this); + } + } + + public boolean isTainted() { + IncQueryEngine engine = key.getEngine();// createEngine(); + return (engine == null) ? true : engine.isTainted(); + } + + public MatcherTreeViewerRootKey getKey() { + return key; + } + + public IEditorPart getEditorPart() { + return this.key.getEditorPart(); + } + + public Notifier getNotifier() { + return this.key.getNotifier(); + } + + @Override + public void engineBecameTainted() { + for (ObservablePatternMatcher matcher : this.matchers.values()) { + matcher.stopMonitoring(); + } + } + + public void registerPattern(final Pattern... patterns) { + boolean wildcardMode = IncQueryGUIPlugin.getDefault().getPreferenceStore() + .getBoolean(PreferenceConstants.WILDCARD_MODE); + IncQueryEngine engine; + try { + // engine = EngineManager.getInstance().getIncQueryEngine(getNotifier()); + engine = key.getEngine(); + try { + engine.setWildcardMode(wildcardMode); + } catch (IllegalStateException ex) { + // could not set wildcard mode + } + + if (engine.getBaseIndex().isInWildcardMode()) { + addMatchersForPatterns(patterns); + } else { + engine.getBaseIndex().coalesceTraversals(new Callable() { + @Override + public Void call() throws Exception { + addMatchersForPatterns(patterns); + return null; + } + }); + } + + } catch (IncQueryException ex) { + logger.log(new Status(IStatus.ERROR, IncQueryGUIPlugin.PLUGIN_ID, + "Cannot initialize pattern matcher engine.", ex)); + } catch (InvocationTargetException e) { + logger.log(new Status(IStatus.ERROR, IncQueryGUIPlugin.PLUGIN_ID, + "Error during pattern matcher construction: " + e.getCause().getMessage(), e.getCause())); + } + } + + private void addMatchersForPatterns(Pattern... patterns) { + for (Pattern pattern : patterns) { + IncQueryMatcher matcher = null; + boolean isGenerated = PatternRegistry.getInstance().isGenerated(pattern); + String message = null; + try { + if (isGenerated) { + matcher = DatabindingUtil.getMatcherFactoryForGeneratedPattern(pattern).getMatcher(key.getEngine()); + } else { + matcher = new GenericPatternMatcher(pattern, key.getEngine()); + } + } catch (Exception e) { + logger.log(new Status(IStatus.ERROR, IncQueryGUIPlugin.PLUGIN_ID, + "Cannot initialize pattern matcher for pattern " + + CorePatternLanguageHelper.getFullyQualifiedName(pattern), e)); + matcher = null; + message = (e instanceof IncQueryException) ? ((IncQueryException) e).getShortMessage() : e.getMessage(); + } + + addMatcher(matcher, CorePatternLanguageHelper.getFullyQualifiedName(pattern), isGenerated, message); + } + } + + public void unregisterPattern(Pattern pattern) { + removeMatcher(CorePatternLanguageHelper.getFullyQualifiedName(pattern)); + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/PatternMatch.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/PatternMatch.java index 37daf853..da49b4e4 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/PatternMatch.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/PatternMatch.java @@ -9,85 +9,83 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.content.matcher; - -import java.util.List; - -import org.eclipse.core.databinding.observable.value.IObservableValue; -import org.eclipse.core.databinding.observable.value.IValueChangeListener; -import org.eclipse.core.databinding.observable.value.ValueChangeEvent; +package org.eclipse.incquery.tooling.ui.queryexplorer.content.matcher; + +import java.util.List; + +import org.eclipse.core.databinding.observable.value.IObservableValue; +import org.eclipse.core.databinding.observable.value.IValueChangeListener; +import org.eclipse.core.databinding.observable.value.ValueChangeEvent; import org.eclipse.incquery.databinding.runtime.adapter.DatabindingAdapterUtil; import org.eclipse.incquery.databinding.runtime.api.IncQueryObservables; import org.eclipse.incquery.runtime.api.IPatternMatch; import org.eclipse.incquery.tooling.ui.queryexplorer.QueryExplorer; import org.eclipse.incquery.tooling.ui.queryexplorer.util.DatabindingUtil; - -/** - * A PatternMatch is associated to every match of a matcher. - * It is the lowest level element is the treeviewer. - * - * @author Tamas Szabo - * - */ -public class PatternMatch { - - private String text; - private IPatternMatch match; - private PatternMatcher parent; - private String message; - private ParameterValueChangedListener listener; - private List affectedValues; - - public PatternMatch(PatternMatcher parent, IPatternMatch match) { - this.parent = parent; - this.match = match; - this.message = DatabindingUtil.getMessage(match, parent.isGenerated()); - this.listener = new ParameterValueChangedListener(); - if (message != null) { - setText(DatabindingAdapterUtil.getMessage(match, message)); - affectedValues = IncQueryObservables.observeFeatures(match, listener, message); - } - else { - this.text = match.toString(); - } - } - - public void dispose() { - if (affectedValues != null) { - for (IObservableValue val : affectedValues) { - val.removeValueChangeListener(listener); - } - } - } - - public void setText(String text) { - this.text = text; - String[] properties = new String[] {"text"}; - if (QueryExplorer.getInstance() != null) { - QueryExplorer.getInstance().getMatcherTreeViewer().update(this, properties); - } - } - - public String getText() { - return text; - } - - public PatternMatcher getParent() { - return parent; - } - - private class ParameterValueChangedListener implements IValueChangeListener { - @Override - public void handleValueChange(ValueChangeEvent event) { - setText(DatabindingAdapterUtil.getMessage(match, message)); - } - } - - public IPatternMatch getPatternMatch() { - return match; - } - - public Object[] getLocationObjects() { - return this.match.toArray(); - } -} + +/** + * A PatternMatch is associated to every match of a matcher. It is the lowest level element is the treeviewer. + * + * @author Tamas Szabo + * + */ +public class PatternMatch { + + private String text; + private IPatternMatch match; + private PatternMatcher parent; + private String message; + private ParameterValueChangedListener listener; + private List affectedValues; + + public PatternMatch(PatternMatcher parent, IPatternMatch match) { + this.parent = parent; + this.match = match; + this.message = DatabindingUtil.getMessage(match, parent.isGenerated()); + this.listener = new ParameterValueChangedListener(); + if (message != null) { + setText(DatabindingAdapterUtil.getMessage(match, message)); + affectedValues = IncQueryObservables.observeFeatures(match, listener, message); + } else { + this.text = match.toString(); + } + } + + public void dispose() { + if (affectedValues != null) { + for (IObservableValue val : affectedValues) { + val.removeValueChangeListener(listener); + } + } + } + + public void setText(String text) { + this.text = text; + String[] properties = new String[] { "text" }; + if (QueryExplorer.getInstance() != null) { + QueryExplorer.getInstance().getMatcherTreeViewer().update(this, properties); + } + } + + public String getText() { + return text; + } + + public PatternMatcher getParent() { + return parent; + } + + private class ParameterValueChangedListener implements IValueChangeListener { + @Override + public void handleValueChange(ValueChangeEvent event) { + setText(DatabindingAdapterUtil.getMessage(match, message)); + } + } + + public IPatternMatch getPatternMatch() { + return match; + } + + public Object[] getLocationObjects() { + return this.match.toArray(); + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/PatternMatcher.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/PatternMatcher.java index 35f3578c..84bab6ef 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/PatternMatcher.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/PatternMatcher.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.content.matcher; - +package org.eclipse.incquery.tooling.ui.queryexplorer.content.matcher; + import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -21,126 +21,127 @@ import org.eclipse.incquery.runtime.api.IncQueryMatcher; import org.eclipse.incquery.runtime.rete.misc.DeltaMonitor; import org.eclipse.incquery.tooling.ui.queryexplorer.QueryExplorer; - -/** - * A PatternMatcher is associated to every IncQueryMatcher which is annotated with PatternUI annotation. - * These elements will be the children of the top level elements in the treeviewer. - * - * @author Tamas Szabo - * - */ -public class PatternMatcher { - - private final List matches; - private final IncQueryMatcher matcher; - private DeltaMonitor deltaMonitor; - private Runnable processMatchesRunnable; - private Map sigMap; - private final PatternMatcherRoot parent; - private final boolean generated; - private final String patternFqn; - - public PatternMatcher(PatternMatcherRoot parent, IncQueryMatcher matcher, String patternFqn, boolean generated) { - this.parent = parent; - this.patternFqn = patternFqn; - this.matches = new ArrayList(); - this.matcher = matcher; - this.generated = generated; - - if (matcher != null) { - this.sigMap = new HashMap(); - this.deltaMonitor = this.matcher.newDeltaMonitor(true); - this.processMatchesRunnable = new Runnable() { - @Override - public void run() { - processNewMatches(deltaMonitor.matchFoundEvents); - processLostMatches(deltaMonitor.matchLostEvents); - deltaMonitor.clear(); - } - }; - - this.matcher.addCallbackAfterUpdates(processMatchesRunnable); - this.processMatchesRunnable.run(); - } - } - - /** - * Call this method to remove the callback handler from the delta monitor of the matcher. - */ - public void dispose() { - if (matcher != null) { - for (PatternMatch pm : matches) { - pm.dispose(); - } - this.matcher.removeCallbackAfterUpdates(processMatchesRunnable); - processMatchesRunnable = null; - } - } - - private void processNewMatches(Collection matches) { - for (IPatternMatch s : matches) { - addMatch(s); - } - } - - private void processLostMatches(Collection matches) { - for (IPatternMatch s : matches) { - removeMatch(s); - } - } - - private void addMatch(IPatternMatch match) { - PatternMatch pm = new PatternMatch(this, match); - this.sigMap.put(match, pm); - this.matches.add(pm); - if (QueryExplorer.getInstance() != null) { - QueryExplorer.getInstance().getMatcherTreeViewer().refresh(this); - } - } - - private void removeMatch(IPatternMatch match) { - this.matches.remove(this.sigMap.remove(match)); - if (QueryExplorer.getInstance() != null) { - QueryExplorer.getInstance().getMatcherTreeViewer().refresh(this); - } - } - - public PatternMatcherRoot getParent() { - return parent; - } - - public String getText() { - String isGeneratedString = isGenerated() ? " (Generated)" : " (Runtime)"; - if (matcher == null) { - return String.format("Matcher could not be created for pattern '%s' %s", patternFqn, isGeneratedString); - } - else { - String matchString; - switch (matches.size()){ - case 0: - matchString = "No matches"; - break; - case 1: - matchString = "1 match"; - break; - default: - matchString = String.format("%d matches", matches.size()); - } - //return this.matcher.getPatternName() + (isGeneratedString +" [size of matchset: "+matches.size()+"]"); - return String.format("%s - %s %s", matcher.getPatternName(), matchString, isGeneratedString); - } - } - - public static final String MATCHES_ID = "matches"; - public List getMatches() { - return matches; - } - - public boolean isGenerated() { - return generated; - } - - public boolean isCreated() { - return matcher != null; - } -} + +/** + * A PatternMatcher is associated to every IncQueryMatcher which is annotated with PatternUI annotation. These elements + * will be the children of the top level elements in the treeviewer. + * + * @author Tamas Szabo + * + */ +public class PatternMatcher { + + private final List matches; + private final IncQueryMatcher matcher; + private DeltaMonitor deltaMonitor; + private Runnable processMatchesRunnable; + private Map sigMap; + private final PatternMatcherRoot parent; + private final boolean generated; + private final String patternFqn; + + public PatternMatcher(PatternMatcherRoot parent, IncQueryMatcher matcher, + String patternFqn, boolean generated) { + this.parent = parent; + this.patternFqn = patternFqn; + this.matches = new ArrayList(); + this.matcher = matcher; + this.generated = generated; + + if (matcher != null) { + this.sigMap = new HashMap(); + this.deltaMonitor = this.matcher.newDeltaMonitor(true); + this.processMatchesRunnable = new Runnable() { + @Override + public void run() { + processNewMatches(deltaMonitor.matchFoundEvents); + processLostMatches(deltaMonitor.matchLostEvents); + deltaMonitor.clear(); + } + }; + + this.matcher.addCallbackAfterUpdates(processMatchesRunnable); + this.processMatchesRunnable.run(); + } + } + + /** + * Call this method to remove the callback handler from the delta monitor of the matcher. + */ + public void dispose() { + if (matcher != null) { + for (PatternMatch pm : matches) { + pm.dispose(); + } + this.matcher.removeCallbackAfterUpdates(processMatchesRunnable); + processMatchesRunnable = null; + } + } + + private void processNewMatches(Collection matches) { + for (IPatternMatch s : matches) { + addMatch(s); + } + } + + private void processLostMatches(Collection matches) { + for (IPatternMatch s : matches) { + removeMatch(s); + } + } + + private void addMatch(IPatternMatch match) { + PatternMatch pm = new PatternMatch(this, match); + this.sigMap.put(match, pm); + this.matches.add(pm); + if (QueryExplorer.getInstance() != null) { + QueryExplorer.getInstance().getMatcherTreeViewer().refresh(this); + } + } + + private void removeMatch(IPatternMatch match) { + this.matches.remove(this.sigMap.remove(match)); + if (QueryExplorer.getInstance() != null) { + QueryExplorer.getInstance().getMatcherTreeViewer().refresh(this); + } + } + + public PatternMatcherRoot getParent() { + return parent; + } + + public String getText() { + String isGeneratedString = isGenerated() ? " (Generated)" : " (Runtime)"; + if (matcher == null) { + return String.format("Matcher could not be created for pattern '%s' %s", patternFqn, isGeneratedString); + } else { + String matchString; + switch (matches.size()) { + case 0: + matchString = "No matches"; + break; + case 1: + matchString = "1 match"; + break; + default: + matchString = String.format("%d matches", matches.size()); + } + // return this.matcher.getPatternName() + (isGeneratedString +" [size of matchset: "+matches.size()+"]"); + return String.format("%s - %s %s", matcher.getPatternName(), matchString, isGeneratedString); + } + } + + public static final String MATCHES_ID = "matches"; + + public List getMatches() { + return matches; + } + + public boolean isGenerated() { + return generated; + } + + public boolean isCreated() { + return matcher != null; + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/PatternMatcherRoot.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/PatternMatcherRoot.java index e8ba39c4..ea65eebc 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/PatternMatcherRoot.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/matcher/PatternMatcherRoot.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.content.matcher; - +package org.eclipse.incquery.tooling.ui.queryexplorer.content.matcher; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -29,118 +29,115 @@ import org.eclipse.incquery.tooling.ui.IncQueryGUIPlugin; import org.eclipse.incquery.tooling.ui.queryexplorer.QueryExplorer; import org.eclipse.ui.IEditorPart; - -/** - * Each IEditingDomainProvider will be associated a PatternMatcherRoot element in the tree viewer. - * PatterMatcherRoots are indexed with a ViewerRootKey. - * - * It's children element will be PatterMatchers. - * - * @author Tamas Szabo - * - */ -public class PatternMatcherRoot { - - private final Map matchers; - private final MatcherTreeViewerRootKey key; - - private final ILog logger = IncQueryGUIPlugin.getDefault().getLog(); - - public PatternMatcherRoot(MatcherTreeViewerRootKey key) { - matchers = new HashMap(); - this.key = key; - } - - public void addMatcher(IncQueryMatcher matcher, String patternFqn, boolean generated) { - PatternMatcher pm = new PatternMatcher(this, matcher, patternFqn, generated); - this.matchers.put(patternFqn, pm); - if (QueryExplorer.getInstance() != null) { - QueryExplorer.getInstance().getMatcherTreeViewer().refresh(this); - } - } - - public void removeMatcher(String patternFqn) { - this.matchers.get(patternFqn).dispose(); - this.matchers.remove(patternFqn); - if (QueryExplorer.getInstance() != null) { - QueryExplorer.getInstance().getMatcherTreeViewer().refresh(this); - } - } - - public static final String MATCHERS_ID = "matchers"; - - public List getMatchers() { - return new ArrayList(matchers.values()); - } - - public String getText() { - return key.toString(); - } - - public void dispose() { - for (PatternMatcher pm : this.matchers.values()) { - pm.dispose(); - } - } - - public IEditorPart getEditorPart() { - return this.key.getEditorPart(); - } - -// public void registerPatternModelFromFile(IFile file, PatternModel pm) { -// if (!runtimeMatcherRegistry.containsKey(file)) { -// Set _patterns = new HashSet(); -// EList patterns = pm.getPatterns(); -// IncQueryMatcher matcher = null; -// -// for (Pattern pattern : patterns) { -// try { -// matcher = new GenericPatternMatcher(pattern, key.getNotifier()); -// } -// catch (IncQueryRuntimeException e) { -// logger.log(new Status(IStatus.ERROR, -// IncQueryGUIPlugin.PLUGIN_ID, -// "Cannot initialize pattern matcher for pattern " -// + pattern.getName(), e)); -// matcher = null; -// } -// _patterns.add(CorePatternLanguageHelper.getFullyQualifiedName(pattern)); -// addMatcher(matcher, CorePatternLanguageHelper.getFullyQualifiedName(pattern), false); -// } -// -// runtimeMatcherRegistry.put(file, _patterns); -// } -// } - - public void registerPattern(Pattern pattern) { - IncQueryMatcher matcher = null; - - try { - matcher = new GenericPatternMatcher(pattern, key.getEngine()); - } - catch (IncQueryException e) { - logger.log(new Status(IStatus.ERROR, - IncQueryGUIPlugin.PLUGIN_ID, - "Cannot initialize pattern matcher for pattern " - + pattern.getName(), e)); - matcher = null; - } - - addMatcher(matcher, CorePatternLanguageHelper.getFullyQualifiedName(pattern), false); - } - -// public void unregisterPatternModelFromFile(IFile file) { -// Set setTmp = runtimeMatcherRegistry.get(file); -// if (setTmp != null) { -// for (String pattern : setTmp) { -// removeMatcher(pattern); -// } -// -// runtimeMatcherRegistry.remove(file); -// } -// } - - public void unregisterPattern(Pattern pattern) { - removeMatcher(CorePatternLanguageHelper.getFullyQualifiedName(pattern)); - } -} + +/** + * Each IEditingDomainProvider will be associated a PatternMatcherRoot element in the tree viewer. PatterMatcherRoots + * are indexed with a ViewerRootKey. + * + * It's children element will be PatterMatchers. + * + * @author Tamas Szabo + * + */ +public class PatternMatcherRoot { + + private final Map matchers; + private final MatcherTreeViewerRootKey key; + + private final ILog logger = IncQueryGUIPlugin.getDefault().getLog(); + + public PatternMatcherRoot(MatcherTreeViewerRootKey key) { + matchers = new HashMap(); + this.key = key; + } + + public void addMatcher(IncQueryMatcher matcher, String patternFqn, boolean generated) { + PatternMatcher pm = new PatternMatcher(this, matcher, patternFqn, generated); + this.matchers.put(patternFqn, pm); + if (QueryExplorer.getInstance() != null) { + QueryExplorer.getInstance().getMatcherTreeViewer().refresh(this); + } + } + + public void removeMatcher(String patternFqn) { + this.matchers.get(patternFqn).dispose(); + this.matchers.remove(patternFqn); + if (QueryExplorer.getInstance() != null) { + QueryExplorer.getInstance().getMatcherTreeViewer().refresh(this); + } + } + + public static final String MATCHERS_ID = "matchers"; + + public List getMatchers() { + return new ArrayList(matchers.values()); + } + + public String getText() { + return key.toString(); + } + + public void dispose() { + for (PatternMatcher pm : this.matchers.values()) { + pm.dispose(); + } + } + + public IEditorPart getEditorPart() { + return this.key.getEditorPart(); + } + + // public void registerPatternModelFromFile(IFile file, PatternModel pm) { + // if (!runtimeMatcherRegistry.containsKey(file)) { + // Set _patterns = new HashSet(); + // EList patterns = pm.getPatterns(); + // IncQueryMatcher matcher = null; + // + // for (Pattern pattern : patterns) { + // try { + // matcher = new GenericPatternMatcher(pattern, key.getNotifier()); + // } + // catch (IncQueryRuntimeException e) { + // logger.log(new Status(IStatus.ERROR, + // IncQueryGUIPlugin.PLUGIN_ID, + // "Cannot initialize pattern matcher for pattern " + // + pattern.getName(), e)); + // matcher = null; + // } + // _patterns.add(CorePatternLanguageHelper.getFullyQualifiedName(pattern)); + // addMatcher(matcher, CorePatternLanguageHelper.getFullyQualifiedName(pattern), false); + // } + // + // runtimeMatcherRegistry.put(file, _patterns); + // } + // } + + public void registerPattern(Pattern pattern) { + IncQueryMatcher matcher = null; + + try { + matcher = new GenericPatternMatcher(pattern, key.getEngine()); + } catch (IncQueryException e) { + logger.log(new Status(IStatus.ERROR, IncQueryGUIPlugin.PLUGIN_ID, + "Cannot initialize pattern matcher for pattern " + pattern.getName(), e)); + matcher = null; + } + + addMatcher(matcher, CorePatternLanguageHelper.getFullyQualifiedName(pattern), false); + } + + // public void unregisterPatternModelFromFile(IFile file) { + // Set setTmp = runtimeMatcherRegistry.get(file); + // if (setTmp != null) { + // for (String pattern : setTmp) { + // removeMatcher(pattern); + // } + // + // runtimeMatcherRegistry.remove(file); + // } + // } + + public void unregisterPattern(Pattern pattern) { + removeMatcher(CorePatternLanguageHelper.getFullyQualifiedName(pattern)); + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternComponent.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternComponent.java index 13edb8bf..3eb5c1b5 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternComponent.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternComponent.java @@ -9,71 +9,72 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.content.patternsviewer; +package org.eclipse.incquery.tooling.ui.queryexplorer.content.patternsviewer; import org.eclipse.jface.viewers.CheckboxTreeViewer; - -/** - * A component inside the pattern hierarchy. - * - * @author Tamas Szabo - * - */ -public abstract class PatternComponent { - protected String patternNameFragment; - protected boolean selected; - protected PatternComposite parent; - - public PatternComponent() { - selected = false; - } - - /** - * Returns the parent element of the component. - * The root component will should return null. - * - * @return the parent of the component - */ - public PatternComposite getParent() { - return this.parent; - } - - /** - * Sets the selected state of the {@link PatternComponent}. - * - * @param selected the selected state - */ - public void setSelected(boolean selected) { - this.selected = selected; - } - - /** - * Updates the checked state of the {@link PatternComponent} in the given {@link CheckboxTreeViewer} instance. - * - * @param treeViewer the {@link CheckboxTreeViewer} instance - * @return true if all children elements of the {@link PatternComponent} are checked, false otherwise - */ - public abstract boolean updateSelection(CheckboxTreeViewer treeViewer); - - /** - * Returns the prefix of the fully qualified pattern name for the given component. - * - * @return the prefix of the pattern fqn - */ - public abstract String getFullPatternNamePrefix(); - - /** - * Returns the fragment inside the fully qualified pattern name for the given component. - * - * @return the pattern fqn fragment - */ - public String getPatternNameFragment() { - return patternNameFragment; - } - - @Override - public String toString() { - return patternNameFragment; - } -} +/** + * A component inside the pattern hierarchy. + * + * @author Tamas Szabo + * + */ +public abstract class PatternComponent { + + protected String patternNameFragment; + protected boolean selected; + protected PatternComposite parent; + + public PatternComponent() { + selected = false; + } + + /** + * Returns the parent element of the component. The root component will should return null. + * + * @return the parent of the component + */ + public PatternComposite getParent() { + return this.parent; + } + + /** + * Sets the selected state of the {@link PatternComponent}. + * + * @param selected + * the selected state + */ + public void setSelected(boolean selected) { + this.selected = selected; + } + + /** + * Updates the checked state of the {@link PatternComponent} in the given {@link CheckboxTreeViewer} instance. + * + * @param treeViewer + * the {@link CheckboxTreeViewer} instance + * @return true if all children elements of the {@link PatternComponent} are checked, false otherwise + */ + public abstract boolean updateSelection(CheckboxTreeViewer treeViewer); + + /** + * Returns the prefix of the fully qualified pattern name for the given component. + * + * @return the prefix of the pattern fqn + */ + public abstract String getFullPatternNamePrefix(); + + /** + * Returns the fragment inside the fully qualified pattern name for the given component. + * + * @return the pattern fqn fragment + */ + public String getPatternNameFragment() { + return patternNameFragment; + } + + @Override + public String toString() { + return patternNameFragment; + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternComposite.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternComposite.java index 2710d8ef..3163e36f 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternComposite.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternComposite.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.content.patternsviewer; - +package org.eclipse.incquery.tooling.ui.queryexplorer.content.patternsviewer; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -18,300 +18,298 @@ import org.eclipse.incquery.tooling.ui.queryexplorer.QueryExplorer; import org.eclipse.jface.viewers.CheckboxTreeViewer; - -/** - * This class represents a composite element inside a pattern hierarchy. - * - * @author Tamas Szabo - * - */ -public class PatternComposite extends PatternComponent { - - protected List children; - private Map fragmentMap; - - public PatternComposite(String patternNameFragment, PatternComposite parent) { - super(); - this.patternNameFragment = patternNameFragment; - this.children = new ArrayList(); - this.fragmentMap = new HashMap(); - this.parent = parent; - } - - /** - * Returns the list of pattern components downwards the tree for the given fully qualified pattern name. - * - * @param patternFragment the fully qualified name of the pattern - * @return the list of components - */ - public List find(String patternFragment) { - List components = new ArrayList(); - find(patternFragment, components); - return components; - } - - /** - * Returns the root above this composite element. - * This will result either the Plug-in or the Runtime composite. - * - * @return the root composite - */ - public PatternComposite getRoot() { - if (parent == null) { - return this; - } - else { - return parent.getRoot(); - } - } - - private void find(String patternFragment, List components) { - String[] tokens = patternFragment.split("\\."); - - if (tokens.length == 1) { - for (PatternComponent pc : children) { - if (pc.getPatternNameFragment().matches(patternFragment)) { - components.add(pc); - } - } - } - else { - String prefix = tokens[0]; - String suffix = patternFragment.substring(prefix.length()+1); - PatternComposite composite = fragmentMap.get(prefix); - if (composite != null) { - components.add(composite); - composite.find(suffix, components); - } - } - } - - /** - * Add a new component under the composite element based on the given pattern name fragment. - * - * @param patternFragment the pattern name fragment - */ - public PatternComponent addComponent(String patternFragment) { - String[] tokens = patternFragment.split("\\."); - - if (tokens.length == 1) { - PatternLeaf leaf = new PatternLeaf(patternFragment, this); - leaf.setSelected(true); - children.add(leaf); - return leaf; - } - else { - String prefix = tokens[0]; - String suffix = patternFragment.substring(prefix.length()+1); - - PatternComposite composite = fragmentMap.get(prefix); - - if (composite == null) { - composite = new PatternComposite(prefix, this); - fragmentMap.put(prefix, composite); - children.add(composite); - } - return composite.addComponent(suffix); - } - } - - /** - * Returns the list of (ALL) leaf objects under this composite. - * - * @return the list of leaves - */ - public List getAllLeaves() { - List leaves = new ArrayList(); - - for (PatternComponent component : children) { - if (component instanceof PatternLeaf) { - leaves.add((PatternLeaf) component); - } - else { - leaves.addAll(((PatternComposite) component).getAllLeaves()); - } - } - - return leaves; - } - - /** - * Returns the direct leaf children elements under this composite. - * - * @return the list of direct leaf elements - */ - public List getDirectLeaves() { - List leaves = new ArrayList(); - - for (PatternComponent component : children) { - if (component instanceof PatternLeaf) { - leaves.add((PatternLeaf) component); - } - } - - return leaves; - } - - /** - * Removes all composite elements which do not have a leaf component under it. - */ - public void purge() { - List copyOfChildren = new ArrayList(children); - - for (PatternComponent component : copyOfChildren) { - if (component instanceof PatternComposite) { - PatternComposite composite = (PatternComposite) component; - composite.purge(); - } - } - - if (this.getAllLeaves().size() == 0) { - QueryExplorer.getInstance().getPatternsViewerInput().getGenericPatternsRoot().removeComponent(getFullPatternNamePrefix()); - } - } - - /** - * Returns ALL children elements under the given composite. - * - * @return - */ - public List getAllChildren() { - List result = new ArrayList(this.children); - - for (PatternComponent component : children) { - if (component instanceof PatternComposite) { - result.addAll(((PatternComposite) component).getAllChildren()); - } - } - - return result; - } - - /** - * Propagates element deselection upwards in the hierarchy. - */ - public void propagateDeSelectionToTop() { - QueryExplorer.getInstance().getPatternsViewer().setChecked(this, false); - this.setSelected(false); - if (this.parent != null) { - this.parent.propagateDeSelectionToTop(); - } - } - - /** - * Propagates element selection upwards in the hierarchy. - */ - public void propagateSelectionToTop(PatternComponent selected) { - boolean allSelected = true; - for (PatternComponent component : children) { - if (!(component == selected) && (!QueryExplorer.getInstance().getPatternsViewer().getChecked(component))) { - allSelected = false; - } - } - - if (allSelected) { - QueryExplorer.getInstance().getPatternsViewer().setChecked(this, true); - this.setSelected(true); - if (this.parent != null) { - this.parent.propagateSelectionToTop(this); - } - } - } - - /** - * This method removes the component matching the given pattern name fragment. - * - * @param patternFragment the pattern name fragment - * @param handleInWhole tells whether to handle the whole pattern fragment - * (this is used when flat presentation is on and the user wants to unregister a non-leaf element) - */ - public void removeComponent(String patternFragment) { - String[] tokens = patternFragment.split("\\."); - if (tokens.length == 1) { - PatternComponent component = null; - for (PatternComponent c : children) { - if (c.getPatternNameFragment().matches(patternFragment)) { - component = c; - } - } - if (component != null) { - children.remove(component); - fragmentMap.remove(patternFragment); - } - } - else { - String prefix = tokens[0]; - String suffix = patternFragment.substring(prefix.length()+1); - - PatternComposite composite = fragmentMap.get(prefix); - - if (composite != null) { - composite.removeComponent(suffix); - } - } - } - - /** - * Returns the list of direct children elements under the composite. - * - * @return the list of children elements - */ - public List getDirectChildren() { - return children; - } - - @Override - public String getFullPatternNamePrefix() { - StringBuilder sb = new StringBuilder(patternNameFragment); - - if (parent != null && parent.getParent()!=null) { - sb.insert(0, "."); - sb.insert(0, parent.getFullPatternNamePrefix()); - } - return sb.toString(); - } - - @Override - public boolean updateSelection(CheckboxTreeViewer treeViewer) { - boolean allSelected = (this.children.size() > 0); - - for (PatternComponent pc : this.children) { - if (!pc.updateSelection(treeViewer)) { - allSelected = false; - } - } - - treeViewer.setChecked(this, allSelected); - - return allSelected; - } - - @Override - public int hashCode() { - int hash = patternNameFragment.hashCode(); - for (PatternComponent pc : children) { - hash += 31 * pc.hashCode(); - } - return hash; - } - - @Override - public boolean equals(Object obj) { - if(this == obj) { - return true; - } - if((obj == null) || (obj.getClass() != this.getClass())) { - return false; - } - - PatternComposite composite = (PatternComposite) obj; - - if ((this.patternNameFragment == composite.patternNameFragment) && - (this.parent == composite.parent) && - (this.children.equals(composite.children))) { - return true; - } - - return false; - } -} + +/** + * This class represents a composite element inside a pattern hierarchy. + * + * @author Tamas Szabo + * + */ +public class PatternComposite extends PatternComponent { + + protected List children; + private Map fragmentMap; + + public PatternComposite(String patternNameFragment, PatternComposite parent) { + super(); + this.patternNameFragment = patternNameFragment; + this.children = new ArrayList(); + this.fragmentMap = new HashMap(); + this.parent = parent; + } + + /** + * Returns the list of pattern components downwards the tree for the given fully qualified pattern name. + * + * @param patternFragment + * the fully qualified name of the pattern + * @return the list of components + */ + public List find(String patternFragment) { + List components = new ArrayList(); + find(patternFragment, components); + return components; + } + + /** + * Returns the root above this composite element. This will result either the Plug-in or the Runtime composite. + * + * @return the root composite + */ + public PatternComposite getRoot() { + if (parent == null) { + return this; + } else { + return parent.getRoot(); + } + } + + private void find(String patternFragment, List components) { + String[] tokens = patternFragment.split("\\."); + + if (tokens.length == 1) { + for (PatternComponent pc : children) { + if (pc.getPatternNameFragment().matches(patternFragment)) { + components.add(pc); + } + } + } else { + String prefix = tokens[0]; + String suffix = patternFragment.substring(prefix.length() + 1); + PatternComposite composite = fragmentMap.get(prefix); + if (composite != null) { + components.add(composite); + composite.find(suffix, components); + } + } + } + + /** + * Add a new component under the composite element based on the given pattern name fragment. + * + * @param patternFragment + * the pattern name fragment + */ + public PatternComponent addComponent(String patternFragment) { + String[] tokens = patternFragment.split("\\."); + + if (tokens.length == 1) { + PatternLeaf leaf = new PatternLeaf(patternFragment, this); + leaf.setSelected(true); + children.add(leaf); + return leaf; + } else { + String prefix = tokens[0]; + String suffix = patternFragment.substring(prefix.length() + 1); + + PatternComposite composite = fragmentMap.get(prefix); + + if (composite == null) { + composite = new PatternComposite(prefix, this); + fragmentMap.put(prefix, composite); + children.add(composite); + } + return composite.addComponent(suffix); + } + } + + /** + * Returns the list of (ALL) leaf objects under this composite. + * + * @return the list of leaves + */ + public List getAllLeaves() { + List leaves = new ArrayList(); + + for (PatternComponent component : children) { + if (component instanceof PatternLeaf) { + leaves.add((PatternLeaf) component); + } else { + leaves.addAll(((PatternComposite) component).getAllLeaves()); + } + } + + return leaves; + } + + /** + * Returns the direct leaf children elements under this composite. + * + * @return the list of direct leaf elements + */ + public List getDirectLeaves() { + List leaves = new ArrayList(); + + for (PatternComponent component : children) { + if (component instanceof PatternLeaf) { + leaves.add((PatternLeaf) component); + } + } + + return leaves; + } + + /** + * Removes all composite elements which do not have a leaf component under it. + */ + public void purge() { + List copyOfChildren = new ArrayList(children); + + for (PatternComponent component : copyOfChildren) { + if (component instanceof PatternComposite) { + PatternComposite composite = (PatternComposite) component; + composite.purge(); + } + } + + if (this.getAllLeaves().size() == 0) { + QueryExplorer.getInstance().getPatternsViewerInput().getGenericPatternsRoot() + .removeComponent(getFullPatternNamePrefix()); + } + } + + /** + * Returns ALL children elements under the given composite. + * + * @return + */ + public List getAllChildren() { + List result = new ArrayList(this.children); + + for (PatternComponent component : children) { + if (component instanceof PatternComposite) { + result.addAll(((PatternComposite) component).getAllChildren()); + } + } + + return result; + } + + /** + * Propagates element deselection upwards in the hierarchy. + */ + public void propagateDeSelectionToTop() { + QueryExplorer.getInstance().getPatternsViewer().setChecked(this, false); + this.setSelected(false); + if (this.parent != null) { + this.parent.propagateDeSelectionToTop(); + } + } + + /** + * Propagates element selection upwards in the hierarchy. + */ + public void propagateSelectionToTop(PatternComponent selected) { + boolean allSelected = true; + for (PatternComponent component : children) { + if (!(component == selected) && (!QueryExplorer.getInstance().getPatternsViewer().getChecked(component))) { + allSelected = false; + } + } + + if (allSelected) { + QueryExplorer.getInstance().getPatternsViewer().setChecked(this, true); + this.setSelected(true); + if (this.parent != null) { + this.parent.propagateSelectionToTop(this); + } + } + } + + /** + * This method removes the component matching the given pattern name fragment. + * + * @param patternFragment + * the pattern name fragment + * @param handleInWhole + * tells whether to handle the whole pattern fragment (this is used when flat presentation is on and the + * user wants to unregister a non-leaf element) + */ + public void removeComponent(String patternFragment) { + String[] tokens = patternFragment.split("\\."); + if (tokens.length == 1) { + PatternComponent component = null; + for (PatternComponent c : children) { + if (c.getPatternNameFragment().matches(patternFragment)) { + component = c; + } + } + if (component != null) { + children.remove(component); + fragmentMap.remove(patternFragment); + } + } else { + String prefix = tokens[0]; + String suffix = patternFragment.substring(prefix.length() + 1); + + PatternComposite composite = fragmentMap.get(prefix); + + if (composite != null) { + composite.removeComponent(suffix); + } + } + } + + /** + * Returns the list of direct children elements under the composite. + * + * @return the list of children elements + */ + public List getDirectChildren() { + return children; + } + + @Override + public String getFullPatternNamePrefix() { + StringBuilder sb = new StringBuilder(patternNameFragment); + + if (parent != null && parent.getParent() != null) { + sb.insert(0, "."); + sb.insert(0, parent.getFullPatternNamePrefix()); + } + return sb.toString(); + } + + @Override + public boolean updateSelection(CheckboxTreeViewer treeViewer) { + boolean allSelected = (this.children.size() > 0); + + for (PatternComponent pc : this.children) { + if (!pc.updateSelection(treeViewer)) { + allSelected = false; + } + } + + treeViewer.setChecked(this, allSelected); + + return allSelected; + } + + @Override + public int hashCode() { + int hash = patternNameFragment.hashCode(); + for (PatternComponent pc : children) { + hash += 31 * pc.hashCode(); + } + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if ((obj == null) || (obj.getClass() != this.getClass())) { + return false; + } + + PatternComposite composite = (PatternComposite) obj; + + if ((this.patternNameFragment == composite.patternNameFragment) && (this.parent == composite.parent) + && (this.children.equals(composite.children))) { + return true; + } + + return false; + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternLeaf.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternLeaf.java index aadd7444..2831fc49 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternLeaf.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternLeaf.java @@ -9,64 +9,63 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.content.patternsviewer; +package org.eclipse.incquery.tooling.ui.queryexplorer.content.patternsviewer; import org.eclipse.incquery.tooling.ui.queryexplorer.QueryExplorer; import org.eclipse.jface.viewers.CheckboxTreeViewer; - -/** - * This class represents a leaf element inside a pattern hierarchy. - * - * @author Tamas Szabo - * - */ -public class PatternLeaf extends PatternComponent { - - public PatternLeaf(String patternNameFragment, PatternComposite parent) { - super(); - this.patternNameFragment = patternNameFragment; - this.parent = parent; - } - - @Override - public String getFullPatternNamePrefix() { - StringBuilder sb = new StringBuilder(patternNameFragment); - PatternsViewerInput input = QueryExplorer.getInstance().getPatternsViewerInput(); - - if (parent != null && !parent.equals(input.getGeneratedPatternsRoot()) && - !parent.equals(input.getGenericPatternsRoot())) { - sb.insert(0, parent.getFullPatternNamePrefix()+"."); - } - return sb.toString(); - } - @Override - public boolean updateSelection(CheckboxTreeViewer treeViewer) { - treeViewer.setChecked(this, selected); - return this.selected; - } - - @Override - public int hashCode() { - return patternNameFragment.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if(this == obj) { - return true; - } - if((obj == null) || (obj.getClass() != this.getClass())) { - return false; - } - - PatternLeaf composite = (PatternLeaf) obj; - - if ((this.patternNameFragment == composite.patternNameFragment) && - (this.parent == composite.parent)) { - return true; - } - - return false; - } -} +/** + * This class represents a leaf element inside a pattern hierarchy. + * + * @author Tamas Szabo + * + */ +public class PatternLeaf extends PatternComponent { + + public PatternLeaf(String patternNameFragment, PatternComposite parent) { + super(); + this.patternNameFragment = patternNameFragment; + this.parent = parent; + } + + @Override + public String getFullPatternNamePrefix() { + StringBuilder sb = new StringBuilder(patternNameFragment); + PatternsViewerInput input = QueryExplorer.getInstance().getPatternsViewerInput(); + + if (parent != null && !parent.equals(input.getGeneratedPatternsRoot()) + && !parent.equals(input.getGenericPatternsRoot())) { + sb.insert(0, parent.getFullPatternNamePrefix() + "."); + } + return sb.toString(); + } + + @Override + public boolean updateSelection(CheckboxTreeViewer treeViewer) { + treeViewer.setChecked(this, selected); + return this.selected; + } + + @Override + public int hashCode() { + return patternNameFragment.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if ((obj == null) || (obj.getClass() != this.getClass())) { + return false; + } + + PatternLeaf composite = (PatternLeaf) obj; + + if ((this.patternNameFragment == composite.patternNameFragment) && (this.parent == composite.parent)) { + return true; + } + + return false; + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternsViewerFlatContentProvider.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternsViewerFlatContentProvider.java index 337b8086..f31b8ec4 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternsViewerFlatContentProvider.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternsViewerFlatContentProvider.java @@ -9,78 +9,77 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.content.patternsviewer; - +package org.eclipse.incquery.tooling.ui.queryexplorer.content.patternsviewer; + import java.util.ArrayList; import java.util.List; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.Viewer; - -public class PatternsViewerFlatContentProvider implements ITreeContentProvider { - - public PatternsViewerFlatContentProvider() {} - - @Override - public void dispose() {} - - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {} - @Override - public Object[] getElements(Object inputElement) { - if (inputElement != null && inputElement instanceof PatternsViewerInput) { - return ((PatternsViewerInput) inputElement).getChildren(); - } - return null; - } - - - @Override - public Object[] getChildren(Object parentElement) { - if (parentElement != null && parentElement instanceof PatternComposite) { - return getLeavesOrComponentsWithLeaves((PatternComposite) parentElement).toArray(); - } - return null; - } +public class PatternsViewerFlatContentProvider implements ITreeContentProvider { + + public PatternsViewerFlatContentProvider() { + } + + @Override + public void dispose() { + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + @Override + public Object[] getElements(Object inputElement) { + if (inputElement != null && inputElement instanceof PatternsViewerInput) { + return ((PatternsViewerInput) inputElement).getChildren(); + } + return null; + } + + @Override + public Object[] getChildren(Object parentElement) { + if (parentElement != null && parentElement instanceof PatternComposite) { + return getLeavesOrComponentsWithLeaves((PatternComposite) parentElement).toArray(); + } + return null; + } - //OK - @Override - public Object getParent(Object element) { - if (element != null && element instanceof PatternLeaf) { - return ((PatternComponent) element).getParent(); - } - else if (element != null && element instanceof PatternComposite) { - return ((PatternComposite) element).getRoot(); - } - return null; - } + // OK + @Override + public Object getParent(Object element) { + if (element != null && element instanceof PatternLeaf) { + return ((PatternComponent) element).getParent(); + } else if (element != null && element instanceof PatternComposite) { + return ((PatternComposite) element).getRoot(); + } + return null; + } - //OK - @Override - public boolean hasChildren(Object element) { - if (element != null && element instanceof PatternComposite) { - return ((PatternComposite) element).getDirectLeaves().size() > 0; - } - return false; - } + // OK + @Override + public boolean hasChildren(Object element) { + if (element != null && element instanceof PatternComposite) { + return ((PatternComposite) element).getDirectLeaves().size() > 0; + } + return false; + } - private List getLeavesOrComponentsWithLeaves(PatternComposite composite) { - List components = new ArrayList(); - for (PatternComponent pc : composite.getDirectChildren()) { - if (pc instanceof PatternLeaf) { - components.add(pc); - } - else { - PatternComposite comp = (PatternComposite) pc; - if (comp.getDirectLeaves().size() > 0) { - components.add(pc); - } - else { - components.addAll(getLeavesOrComponentsWithLeaves(comp)); - } - } - } - return components; - } -} + private List getLeavesOrComponentsWithLeaves(PatternComposite composite) { + List components = new ArrayList(); + for (PatternComponent pc : composite.getDirectChildren()) { + if (pc instanceof PatternLeaf) { + components.add(pc); + } else { + PatternComposite comp = (PatternComposite) pc; + if (comp.getDirectLeaves().size() > 0) { + components.add(pc); + } else { + components.addAll(getLeavesOrComponentsWithLeaves(comp)); + } + } + } + return components; + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternsViewerFlatLabelProvider.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternsViewerFlatLabelProvider.java index 58fdc7c1..3d78aed8 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternsViewerFlatLabelProvider.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternsViewerFlatLabelProvider.java @@ -9,77 +9,73 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.content.patternsviewer; - +package org.eclipse.incquery.tooling.ui.queryexplorer.content.patternsviewer; + import org.eclipse.incquery.tooling.ui.IncQueryGUIPlugin; import org.eclipse.jface.resource.ImageRegistry; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.swt.graphics.Image; - -public class PatternsViewerFlatLabelProvider implements ILabelProvider { - - protected PatternsViewerInput input; - - public PatternsViewerFlatLabelProvider(PatternsViewerInput input) { - this.input = input; - } - - @Override - public void addListener(ILabelProviderListener listener) { - - } - - @Override - public void dispose() { - - } - - @Override - public boolean isLabelProperty(Object element, String property) { - return false; - } - - @Override - public void removeListener(ILabelProviderListener listener) { - - } - - @Override - public Image getImage(Object element) { - ImageRegistry imageRegistry = IncQueryGUIPlugin.getDefault().getImageRegistry(); - - if (element instanceof PatternLeaf) { - return imageRegistry.get(IncQueryGUIPlugin.ICON_EIQ); - } - else if (element instanceof PatternComposite) { - if (!element.equals(input.getGeneratedPatternsRoot()) && !element.equals(input.getGenericPatternsRoot())) { - return imageRegistry.get(IncQueryGUIPlugin.ICON_EPACKAGE); - } - else { - return imageRegistry.get(IncQueryGUIPlugin.ICON_ROOT); - } - } - return null; - } - - @Override - public String getText(Object element) { - if (element instanceof PatternComposite) { - PatternComposite composite = (PatternComposite) element; - - if (composite.equals(input.getGeneratedPatternsRoot()) || composite.equals(input.getGenericPatternsRoot())) { - return composite.getPatternNameFragment(); - } - else { - return composite.getFullPatternNamePrefix(); - } - } - else if (element instanceof PatternLeaf) { - return ((PatternComponent) element).getPatternNameFragment(); - } - - return null; - } - -} + +public class PatternsViewerFlatLabelProvider implements ILabelProvider { + + protected PatternsViewerInput input; + + public PatternsViewerFlatLabelProvider(PatternsViewerInput input) { + this.input = input; + } + + @Override + public void addListener(ILabelProviderListener listener) { + + } + + @Override + public void dispose() { + + } + + @Override + public boolean isLabelProperty(Object element, String property) { + return false; + } + + @Override + public void removeListener(ILabelProviderListener listener) { + + } + + @Override + public Image getImage(Object element) { + ImageRegistry imageRegistry = IncQueryGUIPlugin.getDefault().getImageRegistry(); + + if (element instanceof PatternLeaf) { + return imageRegistry.get(IncQueryGUIPlugin.ICON_EIQ); + } else if (element instanceof PatternComposite) { + if (!element.equals(input.getGeneratedPatternsRoot()) && !element.equals(input.getGenericPatternsRoot())) { + return imageRegistry.get(IncQueryGUIPlugin.ICON_EPACKAGE); + } else { + return imageRegistry.get(IncQueryGUIPlugin.ICON_ROOT); + } + } + return null; + } + + @Override + public String getText(Object element) { + if (element instanceof PatternComposite) { + PatternComposite composite = (PatternComposite) element; + + if (composite.equals(input.getGeneratedPatternsRoot()) || composite.equals(input.getGenericPatternsRoot())) { + return composite.getPatternNameFragment(); + } else { + return composite.getFullPatternNamePrefix(); + } + } else if (element instanceof PatternLeaf) { + return ((PatternComponent) element).getPatternNameFragment(); + } + + return null; + } + +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternsViewerHierarchicalContentProvider.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternsViewerHierarchicalContentProvider.java index 7f5638e3..57ffd130 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternsViewerHierarchicalContentProvider.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternsViewerHierarchicalContentProvider.java @@ -9,53 +9,55 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.content.patternsviewer; - -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.Viewer; - -public class PatternsViewerHierarchicalContentProvider implements ITreeContentProvider { - - public PatternsViewerHierarchicalContentProvider() { - - } - - @Override - public void dispose() {} - - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {} - - @Override - public Object[] getElements(Object inputElement) { - if (inputElement != null && inputElement instanceof PatternsViewerInput) { - return ((PatternsViewerInput) inputElement).getChildren(); - } - return null; - } - - @Override - public Object[] getChildren(Object parentElement) { - if (parentElement != null && parentElement instanceof PatternComposite) { - return ((PatternComposite) parentElement).getDirectChildren().toArray(); - } - return null; - } - - @Override - public Object getParent(Object element) { - if (element != null && element instanceof PatternComponent) { - return ((PatternComponent) element).getParent(); - } - return null; - } - - @Override - public boolean hasChildren(Object element) { - if (element != null && element instanceof PatternComposite) { - return ((PatternComposite) element).getDirectChildren().size() > 0; - } - return false; - } - -} +package org.eclipse.incquery.tooling.ui.queryexplorer.content.patternsviewer; + +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + +public class PatternsViewerHierarchicalContentProvider implements ITreeContentProvider { + + public PatternsViewerHierarchicalContentProvider() { + + } + + @Override + public void dispose() { + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + @Override + public Object[] getElements(Object inputElement) { + if (inputElement != null && inputElement instanceof PatternsViewerInput) { + return ((PatternsViewerInput) inputElement).getChildren(); + } + return null; + } + + @Override + public Object[] getChildren(Object parentElement) { + if (parentElement != null && parentElement instanceof PatternComposite) { + return ((PatternComposite) parentElement).getDirectChildren().toArray(); + } + return null; + } + + @Override + public Object getParent(Object element) { + if (element != null && element instanceof PatternComponent) { + return ((PatternComponent) element).getParent(); + } + return null; + } + + @Override + public boolean hasChildren(Object element) { + if (element != null && element instanceof PatternComposite) { + return ((PatternComposite) element).getDirectChildren().size() > 0; + } + return false; + } + +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternsViewerHierarchicalLabelProvider.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternsViewerHierarchicalLabelProvider.java index 2d0c75ec..c64f6051 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternsViewerHierarchicalLabelProvider.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternsViewerHierarchicalLabelProvider.java @@ -11,19 +11,18 @@ package org.eclipse.incquery.tooling.ui.queryexplorer.content.patternsviewer; -public class PatternsViewerHierarchicalLabelProvider extends - PatternsViewerFlatLabelProvider { +public class PatternsViewerHierarchicalLabelProvider extends PatternsViewerFlatLabelProvider { - public PatternsViewerHierarchicalLabelProvider(PatternsViewerInput input) { - super(input); - } + public PatternsViewerHierarchicalLabelProvider(PatternsViewerInput input) { + super(input); + } - @Override - public String getText(Object element) { - if (element instanceof PatternComponent) { - return ((PatternComponent) element).getPatternNameFragment(); - } - return null; - } + @Override + public String getText(Object element) { + if (element instanceof PatternComponent) { + return ((PatternComponent) element).getPatternNameFragment(); + } + return null; + } } diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternsViewerInput.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternsViewerInput.java index 7510f88d..770dba8f 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternsViewerInput.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/content/patternsviewer/PatternsViewerInput.java @@ -13,31 +13,31 @@ public class PatternsViewerInput { - private PatternComposite generatedPatternsRoot; - private PatternComposite genericPatternsRoot; - - public PatternsViewerInput() { - this.generatedPatternsRoot = new PatternComposite("Plug-in", null); - this.genericPatternsRoot = new PatternComposite("Runtime", null); - } - - public PatternComposite getGeneratedPatternsRoot() { - return generatedPatternsRoot; - } - - public PatternComposite getGenericPatternsRoot() { - return genericPatternsRoot; - } - - public Object[] getChildren() { - Object[] children = new Object[2]; - children[0] = generatedPatternsRoot; - children[1] = genericPatternsRoot; - return children; - } - - @Override - public String toString() { - return this.getClass().getSimpleName(); - } + private PatternComposite generatedPatternsRoot; + private PatternComposite genericPatternsRoot; + + public PatternsViewerInput() { + this.generatedPatternsRoot = new PatternComposite("Plug-in", null); + this.genericPatternsRoot = new PatternComposite("Runtime", null); + } + + public PatternComposite getGeneratedPatternsRoot() { + return generatedPatternsRoot; + } + + public PatternComposite getGenericPatternsRoot() { + return genericPatternsRoot; + } + + public Object[] getChildren() { + Object[] children = new Object[2]; + children[0] = generatedPatternsRoot; + children[1] = genericPatternsRoot; + return children; + } + + @Override + public String toString() { + return this.getClass().getSimpleName(); + } } diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/LoadEiqModelHandler.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/LoadEiqModelHandler.java index f0fd2344..ab49704f 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/LoadEiqModelHandler.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/LoadEiqModelHandler.java @@ -25,23 +25,24 @@ public class LoadEiqModelHandler extends LoadModelHandler { - @Inject - DatabindingUtil dbUtil; + @Inject + DatabindingUtil dbUtil; - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { - try { - IFile file = (IFile) HandlerUtil.getActiveEditorInput(event).getAdapter(IFile.class); - if (file != null) { - MatcherTreeViewerRootKey key = new MatcherTreeViewerRootKey(HandlerUtil.getActiveEditor(event), dbUtil.parseEPM(file)); - ModelConnector contentModel = new EMFModelConnector(key); - QueryExplorer.getInstance().getModelConnectorMap().put(key, contentModel); - contentModel.loadModel(); - } - } catch (Exception e) { - throw new ExecutionException("Cannot load pattern model", e); - } - return null; - } + try { + IFile file = (IFile) HandlerUtil.getActiveEditorInput(event).getAdapter(IFile.class); + if (file != null) { + MatcherTreeViewerRootKey key = new MatcherTreeViewerRootKey(HandlerUtil.getActiveEditor(event), + dbUtil.parseEPM(file)); + ModelConnector contentModel = new EMFModelConnector(key); + QueryExplorer.getInstance().getModelConnectorMap().put(key, contentModel); + contentModel.loadModel(); + } + } catch (Exception e) { + throw new ExecutionException("Cannot load pattern model", e); + } + return null; + } } diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/LoadEiqPatternHandler.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/LoadEiqPatternHandler.java index 24c9acc7..6873d7fa 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/LoadEiqPatternHandler.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/LoadEiqPatternHandler.java @@ -9,37 +9,37 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.resources.IFile; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.handlers.HandlerUtil; - -import com.google.inject.Inject; -import com.google.inject.Injector; - -public class LoadEiqPatternHandler extends AbstractHandler { - - @Inject - Injector injector; - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - - try { - IFile file = (IFile) HandlerUtil.getActiveEditorInput(event).getAdapter(IFile.class); - if (file != null) { - RuntimeMatcherRegistrator registrator = new RuntimeMatcherRegistrator(file); - injector.injectMembers(registrator); - Display.getDefault().asyncExec(registrator); - } - } catch (Exception e) { - throw new ExecutionException("Cannot load pattern file", e); - } - - return null; - } -} +package org.eclipse.incquery.tooling.ui.queryexplorer.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.resources.IFile; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.handlers.HandlerUtil; + +import com.google.inject.Inject; +import com.google.inject.Injector; + +public class LoadEiqPatternHandler extends AbstractHandler { + + @Inject + Injector injector; + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + try { + IFile file = (IFile) HandlerUtil.getActiveEditorInput(event).getAdapter(IFile.class); + if (file != null) { + RuntimeMatcherRegistrator registrator = new RuntimeMatcherRegistrator(file); + injector.injectMembers(registrator); + Display.getDefault().asyncExec(registrator); + } + } catch (Exception e) { + throw new ExecutionException("Cannot load pattern file", e); + } + + return null; + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/LoadResourceHandler.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/LoadResourceHandler.java index 3f515216..70996ebf 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/LoadResourceHandler.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/LoadResourceHandler.java @@ -9,51 +9,50 @@ * Tamas Szabo, Zoltan Ujhelyi - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.handlers; - -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.resource.Resource; +package org.eclipse.incquery.tooling.ui.queryexplorer.handlers; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.incquery.tooling.ui.queryexplorer.QueryExplorer; import org.eclipse.incquery.tooling.ui.queryexplorer.content.matcher.MatcherTreeViewerRootKey; import org.eclipse.incquery.tooling.ui.queryexplorer.handlers.util.EMFModelConnector; import org.eclipse.incquery.tooling.ui.queryexplorer.handlers.util.ModelConnector; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.TreeSelection; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.handlers.HandlerUtil; /** - * Default Resource and EObject loader. + * Default Resource and EObject loader. * * @author Tamas Szabo - * - */ -public class LoadResourceHandler extends LoadModelHandler { - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - IEditorPart editorPart = HandlerUtil.getActiveEditor(event); - - if (editorPart instanceof ISelectionProvider) { - ISelectionProvider selectionProvider = (ISelectionProvider) editorPart; - if (selectionProvider.getSelection() instanceof TreeSelection) { - Object object = ((TreeSelection) selectionProvider.getSelection()).getFirstElement(); - Resource resource = null; - if (object instanceof Resource) { - resource = (Resource) object; - } - else if (object instanceof EObject) { - resource = ((EObject) object).eResource(); - } - MatcherTreeViewerRootKey key = new MatcherTreeViewerRootKey(editorPart, resource); - ModelConnector contentModel = new EMFModelConnector(key); - QueryExplorer.getInstance().getModelConnectorMap().put(key, contentModel); - contentModel.loadModel(); - } - } - - return null; - } -} + * + */ +public class LoadResourceHandler extends LoadModelHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + IEditorPart editorPart = HandlerUtil.getActiveEditor(event); + + if (editorPart instanceof ISelectionProvider) { + ISelectionProvider selectionProvider = (ISelectionProvider) editorPart; + if (selectionProvider.getSelection() instanceof TreeSelection) { + Object object = ((TreeSelection) selectionProvider.getSelection()).getFirstElement(); + Resource resource = null; + if (object instanceof Resource) { + resource = (Resource) object; + } else if (object instanceof EObject) { + resource = ((EObject) object).eResource(); + } + MatcherTreeViewerRootKey key = new MatcherTreeViewerRootKey(editorPart, resource); + ModelConnector contentModel = new EMFModelConnector(key); + QueryExplorer.getInstance().getModelConnectorMap().put(key, contentModel); + contentModel.loadModel(); + } + } + + return null; + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/PackagePresentationHandler.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/PackagePresentationHandler.java index 43fb0464..bfc55905 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/PackagePresentationHandler.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/PackagePresentationHandler.java @@ -9,18 +9,18 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.handlers; - +package org.eclipse.incquery.tooling.ui.queryexplorer.handlers; + import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.incquery.tooling.ui.queryexplorer.QueryExplorer; - -public class PackagePresentationHandler extends AbstractHandler { - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - QueryExplorer.getInstance().setPackagePresentation(event.getCommand().getId(), true); - return null; - } -} + +public class PackagePresentationHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + QueryExplorer.getInstance().setPackagePresentation(event.getCommand().getId(), true); + return null; + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/PatternRegitryShowLocationHandler.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/PatternRegitryShowLocationHandler.java index 66e4c975..efa58f61 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/PatternRegitryShowLocationHandler.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/PatternRegitryShowLocationHandler.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.handlers; - +package org.eclipse.incquery.tooling.ui.queryexplorer.handlers; + import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.incquery.patternlanguage.patternLanguage.Pattern; @@ -20,28 +20,29 @@ import org.eclipse.jface.viewers.TreeSelection; /** - * Show location handler for the pattern registry extension. + * Show location handler for the pattern registry extension. * - * Note that the default handler (used in the middle viewer) cannot be used as the selection providers for the QueryExplorer view - * should be set according to the focus. However, I could not manage to properly listen on focus change events. + * Note that the default handler (used in the middle viewer) cannot be used as the selection providers for the + * QueryExplorer view should be set according to the focus. However, I could not manage to properly listen on focus + * change events. * * @author Tamas Szabo - * - */ -public class PatternRegitryShowLocationHandler extends ShowLocationHandler { - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - TreeSelection selection = (TreeSelection) QueryExplorer.getInstance().getPatternsViewer().getSelection(); - Object firstElement = selection.getFirstElement(); - - if (firstElement instanceof PatternLeaf) { - String patternFqn = ((PatternLeaf) firstElement).getFullPatternNamePrefix(); - Pattern pattern = PatternRegistry.getInstance().getPatternByFqn(patternFqn); - setSelectionToXTextEditor(pattern); - } - - return null; - } - + * + */ +public class PatternRegitryShowLocationHandler extends ShowLocationHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + TreeSelection selection = (TreeSelection) QueryExplorer.getInstance().getPatternsViewer().getSelection(); + Object firstElement = selection.getFirstElement(); + + if (firstElement instanceof PatternLeaf) { + String patternFqn = ((PatternLeaf) firstElement).getFullPatternNamePrefix(); + Pattern pattern = PatternRegistry.getInstance().getPatternByFqn(patternFqn); + setSelectionToXTextEditor(pattern); + } + + return null; + } + } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/PatternUnregistrationHandler.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/PatternUnregistrationHandler.java index 898d127c..cba27092 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/PatternUnregistrationHandler.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/PatternUnregistrationHandler.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.handlers; - +package org.eclipse.incquery.tooling.ui.queryexplorer.handlers; + import java.util.List; import org.eclipse.core.commands.AbstractHandler; @@ -23,56 +23,56 @@ import org.eclipse.incquery.tooling.ui.queryexplorer.content.patternsviewer.PatternLeaf; import org.eclipse.incquery.tooling.ui.queryexplorer.util.PatternRegistry; import org.eclipse.jface.viewers.TreeSelection; - -/** - * Handler used for pattern unregistration (called from Pattern Registry). - * - * @author Tamas Szabo - * - */ -public class PatternUnregistrationHandler extends AbstractHandler { - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - TreeSelection selection = (TreeSelection) QueryExplorer.getInstance().getPatternsViewer().getSelection(); - - for (Object element : selection.toArray()) { - if (element instanceof PatternLeaf) { - PatternLeaf leaf = (PatternLeaf) element; - unregisterPattern(leaf.getFullPatternNamePrefix()); - } - else { - PatternComposite composite = (PatternComposite) element; - List leaves = composite.getAllLeaves(); - for (PatternLeaf leaf : leaves) { - unregisterPattern(leaf.getFullPatternNamePrefix()); - } - } - } - - QueryExplorer.getInstance().getPatternsViewerInput().getGenericPatternsRoot().purge(); - QueryExplorer.getInstance().getPatternsViewer().refresh(); - return null; - } - - /** - * Unregisters the given pattern both from the QueryExplorer and the Pattern Registry. - * - * @param patternFqn the fully qualified name of the pattern - */ - private void unregisterPattern(String patternFqn) { - Pattern pattern = PatternRegistry.getInstance().getPatternByFqn(patternFqn); - if (!PatternRegistry.getInstance().isGenerated(pattern)) { - PatternRegistry.getInstance().unregisterPattern(pattern); - QueryExplorer.getInstance().getPatternsViewerInput().getGenericPatternsRoot().removeComponent(patternFqn); - - //unregister patterns from observable roots - for (ObservablePatternMatcherRoot root : QueryExplorer.getInstance().getMatcherTreeViewerRoot().getRoots()) { - root.unregisterPattern(pattern); - } - - //the pattern is not active anymore - PatternRegistry.getInstance().removeActivePattern(pattern); - } - } -} + +/** + * Handler used for pattern unregistration (called from Pattern Registry). + * + * @author Tamas Szabo + * + */ +public class PatternUnregistrationHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + TreeSelection selection = (TreeSelection) QueryExplorer.getInstance().getPatternsViewer().getSelection(); + + for (Object element : selection.toArray()) { + if (element instanceof PatternLeaf) { + PatternLeaf leaf = (PatternLeaf) element; + unregisterPattern(leaf.getFullPatternNamePrefix()); + } else { + PatternComposite composite = (PatternComposite) element; + List leaves = composite.getAllLeaves(); + for (PatternLeaf leaf : leaves) { + unregisterPattern(leaf.getFullPatternNamePrefix()); + } + } + } + + QueryExplorer.getInstance().getPatternsViewerInput().getGenericPatternsRoot().purge(); + QueryExplorer.getInstance().getPatternsViewer().refresh(); + return null; + } + + /** + * Unregisters the given pattern both from the QueryExplorer and the Pattern Registry. + * + * @param patternFqn + * the fully qualified name of the pattern + */ + private void unregisterPattern(String patternFqn) { + Pattern pattern = PatternRegistry.getInstance().getPatternByFqn(patternFqn); + if (!PatternRegistry.getInstance().isGenerated(pattern)) { + PatternRegistry.getInstance().unregisterPattern(pattern); + QueryExplorer.getInstance().getPatternsViewerInput().getGenericPatternsRoot().removeComponent(patternFqn); + + // unregister patterns from observable roots + for (ObservablePatternMatcherRoot root : QueryExplorer.getInstance().getMatcherTreeViewerRoot().getRoots()) { + root.unregisterPattern(pattern); + } + + // the pattern is not active anymore + PatternRegistry.getInstance().removeActivePattern(pattern); + } + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/ResetUIHandler.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/ResetUIHandler.java index f197e59a..efa24769 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/ResetUIHandler.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/ResetUIHandler.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.handlers; - +package org.eclipse.incquery.tooling.ui.queryexplorer.handlers; + import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; @@ -20,27 +20,27 @@ import org.eclipse.incquery.tooling.ui.queryexplorer.handlers.util.ModelConnector; import org.eclipse.incquery.tooling.ui.queryexplorer.util.PatternRegistry; -public class ResetUIHandler extends AbstractHandler { - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - QueryExplorer explorer = QueryExplorer.getInstance(); - - if (explorer != null) { - for (ModelConnector connector : explorer.getModelConnectorMap().values()) { - connector.unloadModel(); - } - for (Pattern pattern : PatternRegistry.getInstance().getActivePatterns()) { - String patternFqn = CorePatternLanguageHelper.getFullyQualifiedName(pattern); - PatternRegistry.getInstance().unregisterPattern(pattern); - PatternRegistry.getInstance().removeActivePattern(pattern); - explorer.getPatternsViewerInput().getGenericPatternsRoot().removeComponent(patternFqn); - } - - //refresh selection - explorer.getPatternsViewerInput().getGenericPatternsRoot().updateSelection(explorer.getPatternsViewer()); - explorer.getPatternsViewer().refresh(); - } - return null; - } -} +public class ResetUIHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + QueryExplorer explorer = QueryExplorer.getInstance(); + + if (explorer != null) { + for (ModelConnector connector : explorer.getModelConnectorMap().values()) { + connector.unloadModel(); + } + for (Pattern pattern : PatternRegistry.getInstance().getActivePatterns()) { + String patternFqn = CorePatternLanguageHelper.getFullyQualifiedName(pattern); + PatternRegistry.getInstance().unregisterPattern(pattern); + PatternRegistry.getInstance().removeActivePattern(pattern); + explorer.getPatternsViewerInput().getGenericPatternsRoot().removeComponent(patternFqn); + } + + // refresh selection + explorer.getPatternsViewerInput().getGenericPatternsRoot().updateSelection(explorer.getPatternsViewer()); + explorer.getPatternsViewer().refresh(); + } + return null; + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/RuntimeMatcherRegistrationHandler.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/RuntimeMatcherRegistrationHandler.java index 7d9d7813..cfe7cdc6 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/RuntimeMatcherRegistrationHandler.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/RuntimeMatcherRegistrationHandler.java @@ -9,55 +9,54 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.resources.IFile; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.handlers.HandlerUtil; -import org.eclipse.ui.part.FileEditorInput; -import org.eclipse.xtext.xbase.ui.editor.XbaseEditor; - -import com.google.inject.Inject; -import com.google.inject.Injector; - -@SuppressWarnings("restriction") -public class RuntimeMatcherRegistrationHandler extends AbstractHandler { - - @Inject - Injector injector; - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - IFile file = null; - ISelection selection = HandlerUtil.getCurrentSelection(event); - - if (selection != null && selection instanceof IStructuredSelection) { - Object firstElement = ((IStructuredSelection) selection).getFirstElement(); - if (firstElement != null && firstElement instanceof IFile) { - file = (IFile) firstElement; - } - } - else { - IEditorPart editor = HandlerUtil.getActiveEditor(event); - if (editor instanceof XbaseEditor) { - FileEditorInput input = (FileEditorInput) HandlerUtil.getActiveEditorInput(event); - file = input.getFile(); - } - } - - if (file != null) { - RuntimeMatcherRegistrator registrator = new RuntimeMatcherRegistrator(file); - injector.injectMembers(registrator); - Display.getDefault().asyncExec(registrator); - } - - return null; - } - -} +package org.eclipse.incquery.tooling.ui.queryexplorer.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.resources.IFile; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.part.FileEditorInput; +import org.eclipse.xtext.xbase.ui.editor.XbaseEditor; + +import com.google.inject.Inject; +import com.google.inject.Injector; + +@SuppressWarnings("restriction") +public class RuntimeMatcherRegistrationHandler extends AbstractHandler { + + @Inject + Injector injector; + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + IFile file = null; + ISelection selection = HandlerUtil.getCurrentSelection(event); + + if (selection != null && selection instanceof IStructuredSelection) { + Object firstElement = ((IStructuredSelection) selection).getFirstElement(); + if (firstElement != null && firstElement instanceof IFile) { + file = (IFile) firstElement; + } + } else { + IEditorPart editor = HandlerUtil.getActiveEditor(event); + if (editor instanceof XbaseEditor) { + FileEditorInput input = (FileEditorInput) HandlerUtil.getActiveEditorInput(event); + file = input.getFile(); + } + } + + if (file != null) { + RuntimeMatcherRegistrator registrator = new RuntimeMatcherRegistrator(file); + injector.injectMembers(registrator); + Display.getDefault().asyncExec(registrator); + } + + return null; + } + +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/RuntimeMatcherRegistrator.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/RuntimeMatcherRegistrator.java index a281ee1a..2e4c107e 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/RuntimeMatcherRegistrator.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/RuntimeMatcherRegistrator.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.handlers; - +package org.eclipse.incquery.tooling.ui.queryexplorer.handlers; + import java.util.ArrayList; import java.util.List; @@ -30,101 +30,102 @@ import org.eclipse.incquery.tooling.ui.queryexplorer.util.PatternRegistry; import com.google.inject.Inject; - -/** - * Runnable unit of registering patterns in given file. - * - * Note that if the work is implemented as a job, - * NullPointerException will occur when creating observables as the default realm will be null - * (because of non-ui thread). - * - * @author Tamas Szabo - * - */ -public class RuntimeMatcherRegistrator implements Runnable { - - private final IFile file; - - @Inject - DatabindingUtil dbUtil; - - public RuntimeMatcherRegistrator(IFile file) { - this.file = file; - } - - @Override - public void run() { - QueryExplorer queryExplorerInstance = QueryExplorer.getInstance(); - if (queryExplorerInstance != null) { - MatcherTreeViewerRoot vr = queryExplorerInstance.getMatcherTreeViewerRoot(); - PatternComposite viewerInput = queryExplorerInstance.getPatternsViewerInput().getGenericPatternsRoot(); - List oldParsedModel = PatternRegistry.getInstance().getRegisteredPatternsForFile(file); - PatternModel newParsedModel = dbUtil.parseEPM(file); - - //if no patterns were registered before, open the patterns viewer - if (PatternRegistry.getInstance().isEmpty()) { - FlyoutControlComposite flyout = queryExplorerInstance.getPatternsViewerFlyout(); - flyout.getPreferences().setState(IFlyoutPreferences.STATE_OPEN); - //redraw(); - flyout.layout(); - } - - //UNREGISTERING PATTERNS - - List allActivePatterns = PatternRegistry.getInstance().getActivePatterns(); - //deactivate patterns within the given file - PatternRegistry.getInstance().unregisterPatternModel(file); - - //unregister all active patterns from the roots and wipe the appropriate iq engine - for (ObservablePatternMatcherRoot root : vr.getRoots()) { - for (Pattern pattern : allActivePatterns) { - root.unregisterPattern(pattern); - } - //final IncQueryEngine engine = EngineManager.getInstance().getIncQueryEngineIfExists(root.getNotifier()); - final IncQueryEngine engine = root.getKey().getEngine(); - if (engine!=null) { - engine.wipe(); - } - } - - //remove labels from pattern registry for the corresponding pattern model - if (oldParsedModel != null) { - for (Pattern pattern : oldParsedModel) { - viewerInput.removeComponent(CorePatternLanguageHelper.getFullyQualifiedName(pattern)); - } - } - - queryExplorerInstance.getPatternsViewerInput().getGenericPatternsRoot().purge(); - queryExplorerInstance.getPatternsViewer().refresh(); - - //REGISTERING PATTERNS - - //registering patterns from file - List newPatterns = PatternRegistry.getInstance().registerPatternModel(file, newParsedModel); - allActivePatterns = PatternRegistry.getInstance().getActivePatterns(); - - //now the active patterns also contain of the new patterns - for (ObservablePatternMatcherRoot root : vr.getRoots()) { - root.registerPattern(allActivePatterns.toArray(new Pattern[allActivePatterns.size()])); - } - - //setting check states - List components = new ArrayList(); - for (Pattern pattern : newPatterns) { - PatternComponent component = viewerInput.addComponent(CorePatternLanguageHelper.getFullyQualifiedName(pattern)); - components.add(component); - } - //note that after insertion a refresh is necessary otherwise setting check state will not work - queryExplorerInstance.getPatternsViewer().refresh(); - - for (PatternComponent component : components) { - queryExplorerInstance.getPatternsViewer().setChecked(component, true); - } - - //it is enough to just call selection propagation for one pattern - if (components.size() > 0) { - components.get(0).getParent().propagateSelectionToTop(components.get(0)); - } - } - } -} + +/** + * Runnable unit of registering patterns in given file. + * + * Note that if the work is implemented as a job, NullPointerException will occur when creating observables as the + * default realm will be null (because of non-ui thread). + * + * @author Tamas Szabo + * + */ +public class RuntimeMatcherRegistrator implements Runnable { + + private final IFile file; + + @Inject + DatabindingUtil dbUtil; + + public RuntimeMatcherRegistrator(IFile file) { + this.file = file; + } + + @Override + public void run() { + QueryExplorer queryExplorerInstance = QueryExplorer.getInstance(); + if (queryExplorerInstance != null) { + MatcherTreeViewerRoot vr = queryExplorerInstance.getMatcherTreeViewerRoot(); + PatternComposite viewerInput = queryExplorerInstance.getPatternsViewerInput().getGenericPatternsRoot(); + List oldParsedModel = PatternRegistry.getInstance().getRegisteredPatternsForFile(file); + PatternModel newParsedModel = dbUtil.parseEPM(file); + + // if no patterns were registered before, open the patterns viewer + if (PatternRegistry.getInstance().isEmpty()) { + FlyoutControlComposite flyout = queryExplorerInstance.getPatternsViewerFlyout(); + flyout.getPreferences().setState(IFlyoutPreferences.STATE_OPEN); + // redraw(); + flyout.layout(); + } + + // UNREGISTERING PATTERNS + + List allActivePatterns = PatternRegistry.getInstance().getActivePatterns(); + // deactivate patterns within the given file + PatternRegistry.getInstance().unregisterPatternModel(file); + + // unregister all active patterns from the roots and wipe the appropriate iq engine + for (ObservablePatternMatcherRoot root : vr.getRoots()) { + for (Pattern pattern : allActivePatterns) { + root.unregisterPattern(pattern); + } + // final IncQueryEngine engine = + // EngineManager.getInstance().getIncQueryEngineIfExists(root.getNotifier()); + final IncQueryEngine engine = root.getKey().getEngine(); + if (engine != null) { + engine.wipe(); + } + } + + // remove labels from pattern registry for the corresponding pattern model + if (oldParsedModel != null) { + for (Pattern pattern : oldParsedModel) { + viewerInput.removeComponent(CorePatternLanguageHelper.getFullyQualifiedName(pattern)); + } + } + + queryExplorerInstance.getPatternsViewerInput().getGenericPatternsRoot().purge(); + queryExplorerInstance.getPatternsViewer().refresh(); + + // REGISTERING PATTERNS + + // registering patterns from file + List newPatterns = PatternRegistry.getInstance().registerPatternModel(file, newParsedModel); + allActivePatterns = PatternRegistry.getInstance().getActivePatterns(); + + // now the active patterns also contain of the new patterns + for (ObservablePatternMatcherRoot root : vr.getRoots()) { + root.registerPattern(allActivePatterns.toArray(new Pattern[allActivePatterns.size()])); + } + + // setting check states + List components = new ArrayList(); + for (Pattern pattern : newPatterns) { + PatternComponent component = viewerInput.addComponent(CorePatternLanguageHelper + .getFullyQualifiedName(pattern)); + components.add(component); + } + // note that after insertion a refresh is necessary otherwise setting check state will not work + queryExplorerInstance.getPatternsViewer().refresh(); + + for (PatternComponent component : components) { + queryExplorerInstance.getPatternsViewer().setChecked(component, true); + } + + // it is enough to just call selection propagation for one pattern + if (components.size() > 0) { + components.get(0).getParent().propagateSelectionToTop(components.get(0)); + } + } + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/RuntimeMatcherUnRegistrator.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/RuntimeMatcherUnRegistrator.java index c8916003..dae9843f 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/RuntimeMatcherUnRegistrator.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/RuntimeMatcherUnRegistrator.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.handlers; - +package org.eclipse.incquery.tooling.ui.queryexplorer.handlers; + import java.util.List; import org.eclipse.core.resources.IFile; @@ -20,27 +20,28 @@ import org.eclipse.incquery.tooling.ui.queryexplorer.content.matcher.MatcherTreeViewerRoot; import org.eclipse.incquery.tooling.ui.queryexplorer.content.matcher.ObservablePatternMatcherRoot; import org.eclipse.incquery.tooling.ui.queryexplorer.util.PatternRegistry; - -public class RuntimeMatcherUnRegistrator implements Runnable { - - private final IFile file; - - public RuntimeMatcherUnRegistrator(IFile file) { - this.file = file; - } - - @Override - public void run() { - MatcherTreeViewerRoot vr = QueryExplorer.getInstance().getMatcherTreeViewerRoot(); - List removedPatterns = PatternRegistry.getInstance().unregisterPatternModel(file); - for (Pattern pattern : removedPatterns) { - for (ObservablePatternMatcherRoot root : vr.getRoots()) { - root.unregisterPattern(pattern); - } - QueryExplorer.getInstance().getPatternsViewerInput().getGenericPatternsRoot().removeComponent(CorePatternLanguageHelper.getFullyQualifiedName(pattern)); - } - - QueryExplorer.getInstance().getPatternsViewer().refresh(); - } - + +public class RuntimeMatcherUnRegistrator implements Runnable { + + private final IFile file; + + public RuntimeMatcherUnRegistrator(IFile file) { + this.file = file; + } + + @Override + public void run() { + MatcherTreeViewerRoot vr = QueryExplorer.getInstance().getMatcherTreeViewerRoot(); + List removedPatterns = PatternRegistry.getInstance().unregisterPatternModel(file); + for (Pattern pattern : removedPatterns) { + for (ObservablePatternMatcherRoot root : vr.getRoots()) { + root.unregisterPattern(pattern); + } + QueryExplorer.getInstance().getPatternsViewerInput().getGenericPatternsRoot() + .removeComponent(CorePatternLanguageHelper.getFullyQualifiedName(pattern)); + } + + QueryExplorer.getInstance().getPatternsViewer().refresh(); + } + } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/ShowLocationHandler.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/ShowLocationHandler.java index e2c74c8d..d3699814 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/ShowLocationHandler.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/ShowLocationHandler.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.handlers; - +package org.eclipse.incquery.tooling.ui.queryexplorer.handlers; + import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; @@ -35,59 +35,60 @@ import org.eclipse.xtext.util.ITextRegion; import com.google.inject.Inject; - -public class ShowLocationHandler extends AbstractHandler { - - @Inject - private ILocationInFileProvider locationProvider; - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - IStructuredSelection selection = (IStructuredSelection) HandlerUtil.getCurrentSelection(event); - if (selection instanceof TreeSelection) { - Object obj = selection.getFirstElement(); - - if (obj instanceof ObservablePatternMatch) { - ObservablePatternMatch pm = (ObservablePatternMatch) obj; - MatcherTreeViewerRootKey key = pm.getParent().getParent().getKey(); - QueryExplorer.getInstance().getModelConnectorMap().get(key).showLocation(pm.getLocationObjects()); - } - else if (obj instanceof ObservablePatternMatcher) { - ObservablePatternMatcher matcher = (ObservablePatternMatcher) obj; - if (matcher.getMatcher() != null) { - setSelectionToXTextEditor(matcher.getMatcher().getPattern()); - } - } - } - return null; - } - - protected void setSelectionToXTextEditor(Pattern pattern) { - IFile file = PatternRegistry.getInstance().getFileForPattern(pattern); - for (IEditorReference ref : PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getEditorReferences()) { - String id = ref.getId(); - IEditorPart editor = ref.getEditor(true); +public class ShowLocationHandler extends AbstractHandler { + + @Inject + private ILocationInFileProvider locationProvider; + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + IStructuredSelection selection = (IStructuredSelection) HandlerUtil.getCurrentSelection(event); + if (selection instanceof TreeSelection) { + Object obj = selection.getFirstElement(); + + if (obj instanceof ObservablePatternMatch) { + ObservablePatternMatch pm = (ObservablePatternMatch) obj; + MatcherTreeViewerRootKey key = pm.getParent().getParent().getKey(); + QueryExplorer.getInstance().getModelConnectorMap().get(key).showLocation(pm.getLocationObjects()); + } else if (obj instanceof ObservablePatternMatcher) { + ObservablePatternMatcher matcher = (ObservablePatternMatcher) obj; + if (matcher.getMatcher() != null) { + setSelectionToXTextEditor(matcher.getMatcher().getPattern()); + } + } + } + return null; + } + + protected void setSelectionToXTextEditor(Pattern pattern) { + IFile file = PatternRegistry.getInstance().getFileForPattern(pattern); + + for (IEditorReference ref : PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() + .getEditorReferences()) { + String id = ref.getId(); + IEditorPart editor = ref.getEditor(true); if (id.equals("org.eclipse.incquery.patternlanguage.emf.EMFPatternLanguage")) { - //The editor id always registers an Xtext editor - assert editor instanceof XtextEditor; - XtextEditor providerEditor = (XtextEditor) editor; - // Bringing editor to top - IEditorInput input = providerEditor.getEditorInput(); - if (input instanceof FileEditorInput) { - FileEditorInput editorInput = (FileEditorInput) input; - if (editorInput.getFile().equals(file)) { - editor.getSite().getPage().bringToTop(editor); - } - } - // Finding location using location service - ITextRegion location = locationProvider.getSignificantTextRegion(pattern); - //Location can be null in case of error - if (location != null) { - providerEditor.reveal(location.getOffset(),location.getLength()); - providerEditor.getSelectionProvider().setSelection(new TextSelection(location.getOffset(), location.getLength())); - } - } - } - } + // The editor id always registers an Xtext editor + assert editor instanceof XtextEditor; + XtextEditor providerEditor = (XtextEditor) editor; + // Bringing editor to top + IEditorInput input = providerEditor.getEditorInput(); + if (input instanceof FileEditorInput) { + FileEditorInput editorInput = (FileEditorInput) input; + if (editorInput.getFile().equals(file)) { + editor.getSite().getPage().bringToTop(editor); + } + } + // Finding location using location service + ITextRegion location = locationProvider.getSignificantTextRegion(pattern); + // Location can be null in case of error + if (location != null) { + providerEditor.reveal(location.getOffset(), location.getLength()); + providerEditor.getSelectionProvider().setSelection( + new TextSelection(location.getOffset(), location.getLength())); + } + } + } + } } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/UnloadModelHandler.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/UnloadModelHandler.java index 089a1d88..48a29c9c 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/UnloadModelHandler.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/UnloadModelHandler.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.handlers; - +package org.eclipse.incquery.tooling.ui.queryexplorer.handlers; + import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; @@ -19,19 +19,20 @@ import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.TreeSelection; import org.eclipse.ui.handlers.HandlerUtil; - + public class UnloadModelHandler extends AbstractHandler { - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - - ISelection selection = HandlerUtil.getActiveMenuSelection(event); - if (selection instanceof TreeSelection) { - ObservablePatternMatcherRoot root = (ObservablePatternMatcherRoot) ((TreeSelection) selection).getFirstElement(); - QueryExplorer.getInstance().getModelConnectorMap().get(root.getKey()).unloadModel(); - } - - QueryExplorer.getInstance().clearTableViewer(); - return null; - } -} + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + ISelection selection = HandlerUtil.getActiveMenuSelection(event); + if (selection instanceof TreeSelection) { + ObservablePatternMatcherRoot root = (ObservablePatternMatcherRoot) ((TreeSelection) selection) + .getFirstElement(); + QueryExplorer.getInstance().getModelConnectorMap().get(root.getKey()).unloadModel(); + } + + QueryExplorer.getInstance().clearTableViewer(); + return null; + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/util/EMFModelConnector.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/util/EMFModelConnector.java index ef0edff1..8535870b 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/util/EMFModelConnector.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/util/EMFModelConnector.java @@ -30,81 +30,80 @@ import org.eclipse.ui.IEditorPart; public class EMFModelConnector extends ModelConnector { - - public EMFModelConnector(MatcherTreeViewerRootKey key) { - super(key); - } - @Override - public void loadModel() { - workbenchPage.addPartListener(ModelEditorPartListener.getInstance()); - if (QueryExplorer.getInstance() != null) { - QueryExplorer.getInstance().getMatcherTreeViewerRoot().addPatternMatcherRoot(key); - } - } + public EMFModelConnector(MatcherTreeViewerRootKey key) { + super(key); + } - @Override - public void unloadModel() { - workbenchPage.removePartListener(ModelEditorPartListener.getInstance()); - if (QueryExplorer.getInstance() != null) { - QueryExplorer.getInstance().getMatcherTreeViewerRoot().removePatternMatcherRoot(key); - } - } + @Override + public void loadModel() { + workbenchPage.addPartListener(ModelEditorPartListener.getInstance()); + if (QueryExplorer.getInstance() != null) { + QueryExplorer.getInstance().getMatcherTreeViewerRoot().addPatternMatcherRoot(key); + } + } - @Override - public void showLocation(Object[] locationObjects) { - IStructuredSelection preparedSelection = prepareSelection(locationObjects); - navigateToElements(key.getEditorPart(), preparedSelection); - workbenchPage.bringToTop(key.getEditorPart()); - reflectiveSetSelection(key.getEditorPart(), preparedSelection); - } - - private void reflectiveSetSelection(IEditorPart editorPart, IStructuredSelection preparedSelection) { - try { - Method m = editorPart.getClass().getMethod("setSelectionToViewer", Collection.class); - m.invoke(editorPart, preparedSelection.toList()); - } - catch (NoSuchMethodException e) { - logger.log(new Status(IStatus.ERROR, IncQueryGUIPlugin.PLUGIN_ID, "setSelectionToViewer method not found", e)); - } - catch (Exception e) { - logger.log(new Status(IStatus.ERROR, IncQueryGUIPlugin.PLUGIN_ID, "setSelectionToViewer call failed", e)); - } - } - - protected TreeSelection prepareSelection(Object[] locationObjects) { - List paths = new ArrayList(); - for (Object o: locationObjects) { - if(o instanceof EObject) { - TreePath path = createTreePath(key.getEditorPart(), (EObject) o); - if(path != null) { - paths.add(path); - } - } - } + @Override + public void unloadModel() { + workbenchPage.removePartListener(ModelEditorPartListener.getInstance()); + if (QueryExplorer.getInstance() != null) { + QueryExplorer.getInstance().getMatcherTreeViewerRoot().removePatternMatcherRoot(key); + } + } - if(paths.size() > 0) { - return new TreeSelection(paths.toArray(new TreePath[1])); - } - return new TreeSelection(); - } - - protected void navigateToElements(IEditorPart editorPart, IStructuredSelection selection) { - ISelectionProvider selectionProvider = editorPart.getEditorSite().getSelectionProvider(); - selectionProvider.setSelection(selection); - } - - protected TreePath createTreePath(IEditorPart editorPart, EObject obj) { - List nodes = new LinkedList(); - nodes.add(obj); - EObject tmp = obj.eContainer(); - - while (tmp != null) { - nodes.add(0, tmp); - tmp = tmp.eContainer(); - } - - return new TreePath(nodes.toArray()); - } + @Override + public void showLocation(Object[] locationObjects) { + IStructuredSelection preparedSelection = prepareSelection(locationObjects); + navigateToElements(key.getEditorPart(), preparedSelection); + workbenchPage.bringToTop(key.getEditorPart()); + reflectiveSetSelection(key.getEditorPart(), preparedSelection); + } + + private void reflectiveSetSelection(IEditorPart editorPart, IStructuredSelection preparedSelection) { + try { + Method m = editorPart.getClass().getMethod("setSelectionToViewer", Collection.class); + m.invoke(editorPart, preparedSelection.toList()); + } catch (NoSuchMethodException e) { + logger.log(new Status(IStatus.ERROR, IncQueryGUIPlugin.PLUGIN_ID, "setSelectionToViewer method not found", + e)); + } catch (Exception e) { + logger.log(new Status(IStatus.ERROR, IncQueryGUIPlugin.PLUGIN_ID, "setSelectionToViewer call failed", e)); + } + } + + protected TreeSelection prepareSelection(Object[] locationObjects) { + List paths = new ArrayList(); + for (Object o : locationObjects) { + if (o instanceof EObject) { + TreePath path = createTreePath(key.getEditorPart(), (EObject) o); + if (path != null) { + paths.add(path); + } + } + } + + if (paths.size() > 0) { + return new TreeSelection(paths.toArray(new TreePath[1])); + } + return new TreeSelection(); + } + + protected void navigateToElements(IEditorPart editorPart, IStructuredSelection selection) { + ISelectionProvider selectionProvider = editorPart.getEditorSite().getSelectionProvider(); + selectionProvider.setSelection(selection); + } + + protected TreePath createTreePath(IEditorPart editorPart, EObject obj) { + List nodes = new LinkedList(); + nodes.add(obj); + EObject tmp = obj.eContainer(); + + while (tmp != null) { + nodes.add(0, tmp); + tmp = tmp.eContainer(); + } + + return new TreePath(nodes.toArray()); + } } diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/util/ModelConnector.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/util/ModelConnector.java index 01e4f7ec..f8b929b9 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/util/ModelConnector.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/handlers/util/ModelConnector.java @@ -19,38 +19,39 @@ /** * - * The class represents an instance model registered in the Query Explorer along with its source {@link IEditorPart}. - * Subclasses of this class must implement the editor specific handling of load/unload/showLocation actions. + * The class represents an instance model registered in the Query Explorer along with its source {@link IEditorPart}. + * Subclasses of this class must implement the editor specific handling of load/unload/showLocation actions. * * @author Tamas Szabo */ public abstract class ModelConnector { - protected MatcherTreeViewerRootKey key; - protected IWorkbenchPage workbenchPage; - protected ILog logger = IncQueryGUIPlugin.getDefault().getLog(); - - public ModelConnector(MatcherTreeViewerRootKey key) { - this.key = key; - this.logger = IncQueryGUIPlugin.getDefault().getLog(); - this.workbenchPage = key.getEditorPart().getSite().getPage(); - } - - /** - * Loads the instance model into the {@link QueryExplorer} - */ - public abstract void loadModel(); - - /** - * Unloads the instance model from the {@link QueryExplorer} - */ - public abstract void unloadModel(); - - /** - * Shows the location of the given objects inside the specific editor - * - * @param locationObjects the objects whose location will be shown - */ - public abstract void showLocation(Object[] locationObjects); - + protected MatcherTreeViewerRootKey key; + protected IWorkbenchPage workbenchPage; + protected ILog logger = IncQueryGUIPlugin.getDefault().getLog(); + + public ModelConnector(MatcherTreeViewerRootKey key) { + this.key = key; + this.logger = IncQueryGUIPlugin.getDefault().getLog(); + this.workbenchPage = key.getEditorPart().getSite().getPage(); + } + + /** + * Loads the instance model into the {@link QueryExplorer} + */ + public abstract void loadModel(); + + /** + * Unloads the instance model from the {@link QueryExplorer} + */ + public abstract void unloadModel(); + + /** + * Shows the location of the given objects inside the specific editor + * + * @param locationObjects + * the objects whose location will be shown + */ + public abstract void showLocation(Object[] locationObjects); + } diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/preference/PatternInitializationPreferencePage.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/preference/PatternInitializationPreferencePage.java index 0f625095..f2a1d931 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/preference/PatternInitializationPreferencePage.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/preference/PatternInitializationPreferencePage.java @@ -9,62 +9,61 @@ * Tamas Szabo, Zoltan Ujhelyi - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.preference; - +package org.eclipse.incquery.tooling.ui.queryexplorer.preference; + import org.eclipse.incquery.tooling.ui.IncQueryGUIPlugin; -import org.eclipse.jface.preference.BooleanFieldEditor; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.preference.PreferencePage; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPreferencePage; - -public class PatternInitializationPreferencePage extends PreferencePage - implements IWorkbenchPreferencePage { - - private static final String WILDCARD_MODE_DESCRIPTION = - "&In wildcard mode, every aspect of the EMF model is automatically indexed, " + - "as opposed to only indexing model elements and features relevant to the " + - "currently registered patterns; thus patterns can be registered and " + - "unregistered without re-traversing the model. This is typically useful " + - "during query development. Turn off wildcard mode to decrease the memory " + - "usage while working with very large models."; - - @Override - public void init(IWorkbench workbench) { - - } - - @Override - protected Control createContents(Composite parent) { - final IPreferenceStore store = IncQueryGUIPlugin.getDefault().getPreferenceStore(); - Composite control = new Composite(parent, SWT.NONE); - Label wildcardDescriptionLabel = new Label(control, SWT.NONE | SWT.WRAP); - wildcardDescriptionLabel.setText(WILDCARD_MODE_DESCRIPTION); - final GridData layoutData = new GridData(GridData.FILL_HORIZONTAL) ; - layoutData.grabExcessHorizontalSpace = true; - layoutData.horizontalAlignment = SWT.FILL; - layoutData.widthHint = 200; - wildcardDescriptionLabel.setLayoutData(layoutData); - final BooleanFieldEditor wildcardModeEditor = new BooleanFieldEditor(PreferenceConstants.WILDCARD_MODE, "&Wildcard mode", control); - wildcardModeEditor.setPreferenceStore(IncQueryGUIPlugin.getDefault().getPreferenceStore()); - wildcardModeEditor.load(); - wildcardModeEditor.setPropertyChangeListener(new IPropertyChangeListener() { - - @SuppressWarnings("deprecation") - @Override - public void propertyChange(PropertyChangeEvent event) { - store.setValue(PreferenceConstants.WILDCARD_MODE, wildcardModeEditor.getBooleanValue()); - //the mentioned replace method did not work for me - IncQueryGUIPlugin.getDefault().savePluginPreferences(); - } - }); - return control; - } -} +import org.eclipse.jface.preference.BooleanFieldEditor; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; + +public class PatternInitializationPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { + + private static final String WILDCARD_MODE_DESCRIPTION = "&In wildcard mode, every aspect of the EMF model is automatically indexed, " + + "as opposed to only indexing model elements and features relevant to the " + + "currently registered patterns; thus patterns can be registered and " + + "unregistered without re-traversing the model. This is typically useful " + + "during query development. Turn off wildcard mode to decrease the memory " + + "usage while working with very large models."; + + @Override + public void init(IWorkbench workbench) { + + } + + @Override + protected Control createContents(Composite parent) { + final IPreferenceStore store = IncQueryGUIPlugin.getDefault().getPreferenceStore(); + Composite control = new Composite(parent, SWT.NONE); + Label wildcardDescriptionLabel = new Label(control, SWT.NONE | SWT.WRAP); + wildcardDescriptionLabel.setText(WILDCARD_MODE_DESCRIPTION); + final GridData layoutData = new GridData(GridData.FILL_HORIZONTAL); + layoutData.grabExcessHorizontalSpace = true; + layoutData.horizontalAlignment = SWT.FILL; + layoutData.widthHint = 200; + wildcardDescriptionLabel.setLayoutData(layoutData); + final BooleanFieldEditor wildcardModeEditor = new BooleanFieldEditor(PreferenceConstants.WILDCARD_MODE, + "&Wildcard mode", control); + wildcardModeEditor.setPreferenceStore(IncQueryGUIPlugin.getDefault().getPreferenceStore()); + wildcardModeEditor.load(); + wildcardModeEditor.setPropertyChangeListener(new IPropertyChangeListener() { + + @SuppressWarnings("deprecation") + @Override + public void propertyChange(PropertyChangeEvent event) { + store.setValue(PreferenceConstants.WILDCARD_MODE, wildcardModeEditor.getBooleanValue()); + // the mentioned replace method did not work for me + IncQueryGUIPlugin.getDefault().savePluginPreferences(); + } + }); + return control; + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/preference/PreferenceConstants.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/preference/PreferenceConstants.java index 961fe5d9..b89e464d 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/preference/PreferenceConstants.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/preference/PreferenceConstants.java @@ -9,10 +9,10 @@ * Tamas Szabo, Zoltan Ujhelyi - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.preference; - -public class PreferenceConstants { - - public static final String WILDCARD_MODE = "org.eclipse.incquery.tooling.gui.queryexplorer.WildcardMode"; - -} +package org.eclipse.incquery.tooling.ui.queryexplorer.preference; + +public class PreferenceConstants { + + public static final String WILDCARD_MODE = "org.eclipse.incquery.tooling.gui.queryexplorer.WildcardMode"; + +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/CheckStateListener.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/CheckStateListener.java index fb35a6b8..f50a16b3 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/CheckStateListener.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/CheckStateListener.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.util; - +package org.eclipse.incquery.tooling.ui.queryexplorer.util; + import org.eclipse.incquery.patternlanguage.patternLanguage.Pattern; import org.eclipse.incquery.tooling.ui.queryexplorer.QueryExplorer; import org.eclipse.incquery.tooling.ui.queryexplorer.content.matcher.ObservablePatternMatcherRoot; @@ -19,67 +19,65 @@ import org.eclipse.incquery.tooling.ui.queryexplorer.content.patternsviewer.PatternLeaf; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.ICheckStateListener; - -public class CheckStateListener implements ICheckStateListener { - - @Override - public void checkStateChanged(CheckStateChangedEvent event) { - Object element = event.getElement(); - - if (element instanceof PatternLeaf) { - processLeaf((PatternLeaf) element, event); - } - else if (element instanceof PatternComposite){ - processComposite((PatternComposite) element, event); - } - - if (event.getChecked()) { - PatternComponent component = (PatternComponent) element; - if (component.getParent() != null) { - component.getParent().propagateSelectionToTop(component); - } - } - else { - PatternComposite composite = (element instanceof PatternLeaf) ? ((PatternLeaf) element).getParent() : (PatternComposite) element; - composite.propagateDeSelectionToTop(); - } - } - - private void processComposite(PatternComposite composite, CheckStateChangedEvent event) { - for (PatternLeaf leaf : composite.getAllLeaves()) { - processLeaf(leaf, event); - } - - if (event.getChecked()) { - composite.setSelected(true); - for (PatternComponent component : composite.getAllChildren()) { - QueryExplorer.getInstance().getPatternsViewer().setChecked(component, true); - } - } - else { - composite.setSelected(false); - for (PatternComponent component : composite.getAllChildren()) { - QueryExplorer.getInstance().getPatternsViewer().setChecked(component, false); - } - } - } - - private void processLeaf(PatternLeaf leaf, CheckStateChangedEvent event) { - String patternFqn = leaf.getFullPatternNamePrefix(); - Pattern pattern = PatternRegistry.getInstance().getPatternByFqn(patternFqn); - - if (event.getChecked() && !PatternRegistry.getInstance().isActive(patternFqn)) { - leaf.setSelected(true); - for (ObservablePatternMatcherRoot root : QueryExplorer.getInstance().getMatcherTreeViewerRoot().getRoots()) { - root.registerPattern(pattern); - } - PatternRegistry.getInstance().addActivePattern(pattern); - } else if (!event.getChecked()) { - leaf.setSelected(false); - for (ObservablePatternMatcherRoot root : QueryExplorer.getInstance().getMatcherTreeViewerRoot().getRoots()) { - root.unregisterPattern(pattern); - } - PatternRegistry.getInstance().removeActivePattern(pattern); - } - } -} + +public class CheckStateListener implements ICheckStateListener { + + @Override + public void checkStateChanged(CheckStateChangedEvent event) { + Object element = event.getElement(); + + if (element instanceof PatternLeaf) { + processLeaf((PatternLeaf) element, event); + } else if (element instanceof PatternComposite) { + processComposite((PatternComposite) element, event); + } + + if (event.getChecked()) { + PatternComponent component = (PatternComponent) element; + if (component.getParent() != null) { + component.getParent().propagateSelectionToTop(component); + } + } else { + PatternComposite composite = (element instanceof PatternLeaf) ? ((PatternLeaf) element).getParent() + : (PatternComposite) element; + composite.propagateDeSelectionToTop(); + } + } + + private void processComposite(PatternComposite composite, CheckStateChangedEvent event) { + for (PatternLeaf leaf : composite.getAllLeaves()) { + processLeaf(leaf, event); + } + + if (event.getChecked()) { + composite.setSelected(true); + for (PatternComponent component : composite.getAllChildren()) { + QueryExplorer.getInstance().getPatternsViewer().setChecked(component, true); + } + } else { + composite.setSelected(false); + for (PatternComponent component : composite.getAllChildren()) { + QueryExplorer.getInstance().getPatternsViewer().setChecked(component, false); + } + } + } + + private void processLeaf(PatternLeaf leaf, CheckStateChangedEvent event) { + String patternFqn = leaf.getFullPatternNamePrefix(); + Pattern pattern = PatternRegistry.getInstance().getPatternByFqn(patternFqn); + + if (event.getChecked() && !PatternRegistry.getInstance().isActive(patternFqn)) { + leaf.setSelected(true); + for (ObservablePatternMatcherRoot root : QueryExplorer.getInstance().getMatcherTreeViewerRoot().getRoots()) { + root.registerPattern(pattern); + } + PatternRegistry.getInstance().addActivePattern(pattern); + } else if (!event.getChecked()) { + leaf.setSelected(false); + for (ObservablePatternMatcherRoot root : QueryExplorer.getInstance().getMatcherTreeViewerRoot().getRoots()) { + root.unregisterPattern(pattern); + } + PatternRegistry.getInstance().removeActivePattern(pattern); + } + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/CommandConstants.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/CommandConstants.java index 204a3588..c5eeb32e 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/CommandConstants.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/CommandConstants.java @@ -12,10 +12,10 @@ /** * @author Abel Hegedus - * + * */ public class CommandConstants { public static String SHOW_LOCATION_COMMAND_ID = "org.eclipse.incquery.tooling.ui.showlocation"; - + } diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/DatabindingUtil.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/DatabindingUtil.java index af644a89..e09b9303 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/DatabindingUtil.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/DatabindingUtil.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.util; - +package org.eclipse.incquery.tooling.ui.queryexplorer.util; + import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -61,358 +61,364 @@ import com.google.inject.Inject; import com.google.inject.Singleton; - -/** - * The util contains several useful methods for the databinding operations. - * - * @author Tamas Szabo - * - */ -@Singleton -public class DatabindingUtil { - + +/** + * The util contains several useful methods for the databinding operations. + * + * @author Tamas Szabo + * + */ +@Singleton +public class DatabindingUtil { + /** * */ private static final String DATABINDING_EXTENSION = "org.eclipse.incquery.databinding.runtime.databinding"; - private static Map registeredItemProviders = new HashMap(); - private static Map uriConfElementMap = null; - private static ILog logger = IncQueryGUIPlugin.getDefault().getLog(); - private static Map orderByPatternMarkers = new HashMap(); - private static List generatedPatterns; - private static Map> generatedMatcherFactories; - public static final String QUERY_EXPLORER_ANNOTATION = "QueryExplorer"; - public static final String PATTERNUI_ANNOTATION = "PatternUI"; - public static final String ORDERBY_ANNOTATION = "OrderBy"; - @Inject - private IResourceSetProvider resSetProvider; - - /** - * Creates a marker with a warning for the given pattern. - * The marker's message will be set to the given message parameter. - * - * @param patternFqn the fully qualified name of the pattern - * @param message the warning message for the marker - */ - public static void addOrderByPatternWarning(String patternFqn, String message) { - if (orderByPatternMarkers.get(patternFqn) == null) { - Pattern pattern = PatternRegistry.getInstance().getPatternByFqn(patternFqn); - URI uri = pattern.eResource().getURI(); - String platformString = uri.toPlatformString(true); - IResource markerLoc = ResourcesPlugin.getWorkspace().getRoot().findMember(platformString); - try { - IMarker marker = markerLoc.createMarker(EValidator.MARKER); - marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_WARNING); - marker.setAttribute(IMarker.TRANSIENT, true); - marker.setAttribute(IMarker.LOCATION, pattern.getName()); - marker.setAttribute(EValidator.URI_ATTRIBUTE, EcoreUtil.getURI(pattern).toString()); - marker.setAttribute(IMarker.MESSAGE, message); - orderByPatternMarkers.put(patternFqn, marker); - } catch (CoreException e) { - logger.log(new Status(IStatus.ERROR, IncQueryGUIPlugin.PLUGIN_ID, "Marker could not be created for pattern: " + patternFqn, e)); - } - } - } - - private static Map> collectGeneratedMatcherFactories() { - Map> factories = new HashMap>(); - for (IMatcherFactory factory : MatcherFactoryRegistry.getContributedMatcherFactories()) { - Pattern pattern = factory.getPattern(); - Boolean annotationValue = getValueOfQueryExplorerAnnotation(pattern); - if (annotationValue != null && annotationValue) { - factories.put(pattern, factory); - } - } - return factories; - } - - public static Boolean getValueOfQueryExplorerAnnotation(Pattern pattern) { - Annotation annotation = CorePatternLanguageHelper.getFirstAnnotationByName(pattern, QUERY_EXPLORER_ANNOTATION); - if (annotation == null) { - return null; - } - else { - for (AnnotationParameter ap : annotation.getParameters()) { - if (ap.getName().equalsIgnoreCase("display")) { - return Boolean.valueOf(((BoolValueImpl) ap.getValue()).isValue()); - } - } - return Boolean.TRUE; - } - } - - public static synchronized Collection> getGeneratedMatcherFactories() { - if (generatedMatcherFactories == null) { - generatedMatcherFactories = collectGeneratedMatcherFactories(); - } - return Collections.unmodifiableCollection(generatedMatcherFactories.values()); - } - - public static synchronized List getGeneratedPatterns() { - if (generatedPatterns == null) { - generatedPatterns = collectGeneratedPatterns(); - } - return Collections.unmodifiableList(generatedPatterns); - } - - private static List collectGeneratedPatterns() { - List patterns = new ArrayList(); - for (IMatcherFactory factory : getGeneratedMatcherFactories()) { - patterns.add(factory.getPattern()); - } - return patterns; - } - - /** - * Removes the marker for the given pattern if it is present. - * - * @param patternFqn the fully qualified name of the pattern - */ - public static void removeOrderByPatternWarning(String patternFqn) { - IMarker marker = orderByPatternMarkers.remove(patternFqn); - if (marker != null) { - try { - marker.delete(); - } - catch (CoreException e) { - logger.log(new Status(IStatus.ERROR, IncQueryGUIPlugin.PLUGIN_ID, "Marker could not be deleted: " + marker.toString(), e)); - } - } - } - - /** - * Returns the {@link AdapterFactoryLabelProvider} instance for the given uri. - * - * @param uri the uri - * @return the {@link AdapterFactoryLabelProvider} instance - */ - public synchronized static AdapterFactoryLabelProvider getAdapterFactoryLabelProvider(URI uri) { - if (uriConfElementMap == null) { - uriConfElementMap = collectItemProviders(); - } - AdapterFactoryLabelProvider af = registeredItemProviders.get(uri); - if (af != null) { - return af; - } - else { - IConfigurationElement ce = uriConfElementMap.get(uri); - try { - if (ce != null) { - Object obj = ce.createExecutableExtension("class"); - AdapterFactoryLabelProvider lp = new AdapterFactoryLabelProvider((AdapterFactory) obj); - registeredItemProviders.put(uri, lp); - return lp; - } - } catch (CoreException e) { - logger.log(new Status(IStatus.ERROR, IncQueryGUIPlugin.PLUGIN_ID, "AdapterFactory could not be created for uri: " + uri.toString(), e)); - } - return null; - } - } - - private static Map collectItemProviders() { - Map result = new HashMap(); - try { - IExtensionRegistry reg = Platform.getExtensionRegistry(); - IExtensionPoint ep = reg.getExtensionPoint("org.eclipse.emf.edit.itemProviderAdapterFactories"); - for (IExtension e : ep.getExtensions()) { - for (IConfigurationElement ce : e.getConfigurationElements()) { - if (ce.getName().matches("factory")) { - URI uri = URI.createURI(ce.getAttribute("uri")); - result.put(uri, ce); - } - } - } - } catch (Exception e) { - logger.log(new Status(IStatus.ERROR, IncQueryGUIPlugin.PLUGIN_ID, "Collecting item providers failed.", e)); - } - return result; - } - - /** - * Returns a text message for a generated, not filtered matcher about the current match size. - * @param matcher - * @param matchesSize - * @param patternFqn - * @return - */ - public static String getMessage( - IncQueryMatcher matcher, int matchesSize, - String patternFqn) { - return getMessage(matcher, matchesSize, patternFqn, true, false, null); - } - - /** - * Returns a text message about the matches size for the given matcher. - * - * @param matcher the {@link IncQueryMatcher} instance - * @param matchesSize the size of the matchset - * @param patternFqn the pattern fqn - * @param isGenerated true, if the matcher is generated, false if generic - * @param isFiltered true, if the matcher is filtered, false otherwise - * @return the label associated to the matcher - */ - public static String getMessage( - IncQueryMatcher matcher, - int matchesSize, String patternFqn, - boolean isGenerated, boolean isFiltered, String exceptionMessage) { - String isGeneratedString = isGenerated ? " (Generated)" : " (Runtime)"; - if (matcher == null) { - return String.format("%s - %s (see Error Log)", patternFqn, exceptionMessage); - } else { - String matchString; - switch (matchesSize){ - case 0: - matchString = "No matches"; - break; - case 1: - matchString = "1 match"; - break; - default: - matchString = String.format("%d matches", matchesSize); - } - - String filtered = isFiltered ? " - Filtered" : ""; - - return String.format("%s - %s %s %s", matcher.getPatternName(), matchString, filtered, isGeneratedString); - } - } - - /** - * Get the value of the PatternUI annotation's message attribute for the pattern which name is patternName. - * - * @param patternName the name of the pattern - * @return the content of the message attribute - */ - public static String getMessage(IPatternMatch match, boolean generatedMatcher) { - if (generatedMatcher) { - return getMessageForGeneratedMatcher(match); - } - else { - return getMessageForGenericMatcher(match); - } - } - - private static String getMessageForGeneratedMatcher(IPatternMatch match) { - String patternName = match.patternName(); - try { - IExtensionRegistry reg = Platform.getExtensionRegistry(); - IExtensionPoint ep = reg -.getExtensionPoint(DATABINDING_EXTENSION); - for (IExtension e : ep.getExtensions()) { - for (IConfigurationElement ce : e.getConfigurationElements()) { - String[] tokens = patternName.split("\\."); - String pattern = tokens[tokens.length - 1]; - - if (ce.getName().equals("databinding") && ce.getAttribute("patternName").equalsIgnoreCase( - pattern)) { - return ce.getAttribute("message"); - } - } - } - } catch (Exception e) { - logger.log(new Status(IStatus.ERROR, IncQueryGUIPlugin.PLUGIN_ID, "Message could not be retrieved for generated matcher.", e)); - } - - return null; - } - - private static String getMessageForGenericMatcher(IPatternMatch match) { - String patternName = match.patternName(); - Pattern pattern = null; - - //find PatternUI annotation - for (Pattern p : PatternRegistry.getInstance().getPatterns()) { - if (CorePatternLanguageHelper.getFullyQualifiedName(p).matches(patternName)) { - pattern = p; - - Annotation annotation = CorePatternLanguageHelper.getFirstAnnotationByName(p, QUERY_EXPLORER_ANNOTATION); - if (annotation == null) { - // Try with deprecated PatternUI annotation - annotation = CorePatternLanguageHelper.getFirstAnnotationByName(p, PATTERNUI_ANNOTATION); - } - if (annotation != null) { - for (AnnotationParameter ap : annotation.getParameters()) { - if (ap.getName().matches("message")) { - ValueReference valRef = ap.getValue(); - if (valRef instanceof StringValueImpl) { - return ((StringValueImpl) valRef).getValue(); - } - } - } - } - } - } - - //PatternUI annotation was not found - if (pattern != null) { - StringBuilder message = new StringBuilder(); - if (pattern.getParameters().size() == 0) { - message.append("(Match)"); - } - else { - int i = 0; - for (Variable v : pattern.getParameters()) { - if (i > 0) { - message.append(", "); - } - //message += v.getName()+"=$"+v.getName()+"$"; - message.append(String.format("%s=$%s$", v.getName(), v.getName())); - i++; - } - } - return message.toString(); - } - - return null; - } - - /** - * Get the DatabindingAdapter generated for the pattern whose name is patternName - * - * @param patternName the name of the pattern - * @return an instance of the DatabindingAdapter class generated for the pattern - */ - public static DatabindingAdapter getDatabindingAdapter(String patternName, boolean generatedMatcher) { - if (generatedMatcher) { - return getDatabindingAdapterForGeneratedMatcher(patternName); - } - else { - return getDatabindingAdapterForGenericMatcher(patternName); - } - } - - @SuppressWarnings("unchecked") - private static DatabindingAdapter getDatabindingAdapterForGeneratedMatcher(String patternName) { - try { - IExtensionRegistry reg = Platform.getExtensionRegistry(); - IExtensionPoint ep = reg.getExtensionPoint(DATABINDING_EXTENSION); - for (IExtension e : ep.getExtensions()) { - for (IConfigurationElement ce : e.getConfigurationElements()) { - String[] tokens = patternName.split("\\."); - String pattern = tokens[tokens.length - 1]; - - if (ce.getName().equals("databinding") && ce.getAttribute("patternName").equalsIgnoreCase(pattern)) { - Object obj = ce.createExecutableExtension("class"); - - if (obj instanceof DatabindingAdapter) { - return (DatabindingAdapter) obj; - } - } - } - } - } catch (Exception e) { - logger.log(new Status(IStatus.ERROR, IncQueryGUIPlugin.PLUGIN_ID, "Could not find DatabindableMatcher for pattern named: "+patternName, e)); - } - - return null; - } - - private static DatabindingAdapter getDatabindingAdapterForGenericMatcher(String patternName) { - Pattern pattern = PatternRegistry.getInstance().getPatternByFqn(patternName); - GenericDatabindingAdapter adapter = new GenericDatabindingAdapter(pattern); - return adapter; - } + private static Map registeredItemProviders = new HashMap(); + private static Map uriConfElementMap = null; + private static ILog logger = IncQueryGUIPlugin.getDefault().getLog(); + private static Map orderByPatternMarkers = new HashMap(); + private static List generatedPatterns; + private static Map> generatedMatcherFactories; + public static final String QUERY_EXPLORER_ANNOTATION = "QueryExplorer"; + public static final String PATTERNUI_ANNOTATION = "PatternUI"; + public static final String ORDERBY_ANNOTATION = "OrderBy"; + @Inject + private IResourceSetProvider resSetProvider; + + /** + * Creates a marker with a warning for the given pattern. The marker's message will be set to the given message + * parameter. + * + * @param patternFqn + * the fully qualified name of the pattern + * @param message + * the warning message for the marker + */ + public static void addOrderByPatternWarning(String patternFqn, String message) { + if (orderByPatternMarkers.get(patternFqn) == null) { + Pattern pattern = PatternRegistry.getInstance().getPatternByFqn(patternFqn); + URI uri = pattern.eResource().getURI(); + String platformString = uri.toPlatformString(true); + IResource markerLoc = ResourcesPlugin.getWorkspace().getRoot().findMember(platformString); + try { + IMarker marker = markerLoc.createMarker(EValidator.MARKER); + marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_WARNING); + marker.setAttribute(IMarker.TRANSIENT, true); + marker.setAttribute(IMarker.LOCATION, pattern.getName()); + marker.setAttribute(EValidator.URI_ATTRIBUTE, EcoreUtil.getURI(pattern).toString()); + marker.setAttribute(IMarker.MESSAGE, message); + orderByPatternMarkers.put(patternFqn, marker); + } catch (CoreException e) { + logger.log(new Status(IStatus.ERROR, IncQueryGUIPlugin.PLUGIN_ID, + "Marker could not be created for pattern: " + patternFqn, e)); + } + } + } + + private static Map> collectGeneratedMatcherFactories() { + Map> factories = new HashMap>(); + for (IMatcherFactory factory : MatcherFactoryRegistry.getContributedMatcherFactories()) { + Pattern pattern = factory.getPattern(); + Boolean annotationValue = getValueOfQueryExplorerAnnotation(pattern); + if (annotationValue != null && annotationValue) { + factories.put(pattern, factory); + } + } + return factories; + } + + public static Boolean getValueOfQueryExplorerAnnotation(Pattern pattern) { + Annotation annotation = CorePatternLanguageHelper.getFirstAnnotationByName(pattern, QUERY_EXPLORER_ANNOTATION); + if (annotation == null) { + return null; + } else { + for (AnnotationParameter ap : annotation.getParameters()) { + if (ap.getName().equalsIgnoreCase("display")) { + return Boolean.valueOf(((BoolValueImpl) ap.getValue()).isValue()); + } + } + return Boolean.TRUE; + } + } + + public static synchronized Collection> getGeneratedMatcherFactories() { + if (generatedMatcherFactories == null) { + generatedMatcherFactories = collectGeneratedMatcherFactories(); + } + return Collections.unmodifiableCollection(generatedMatcherFactories.values()); + } + + public static synchronized List getGeneratedPatterns() { + if (generatedPatterns == null) { + generatedPatterns = collectGeneratedPatterns(); + } + return Collections.unmodifiableList(generatedPatterns); + } + + private static List collectGeneratedPatterns() { + List patterns = new ArrayList(); + for (IMatcherFactory factory : getGeneratedMatcherFactories()) { + patterns.add(factory.getPattern()); + } + return patterns; + } + + /** + * Removes the marker for the given pattern if it is present. + * + * @param patternFqn + * the fully qualified name of the pattern + */ + public static void removeOrderByPatternWarning(String patternFqn) { + IMarker marker = orderByPatternMarkers.remove(patternFqn); + if (marker != null) { + try { + marker.delete(); + } catch (CoreException e) { + logger.log(new Status(IStatus.ERROR, IncQueryGUIPlugin.PLUGIN_ID, "Marker could not be deleted: " + + marker.toString(), e)); + } + } + } + + /** + * Returns the {@link AdapterFactoryLabelProvider} instance for the given uri. + * + * @param uri + * the uri + * @return the {@link AdapterFactoryLabelProvider} instance + */ + public synchronized static AdapterFactoryLabelProvider getAdapterFactoryLabelProvider(URI uri) { + if (uriConfElementMap == null) { + uriConfElementMap = collectItemProviders(); + } + AdapterFactoryLabelProvider af = registeredItemProviders.get(uri); + if (af != null) { + return af; + } else { + IConfigurationElement ce = uriConfElementMap.get(uri); + try { + if (ce != null) { + Object obj = ce.createExecutableExtension("class"); + AdapterFactoryLabelProvider lp = new AdapterFactoryLabelProvider((AdapterFactory) obj); + registeredItemProviders.put(uri, lp); + return lp; + } + } catch (CoreException e) { + logger.log(new Status(IStatus.ERROR, IncQueryGUIPlugin.PLUGIN_ID, + "AdapterFactory could not be created for uri: " + uri.toString(), e)); + } + return null; + } + } + + private static Map collectItemProviders() { + Map result = new HashMap(); + try { + IExtensionRegistry reg = Platform.getExtensionRegistry(); + IExtensionPoint ep = reg.getExtensionPoint("org.eclipse.emf.edit.itemProviderAdapterFactories"); + for (IExtension e : ep.getExtensions()) { + for (IConfigurationElement ce : e.getConfigurationElements()) { + if (ce.getName().matches("factory")) { + URI uri = URI.createURI(ce.getAttribute("uri")); + result.put(uri, ce); + } + } + } + } catch (Exception e) { + logger.log(new Status(IStatus.ERROR, IncQueryGUIPlugin.PLUGIN_ID, "Collecting item providers failed.", e)); + } + return result; + } + + /** + * Returns a text message for a generated, not filtered matcher about the current match size. + * + * @param matcher + * @param matchesSize + * @param patternFqn + * @return + */ + public static String getMessage(IncQueryMatcher matcher, int matchesSize, String patternFqn) { + return getMessage(matcher, matchesSize, patternFqn, true, false, null); + } + + /** + * Returns a text message about the matches size for the given matcher. + * + * @param matcher + * the {@link IncQueryMatcher} instance + * @param matchesSize + * the size of the matchset + * @param patternFqn + * the pattern fqn + * @param isGenerated + * true, if the matcher is generated, false if generic + * @param isFiltered + * true, if the matcher is filtered, false otherwise + * @return the label associated to the matcher + */ + public static String getMessage(IncQueryMatcher matcher, int matchesSize, + String patternFqn, boolean isGenerated, boolean isFiltered, String exceptionMessage) { + String isGeneratedString = isGenerated ? " (Generated)" : " (Runtime)"; + if (matcher == null) { + return String.format("%s - %s (see Error Log)", patternFqn, exceptionMessage); + } else { + String matchString; + switch (matchesSize) { + case 0: + matchString = "No matches"; + break; + case 1: + matchString = "1 match"; + break; + default: + matchString = String.format("%d matches", matchesSize); + } + + String filtered = isFiltered ? " - Filtered" : ""; + + return String.format("%s - %s %s %s", matcher.getPatternName(), matchString, filtered, isGeneratedString); + } + } + + /** + * Get the value of the PatternUI annotation's message attribute for the pattern which name is patternName. + * + * @param patternName + * the name of the pattern + * @return the content of the message attribute + */ + public static String getMessage(IPatternMatch match, boolean generatedMatcher) { + if (generatedMatcher) { + return getMessageForGeneratedMatcher(match); + } else { + return getMessageForGenericMatcher(match); + } + } + + private static String getMessageForGeneratedMatcher(IPatternMatch match) { + String patternName = match.patternName(); + try { + IExtensionRegistry reg = Platform.getExtensionRegistry(); + IExtensionPoint ep = reg.getExtensionPoint(DATABINDING_EXTENSION); + for (IExtension e : ep.getExtensions()) { + for (IConfigurationElement ce : e.getConfigurationElements()) { + String[] tokens = patternName.split("\\."); + String pattern = tokens[tokens.length - 1]; + + if (ce.getName().equals("databinding") && ce.getAttribute("patternName").equalsIgnoreCase(pattern)) { + return ce.getAttribute("message"); + } + } + } + } catch (Exception e) { + logger.log(new Status(IStatus.ERROR, IncQueryGUIPlugin.PLUGIN_ID, + "Message could not be retrieved for generated matcher.", e)); + } + + return null; + } + + private static String getMessageForGenericMatcher(IPatternMatch match) { + String patternName = match.patternName(); + Pattern pattern = null; + + // find PatternUI annotation + for (Pattern p : PatternRegistry.getInstance().getPatterns()) { + if (CorePatternLanguageHelper.getFullyQualifiedName(p).matches(patternName)) { + pattern = p; + + Annotation annotation = CorePatternLanguageHelper + .getFirstAnnotationByName(p, QUERY_EXPLORER_ANNOTATION); + if (annotation == null) { + // Try with deprecated PatternUI annotation + annotation = CorePatternLanguageHelper.getFirstAnnotationByName(p, PATTERNUI_ANNOTATION); + } + if (annotation != null) { + for (AnnotationParameter ap : annotation.getParameters()) { + if (ap.getName().matches("message")) { + ValueReference valRef = ap.getValue(); + if (valRef instanceof StringValueImpl) { + return ((StringValueImpl) valRef).getValue(); + } + } + } + } + } + } + + // PatternUI annotation was not found + if (pattern != null) { + StringBuilder message = new StringBuilder(); + if (pattern.getParameters().size() == 0) { + message.append("(Match)"); + } else { + int i = 0; + for (Variable v : pattern.getParameters()) { + if (i > 0) { + message.append(", "); + } + // message += v.getName()+"=$"+v.getName()+"$"; + message.append(String.format("%s=$%s$", v.getName(), v.getName())); + i++; + } + } + return message.toString(); + } + + return null; + } + + /** + * Get the DatabindingAdapter generated for the pattern whose name is patternName + * + * @param patternName + * the name of the pattern + * @return an instance of the DatabindingAdapter class generated for the pattern + */ + public static DatabindingAdapter getDatabindingAdapter(String patternName, boolean generatedMatcher) { + if (generatedMatcher) { + return getDatabindingAdapterForGeneratedMatcher(patternName); + } else { + return getDatabindingAdapterForGenericMatcher(patternName); + } + } + + @SuppressWarnings("unchecked") + private static DatabindingAdapter getDatabindingAdapterForGeneratedMatcher(String patternName) { + try { + IExtensionRegistry reg = Platform.getExtensionRegistry(); + IExtensionPoint ep = reg.getExtensionPoint(DATABINDING_EXTENSION); + for (IExtension e : ep.getExtensions()) { + for (IConfigurationElement ce : e.getConfigurationElements()) { + String[] tokens = patternName.split("\\."); + String pattern = tokens[tokens.length - 1]; + + if (ce.getName().equals("databinding") && ce.getAttribute("patternName").equalsIgnoreCase(pattern)) { + Object obj = ce.createExecutableExtension("class"); + + if (obj instanceof DatabindingAdapter) { + return (DatabindingAdapter) obj; + } + } + } + } + } catch (Exception e) { + logger.log(new Status(IStatus.ERROR, IncQueryGUIPlugin.PLUGIN_ID, + "Could not find DatabindableMatcher for pattern named: " + patternName, e)); + } + + return null; + } + + private static DatabindingAdapter getDatabindingAdapterForGenericMatcher(String patternName) { + Pattern pattern = PatternRegistry.getInstance().getPatternByFqn(patternName); + GenericDatabindingAdapter adapter = new GenericDatabindingAdapter(pattern); + return adapter; + } /** * Returns the generated matcher factory for the given generated pattern. @@ -421,47 +427,49 @@ private static DatabindingAdapter getDatabindingAdapterForGeneric * the pattern instance * @return the matcher factory for the given pattern */ - public static IMatcherFactory getMatcherFactoryForGeneratedPattern(Pattern pattern) { - return generatedMatcherFactories.get(pattern); - } - - /** - * Create a PatternMatcher root for the given key element. - * - * @param key the key element (editorpart + notifier) - * @return the PatternMatcherRoot element - */ - public static ObservablePatternMatcherRoot createPatternMatcherRoot(MatcherTreeViewerRootKey key) { - ObservablePatternMatcherRoot root = new ObservablePatternMatcherRoot(key); - List activePatterns = PatternRegistry.getInstance().getActivePatterns(); - //runtime & generated matchers - root.registerPattern(activePatterns.toArray(new Pattern[activePatterns.size()])); - return root; - } - - /** - * Parses the given .eiq file into a {@link PatternModel}. - * - * @param file the .eiq file instance - * @return the parsed pattern model - */ - public PatternModel parseEPM(IFile file) { - if (file == null) { - return null; - } - ResourceSet resourceSet = resSetProvider.get(file.getProject()); - URI fileURI = URI.createPlatformResourceURI(file.getFullPath().toString(), false); - Resource resource = resourceSet.getResource(fileURI, true); - - if (resource != null) { - if (resource.getErrors().size() > 0) { - return null; - } - if (resource.getContents().size() >= 1) { - EObject topElement = resource.getContents().get(0); - return topElement instanceof PatternModel ? (PatternModel) topElement : null; - } - } - return null; - } -} + public static IMatcherFactory getMatcherFactoryForGeneratedPattern(Pattern pattern) { + return generatedMatcherFactories.get(pattern); + } + + /** + * Create a PatternMatcher root for the given key element. + * + * @param key + * the key element (editorpart + notifier) + * @return the PatternMatcherRoot element + */ + public static ObservablePatternMatcherRoot createPatternMatcherRoot(MatcherTreeViewerRootKey key) { + ObservablePatternMatcherRoot root = new ObservablePatternMatcherRoot(key); + List activePatterns = PatternRegistry.getInstance().getActivePatterns(); + // runtime & generated matchers + root.registerPattern(activePatterns.toArray(new Pattern[activePatterns.size()])); + return root; + } + + /** + * Parses the given .eiq file into a {@link PatternModel}. + * + * @param file + * the .eiq file instance + * @return the parsed pattern model + */ + public PatternModel parseEPM(IFile file) { + if (file == null) { + return null; + } + ResourceSet resourceSet = resSetProvider.get(file.getProject()); + URI fileURI = URI.createPlatformResourceURI(file.getFullPath().toString(), false); + Resource resource = resourceSet.getResource(fileURI, true); + + if (resource != null) { + if (resource.getErrors().size() > 0) { + return null; + } + if (resource.getContents().size() >= 1) { + EObject topElement = resource.getContents().get(0); + return topElement instanceof PatternModel ? (PatternModel) topElement : null; + } + } + return null; + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/DeltaVisitor.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/DeltaVisitor.java index d1e7c0e5..9adf3eb9 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/DeltaVisitor.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/DeltaVisitor.java @@ -21,25 +21,25 @@ import com.google.inject.Injector; class DeltaVisitor implements IResourceDeltaVisitor { - private final Injector injector; - - public DeltaVisitor(Injector injector) { - this.injector = injector; - } - - public boolean visit(IResourceDelta delta) { - IResource res = delta.getResource(); - - if (res instanceof IFile && delta.getKind() == IResourceDelta.CHANGED) { - - IFile file = (IFile) res; - if (PatternRegistry.getInstance().getFiles().contains(file)) { - RuntimeMatcherRegistrator registrator = new RuntimeMatcherRegistrator((IFile) file); - injector.injectMembers(registrator); - Display.getDefault().asyncExec(registrator); - } - return false; - } - return true; - } + private final Injector injector; + + public DeltaVisitor(Injector injector) { + this.injector = injector; + } + + public boolean visit(IResourceDelta delta) { + IResource res = delta.getResource(); + + if (res instanceof IFile && delta.getKind() == IResourceDelta.CHANGED) { + + IFile file = (IFile) res; + if (PatternRegistry.getInstance().getFiles().contains(file)) { + RuntimeMatcherRegistrator registrator = new RuntimeMatcherRegistrator((IFile) file); + injector.injectMembers(registrator); + Display.getDefault().asyncExec(registrator); + } + return false; + } + return true; + } } diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/DoubleClickListener.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/DoubleClickListener.java index 831a60e1..0622bcd2 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/DoubleClickListener.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/DoubleClickListener.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.util; - +package org.eclipse.incquery.tooling.ui.queryexplorer.util; + import org.apache.log4j.Logger; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.commands.NotEnabledException; @@ -24,31 +24,32 @@ import org.eclipse.ui.handlers.IHandlerService; import com.google.inject.Inject; - -public class DoubleClickListener implements IDoubleClickListener { - - private static final String EXCEPTION_WHEN_ACTIVATING_SHOW_LOCATION = "Exception when activating show location!"; - - @Inject - private Logger logger; - - @Override - public void doubleClick(DoubleClickEvent event) { - ISelection selection = event.getSelection(); - if (selection instanceof TreeSelection) { - IHandlerService handlerService = (IHandlerService) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getService(IHandlerService.class); - try { - handlerService.executeCommand(CommandConstants.SHOW_LOCATION_COMMAND_ID, null); - } catch (ExecutionException e) { - logger.error(EXCEPTION_WHEN_ACTIVATING_SHOW_LOCATION, e); - } catch (NotDefinedException e) { - logger.error(EXCEPTION_WHEN_ACTIVATING_SHOW_LOCATION, e); - } catch (NotEnabledException e) { - logger.error(EXCEPTION_WHEN_ACTIVATING_SHOW_LOCATION, e); - } catch (NotHandledException e) { - logger.error(EXCEPTION_WHEN_ACTIVATING_SHOW_LOCATION, e); - } - } - } - -} + +public class DoubleClickListener implements IDoubleClickListener { + + private static final String EXCEPTION_WHEN_ACTIVATING_SHOW_LOCATION = "Exception when activating show location!"; + + @Inject + private Logger logger; + + @Override + public void doubleClick(DoubleClickEvent event) { + ISelection selection = event.getSelection(); + if (selection instanceof TreeSelection) { + IHandlerService handlerService = (IHandlerService) PlatformUI.getWorkbench().getActiveWorkbenchWindow() + .getService(IHandlerService.class); + try { + handlerService.executeCommand(CommandConstants.SHOW_LOCATION_COMMAND_ID, null); + } catch (ExecutionException e) { + logger.error(EXCEPTION_WHEN_ACTIVATING_SHOW_LOCATION, e); + } catch (NotDefinedException e) { + logger.error(EXCEPTION_WHEN_ACTIVATING_SHOW_LOCATION, e); + } catch (NotEnabledException e) { + logger.error(EXCEPTION_WHEN_ACTIVATING_SHOW_LOCATION, e); + } catch (NotHandledException e) { + logger.error(EXCEPTION_WHEN_ACTIVATING_SHOW_LOCATION, e); + } + } + } + +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/FileEditorPartListener.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/FileEditorPartListener.java index 61180452..561371e6 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/FileEditorPartListener.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/FileEditorPartListener.java @@ -8,8 +8,8 @@ * Contributors: * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.queryexplorer.util; - +package org.eclipse.incquery.tooling.ui.queryexplorer.util; + import org.eclipse.core.resources.IFile; import org.eclipse.incquery.tooling.ui.queryexplorer.handlers.RuntimeMatcherUnRegistrator; import org.eclipse.jface.dialogs.MessageDialog; @@ -17,35 +17,38 @@ import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.part.FileEditorInput; - -/** - * The PartListener is used to observe EditorPart close actions. - * - * @author Tamas Szabo - */ -public class FileEditorPartListener extends BasePartListener { - - private final String dialogTitle = ".eiq file editor closing"; - - @Override - public void partClosed(IWorkbenchPart part) { - if (part != null && part instanceof IEditorPart) { - IEditorPart closedEditor = (IEditorPart) part; - IEditorInput editorInput = closedEditor.getEditorInput(); - - if (editorInput != null && editorInput instanceof FileEditorInput) { - IFile file = ((FileEditorInput) editorInput).getFile(); - - if (file != null && file.getFileExtension().matches("eiq") && PatternRegistry.getInstance().getFiles().contains(file)) { - String question = "There are patterns (from file named '"+file.getName()+"') registered in the Query Explorer.\nWould you like to unregister them?"; - boolean answer = MessageDialog.openQuestion(closedEditor.getSite().getShell(), dialogTitle, question); - if (answer) { - RuntimeMatcherUnRegistrator job = new RuntimeMatcherUnRegistrator(file); - job.run(); - } - } - } - } - } - -} + +/** + * The PartListener is used to observe EditorPart close actions. + * + * @author Tamas Szabo + */ +public class FileEditorPartListener extends BasePartListener { + + private final String dialogTitle = ".eiq file editor closing"; + + @Override + public void partClosed(IWorkbenchPart part) { + if (part != null && part instanceof IEditorPart) { + IEditorPart closedEditor = (IEditorPart) part; + IEditorInput editorInput = closedEditor.getEditorInput(); + + if (editorInput != null && editorInput instanceof FileEditorInput) { + IFile file = ((FileEditorInput) editorInput).getFile(); + + if (file != null && file.getFileExtension().matches("eiq") + && PatternRegistry.getInstance().getFiles().contains(file)) { + String question = "There are patterns (from file named '" + file.getName() + + "') registered in the Query Explorer.\nWould you like to unregister them?"; + boolean answer = MessageDialog.openQuestion(closedEditor.getSite().getShell(), dialogTitle, + question); + if (answer) { + RuntimeMatcherUnRegistrator job = new RuntimeMatcherUnRegistrator(file); + job.run(); + } + } + } + } + } + +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/PatternRegistry.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/PatternRegistry.java index da5519c0..82432d9c 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/PatternRegistry.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/PatternRegistry.java @@ -72,10 +72,11 @@ public boolean isGenerated(Pattern pattern) { /** * Unregisters the given pattern from the registry. * - * @param pattern the pattern instance to be unregistered + * @param pattern + * the pattern instance to be unregistered */ public void unregisterPattern(Pattern pattern) { - String patternFqn = CorePatternLanguageHelper.getFullyQualifiedName(pattern); + String patternFqn = CorePatternLanguageHelper.getFullyQualifiedName(pattern); patternNameMap.remove(patternFqn); } diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/ResourceChangeListener.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/ResourceChangeListener.java index 05c20f18..d0002df1 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/ResourceChangeListener.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/queryexplorer/util/ResourceChangeListener.java @@ -19,19 +19,19 @@ import com.google.inject.Injector; public class ResourceChangeListener implements IResourceChangeListener { - private final Injector injector; + private final Injector injector; - public ResourceChangeListener(Injector injector) { - this.injector = injector; - } + public ResourceChangeListener(Injector injector) { + this.injector = injector; + } - public void resourceChanged(IResourceChangeEvent event) { - if (event.getType() == IResourceChangeEvent.PRE_BUILD) { - try { - event.getDelta().accept(new DeltaVisitor(injector)); - } catch (CoreException e) { - IncQueryGUIPlugin.getDefault().logException("Visitor failed on delta", e); - } - } - } + public void resourceChanged(IResourceChangeEvent event) { + if (event.getType() == IResourceChangeEvent.PRE_BUILD) { + try { + event.getDelta().accept(new DeltaVisitor(injector)); + } catch (CoreException e) { + IncQueryGUIPlugin.getDefault().logException("Visitor failed on delta", e); + } + } + } } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/NewEiqFileWizard.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/NewEiqFileWizard.java index e32104f0..37782581 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/NewEiqFileWizard.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/NewEiqFileWizard.java @@ -56,151 +56,150 @@ * A wizard implementation used to create new eiq files. * * @author Tamas Szabo - * + * */ public class NewEiqFileWizard extends Wizard implements INewWizard { - - private static final String NEW_EMF_INC_QUERY_QUERY_DEFINITION_FILE = "Create a new EMF-IncQuery Query Definition file."; - private NewEiqFileWizardContainerConfigurationPage page1; - private NewEiqFileWizardPatternConfigurationPage page2; - private ISelection selection; - private IWorkbench workbench; - private final IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); - private IPath filePath; - - @Inject - private IResourceSetProvider resourceSetProvider; - - @Inject - private Injector injector; - - public NewEiqFileWizard() { - super(); - setNeedsProgressMonitor(true); - } - - @Override - public void addPages() { - page1 = new NewEiqFileWizardContainerConfigurationPage(); - page1.init((IStructuredSelection) selection); - page1.setDescription(NEW_EMF_INC_QUERY_QUERY_DEFINITION_FILE); - page2 = new NewEiqFileWizardPatternConfigurationPage(); - injector.injectMembers(page2); - addPage(page1); - addPage(page2); - setForcePreviousAndNextButtons(false); - } - - @Override - public boolean performFinish() { - final String containerName = page1.getContainerName(); - final String fileName = page1.getFileName(); - - //replace dots with slash in the path - final String packageName = page1.getPackageName().replaceAll("\\.", "/"); - final String patternName = page2.getPatternName(); - final List imports = page2.getImports(); - final List parameters = page2.getParameters(); - - IRunnableWithProgress op = new IRunnableWithProgress() { - @Override + + private static final String NEW_EMF_INC_QUERY_QUERY_DEFINITION_FILE = "Create a new EMF-IncQuery Query Definition file."; + private NewEiqFileWizardContainerConfigurationPage page1; + private NewEiqFileWizardPatternConfigurationPage page2; + private ISelection selection; + private IWorkbench workbench; + private final IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); + private IPath filePath; + + @Inject + private IResourceSetProvider resourceSetProvider; + + @Inject + private Injector injector; + + public NewEiqFileWizard() { + super(); + setNeedsProgressMonitor(true); + } + + @Override + public void addPages() { + page1 = new NewEiqFileWizardContainerConfigurationPage(); + page1.init((IStructuredSelection) selection); + page1.setDescription(NEW_EMF_INC_QUERY_QUERY_DEFINITION_FILE); + page2 = new NewEiqFileWizardPatternConfigurationPage(); + injector.injectMembers(page2); + addPage(page1); + addPage(page2); + setForcePreviousAndNextButtons(false); + } + + @Override + public boolean performFinish() { + final String containerName = page1.getContainerName(); + final String fileName = page1.getFileName(); + + // replace dots with slash in the path + final String packageName = page1.getPackageName().replaceAll("\\.", "/"); + final String patternName = page2.getPatternName(); + final List imports = page2.getImports(); + final List parameters = page2.getParameters(); + + IRunnableWithProgress op = new IRunnableWithProgress() { + @Override public void run(IProgressMonitor monitor) throws InvocationTargetException { - try { - doFinish(containerName, fileName, packageName, patternName, imports, parameters, monitor); - } catch (Exception e) { - throw new InvocationTargetException(e); - } finally { - monitor.done(); - } - } - }; - try { - getContainer().run(true, false, op); - IFile file = (IFile) root.findMember(filePath); - BasicNewResourceWizard.selectAndReveal(file, workbench.getActiveWorkbenchWindow()); - IDE.openEditor(workbench.getActiveWorkbenchWindow().getActivePage(), file, true); - } catch (InterruptedException e) { - //This is never thrown as of false cancellable parameter of getContainer().run - return false; - } catch (InvocationTargetException e) { - Throwable realException = e.getTargetException(); - IncQueryGUIPlugin.getDefault().logException( - "Cannot create Query Definition file: " - + realException.getMessage(), realException); - MessageDialog.openError(getShell(), "Error", - realException.getMessage()); - return false; - } catch (PartInitException e) { - IncQueryGUIPlugin.getDefault().logException("Cannot open editor: " + e.getMessage(), e); - MessageDialog.openError(getShell(), "Error", e.getMessage()); - } - return true; - } - - private void doFinish(String containerName, String fileName, String packageName, String patternName, List imports, List parameters, IProgressMonitor monitor) { - monitor.beginTask("Creating " + fileName, 1); - createEiqFile(containerName, fileName, packageName, patternName, imports, parameters); - monitor.worked(1); - } - - @Override - public void init(IWorkbench workbench, IStructuredSelection selection) { - this.selection = selection; - this.workbench = workbench; - } - - private void createEiqFile(String containerName, String fileName, String packageName, String patternName, List imports, List parameters) { - IResource containerResource = root.findMember(new Path(containerName)); - ResourceSet resourceSet = resourceSetProvider.get(containerResource.getProject()); - - filePath = containerResource.getFullPath().append(packageName+"/"+fileName); - String fullPath = filePath.toString(); - - URI fileURI = URI.createPlatformResourceURI(fullPath, false); - Resource resource = resourceSet.createResource(fileURI); - - PatternModel pm = EMFPatternLanguageFactory.eINSTANCE.createPatternModel(); - - //Setting package name - if (packageName != null && !packageName.isEmpty()) { - pm.setPackageName(packageName.replace("/", ".")); - } - - //Setting imports - for (EPackage importedPackage : imports) { - PackageImport importDecl = EMFPatternLanguageFactory.eINSTANCE.createPackageImport(); - importDecl.setEPackage(importedPackage); - pm.getImportPackages().add(importDecl); - } - - //Creating pattern - if (patternName != null && patternName.length() > 0) { - Pattern pattern = PatternLanguageFactory.eINSTANCE.createPattern(); - pattern.setName(patternName); - PatternBody body = PatternLanguageFactory.eINSTANCE.createPatternBody(); - pattern.getBodies().add(body); - - //Setting pattern parameters - for (ObjectParameter parameter : parameters) { - Variable var = PatternLanguageFactory.eINSTANCE.createVariable(); - var.setName(parameter.getParameterName()); - - ClassType classType = EMFPatternLanguageFactory.eINSTANCE.createClassType(); - //it is enough to set only the class name for the class type - classType.setClassname(parameter.getObject()); - var.setType(classType); - pattern.getParameters().add(var); - } - - pm.getPatterns().add(pattern); - } - resource.getContents().add(pm); - - try { - resource.save(Collections.EMPTY_MAP); - } - catch (IOException e) { - IncQueryGUIPlugin.getDefault().logException("Resource could not be saved", e); - } - } + try { + doFinish(containerName, fileName, packageName, patternName, imports, parameters, monitor); + } catch (Exception e) { + throw new InvocationTargetException(e); + } finally { + monitor.done(); + } + } + }; + try { + getContainer().run(true, false, op); + IFile file = (IFile) root.findMember(filePath); + BasicNewResourceWizard.selectAndReveal(file, workbench.getActiveWorkbenchWindow()); + IDE.openEditor(workbench.getActiveWorkbenchWindow().getActivePage(), file, true); + } catch (InterruptedException e) { + // This is never thrown as of false cancellable parameter of getContainer().run + return false; + } catch (InvocationTargetException e) { + Throwable realException = e.getTargetException(); + IncQueryGUIPlugin.getDefault().logException( + "Cannot create Query Definition file: " + realException.getMessage(), realException); + MessageDialog.openError(getShell(), "Error", realException.getMessage()); + return false; + } catch (PartInitException e) { + IncQueryGUIPlugin.getDefault().logException("Cannot open editor: " + e.getMessage(), e); + MessageDialog.openError(getShell(), "Error", e.getMessage()); + } + return true; + } + + private void doFinish(String containerName, String fileName, String packageName, String patternName, + List imports, List parameters, IProgressMonitor monitor) { + monitor.beginTask("Creating " + fileName, 1); + createEiqFile(containerName, fileName, packageName, patternName, imports, parameters); + monitor.worked(1); + } + + @Override + public void init(IWorkbench workbench, IStructuredSelection selection) { + this.selection = selection; + this.workbench = workbench; + } + + private void createEiqFile(String containerName, String fileName, String packageName, String patternName, + List imports, List parameters) { + IResource containerResource = root.findMember(new Path(containerName)); + ResourceSet resourceSet = resourceSetProvider.get(containerResource.getProject()); + + filePath = containerResource.getFullPath().append(packageName + "/" + fileName); + String fullPath = filePath.toString(); + + URI fileURI = URI.createPlatformResourceURI(fullPath, false); + Resource resource = resourceSet.createResource(fileURI); + + PatternModel pm = EMFPatternLanguageFactory.eINSTANCE.createPatternModel(); + + // Setting package name + if (packageName != null && !packageName.isEmpty()) { + pm.setPackageName(packageName.replace("/", ".")); + } + + // Setting imports + for (EPackage importedPackage : imports) { + PackageImport importDecl = EMFPatternLanguageFactory.eINSTANCE.createPackageImport(); + importDecl.setEPackage(importedPackage); + pm.getImportPackages().add(importDecl); + } + + // Creating pattern + if (patternName != null && patternName.length() > 0) { + Pattern pattern = PatternLanguageFactory.eINSTANCE.createPattern(); + pattern.setName(patternName); + PatternBody body = PatternLanguageFactory.eINSTANCE.createPatternBody(); + pattern.getBodies().add(body); + + // Setting pattern parameters + for (ObjectParameter parameter : parameters) { + Variable var = PatternLanguageFactory.eINSTANCE.createVariable(); + var.setName(parameter.getParameterName()); + + ClassType classType = EMFPatternLanguageFactory.eINSTANCE.createClassType(); + // it is enough to set only the class name for the class type + classType.setClassname(parameter.getObject()); + var.setType(classType); + pattern.getParameters().add(var); + } + + pm.getPatterns().add(pattern); + } + resource.getContents().add(pm); + + try { + resource.save(Collections.EMPTY_MAP); + } catch (IOException e) { + IncQueryGUIPlugin.getDefault().logException("Resource could not be saved", e); + } + } } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/NewEiqFileWizardContainerConfigurationPage.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/NewEiqFileWizardContainerConfigurationPage.java index 8db8e761..a83dd304 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/NewEiqFileWizardContainerConfigurationPage.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/NewEiqFileWizardContainerConfigurationPage.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.wizards; - +package org.eclipse.incquery.tooling.ui.wizards; + import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRoot; @@ -41,210 +41,210 @@ import org.eclipse.swt.widgets.Text; /** - * First page of the {@link NewEiqFileWizard} which allows to specify the details of the container for a pattern. + * First page of the {@link NewEiqFileWizard} which allows to specify the details of the container for a pattern. * * @author Tamas Szabo - * - */ -@SuppressWarnings("restriction") -public class NewEiqFileWizardContainerConfigurationPage extends NewTypeWizardPage { - - private Text fileText; - private static final String TITLE = "EMF-IncQuery Query Definition Wizard"; - private static final String THE_GIVEN_FILE_ALREADY_EXISTS = "The given file already exists!"; - private static final String defaultEiqFileName = ""; - private static final String SOURCE_FOLDER_ERROR = "You must specify a valid source folder!"; - private static final String FILE_NAME_ERROR = "File name must be specified!"; - private static final String FILE_NAME_NOT_VALID = "File name must be valid!"; - private static final String FILE_EXTENSION_ERROR = "File extension must be \"eiq\"!"; - private static final String DEFAULT_PACKAGE_WARNING = "The use of default package is discouraged."; - private static final String PACKAGE_NAME_WARNING = "Only lower case package names supported."; - - public NewEiqFileWizardContainerConfigurationPage() { - super(false, "eiq"); - setTitle(TITLE); - } - - /** - * Initialization based on the current selection. - * - * @param selection the current selection in the workspace - */ - public void init(IStructuredSelection selection) { - IJavaElement jElement= getInitialJavaElement(selection); - initContainerPage(jElement); - - if (jElement != null) { - IPackageFragment pack = (IPackageFragment) jElement.getAncestor(IJavaElement.PACKAGE_FRAGMENT); - setPackageFragment(pack, true); - } - - packageChanged(); - } - - @Override - public void createControl(Composite parent) { - initializeDialogUnits(parent); - - Composite composite= new Composite(parent, SWT.NONE); - composite.setFont(parent.getFont()); - - int nColumns= 4; - - GridLayout layout= new GridLayout(); - layout.numColumns= nColumns; - composite.setLayout(layout); - - createContainerControls(composite, nColumns); - createPackageControls(composite, nColumns); - - Label label = new Label(composite, SWT.NULL); - label.setText("&File name:"); - fileText = new Text(composite, SWT.BORDER | SWT.SINGLE); - fileText.setText(defaultEiqFileName); - GridData gd_1 = new GridData(GridData.FILL_HORIZONTAL); - gd_1.horizontalSpan = 3; - fileText.setLayoutData(gd_1); - fileText.addModifyListener(new ModifyListener() { - public void modifyText(ModifyEvent e) { - validatePage(); - } - }); - - setControl(composite); - - validatePage(); - } - - @Override - protected void handleFieldChanged(String fieldName) { - super.handleFieldChanged(fieldName); - validatePage(); - } - - /** - * Used to validate the page. - * - * Note that because of policy restrictions, a wizard must not come up with an error. - * - */ - private void validatePage() { - IStatus packageStatus = validatePackageName(getPackageText()); - StatusInfo si = new StatusInfo(packageStatus.getSeverity(), packageStatus.getMessage()); - String containerPath = getPackageFragmentRootText(); - IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); - IResource containerResource = root.findMember(new Path(containerPath)); - - if (containerPath.matches("") || containerResource == null) { - si.setError(SOURCE_FOLDER_ERROR); - } - - if (fileText != null) { - - String fileName = fileText.getText(); - String packageName = getPackageText().replaceAll("\\.", "/"); - - if (root.findMember(new Path(containerPath+"/"+packageName+"/"+fileText.getText())) != null) { - si.setError(THE_GIVEN_FILE_ALREADY_EXISTS); - } - - if (fileName.length() == 0) { - si.setError(FILE_NAME_ERROR); - } - - if (fileName.replace('\\', '/').indexOf('/', 1) > 0) { - si.setError(FILE_NAME_NOT_VALID); - } - - boolean wrongExtension = false; - - if (!fileName.contains(".")) { - wrongExtension = true; - } else { - int dotLoc = fileName.lastIndexOf('.'); - String ext = fileName.substring(dotLoc + 1); - wrongExtension = !ext.equalsIgnoreCase("eiq"); - - String name = fileName.substring(0, dotLoc); - IStatus nameValidatorStatus = JavaConventions.validateTypeVariableName(name, JavaCore.VERSION_1_6, JavaCore.VERSION_1_6); - if (nameValidatorStatus.getSeverity() == IStatus.ERROR) { - si.setError(String.format("Filename %s is not a valid Java type name.", name)); - } - } - - if (wrongExtension) { - si.setError(FILE_EXTENSION_ERROR); - } - } - - if (si.getSeverity() == IStatus.OK) { - si.setInfo(""); - } - - if (si.isError()) { - setErrorMessage(si.getMessage()); - } - - updateStatus(si); - } - - private IStatus validatePackageName(String text) { - if (text == null || text.isEmpty()) { - return new Status(IStatus.WARNING, IncQueryGUIPlugin.PLUGIN_ID, DEFAULT_PACKAGE_WARNING); - } - IJavaProject project = getJavaProject(); - if (project == null || !project.exists()) { - return JavaConventions.validatePackageName(text, JavaCore.VERSION_1_6, JavaCore.VERSION_1_6); - } - IStatus status = JavaConventionsUtil.validatePackageName(text, project); - if (!text.toLowerCase().equals(text)) { - return new Status(IStatus.ERROR, IncQueryGUIPlugin.PLUGIN_ID, PACKAGE_NAME_WARNING); - } - return status; - } - - /** - * Returns the name of the new eiq file set in the wizard. - * - * @return the name of the file - */ - public String getFileName() { - return fileText.getText(); - } - - /** - * Returns the name of the container set in the wizard. - * - * @return the name of the container (folder) - */ - public String getContainerName() { - return getPackageFragmentRootText(); - } - - /** - * Returns the name of the package set in the wizard. - * - * @return the name of the package - */ - public String getPackageName() { - IPackageFragmentRoot root = getPackageFragmentRoot(); - - IPackageFragment fragment = root.getPackageFragment(getPackageText()); - - if (!fragment.exists()) { - try { - root.createPackageFragment(getPackageText(), true, new NullProgressMonitor()); - } - catch (JavaModelException e) { - IncQueryGUIPlugin.getDefault().logException( - "Cannot load packages " + e.getMessage(), e); - } - } - - return getPackageText(); - } - - public IProject getProject() { - return this.getPackageFragmentRoot().getJavaProject().getProject(); - } -} + * + */ +@SuppressWarnings("restriction") +public class NewEiqFileWizardContainerConfigurationPage extends NewTypeWizardPage { + + private Text fileText; + private static final String TITLE = "EMF-IncQuery Query Definition Wizard"; + private static final String THE_GIVEN_FILE_ALREADY_EXISTS = "The given file already exists!"; + private static final String defaultEiqFileName = ""; + private static final String SOURCE_FOLDER_ERROR = "You must specify a valid source folder!"; + private static final String FILE_NAME_ERROR = "File name must be specified!"; + private static final String FILE_NAME_NOT_VALID = "File name must be valid!"; + private static final String FILE_EXTENSION_ERROR = "File extension must be \"eiq\"!"; + private static final String DEFAULT_PACKAGE_WARNING = "The use of default package is discouraged."; + private static final String PACKAGE_NAME_WARNING = "Only lower case package names supported."; + + public NewEiqFileWizardContainerConfigurationPage() { + super(false, "eiq"); + setTitle(TITLE); + } + + /** + * Initialization based on the current selection. + * + * @param selection + * the current selection in the workspace + */ + public void init(IStructuredSelection selection) { + IJavaElement jElement = getInitialJavaElement(selection); + initContainerPage(jElement); + + if (jElement != null) { + IPackageFragment pack = (IPackageFragment) jElement.getAncestor(IJavaElement.PACKAGE_FRAGMENT); + setPackageFragment(pack, true); + } + + packageChanged(); + } + + @Override + public void createControl(Composite parent) { + initializeDialogUnits(parent); + + Composite composite = new Composite(parent, SWT.NONE); + composite.setFont(parent.getFont()); + + int nColumns = 4; + + GridLayout layout = new GridLayout(); + layout.numColumns = nColumns; + composite.setLayout(layout); + + createContainerControls(composite, nColumns); + createPackageControls(composite, nColumns); + + Label label = new Label(composite, SWT.NULL); + label.setText("&File name:"); + fileText = new Text(composite, SWT.BORDER | SWT.SINGLE); + fileText.setText(defaultEiqFileName); + GridData gd_1 = new GridData(GridData.FILL_HORIZONTAL); + gd_1.horizontalSpan = 3; + fileText.setLayoutData(gd_1); + fileText.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + validatePage(); + } + }); + + setControl(composite); + + validatePage(); + } + + @Override + protected void handleFieldChanged(String fieldName) { + super.handleFieldChanged(fieldName); + validatePage(); + } + + /** + * Used to validate the page. + * + * Note that because of policy restrictions, a wizard must not come up with an error. + * + */ + private void validatePage() { + IStatus packageStatus = validatePackageName(getPackageText()); + StatusInfo si = new StatusInfo(packageStatus.getSeverity(), packageStatus.getMessage()); + String containerPath = getPackageFragmentRootText(); + IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); + IResource containerResource = root.findMember(new Path(containerPath)); + + if (containerPath.matches("") || containerResource == null) { + si.setError(SOURCE_FOLDER_ERROR); + } + + if (fileText != null) { + + String fileName = fileText.getText(); + String packageName = getPackageText().replaceAll("\\.", "/"); + + if (root.findMember(new Path(containerPath + "/" + packageName + "/" + fileText.getText())) != null) { + si.setError(THE_GIVEN_FILE_ALREADY_EXISTS); + } + + if (fileName.length() == 0) { + si.setError(FILE_NAME_ERROR); + } + + if (fileName.replace('\\', '/').indexOf('/', 1) > 0) { + si.setError(FILE_NAME_NOT_VALID); + } + + boolean wrongExtension = false; + + if (!fileName.contains(".")) { + wrongExtension = true; + } else { + int dotLoc = fileName.lastIndexOf('.'); + String ext = fileName.substring(dotLoc + 1); + wrongExtension = !ext.equalsIgnoreCase("eiq"); + + String name = fileName.substring(0, dotLoc); + IStatus nameValidatorStatus = JavaConventions.validateTypeVariableName(name, JavaCore.VERSION_1_6, + JavaCore.VERSION_1_6); + if (nameValidatorStatus.getSeverity() == IStatus.ERROR) { + si.setError(String.format("Filename %s is not a valid Java type name.", name)); + } + } + + if (wrongExtension) { + si.setError(FILE_EXTENSION_ERROR); + } + } + + if (si.getSeverity() == IStatus.OK) { + si.setInfo(""); + } + + if (si.isError()) { + setErrorMessage(si.getMessage()); + } + + updateStatus(si); + } + + private IStatus validatePackageName(String text) { + if (text == null || text.isEmpty()) { + return new Status(IStatus.WARNING, IncQueryGUIPlugin.PLUGIN_ID, DEFAULT_PACKAGE_WARNING); + } + IJavaProject project = getJavaProject(); + if (project == null || !project.exists()) { + return JavaConventions.validatePackageName(text, JavaCore.VERSION_1_6, JavaCore.VERSION_1_6); + } + IStatus status = JavaConventionsUtil.validatePackageName(text, project); + if (!text.toLowerCase().equals(text)) { + return new Status(IStatus.ERROR, IncQueryGUIPlugin.PLUGIN_ID, PACKAGE_NAME_WARNING); + } + return status; + } + + /** + * Returns the name of the new eiq file set in the wizard. + * + * @return the name of the file + */ + public String getFileName() { + return fileText.getText(); + } + + /** + * Returns the name of the container set in the wizard. + * + * @return the name of the container (folder) + */ + public String getContainerName() { + return getPackageFragmentRootText(); + } + + /** + * Returns the name of the package set in the wizard. + * + * @return the name of the package + */ + public String getPackageName() { + IPackageFragmentRoot root = getPackageFragmentRoot(); + + IPackageFragment fragment = root.getPackageFragment(getPackageText()); + + if (!fragment.exists()) { + try { + root.createPackageFragment(getPackageText(), true, new NullProgressMonitor()); + } catch (JavaModelException e) { + IncQueryGUIPlugin.getDefault().logException("Cannot load packages " + e.getMessage(), e); + } + } + + return getPackageText(); + } + + public IProject getProject() { + return this.getPackageFragmentRoot().getJavaProject().getProject(); + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/NewEiqFileWizardPatternConfigurationPage.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/NewEiqFileWizardPatternConfigurationPage.java index 009621e1..50ad89e2 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/NewEiqFileWizardPatternConfigurationPage.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/NewEiqFileWizardPatternConfigurationPage.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.wizards; - +package org.eclipse.incquery.tooling.ui.wizards; + import java.util.List; import org.eclipse.core.runtime.IStatus; @@ -37,157 +37,158 @@ import com.google.inject.Inject; /** - * Second page of the {@link NewEiqFileWizard} which allows to specify pattern parameters and imported {@link EPackage}s. + * Second page of the {@link NewEiqFileWizard} which allows to specify pattern parameters and imported {@link EPackage} + * s. * * @author Tamas Szabo - * - */ -@SuppressWarnings("restriction") -public class NewEiqFileWizardPatternConfigurationPage extends WizardPage { - - private static final String TITLE = "EMF-IncQuery Query Definition Wizard"; - private static final String PATTERN_NAME_SHOULD_BE_SPECIFIED = "Pattern name should be specified!"; - private static final String PATTERN_NAME_MUST_BE_SPECIFIED = "Pattern name must be specified, if at least one parameter is set!"; - private Text patternText; - private ListDialogField importList; - private ListDialogField objectList; - private ImportListLabelProvider importListLabelProvider; - private ObjectListLabelProvider objectListLabelProvider; - private ImportListAdapter importListAdapter; - private ObjectListAdapter objectListAdapter; - public boolean parameterSet; - - @Inject - private IEiqGenmodelProvider metamodelProviderService; - - public NewEiqFileWizardPatternConfigurationPage() { - super(TITLE); - setTitle(TITLE); - parameterSet = false; - } - - private void createImportsControl(Composite parent, int nColumns) { - String[] buttonLiterals= new String[] {"Add", "Remove"}; - - NewEiqFileWizardContainerConfigurationPage firstPage = (NewEiqFileWizardContainerConfigurationPage) this.getPreviousPage(); - - importListAdapter = new ImportListAdapter(firstPage, metamodelProviderService); - importListLabelProvider = new ImportListLabelProvider(); - - importList = new ListDialogField(importListAdapter, buttonLiterals, importListLabelProvider); - importList.setLabelText("&Imported packages:"); - importList.setTableColumns(new ListDialogField.ColumnsDescription(new String[] {"EPackage"}, true)); - importList.setRemoveButtonIndex(1); - importList.doFillIntoGrid(parent, nColumns); - } - - private void createObjectSelectionControl(Composite parent, int nColumns) { - String[] buttonLiterals= new String[] {"Add", "Modify", "Remove"}; - objectListAdapter = new ObjectListAdapter(this, importList); - objectListLabelProvider = new ObjectListLabelProvider(); - - objectList = new ListDialogField(objectListAdapter, buttonLiterals, objectListLabelProvider); - objectList.setLabelText("&Pattern parameters:"); - objectList.setTableColumns(new ListDialogField.ColumnsDescription(new String[] {"Name", "Type"}, true)); - //disable modify button for an empty list - objectList.enableButton(1, false); - objectList.setRemoveButtonIndex(2); - objectList.doFillIntoGrid(parent, nColumns); - } - - @Override - public void createControl(Composite parent) { - int nColumns= 5; - - initializeDialogUnits(parent); - Composite composite= new Composite(parent, SWT.NONE); - composite.setFont(parent.getFont()); - - GridLayout layout= new GridLayout(); - layout.numColumns= nColumns; - composite.setLayout(layout); - - Label label = new Label(composite, SWT.NULL); - label.setText("&Pattern name:"); - patternText = new Text(composite, SWT.BORDER | SWT.SINGLE); - patternText.setText(""); - GridData gd_1 = new GridData(GridData.FILL_HORIZONTAL); - gd_1.horizontalSpan = 3; - patternText.setLayoutData(gd_1); - patternText.addModifyListener(new ModifyListener() { - public void modifyText(ModifyEvent e) { - validatePage(); - } - }); - - label = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL); - GridData gd_2 = new GridData(GridData.FILL_HORIZONTAL); - gd_2.horizontalSpan = nColumns; - label.setLayoutData(gd_2); - - createImportsControl(composite, nColumns); - createObjectSelectionControl(composite, nColumns); - - setControl(composite); - validatePage(); - } - - public void validatePage() { - - StatusInfo si = new StatusInfo(StatusInfo.OK, ""); - - if (patternText != null) { - String patternName = patternText.getText(); - if (patternName == null || patternName.length() == 0) { - if (parameterSet) { - si.setError(PATTERN_NAME_MUST_BE_SPECIFIED); - } - else { - si.setWarning(PATTERN_NAME_SHOULD_BE_SPECIFIED); - } - } - } - - if (si.getSeverity() == IStatus.OK) { - si.setInfo(""); - } - - updateStatus(si); - - if (si.isError()) { - setErrorMessage(si.getMessage()); - } - } - - protected void updateStatus(IStatus status) { - setPageComplete(!status.matches(IStatus.ERROR)); - StatusUtil.applyToStatusLine(this, status); - } - - /** - * Returns the name of the pattern specified in the wizard. - * - * @return the name of the pattern - */ - public String getPatternName() { - return patternText.getText(); - } - - /** - * Returns the import list of {@link EPackage}s specified in the wizard. - * - * @return the list of imports - */ - public List getImports() { - return importList.getElements(); - } - - /** - * Returns the list of pattern parameters specified in the wizard. - * - * @return the list of pattern parameters - */ - public List getParameters() { - return objectList.getElements(); - } -} + * + */ +@SuppressWarnings("restriction") +public class NewEiqFileWizardPatternConfigurationPage extends WizardPage { + + private static final String TITLE = "EMF-IncQuery Query Definition Wizard"; + private static final String PATTERN_NAME_SHOULD_BE_SPECIFIED = "Pattern name should be specified!"; + private static final String PATTERN_NAME_MUST_BE_SPECIFIED = "Pattern name must be specified, if at least one parameter is set!"; + private Text patternText; + private ListDialogField importList; + private ListDialogField objectList; + private ImportListLabelProvider importListLabelProvider; + private ObjectListLabelProvider objectListLabelProvider; + private ImportListAdapter importListAdapter; + private ObjectListAdapter objectListAdapter; + public boolean parameterSet; + + @Inject + private IEiqGenmodelProvider metamodelProviderService; + + public NewEiqFileWizardPatternConfigurationPage() { + super(TITLE); + setTitle(TITLE); + parameterSet = false; + } + + private void createImportsControl(Composite parent, int nColumns) { + String[] buttonLiterals = new String[] { "Add", "Remove" }; + + NewEiqFileWizardContainerConfigurationPage firstPage = (NewEiqFileWizardContainerConfigurationPage) this + .getPreviousPage(); + + importListAdapter = new ImportListAdapter(firstPage, metamodelProviderService); + importListLabelProvider = new ImportListLabelProvider(); + + importList = new ListDialogField(importListAdapter, buttonLiterals, importListLabelProvider); + importList.setLabelText("&Imported packages:"); + importList.setTableColumns(new ListDialogField.ColumnsDescription(new String[] { "EPackage" }, true)); + importList.setRemoveButtonIndex(1); + importList.doFillIntoGrid(parent, nColumns); + } + + private void createObjectSelectionControl(Composite parent, int nColumns) { + String[] buttonLiterals = new String[] { "Add", "Modify", "Remove" }; + objectListAdapter = new ObjectListAdapter(this, importList); + objectListLabelProvider = new ObjectListLabelProvider(); + + objectList = new ListDialogField(objectListAdapter, buttonLiterals, objectListLabelProvider); + objectList.setLabelText("&Pattern parameters:"); + objectList.setTableColumns(new ListDialogField.ColumnsDescription(new String[] { "Name", "Type" }, true)); + // disable modify button for an empty list + objectList.enableButton(1, false); + objectList.setRemoveButtonIndex(2); + objectList.doFillIntoGrid(parent, nColumns); + } + + @Override + public void createControl(Composite parent) { + int nColumns = 5; + + initializeDialogUnits(parent); + Composite composite = new Composite(parent, SWT.NONE); + composite.setFont(parent.getFont()); + + GridLayout layout = new GridLayout(); + layout.numColumns = nColumns; + composite.setLayout(layout); + + Label label = new Label(composite, SWT.NULL); + label.setText("&Pattern name:"); + patternText = new Text(composite, SWT.BORDER | SWT.SINGLE); + patternText.setText(""); + GridData gd_1 = new GridData(GridData.FILL_HORIZONTAL); + gd_1.horizontalSpan = 3; + patternText.setLayoutData(gd_1); + patternText.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + validatePage(); + } + }); + + label = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL); + GridData gd_2 = new GridData(GridData.FILL_HORIZONTAL); + gd_2.horizontalSpan = nColumns; + label.setLayoutData(gd_2); + + createImportsControl(composite, nColumns); + createObjectSelectionControl(composite, nColumns); + + setControl(composite); + validatePage(); + } + + public void validatePage() { + + StatusInfo si = new StatusInfo(StatusInfo.OK, ""); + + if (patternText != null) { + String patternName = patternText.getText(); + if (patternName == null || patternName.length() == 0) { + if (parameterSet) { + si.setError(PATTERN_NAME_MUST_BE_SPECIFIED); + } else { + si.setWarning(PATTERN_NAME_SHOULD_BE_SPECIFIED); + } + } + } + + if (si.getSeverity() == IStatus.OK) { + si.setInfo(""); + } + + updateStatus(si); + + if (si.isError()) { + setErrorMessage(si.getMessage()); + } + } + + protected void updateStatus(IStatus status) { + setPageComplete(!status.matches(IStatus.ERROR)); + StatusUtil.applyToStatusLine(this, status); + } + + /** + * Returns the name of the pattern specified in the wizard. + * + * @return the name of the pattern + */ + public String getPatternName() { + return patternText.getText(); + } + + /** + * Returns the import list of {@link EPackage}s specified in the wizard. + * + * @return the list of imports + */ + public List getImports() { + return importList.getElements(); + } + + /** + * Returns the list of pattern parameters specified in the wizard. + * + * @return the list of pattern parameters + */ + public List getParameters() { + return objectList.getElements(); + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/NewEiqGenmodelPage.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/NewEiqGenmodelPage.java index ef24e5f6..76df0534 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/NewEiqGenmodelPage.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/NewEiqGenmodelPage.java @@ -54,247 +54,233 @@ import com.google.common.collect.Lists; public class NewEiqGenmodelPage extends WizardPage { - //private DataBindingContext m_bindingContext; - private final FormToolkit formToolkit = new FormToolkit( - Display.getDefault()); - private Tree referencedGenmodels; - private TreeViewer genModelViewer; - private Button btnInitializeGeneratorModel; - private Button addGenmodel; - - private ResourceSet set; - private List selectedGenmodels = Lists.newArrayList(); - private boolean displayCreateComposite; - - /** - * Create the wizard. - */ - public NewEiqGenmodelPage(boolean displayCreateComposite) { - super("wizardPage"); - this.displayCreateComposite = displayCreateComposite; - setTitle("EMF-IncQuery Generator model"); - setDescription("Set up a generator model used for code generation."); - set = new ResourceSetImpl(); - } - - /** - * Create contents of the wizard. - * - * @param parent - */ - public void createControl(Composite parent) { - Composite container = new Composite(parent, SWT.NULL); - - setControl(container); - container.setLayout(new GridLayout(1, false)); - - if (displayCreateComposite) { - Section sctnGenmodel = formToolkit.createSection(container, - Section.EXPANDED | Section.TITLE_BAR); - sctnGenmodel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, - false, 1, 1)); - formToolkit.paintBordersFor(sctnGenmodel); - sctnGenmodel.setText("Genmodel"); - - Composite composite = formToolkit.createComposite(sctnGenmodel, - SWT.NONE); - formToolkit.paintBordersFor(composite); - sctnGenmodel.setClient(composite); - composite.setLayout(new GridLayout(3, false)); - new Label(composite, SWT.NONE); - new Label(composite, SWT.NONE); - - btnInitializeGeneratorModel = formToolkit.createButton(composite, - "Initialize Generator Model", SWT.CHECK); - new Label(composite, SWT.NONE); - - formToolkit.createLabel(composite, "Filename", SWT.NONE); - - formToolkit.createLabel(composite, "generator.eiqgen", SWT.NONE); - } - - Section sctnReferencedEmfGenerator = formToolkit.createSection( - container, Section.EXPANDED | Section.TITLE_BAR); - sctnReferencedEmfGenerator.setLayoutData(new GridData(SWT.FILL, - SWT.FILL, true, true, 1, 1)); - formToolkit.paintBordersFor(sctnReferencedEmfGenerator); - sctnReferencedEmfGenerator.setText("Referenced EMF Generator models"); - - referencedGenmodels = formToolkit.createTree( - sctnReferencedEmfGenerator, SWT.NONE); - referencedGenmodels.setEnabled(false); - formToolkit.paintBordersFor(referencedGenmodels); - sctnReferencedEmfGenerator.setClient(referencedGenmodels); - referencedGenmodels.setHeaderVisible(true); - referencedGenmodels.setLinesVisible(true); - - genModelViewer = new TreeViewer(referencedGenmodels); - genModelViewer.setContentProvider(new ITreeContentProvider() { - - List genmodels; - - @SuppressWarnings("unchecked") - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - if (newInput instanceof List) { - genmodels = (List) newInput; - } - } - - @Override - public void dispose() { } - - @Override - public boolean hasChildren(Object element) { - return element instanceof GenModel && !((GenModel)element).getGenPackages().isEmpty(); - } - - @Override - public Object getParent(Object element) { - if (element instanceof GenPackage) { - return ((GenPackage) element).getGenModel(); - } - return null; - } - - @Override - public Object[] getElements(Object inputElement) { - return genmodels.toArray(new GenModel[genmodels.size()]); - } - - @Override - public Object[] getChildren(Object parentElement) { - if (parentElement instanceof GenModel) { - List packages = ((GenModel) parentElement).getGenPackages(); - return packages.toArray(new GenPackage[packages.size()]); - } - return null; - } - }); - genModelViewer.setLabelProvider(new LabelProvider() { - - }); - TreeViewerColumn resourcePathColumn = new TreeViewerColumn(genModelViewer, SWT.LEFT); - resourcePathColumn.setLabelProvider(new ColumnLabelProvider() { - - @Override - public String getText(Object element) { - if (element instanceof GenModel) { - return ((GenModel) element).eResource().getURI().toPlatformString(true); - } else if (element instanceof GenPackage) { - return ((GenPackage) element).getNSURI(); - } - return super.getText(element); - } - }); - TreeViewerColumn packageURIColumn = new TreeViewerColumn(genModelViewer, SWT.LEFT); - packageURIColumn.setLabelProvider(new ColumnLabelProvider() { - - @Override - public String getText(Object element) { - if (element instanceof GenModel) { - return String.format("Plug-in dependency: %s",((GenModel) element).getModelPluginID()); - } else if (element instanceof GenPackage) { - return ""; - } - return super.getText(element); - } - - }); - TableLayout tableLayout = new TableLayout(); - tableLayout.addColumnData(new ColumnWeightData(50, true)); - tableLayout.addColumnData(new ColumnWeightData(50, true)); - referencedGenmodels.setLayout(tableLayout); - - genModelViewer.setInput(selectedGenmodels); - - Composite composite_1 = formToolkit.createComposite( - sctnReferencedEmfGenerator, SWT.NONE); - formToolkit.paintBordersFor(composite_1); - sctnReferencedEmfGenerator.setTextClient(composite_1); - composite_1.setLayout(new RowLayout(SWT.HORIZONTAL)); - - addGenmodel = formToolkit.createButton(composite_1, "Add", SWT.NONE); - addGenmodel.setEnabled(false); - addGenmodel.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - selectGenmodelFromWorkspace(); - } - }); - if (displayCreateComposite) { - /*m_bindingContext = */initDataBindings(); - } - } - - protected DataBindingContext initDataBindings() { - DataBindingContext bindingContext = new DataBindingContext(); - // - IObservableValue observeSelectionBtnInitializeGeneratorModelObserveWidget = WidgetProperties - .selection().observe(btnInitializeGeneratorModel); - IObservableValue enabledReferencedGenmodelsObserveValue = PojoProperties - .value("enabled").observe(referencedGenmodels); - bindingContext.bindValue( - observeSelectionBtnInitializeGeneratorModelObserveWidget, - enabledReferencedGenmodelsObserveValue, null, null); - // - IObservableValue observeEnabledAddGenmodelObserveWidget = WidgetProperties - .enabled().observe(addGenmodel); - IObservableValue observeSelectionBtnInitializeGeneratorModelObserveWidget_1 = WidgetProperties - .selection().observe(btnInitializeGeneratorModel); - bindingContext.bindValue(observeEnabledAddGenmodelObserveWidget, - observeSelectionBtnInitializeGeneratorModelObserveWidget_1, - null, null); - // - return bindingContext; - } - - @Override - public void setVisible(boolean visible) { - if (visible) { - if (displayCreateComposite) { - btnInitializeGeneratorModel.setSelection(true); - } - addGenmodel.setEnabled(true); - referencedGenmodels.setEnabled(true); - } - super.setVisible(visible); - } - - public void selectGenmodelFromWorkspace() { - ViewerFilter genmodelFileFilter = new ViewerFilter() { - - @Override - public boolean select(Viewer viewer, Object parentElement, Object element) { - if (element instanceof IFile) { - return "genmodel".equals(((IFile) element).getFileExtension()); - } - return true; - } - }; - IFile[] files = WorkspaceResourceDialog - .openFileSelection( - getShell(), - "Select EMF Generator model", - "Select EMF generator model(s) to add to the initialized EMF-IncQuery generator model", - true, null, ImmutableList.of(genmodelFileFilter)); - for (IFile file : files) { - URI uri = URI.createPlatformResourceURI(file.getFullPath().toString(), true); - Resource res = set.getResource(uri, true); - for (EObject obj : res.getContents()) { - if (obj instanceof GenModel) { - selectedGenmodels.add((GenModel) obj); - } - } - genModelViewer.refresh(); - } - } - - public List getSelectedGenmodels() { - return selectedGenmodels; - } - - public boolean isCreateGenmodelChecked() { - return !displayCreateComposite || btnInitializeGeneratorModel.getSelection(); - } + // private DataBindingContext m_bindingContext; + private final FormToolkit formToolkit = new FormToolkit(Display.getDefault()); + private Tree referencedGenmodels; + private TreeViewer genModelViewer; + private Button btnInitializeGeneratorModel; + private Button addGenmodel; + + private ResourceSet set; + private List selectedGenmodels = Lists.newArrayList(); + private boolean displayCreateComposite; + + /** + * Create the wizard. + */ + public NewEiqGenmodelPage(boolean displayCreateComposite) { + super("wizardPage"); + this.displayCreateComposite = displayCreateComposite; + setTitle("EMF-IncQuery Generator model"); + setDescription("Set up a generator model used for code generation."); + set = new ResourceSetImpl(); + } + + /** + * Create contents of the wizard. + * + * @param parent + */ + public void createControl(Composite parent) { + Composite container = new Composite(parent, SWT.NULL); + + setControl(container); + container.setLayout(new GridLayout(1, false)); + + if (displayCreateComposite) { + Section sctnGenmodel = formToolkit.createSection(container, Section.EXPANDED | Section.TITLE_BAR); + sctnGenmodel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); + formToolkit.paintBordersFor(sctnGenmodel); + sctnGenmodel.setText("Genmodel"); + + Composite composite = formToolkit.createComposite(sctnGenmodel, SWT.NONE); + formToolkit.paintBordersFor(composite); + sctnGenmodel.setClient(composite); + composite.setLayout(new GridLayout(3, false)); + new Label(composite, SWT.NONE); + new Label(composite, SWT.NONE); + + btnInitializeGeneratorModel = formToolkit.createButton(composite, "Initialize Generator Model", SWT.CHECK); + new Label(composite, SWT.NONE); + + formToolkit.createLabel(composite, "Filename", SWT.NONE); + + formToolkit.createLabel(composite, "generator.eiqgen", SWT.NONE); + } + + Section sctnReferencedEmfGenerator = formToolkit.createSection(container, Section.EXPANDED | Section.TITLE_BAR); + sctnReferencedEmfGenerator.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); + formToolkit.paintBordersFor(sctnReferencedEmfGenerator); + sctnReferencedEmfGenerator.setText("Referenced EMF Generator models"); + + referencedGenmodels = formToolkit.createTree(sctnReferencedEmfGenerator, SWT.NONE); + referencedGenmodels.setEnabled(false); + formToolkit.paintBordersFor(referencedGenmodels); + sctnReferencedEmfGenerator.setClient(referencedGenmodels); + referencedGenmodels.setHeaderVisible(true); + referencedGenmodels.setLinesVisible(true); + + genModelViewer = new TreeViewer(referencedGenmodels); + genModelViewer.setContentProvider(new ITreeContentProvider() { + + List genmodels; + + @SuppressWarnings("unchecked") + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + if (newInput instanceof List) { + genmodels = (List) newInput; + } + } + + @Override + public void dispose() { + } + + @Override + public boolean hasChildren(Object element) { + return element instanceof GenModel && !((GenModel) element).getGenPackages().isEmpty(); + } + + @Override + public Object getParent(Object element) { + if (element instanceof GenPackage) { + return ((GenPackage) element).getGenModel(); + } + return null; + } + + @Override + public Object[] getElements(Object inputElement) { + return genmodels.toArray(new GenModel[genmodels.size()]); + } + + @Override + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof GenModel) { + List packages = ((GenModel) parentElement).getGenPackages(); + return packages.toArray(new GenPackage[packages.size()]); + } + return null; + } + }); + genModelViewer.setLabelProvider(new LabelProvider() { + + }); + TreeViewerColumn resourcePathColumn = new TreeViewerColumn(genModelViewer, SWT.LEFT); + resourcePathColumn.setLabelProvider(new ColumnLabelProvider() { + + @Override + public String getText(Object element) { + if (element instanceof GenModel) { + return ((GenModel) element).eResource().getURI().toPlatformString(true); + } else if (element instanceof GenPackage) { + return ((GenPackage) element).getNSURI(); + } + return super.getText(element); + } + }); + TreeViewerColumn packageURIColumn = new TreeViewerColumn(genModelViewer, SWT.LEFT); + packageURIColumn.setLabelProvider(new ColumnLabelProvider() { + + @Override + public String getText(Object element) { + if (element instanceof GenModel) { + return String.format("Plug-in dependency: %s", ((GenModel) element).getModelPluginID()); + } else if (element instanceof GenPackage) { + return ""; + } + return super.getText(element); + } + + }); + TableLayout tableLayout = new TableLayout(); + tableLayout.addColumnData(new ColumnWeightData(50, true)); + tableLayout.addColumnData(new ColumnWeightData(50, true)); + referencedGenmodels.setLayout(tableLayout); + + genModelViewer.setInput(selectedGenmodels); + + Composite composite_1 = formToolkit.createComposite(sctnReferencedEmfGenerator, SWT.NONE); + formToolkit.paintBordersFor(composite_1); + sctnReferencedEmfGenerator.setTextClient(composite_1); + composite_1.setLayout(new RowLayout(SWT.HORIZONTAL)); + + addGenmodel = formToolkit.createButton(composite_1, "Add", SWT.NONE); + addGenmodel.setEnabled(false); + addGenmodel.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + selectGenmodelFromWorkspace(); + } + }); + if (displayCreateComposite) { + /* m_bindingContext = */initDataBindings(); + } + } + + protected DataBindingContext initDataBindings() { + DataBindingContext bindingContext = new DataBindingContext(); + // + IObservableValue observeSelectionBtnInitializeGeneratorModelObserveWidget = WidgetProperties.selection() + .observe(btnInitializeGeneratorModel); + IObservableValue enabledReferencedGenmodelsObserveValue = PojoProperties.value("enabled").observe( + referencedGenmodels); + bindingContext.bindValue(observeSelectionBtnInitializeGeneratorModelObserveWidget, + enabledReferencedGenmodelsObserveValue, null, null); + // + IObservableValue observeEnabledAddGenmodelObserveWidget = WidgetProperties.enabled().observe(addGenmodel); + IObservableValue observeSelectionBtnInitializeGeneratorModelObserveWidget_1 = WidgetProperties.selection() + .observe(btnInitializeGeneratorModel); + bindingContext.bindValue(observeEnabledAddGenmodelObserveWidget, + observeSelectionBtnInitializeGeneratorModelObserveWidget_1, null, null); + // + return bindingContext; + } + + @Override + public void setVisible(boolean visible) { + if (visible) { + if (displayCreateComposite) { + btnInitializeGeneratorModel.setSelection(true); + } + addGenmodel.setEnabled(true); + referencedGenmodels.setEnabled(true); + } + super.setVisible(visible); + } + + public void selectGenmodelFromWorkspace() { + ViewerFilter genmodelFileFilter = new ViewerFilter() { + + @Override + public boolean select(Viewer viewer, Object parentElement, Object element) { + if (element instanceof IFile) { + return "genmodel".equals(((IFile) element).getFileExtension()); + } + return true; + } + }; + IFile[] files = WorkspaceResourceDialog.openFileSelection(getShell(), "Select EMF Generator model", + "Select EMF generator model(s) to add to the initialized EMF-IncQuery generator model", true, null, + ImmutableList.of(genmodelFileFilter)); + for (IFile file : files) { + URI uri = URI.createPlatformResourceURI(file.getFullPath().toString(), true); + Resource res = set.getResource(uri, true); + for (EObject obj : res.getContents()) { + if (obj instanceof GenModel) { + selectedGenmodels.add((GenModel) obj); + } + } + genModelViewer.refresh(); + } + } + + public List getSelectedGenmodels() { + return selectedGenmodels; + } + + public boolean isCreateGenmodelChecked() { + return !displayCreateComposite || btnInitializeGeneratorModel.getSelection(); + } } diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/NewGenmodelWizard.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/NewGenmodelWizard.java index 4a4035c7..6e980053 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/NewGenmodelWizard.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/NewGenmodelWizard.java @@ -40,79 +40,74 @@ public class NewGenmodelWizard extends Wizard implements INewWizard { - private IWorkbench workbench; - private IStructuredSelection selection; - private SelectIncQueryProjectPage projectPage; - private NewEiqGenmodelPage genmodelPage; - - @Inject - private IEiqGenmodelProvider genmodelProvider; - @Inject - private IResourceSetProvider resourceSetProvider; - @Inject - private Logger logger; - - @Override - public void addPages() { - projectPage = new SelectIncQueryProjectPage( - "Select EMF-IncQuery project", selection, logger); - addPage(projectPage); - genmodelPage = new NewEiqGenmodelPage(false); - addPage(genmodelPage); - } - - @Override - public void init(IWorkbench workbench, IStructuredSelection selection) { - this.workbench = workbench; - this.selection = selection; - - } - - @Override - public boolean performFinish() { - IProject project = projectPage.getSelectedProject(); - - WorkspaceModifyOperation op = null; - List genmodelDependencies = new ArrayList(); - for (GenModel model : genmodelPage.getSelectedGenmodels()) { - String modelPluginID = model.getModelPluginID(); - if (!genmodelDependencies.contains(modelPluginID)) { - genmodelDependencies.add(modelPluginID); - } - } - WorkspaceModifyOperation projectOp = new EnsureProjectDependencies( - project, genmodelDependencies); - WorkspaceModifyOperation genmodelOp = new CreateGenmodelOperation( - project, genmodelPage.getSelectedGenmodels(), genmodelProvider, - resourceSetProvider); - op = new CompositeWorkspaceModifyOperation( - new WorkspaceModifyOperation[] { projectOp, genmodelOp }, - "Creating generator model"); - - try { - getContainer().run(true, true, op); - } catch (InterruptedException e) { - return false; - } catch (InvocationTargetException e) { - Throwable realException = e.getTargetException(); - logger.error("Cannot initialize EMF-IncQuery generator model " + realException.getMessage(), realException); - MessageDialog.openError(getShell(), "Error", - realException.getMessage()); - return false; - } - - IFile genmodelFile = (IFile) project.findMember(IncQueryNature.IQGENMODEL); - BasicNewProjectResourceWizard.selectAndReveal(genmodelFile, - workbench.getActiveWorkbenchWindow()); - - IWorkbenchPage page = workbench.getActiveWorkbenchWindow().getActivePage(); - - try { - page.openEditor(new FileEditorInput(genmodelFile), workbench.getEditorRegistry().getDefaultEditor(genmodelFile.getName()).getId()); - } catch (PartInitException e) { - logger.error("Cannot open EMF-IncQuery generator model", e); - } - return true; - } + private IWorkbench workbench; + private IStructuredSelection selection; + private SelectIncQueryProjectPage projectPage; + private NewEiqGenmodelPage genmodelPage; + + @Inject + private IEiqGenmodelProvider genmodelProvider; + @Inject + private IResourceSetProvider resourceSetProvider; + @Inject + private Logger logger; + + @Override + public void addPages() { + projectPage = new SelectIncQueryProjectPage("Select EMF-IncQuery project", selection, logger); + addPage(projectPage); + genmodelPage = new NewEiqGenmodelPage(false); + addPage(genmodelPage); + } + + @Override + public void init(IWorkbench workbench, IStructuredSelection selection) { + this.workbench = workbench; + this.selection = selection; + + } + + @Override + public boolean performFinish() { + IProject project = projectPage.getSelectedProject(); + + WorkspaceModifyOperation op = null; + List genmodelDependencies = new ArrayList(); + for (GenModel model : genmodelPage.getSelectedGenmodels()) { + String modelPluginID = model.getModelPluginID(); + if (!genmodelDependencies.contains(modelPluginID)) { + genmodelDependencies.add(modelPluginID); + } + } + WorkspaceModifyOperation projectOp = new EnsureProjectDependencies(project, genmodelDependencies); + WorkspaceModifyOperation genmodelOp = new CreateGenmodelOperation(project, genmodelPage.getSelectedGenmodels(), + genmodelProvider, resourceSetProvider); + op = new CompositeWorkspaceModifyOperation(new WorkspaceModifyOperation[] { projectOp, genmodelOp }, + "Creating generator model"); + + try { + getContainer().run(true, true, op); + } catch (InterruptedException e) { + return false; + } catch (InvocationTargetException e) { + Throwable realException = e.getTargetException(); + logger.error("Cannot initialize EMF-IncQuery generator model " + realException.getMessage(), realException); + MessageDialog.openError(getShell(), "Error", realException.getMessage()); + return false; + } + + IFile genmodelFile = (IFile) project.findMember(IncQueryNature.IQGENMODEL); + BasicNewProjectResourceWizard.selectAndReveal(genmodelFile, workbench.getActiveWorkbenchWindow()); + + IWorkbenchPage page = workbench.getActiveWorkbenchWindow().getActivePage(); + + try { + page.openEditor(new FileEditorInput(genmodelFile), + workbench.getEditorRegistry().getDefaultEditor(genmodelFile.getName()).getId()); + } catch (PartInitException e) { + logger.error("Cannot open EMF-IncQuery generator model", e); + } + return true; + } } diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/NewProjectWizard.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/NewProjectWizard.java index 40f8b5b1..8198cdd0 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/NewProjectWizard.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/NewProjectWizard.java @@ -49,103 +49,96 @@ */ public class NewProjectWizard extends Wizard implements INewWizard { - private WizardNewProjectCreationPage projectCreationPage; - private NewEiqGenmodelPage genmodelPage; - private IProject project; - private IWorkbench workbench; - private IWorkspace workspace; - - @Inject - private IEiqGenmodelProvider genmodelProvider; - @Inject - private IResourceSetProvider resourceSetProvider; - @Inject - private Logger logger; - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.wizard.Wizard#addPages() - */ - @Override - public void addPages() { - projectCreationPage = new WizardNewProjectCreationPage( - "NewIncQueryProject"); - projectCreationPage.setTitle("New EMF IncQuery Project"); - projectCreationPage - .setDescription("Create a new EMF IncQuery project."); - addPage(projectCreationPage); - genmodelPage = new NewEiqGenmodelPage(true); - addPage(genmodelPage); - } - - public void init(IWorkbench workbench, IStructuredSelection selection) { - this.workbench = workbench; - workspace = ResourcesPlugin.getWorkspace(); - } - - @Override - public boolean performFinish() { - if (project != null) { - return true; - } - final IProject projectHandle = projectCreationPage.getProjectHandle(); - if (projectHandle.exists()) { - return false; - } - URI projectURI = (!projectCreationPage.useDefaults()) ? projectCreationPage - .getLocationURI() : null; - final IProjectDescription description = workspace - .newProjectDescription(projectHandle.getName()); - description.setLocationURI(projectURI); - - WorkspaceModifyOperation op = null; - if (genmodelPage.isCreateGenmodelChecked()) { - List genmodelDependencies = new ArrayList(); - for (GenModel model : genmodelPage.getSelectedGenmodels()) { - String modelPluginID = model.getModelPluginID(); - if (!genmodelDependencies.contains(modelPluginID)) { - genmodelDependencies.add(modelPluginID); - } - } - WorkspaceModifyOperation projectOp = new CreateProjectOperation( - projectHandle, description, genmodelDependencies); - WorkspaceModifyOperation genmodelOp = new CreateGenmodelOperation( - projectHandle, genmodelPage.getSelectedGenmodels(), - genmodelProvider, resourceSetProvider); - op = new CompositeWorkspaceModifyOperation( - new WorkspaceModifyOperation[] { projectOp, genmodelOp }, - "Creating project"); - } else { - op = new CreateProjectOperation(projectHandle, description, ImmutableList.of()); - } - - try { - getContainer().run(true, true, op); - } catch (InterruptedException e) { - return false; - } catch (InvocationTargetException e) { - //Removing project if it is partially created - if (projectHandle.exists()) { - try { - projectHandle.delete(true, new NullProgressMonitor()); - } catch (CoreException e1) { - logger.error("Cannot remove partially created EMF-IncQuery project.", e1); - } - } - Throwable realException = e.getTargetException(); - logger.error("Cannot create EMF-IncQuery project: " + realException.getMessage(), realException); - MessageDialog.openError(getShell(), "Error", - realException.getMessage()); - return false; - } - - project = projectHandle; - - BasicNewProjectResourceWizard.selectAndReveal(project, - workbench.getActiveWorkbenchWindow()); - - return true; - - } + private WizardNewProjectCreationPage projectCreationPage; + private NewEiqGenmodelPage genmodelPage; + private IProject project; + private IWorkbench workbench; + private IWorkspace workspace; + + @Inject + private IEiqGenmodelProvider genmodelProvider; + @Inject + private IResourceSetProvider resourceSetProvider; + @Inject + private Logger logger; + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.wizard.Wizard#addPages() + */ + @Override + public void addPages() { + projectCreationPage = new WizardNewProjectCreationPage("NewIncQueryProject"); + projectCreationPage.setTitle("New EMF IncQuery Project"); + projectCreationPage.setDescription("Create a new EMF IncQuery project."); + addPage(projectCreationPage); + genmodelPage = new NewEiqGenmodelPage(true); + addPage(genmodelPage); + } + + public void init(IWorkbench workbench, IStructuredSelection selection) { + this.workbench = workbench; + workspace = ResourcesPlugin.getWorkspace(); + } + + @Override + public boolean performFinish() { + if (project != null) { + return true; + } + final IProject projectHandle = projectCreationPage.getProjectHandle(); + if (projectHandle.exists()) { + return false; + } + URI projectURI = (!projectCreationPage.useDefaults()) ? projectCreationPage.getLocationURI() : null; + final IProjectDescription description = workspace.newProjectDescription(projectHandle.getName()); + description.setLocationURI(projectURI); + + WorkspaceModifyOperation op = null; + if (genmodelPage.isCreateGenmodelChecked()) { + List genmodelDependencies = new ArrayList(); + for (GenModel model : genmodelPage.getSelectedGenmodels()) { + String modelPluginID = model.getModelPluginID(); + if (!genmodelDependencies.contains(modelPluginID)) { + genmodelDependencies.add(modelPluginID); + } + } + WorkspaceModifyOperation projectOp = new CreateProjectOperation(projectHandle, description, + genmodelDependencies); + WorkspaceModifyOperation genmodelOp = new CreateGenmodelOperation(projectHandle, + genmodelPage.getSelectedGenmodels(), genmodelProvider, resourceSetProvider); + op = new CompositeWorkspaceModifyOperation(new WorkspaceModifyOperation[] { projectOp, genmodelOp }, + "Creating project"); + } else { + op = new CreateProjectOperation(projectHandle, description, ImmutableList. of()); + } + + try { + getContainer().run(true, true, op); + } catch (InterruptedException e) { + return false; + } catch (InvocationTargetException e) { + // Removing project if it is partially created + if (projectHandle.exists()) { + try { + projectHandle.delete(true, new NullProgressMonitor()); + } catch (CoreException e1) { + logger.error("Cannot remove partially created EMF-IncQuery project.", e1); + } + } + Throwable realException = e.getTargetException(); + logger.error("Cannot create EMF-IncQuery project: " + realException.getMessage(), realException); + MessageDialog.openError(getShell(), "Error", realException.getMessage()); + return false; + } + + project = projectHandle; + + BasicNewProjectResourceWizard.selectAndReveal(project, workbench.getActiveWorkbenchWindow()); + + return true; + + } } diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/SelectIncQueryProjectPage.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/SelectIncQueryProjectPage.java index b1ab9df8..7d354d84 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/SelectIncQueryProjectPage.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/SelectIncQueryProjectPage.java @@ -43,161 +43,147 @@ import org.eclipse.ui.forms.widgets.FormToolkit; public class SelectIncQueryProjectPage extends WizardPage { - private final static class ProjectColumnLabelProvider extends - ColumnLabelProvider { - private Color disabledColor; - - public ProjectColumnLabelProvider(Color disabledColor) { - super(); - this.disabledColor = disabledColor; - } - - @Override - public String getText(Object element) { - if (element instanceof IProject) { - return ((IProject) element).getName(); - } - return super.getText(element); - } - - @Override - public Color getForeground(Object element) { - if (element instanceof IProject - && ((IProject) element) - .findMember(IncQueryNature.IQGENMODEL) != null) { - return disabledColor; - } - return super.getForeground(element); - } - - @Override - public String getToolTipText(Object element) { - if (element instanceof IProject - && ((IProject) element) - .findMember(IncQueryNature.IQGENMODEL) != null) { - return String - .format("Project %s has already defined an EMF-IncQuery Generator model.", - ((IProject) element).getName()); - } - return super.getToolTipText(element); - } - } - - private final FormToolkit formToolkit = new FormToolkit( - Display.getDefault()); - private IStructuredSelection selection; - private TableViewer viewer; - - private Logger logger; - - /** - * Create the wizard. - */ - public SelectIncQueryProjectPage(String title, - IStructuredSelection selection, - Logger logger) { - super("wizardPage"); - this.selection = selection; - this.logger = logger; - setTitle(title); - setDescription("Select an EMF-IncQuery project without an EMF-IncQuery Generator model"); - } - - /** - * Create contents of the wizard. - * - * @param parent - */ - public void createControl(Composite parent) { - Composite container = new Composite(parent, SWT.NULL); - - setControl(container); - container.setLayout(new FillLayout(SWT.HORIZONTAL)); - - Table table = formToolkit.createTable(container, SWT.NONE); - formToolkit.paintBordersFor(table); - table.setHeaderVisible(true); - table.setLinesVisible(true); - - IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); - - viewer = new TableViewer(table); - viewer.setContentProvider(new ArrayContentProvider()); - TableViewerColumn column = new TableViewerColumn(viewer, SWT.LEFT); - column.setLabelProvider(new ProjectColumnLabelProvider(parent.getDisplay().getSystemColor(SWT.COLOR_GRAY))); - viewer.addFilter(new ViewerFilter() { - - @Override - public boolean select(Viewer viewer, Object parentElement, - Object element) { - if (element instanceof IProject) { - try { - IProject project = (IProject) element; - return project.exists() && project.isOpen() - && project.hasNature(IncQueryNature.NATURE_ID); - } catch (CoreException e) { - // This exception shall not come forth - logger.error("Error while filtering project list", e); - } - } - return false; - } - }); - - viewer.addSelectionChangedListener(new ISelectionChangedListener() { - - @Override - public void selectionChanged(SelectionChangedEvent event) { - if (getContainer().getCurrentPage() != null) { - getContainer().updateButtons(); - } - } - }); - - viewer.setInput(root.getProjects()); - TableLayout layout = new TableLayout(); - layout.addColumnData(new ColumnWeightData(100)); - table.setLayout(layout); - - Iterator it = selection.iterator(); - while (it.hasNext()) { - Object obj = it.next(); - if (obj instanceof IResource) { - IProject containerProject = ((IResource) obj).getProject(); - setSelectedProject(viewer, containerProject); - } else if (obj instanceof IAdaptable) { - IProject containerProject = ((IResource) ((IAdaptable) obj) - .getAdapter(IResource.class)).getProject(); - setSelectedProject(viewer, containerProject); - } - } - - } - - private void setSelectedProject(TableViewer viewer, - IProject containerProject) { - try { - if (containerProject.hasNature(IncQueryNature.NATURE_ID)) { - viewer.setSelection(new StructuredSelection(containerProject)); - } - } catch (CoreException e) { - // This exception shall not come forth - logger.error("Error while selecting project " + containerProject.getName(), e); - } - } - - public IProject getSelectedProject() { - if (!viewer.getSelection().isEmpty()) { - return (IProject) ((IStructuredSelection) viewer.getSelection()) - .getFirstElement(); - } - return null; - } - - @Override - public boolean isPageComplete() { - return !viewer.getSelection().isEmpty() - && !(getSelectedProject().findMember(IncQueryNature.IQGENMODEL) != null); - } + private final static class ProjectColumnLabelProvider extends ColumnLabelProvider { + private Color disabledColor; + + public ProjectColumnLabelProvider(Color disabledColor) { + super(); + this.disabledColor = disabledColor; + } + + @Override + public String getText(Object element) { + if (element instanceof IProject) { + return ((IProject) element).getName(); + } + return super.getText(element); + } + + @Override + public Color getForeground(Object element) { + if (element instanceof IProject && ((IProject) element).findMember(IncQueryNature.IQGENMODEL) != null) { + return disabledColor; + } + return super.getForeground(element); + } + + @Override + public String getToolTipText(Object element) { + if (element instanceof IProject && ((IProject) element).findMember(IncQueryNature.IQGENMODEL) != null) { + return String.format("Project %s has already defined an EMF-IncQuery Generator model.", + ((IProject) element).getName()); + } + return super.getToolTipText(element); + } + } + + private final FormToolkit formToolkit = new FormToolkit(Display.getDefault()); + private IStructuredSelection selection; + private TableViewer viewer; + + private Logger logger; + + /** + * Create the wizard. + */ + public SelectIncQueryProjectPage(String title, IStructuredSelection selection, Logger logger) { + super("wizardPage"); + this.selection = selection; + this.logger = logger; + setTitle(title); + setDescription("Select an EMF-IncQuery project without an EMF-IncQuery Generator model"); + } + + /** + * Create contents of the wizard. + * + * @param parent + */ + public void createControl(Composite parent) { + Composite container = new Composite(parent, SWT.NULL); + + setControl(container); + container.setLayout(new FillLayout(SWT.HORIZONTAL)); + + Table table = formToolkit.createTable(container, SWT.NONE); + formToolkit.paintBordersFor(table); + table.setHeaderVisible(true); + table.setLinesVisible(true); + + IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); + + viewer = new TableViewer(table); + viewer.setContentProvider(new ArrayContentProvider()); + TableViewerColumn column = new TableViewerColumn(viewer, SWT.LEFT); + column.setLabelProvider(new ProjectColumnLabelProvider(parent.getDisplay().getSystemColor(SWT.COLOR_GRAY))); + viewer.addFilter(new ViewerFilter() { + + @Override + public boolean select(Viewer viewer, Object parentElement, Object element) { + if (element instanceof IProject) { + try { + IProject project = (IProject) element; + return project.exists() && project.isOpen() && project.hasNature(IncQueryNature.NATURE_ID); + } catch (CoreException e) { + // This exception shall not come forth + logger.error("Error while filtering project list", e); + } + } + return false; + } + }); + + viewer.addSelectionChangedListener(new ISelectionChangedListener() { + + @Override + public void selectionChanged(SelectionChangedEvent event) { + if (getContainer().getCurrentPage() != null) { + getContainer().updateButtons(); + } + } + }); + + viewer.setInput(root.getProjects()); + TableLayout layout = new TableLayout(); + layout.addColumnData(new ColumnWeightData(100)); + table.setLayout(layout); + + Iterator it = selection.iterator(); + while (it.hasNext()) { + Object obj = it.next(); + if (obj instanceof IResource) { + IProject containerProject = ((IResource) obj).getProject(); + setSelectedProject(viewer, containerProject); + } else if (obj instanceof IAdaptable) { + IProject containerProject = ((IResource) ((IAdaptable) obj).getAdapter(IResource.class)).getProject(); + setSelectedProject(viewer, containerProject); + } + } + + } + + private void setSelectedProject(TableViewer viewer, IProject containerProject) { + try { + if (containerProject.hasNature(IncQueryNature.NATURE_ID)) { + viewer.setSelection(new StructuredSelection(containerProject)); + } + } catch (CoreException e) { + // This exception shall not come forth + logger.error("Error while selecting project " + containerProject.getName(), e); + } + } + + public IProject getSelectedProject() { + if (!viewer.getSelection().isEmpty()) { + return (IProject) ((IStructuredSelection) viewer.getSelection()).getFirstElement(); + } + return null; + } + + @Override + public boolean isPageComplete() { + return !viewer.getSelection().isEmpty() + && !(getSelectedProject().findMember(IncQueryNature.IQGENMODEL) != null); + } } diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ElementSelectionDialog.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ElementSelectionDialog.java index e847aa41..4a493648 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ElementSelectionDialog.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ElementSelectionDialog.java @@ -39,96 +39,92 @@ /** * @author Tamas Szabo - * + * */ @SuppressWarnings("restriction") public class ElementSelectionDialog extends SelectionStatusDialog { - private StyledCellLabelProvider labelProvider; - private IStructuredContentProvider contentProvider; - private TableViewer tableViewer; - //private Map elementMap; - private List elements; + private StyledCellLabelProvider labelProvider; + private IStructuredContentProvider contentProvider; + private TableViewer tableViewer; + // private Map elementMap; + private List elements; private String filter = ""; private Text filterText; private String header; - private ImportFilter importFilter; - - private class ImportFilter extends ViewerFilter { - - private String filterString = ""; - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers - * .Viewer, java.lang.Object, java.lang.Object) - */ - @Override - public boolean select(Viewer viewer, Object parentElement, - Object element) { - StringMatcher matcher = new StringMatcher("*" + filterString + "*", - true, - false); - if (element instanceof EPackage) { - return matcher.match(((EPackage) element).getNsURI()); - } - return true; - } - - } - - public ElementSelectionDialog(Shell parent, - StyledCellLabelProvider labelProvider, String header) { - super(parent); - this.labelProvider = labelProvider; - this.contentProvider = new ElementSelectionDialogContentProvider(); - this.elements = new ArrayList(); - this.header = header; - } - - public void setElements(Object[] elements) { - this.elements.clear(); - for (Object element : elements) { - this.elements.add(element); - } - } - - @Override - protected void computeResult() { - TableItem[] selection = this.tableViewer.getTable().getSelection(); - List result = new ArrayList(); - for (TableItem item : selection) { - result.add(item.getData()); - } - setResult(result); - } - - @Override - protected Control createDialogArea(Composite parent) { + private ImportFilter importFilter; + + private class ImportFilter extends ViewerFilter { + + private String filterString = ""; + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers .Viewer, java.lang.Object, + * java.lang.Object) + */ + @Override + public boolean select(Viewer viewer, Object parentElement, Object element) { + StringMatcher matcher = new StringMatcher("*" + filterString + "*", true, false); + if (element instanceof EPackage) { + return matcher.match(((EPackage) element).getNsURI()); + } + return true; + } + + } + + public ElementSelectionDialog(Shell parent, StyledCellLabelProvider labelProvider, String header) { + super(parent); + this.labelProvider = labelProvider; + this.contentProvider = new ElementSelectionDialogContentProvider(); + this.elements = new ArrayList(); + this.header = header; + } + + public void setElements(Object[] elements) { + this.elements.clear(); + for (Object element : elements) { + this.elements.add(element); + } + } + + @Override + protected void computeResult() { + TableItem[] selection = this.tableViewer.getTable().getSelection(); + List result = new ArrayList(); + for (TableItem item : selection) { + result.add(item.getData()); + } + setResult(result); + } + + @Override + protected Control createDialogArea(Composite parent) { Composite contents = (Composite) super.createDialogArea(parent); createMessageArea(contents); createFilterText(contents); createElementTable(contents); return contents; - } - - private void createElementTable(Composite parent) { - this.tableViewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER); - this.tableViewer.setContentProvider(this.contentProvider); - importFilter = new ImportFilter(); - this.tableViewer.addFilter(importFilter); - - TableViewerColumn column = new TableViewerColumn(tableViewer, SWT.NONE); - column.getColumn().setWidth(400); - column.getColumn().setText(this.header); - column.setLabelProvider(labelProvider); - + } + + private void createElementTable(Composite parent) { + this.tableViewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION + | SWT.BORDER); + this.tableViewer.setContentProvider(this.contentProvider); + importFilter = new ImportFilter(); + this.tableViewer.addFilter(importFilter); + + TableViewerColumn column = new TableViewerColumn(tableViewer, SWT.NONE); + column.getColumn().setWidth(400); + column.getColumn().setText(this.header); + column.setLabelProvider(labelProvider); + final Table table = tableViewer.getTable(); - table.setLayoutData(new GridData(GridData.FILL_BOTH)); - table.setLinesVisible(true); - table.setHeaderVisible(true); + table.setLayoutData(new GridData(GridData.FILL_BOTH)); + table.setLinesVisible(true); + table.setHeaderVisible(true); table.addMouseListener(new MouseAdapter() { @@ -146,9 +142,9 @@ public void mouseDoubleClick(MouseEvent e) { }); - tableViewer.setInput(elements); - } - + tableViewer.setInput(elements); + } + protected Text createFilterText(Composite parent) { Text text = new Text(parent, SWT.BORDER); @@ -164,29 +160,29 @@ protected Text createFilterText(Composite parent) { Listener listener = new Listener() { public void handleEvent(Event e) { - importFilter.filterString = filterText.getText(); - tableViewer.refresh(); - // filterElements(filterText.getText()); + importFilter.filterString = filterText.getText(); + tableViewer.refresh(); + // filterElements(filterText.getText()); } }; text.addListener(SWT.Modify, listener); text.addKeyListener(new KeyListener() { - public void keyPressed(KeyEvent e) { - if (e.keyCode == SWT.ARROW_DOWN) { - tableViewer.getTable().setFocus(); - } - } - - public void keyReleased(KeyEvent e) { - } + public void keyPressed(KeyEvent e) { + if (e.keyCode == SWT.ARROW_DOWN) { + tableViewer.getTable().setFocus(); + } + } + + public void keyReleased(KeyEvent e) { + } }); filterText = text; return text; } - + @Override public int open() { super.open(); diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ElementSelectionDialogContentProvider.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ElementSelectionDialogContentProvider.java index bd8504d7..a1a9f7c6 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ElementSelectionDialogContentProvider.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ElementSelectionDialogContentProvider.java @@ -17,29 +17,28 @@ /** * @author Tamas Szabo - * + * */ public class ElementSelectionDialogContentProvider implements IStructuredContentProvider { - @Override - public void dispose() { - - } - - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - - } - - @Override - public Object[] getElements(Object inputElement) { - if (inputElement instanceof Object[]) { - return (Object[]) inputElement; - } - else if (inputElement instanceof Collection) { - return ((Collection) inputElement).toArray(); - } - return null; - } + @Override + public void dispose() { + + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + + } + + @Override + public Object[] getElements(Object inputElement) { + if (inputElement instanceof Object[]) { + return (Object[]) inputElement; + } else if (inputElement instanceof Collection) { + return ((Collection) inputElement).toArray(); + } + return null; + } } diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ImportListAdapter.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ImportListAdapter.java index 0a6b1067..a34eddf9 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ImportListAdapter.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ImportListAdapter.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.wizards.internal; - +package org.eclipse.incquery.tooling.ui.wizards.internal; + import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -31,84 +31,80 @@ * An {@link IListAdapter} implementation for importing {@link EPackage}s. * * @author Tamas Szabo - * - */ -@SuppressWarnings("restriction") -public class ImportListAdapter implements IListAdapter { - - private NewEiqFileWizardContainerConfigurationPage firstPage; - private IEiqGenmodelProvider metamodelProviderService; - private ILog logger = IncQueryGUIPlugin.getDefault().getLog(); - - public ImportListAdapter( - NewEiqFileWizardContainerConfigurationPage firstPage, - IEiqGenmodelProvider metamodelProviderService) { - this.firstPage = firstPage; - this.metamodelProviderService = metamodelProviderService; - } + * + */ +@SuppressWarnings("restriction") +public class ImportListAdapter implements IListAdapter { + + private NewEiqFileWizardContainerConfigurationPage firstPage; + private IEiqGenmodelProvider metamodelProviderService; + private ILog logger = IncQueryGUIPlugin.getDefault().getLog(); + + public ImportListAdapter(NewEiqFileWizardContainerConfigurationPage firstPage, + IEiqGenmodelProvider metamodelProviderService) { + this.firstPage = firstPage; + this.metamodelProviderService = metamodelProviderService; + } + + @Override + public void customButtonPressed(ListDialogField field, int index) { + // if Add button is pressed + if (index == 0) { + ElementSelectionDialog listDialog = new ElementSelectionDialog(PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getShell(), new ImportListLabelProvider(), "EPackage"); + listDialog.setTitle("Select packages to import"); + listDialog.setMessage("Select one or more package(s) (* = any string, ? = any char):"); + Object[] input = getElements(field); + listDialog.setElements(input); + listDialog.open(); + Object[] result = listDialog.getResult(); + if (result != null && result.length > 0) { + for (Object obj : result) { + field.addElement((EPackage) obj); + } + } + } + } + + /** + * Returns the available {@link EPackage}s. + * + * @param field + * the {@link ListDialogField} instance to avoid duplicate importing + * @return the array of {@link EPackage}s + */ + private Object[] getElements(ListDialogField field) { + List result = new ArrayList(); + + try { + Collection packages = metamodelProviderService.getAllMetamodelObjects(firstPage.getProject()); + for (EPackage ePackage : packages) { + if (!fieldContains(field, ePackage)) { + result.add(ePackage); + } + } + } catch (CoreException e) { + logger.log(new Status(IStatus.ERROR, IncQueryGUIPlugin.PLUGIN_ID, "Error during EPackage collecting: " + + e.getCause().getMessage(), e.getCause())); + } + + return result.toArray(); + } + + private boolean fieldContains(ListDialogField field, EPackage _package) { + for (EPackage _p : field.getElements()) { + if (_p.getNsURI().matches(_package.getNsURI())) { + return true; + } + } + return false; + } + + @Override + public void selectionChanged(ListDialogField field) { + } - @Override - public void customButtonPressed(ListDialogField field, int index) { - //if Add button is pressed - if (index == 0) { - ElementSelectionDialog listDialog = - new ElementSelectionDialog( - PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), - new ImportListLabelProvider(), - "EPackage" - ); - listDialog.setTitle("Select packages to import"); - listDialog.setMessage("Select one or more package(s) (* = any string, ? = any char):"); - Object[] input = getElements(field); - listDialog.setElements(input); - listDialog.open(); - Object[] result = listDialog.getResult(); - if (result != null && result.length > 0) { - for (Object obj : result) { - field.addElement((EPackage) obj); - } - } - } - } - - /** - * Returns the available {@link EPackage}s. - * - * @param field the {@link ListDialogField} instance to avoid duplicate importing - * @return the array of {@link EPackage}s - */ - private Object[] getElements(ListDialogField field) { - List result = new ArrayList(); - - try { - Collection packages = metamodelProviderService.getAllMetamodelObjects(firstPage.getProject()); - for (EPackage ePackage : packages) { - if (!fieldContains(field, ePackage)) { - result.add(ePackage); - } - } - } - catch (CoreException e) { - logger.log(new Status(IStatus.ERROR, - IncQueryGUIPlugin.PLUGIN_ID, - "Error during EPackage collecting: " + e.getCause().getMessage(), e.getCause())); - } - - return result.toArray(); - } - - private boolean fieldContains(ListDialogField field, EPackage _package) { - for (EPackage _p : field.getElements()) { - if (_p.getNsURI().matches(_package.getNsURI())) { - return true; - } - } - return false; - } - - @Override - public void selectionChanged(ListDialogField field) {} - - @Override - public void doubleClicked(ListDialogField field) {} -} + @Override + public void doubleClicked(ListDialogField field) { + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ImportListLabelProvider.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ImportListLabelProvider.java index 34664ae6..3c9fd26f 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ImportListLabelProvider.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ImportListLabelProvider.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.wizards.internal; - +package org.eclipse.incquery.tooling.ui.wizards.internal; + import org.eclipse.emf.ecore.EPackage; import org.eclipse.incquery.tooling.ui.IncQueryGUIPlugin; import org.eclipse.jface.resource.ImageRegistry; @@ -24,68 +24,62 @@ * {@link ILabelProvider} implementation for the {@link ImportListAdapter}. * * @author Tamas Szabo - * - */ -public class ImportListLabelProvider extends StyledCellLabelProvider implements - ILabelProvider { - - private ImageRegistry imageRegistry; - - public ImportListLabelProvider() { - imageRegistry = IncQueryGUIPlugin.getDefault().getImageRegistry(); - } + * + */ +public class ImportListLabelProvider extends StyledCellLabelProvider implements ILabelProvider { + + private ImageRegistry imageRegistry; + + public ImportListLabelProvider() { + imageRegistry = IncQueryGUIPlugin.getDefault().getImageRegistry(); + } - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object) - */ - @Override - public Image getImage(Object element) { - if (element instanceof EPackage) { - return imageRegistry.get(IncQueryGUIPlugin.ICON_EPACKAGE); - } - return null; - } + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object) + */ + @Override + public Image getImage(Object element) { + if (element instanceof EPackage) { + return imageRegistry.get(IncQueryGUIPlugin.ICON_EPACKAGE); + } + return null; + } - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object) - */ - @Override - public String getText(Object element) { - if (element instanceof EPackage) { - return ((EPackage) element).getNsURI(); - } - return null; - } + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object) + */ + @Override + public String getText(Object element) { + if (element instanceof EPackage) { + return ((EPackage) element).getNsURI(); + } + return null; + } - /* - * (non-Javadoc) - * - * @see - * org.eclipse.jface.viewers.StyledCellLabelProvider#update(org.eclipse. - * jface.viewers.ViewerCell) - */ - @Override - public void update(ViewerCell cell) { - Object element = cell.getElement(); - StyledString text = new StyledString(); - if (element instanceof EPackage) { - EPackage ePackage = (EPackage) element; - text.append(ePackage.getNsURI()); - if (ePackage.eResource().getURI().isPlatform()) { - text.append( - String.format(" (%s)", ePackage.eResource().getURI()), - StyledString.QUALIFIER_STYLER); - } - cell.setImage(imageRegistry.get(IncQueryGUIPlugin.ICON_EPACKAGE)); - } - cell.setText(text.getString()); - cell.setStyleRanges(text.getStyleRanges()); - super.update(cell); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.StyledCellLabelProvider#update(org.eclipse. jface.viewers.ViewerCell) + */ + @Override + public void update(ViewerCell cell) { + Object element = cell.getElement(); + StyledString text = new StyledString(); + if (element instanceof EPackage) { + EPackage ePackage = (EPackage) element; + text.append(ePackage.getNsURI()); + if (ePackage.eResource().getURI().isPlatform()) { + text.append(String.format(" (%s)", ePackage.eResource().getURI()), StyledString.QUALIFIER_STYLER); + } + cell.setImage(imageRegistry.get(IncQueryGUIPlugin.ICON_EPACKAGE)); + } + cell.setText(text.getString()); + cell.setStyleRanges(text.getStyleRanges()); + super.update(cell); + } - -} +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ObjectListAdapter.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ObjectListAdapter.java index abf7d512..2d5e5166 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ObjectListAdapter.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ObjectListAdapter.java @@ -9,73 +9,71 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.wizards.internal; - -import org.eclipse.emf.ecore.EPackage; +package org.eclipse.incquery.tooling.ui.wizards.internal; + +import org.eclipse.emf.ecore.EPackage; import org.eclipse.incquery.tooling.ui.wizards.NewEiqFileWizardPatternConfigurationPage; -import org.eclipse.jdt.internal.ui.wizards.dialogfields.IListAdapter; -import org.eclipse.jdt.internal.ui.wizards.dialogfields.ListDialogField; -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.ui.PlatformUI; +import org.eclipse.jdt.internal.ui.wizards.dialogfields.IListAdapter; +import org.eclipse.jdt.internal.ui.wizards.dialogfields.ListDialogField; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.ui.PlatformUI; /** * An {@link IListAdapter} implementation for specifying pattern parameters in the wizard. * * @author Tamas Szabo - * - */ -@SuppressWarnings("restriction") -public class ObjectListAdapter implements IListAdapter { - - private ListDialogField importList; - private NewEiqFileWizardPatternConfigurationPage page; - - public ObjectListAdapter(NewEiqFileWizardPatternConfigurationPage page, ListDialogField importList) { - this.importList = importList; - this.page = page; - } - - @Override - public void customButtonPressed(ListDialogField field, int index) { - ObjectParameter parameter = new ObjectParameter(); - ObjectParameterConfigurationDialog dialog = new ObjectParameterConfigurationDialog( - PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), - importList.getElements(), parameter); - //a unique parameter object is needed because the dialog will be disposed after the ok button is pressed - if (index == 0) { - //Add - if (dialog.open() == Dialog.OK) { - field.addElement(parameter); - } - } - else if (index == 1) { - //Modify - ObjectParameter firstElement = field.getSelectedElements().get(0); - parameter.setObject(firstElement.getObject()); - parameter.setParameterName(firstElement.getParameterName()); - if (dialog.open() == Dialog.OK) { - firstElement.setObject(parameter.getObject()); - firstElement.setParameterName(parameter.getParameterName()); - } - } - - field.refresh(); - } - - @Override - public void selectionChanged(ListDialogField field) { - if (field.getElements().size() > 0) { - field.enableButton(1, true); - page.parameterSet = true; - } - else { - field.enableButton(1, false); - page.parameterSet = false; - } - - page.validatePage(); - } - - @Override - public void doubleClicked(ListDialogField field) {} -} + * + */ +@SuppressWarnings("restriction") +public class ObjectListAdapter implements IListAdapter { + + private ListDialogField importList; + private NewEiqFileWizardPatternConfigurationPage page; + + public ObjectListAdapter(NewEiqFileWizardPatternConfigurationPage page, ListDialogField importList) { + this.importList = importList; + this.page = page; + } + + @Override + public void customButtonPressed(ListDialogField field, int index) { + ObjectParameter parameter = new ObjectParameter(); + ObjectParameterConfigurationDialog dialog = new ObjectParameterConfigurationDialog(PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getShell(), importList.getElements(), parameter); + // a unique parameter object is needed because the dialog will be disposed after the ok button is pressed + if (index == 0) { + // Add + if (dialog.open() == Dialog.OK) { + field.addElement(parameter); + } + } else if (index == 1) { + // Modify + ObjectParameter firstElement = field.getSelectedElements().get(0); + parameter.setObject(firstElement.getObject()); + parameter.setParameterName(firstElement.getParameterName()); + if (dialog.open() == Dialog.OK) { + firstElement.setObject(parameter.getObject()); + firstElement.setParameterName(parameter.getParameterName()); + } + } + + field.refresh(); + } + + @Override + public void selectionChanged(ListDialogField field) { + if (field.getElements().size() > 0) { + field.enableButton(1, true); + page.parameterSet = true; + } else { + field.enableButton(1, false); + page.parameterSet = false; + } + + page.validatePage(); + } + + @Override + public void doubleClicked(ListDialogField field) { + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ObjectListLabelProvider.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ObjectListLabelProvider.java index 4e14a692..78475841 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ObjectListLabelProvider.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ObjectListLabelProvider.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.wizards.internal; - +package org.eclipse.incquery.tooling.ui.wizards.internal; + import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.swt.graphics.Image; @@ -19,27 +19,26 @@ * {@link ITableLabelProvider} implementation for the {@link ObjectListAdapter}. * * @author Tamas Szabo - * - */ -public class ObjectListLabelProvider extends LabelProvider implements ITableLabelProvider { - - @Override - public Image getColumnImage(Object element, int columnIndex) { - return null; - } - - @Override - public String getColumnText(Object element, int columnIndex) { - if (element != null && element instanceof ObjectParameter) { - ObjectParameter parameter = (ObjectParameter) element; - if (columnIndex == 0) { - return parameter.getParameterName(); - } - else { - return parameter.getObject() != null ? parameter.getObject().getName() : ""; - } - } - return null; - } - -} + * + */ +public class ObjectListLabelProvider extends LabelProvider implements ITableLabelProvider { + + @Override + public Image getColumnImage(Object element, int columnIndex) { + return null; + } + + @Override + public String getColumnText(Object element, int columnIndex) { + if (element != null && element instanceof ObjectParameter) { + ObjectParameter parameter = (ObjectParameter) element; + if (columnIndex == 0) { + return parameter.getParameterName(); + } else { + return parameter.getObject() != null ? parameter.getObject().getName() : ""; + } + } + return null; + } + +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ObjectParameter.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ObjectParameter.java index 3e2fc596..5be78ebc 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ObjectParameter.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ObjectParameter.java @@ -9,48 +9,48 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.wizards.internal; - +package org.eclipse.incquery.tooling.ui.wizards.internal; + import org.eclipse.emf.ecore.EClassifier; /** - * Instances of this class represents the specification of a pattern parameter. - * It has a parameter name and type specification as an {@link EClassifier} instance. + * Instances of this class represents the specification of a pattern parameter. It has a parameter name and type + * specification as an {@link EClassifier} instance. * * @author Tamas Szabo - * - */ -public class ObjectParameter { - - private EClassifier object; - private String parameterName; - - public ObjectParameter() { - super(); - this.object = null; - this.parameterName = ""; - } - - public ObjectParameter(EClassifier object, String parameterName) { - super(); - this.object = object; - this.parameterName = parameterName; - } - - public EClassifier getObject() { - return object; - } - - public String getParameterName() { - return parameterName; - } - - public void setObject(EClassifier object) { - this.object = object; - } - - public void setParameterName(String parameterName) { - this.parameterName = parameterName; - } - -} + * + */ +public class ObjectParameter { + + private EClassifier object; + private String parameterName; + + public ObjectParameter() { + super(); + this.object = null; + this.parameterName = ""; + } + + public ObjectParameter(EClassifier object, String parameterName) { + super(); + this.object = object; + this.parameterName = parameterName; + } + + public EClassifier getObject() { + return object; + } + + public String getParameterName() { + return parameterName; + } + + public void setObject(EClassifier object) { + this.object = object; + } + + public void setParameterName(String parameterName) { + this.parameterName = parameterName; + } + +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ObjectParameterConfigurationDialog.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ObjectParameterConfigurationDialog.java index ed111b44..cfa9fe74 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ObjectParameterConfigurationDialog.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ObjectParameterConfigurationDialog.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.wizards.internal; - +package org.eclipse.incquery.tooling.ui.wizards.internal; + import java.util.ArrayList; import java.util.List; @@ -39,133 +39,130 @@ * A {@link Dialog} implementation for configuring one parameter of a pattern. * * @author Tamas Szabo - * - */ -public class ObjectParameterConfigurationDialog extends Dialog { - - private static final String SELECT_A_MODEL_ELEMENT = "Select a model element (* = any string, ? = any char):"; - private static final String PARAMETER_TYPE_SELECTION = "Parameter type selection"; - private static final String PARAMETER_TYPE = "&Parameter type:"; - private static final String PARAMETER_NAME = "&Parameter name:"; - private static final String TITLE = "&Pattern parameter configuration"; - private Text parameterName; - private Text parameterType; - private List currentPackages; - private ObjectParameter result; - - protected ObjectParameterConfigurationDialog(Shell shell, List currentPackages, ObjectParameter result) { - super(shell); - shell.setText(TITLE); - this.currentPackages = currentPackages; - this.result = result; - } - - @Override - protected Control createDialogArea(Composite parent) { - int nColumns = 4; - - Composite composite= new Composite(parent, SWT.NONE); - composite.setFont(parent.getFont()); - - GridLayout layout= new GridLayout(); - layout.numColumns= nColumns; - composite.setLayout(layout); - - Label label = new Label(composite, SWT.NULL); - label.setText(PARAMETER_NAME); - GridData gridData = new GridData(GridData.FILL_HORIZONTAL); - gridData.horizontalSpan = 1; - label.setLayoutData(gridData); - - parameterName = new Text(composite, SWT.BORDER | SWT.SINGLE); - parameterName.setText(result.getParameterName()); - parameterName.setEditable(true); - gridData = new GridData(GridData.FILL_HORIZONTAL); - gridData.horizontalSpan = 3; - parameterName.setLayoutData(gridData); - parameterName.addKeyListener(new KeyAdapter() { - @Override - public void keyReleased(KeyEvent e) { - result.setParameterName(parameterName.getText()); - super.keyReleased(e); - } - }); - - label = new Label(composite, SWT.NULL); - label.setText(PARAMETER_TYPE); - gridData = new GridData(GridData.FILL_HORIZONTAL); - gridData.horizontalSpan = 1; - label.setLayoutData(gridData); - - parameterType = new Text(composite, SWT.BORDER | SWT.SINGLE); - parameterType.setText(result.getObject() == null ? "" : ((EClassifier) result.getObject()).getName()); - parameterType.setEditable(false); - gridData = new GridData(GridData.FILL_HORIZONTAL); - gridData.horizontalSpan = 1; - parameterType.setLayoutData(gridData); - - Button button = new Button(composite, SWT.PUSH); - button.setText("Browse..."); - gridData = new GridData(GridData.FILL_HORIZONTAL); - gridData.horizontalSpan = 1; - button.setLayoutData(gridData); - - button.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - setParameterType(openDialogBox()); - } - }); - - return super.createDialogArea(parent); - } - - /** - * Opens an element selection dialog for choosing the type of the parameter as an {@link EClassifier}. - * - * @return the type of the parameter - */ - private EClassifier openDialogBox() { - ElementListSelectionDialog listDialog = - new ElementListSelectionDialog( - PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), - new ObjectParameterConfigurationLabelProvider() - ); - listDialog.setTitle(PARAMETER_TYPE_SELECTION); - listDialog.setMessage(SELECT_A_MODEL_ELEMENT); - listDialog.setElements(getElements()); - listDialog.open(); - Object[] result = listDialog.getResult(); - if (result != null && result.length > 0) { - return (EClassifier) result[0]; - } - return null; - } - - /** - * Returns the array of {@link EClassifier} instances based on the imported {@link EPackage}s. - * - * @return the array of {@link EClassifier}s - */ - private Object[] getElements() { - List result = new ArrayList(); - for (EPackage _package : currentPackages) { - TreeIterator iterator = _package.eAllContents(); - - while (iterator.hasNext()) { - EObject nextObject = iterator.next(); - if (nextObject instanceof EClassifier) { - result.add(nextObject); - } - } - } - return result.toArray(); - } - - private void setParameterType(EClassifier object) { - this.result.setObject(object); - if (object != null) { - parameterType.setText(((EClassifier) object).getName()); - } - } -} + * + */ +public class ObjectParameterConfigurationDialog extends Dialog { + + private static final String SELECT_A_MODEL_ELEMENT = "Select a model element (* = any string, ? = any char):"; + private static final String PARAMETER_TYPE_SELECTION = "Parameter type selection"; + private static final String PARAMETER_TYPE = "&Parameter type:"; + private static final String PARAMETER_NAME = "&Parameter name:"; + private static final String TITLE = "&Pattern parameter configuration"; + private Text parameterName; + private Text parameterType; + private List currentPackages; + private ObjectParameter result; + + protected ObjectParameterConfigurationDialog(Shell shell, List currentPackages, ObjectParameter result) { + super(shell); + shell.setText(TITLE); + this.currentPackages = currentPackages; + this.result = result; + } + + @Override + protected Control createDialogArea(Composite parent) { + int nColumns = 4; + + Composite composite = new Composite(parent, SWT.NONE); + composite.setFont(parent.getFont()); + + GridLayout layout = new GridLayout(); + layout.numColumns = nColumns; + composite.setLayout(layout); + + Label label = new Label(composite, SWT.NULL); + label.setText(PARAMETER_NAME); + GridData gridData = new GridData(GridData.FILL_HORIZONTAL); + gridData.horizontalSpan = 1; + label.setLayoutData(gridData); + + parameterName = new Text(composite, SWT.BORDER | SWT.SINGLE); + parameterName.setText(result.getParameterName()); + parameterName.setEditable(true); + gridData = new GridData(GridData.FILL_HORIZONTAL); + gridData.horizontalSpan = 3; + parameterName.setLayoutData(gridData); + parameterName.addKeyListener(new KeyAdapter() { + @Override + public void keyReleased(KeyEvent e) { + result.setParameterName(parameterName.getText()); + super.keyReleased(e); + } + }); + + label = new Label(composite, SWT.NULL); + label.setText(PARAMETER_TYPE); + gridData = new GridData(GridData.FILL_HORIZONTAL); + gridData.horizontalSpan = 1; + label.setLayoutData(gridData); + + parameterType = new Text(composite, SWT.BORDER | SWT.SINGLE); + parameterType.setText(result.getObject() == null ? "" : ((EClassifier) result.getObject()).getName()); + parameterType.setEditable(false); + gridData = new GridData(GridData.FILL_HORIZONTAL); + gridData.horizontalSpan = 1; + parameterType.setLayoutData(gridData); + + Button button = new Button(composite, SWT.PUSH); + button.setText("Browse..."); + gridData = new GridData(GridData.FILL_HORIZONTAL); + gridData.horizontalSpan = 1; + button.setLayoutData(gridData); + + button.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + setParameterType(openDialogBox()); + } + }); + + return super.createDialogArea(parent); + } + + /** + * Opens an element selection dialog for choosing the type of the parameter as an {@link EClassifier}. + * + * @return the type of the parameter + */ + private EClassifier openDialogBox() { + ElementListSelectionDialog listDialog = new ElementListSelectionDialog(PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getShell(), new ObjectParameterConfigurationLabelProvider()); + listDialog.setTitle(PARAMETER_TYPE_SELECTION); + listDialog.setMessage(SELECT_A_MODEL_ELEMENT); + listDialog.setElements(getElements()); + listDialog.open(); + Object[] result = listDialog.getResult(); + if (result != null && result.length > 0) { + return (EClassifier) result[0]; + } + return null; + } + + /** + * Returns the array of {@link EClassifier} instances based on the imported {@link EPackage}s. + * + * @return the array of {@link EClassifier}s + */ + private Object[] getElements() { + List result = new ArrayList(); + for (EPackage _package : currentPackages) { + TreeIterator iterator = _package.eAllContents(); + + while (iterator.hasNext()) { + EObject nextObject = iterator.next(); + if (nextObject instanceof EClassifier) { + result.add(nextObject); + } + } + } + return result.toArray(); + } + + private void setParameterType(EClassifier object) { + this.result.setObject(object); + if (object != null) { + parameterType.setText(((EClassifier) object).getName()); + } + } +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ObjectParameterConfigurationLabelProvider.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ObjectParameterConfigurationLabelProvider.java index ad4f0e64..9053e02a 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ObjectParameterConfigurationLabelProvider.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/ObjectParameterConfigurationLabelProvider.java @@ -9,49 +9,51 @@ * Zoltan Ujhelyi, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.tooling.ui.wizards.internal; - +package org.eclipse.incquery.tooling.ui.wizards.internal; + import org.eclipse.emf.ecore.EClassifier; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.swt.graphics.Image; /** - * An {@link ILabelProvider} implementation used in the - * {@link ElementListSelectionDialog} when choosing the type of a pattern parameter. + * An {@link ILabelProvider} implementation used in the {@link ElementListSelectionDialog} when choosing the type of a + * pattern parameter. * * @author Tamas Szabo - * - */ -public class ObjectParameterConfigurationLabelProvider implements ILabelProvider { - - @Override - public void addListener(ILabelProviderListener listener) {} - - @Override - public void dispose() {} - - @Override - public boolean isLabelProperty(Object element, String property) { - return false; - } - - @Override - public void removeListener(ILabelProviderListener listener) {} - - @Override - public Image getImage(Object element) { - return null; - } - - @Override - public String getText(Object element) { - if (element instanceof EClassifier) { - return ((EClassifier) element).getName(); - } - else { - return element.toString(); - } - } - -} + * + */ +public class ObjectParameterConfigurationLabelProvider implements ILabelProvider { + + @Override + public void addListener(ILabelProviderListener listener) { + } + + @Override + public void dispose() { + } + + @Override + public boolean isLabelProperty(Object element, String property) { + return false; + } + + @Override + public void removeListener(ILabelProviderListener listener) { + } + + @Override + public Image getImage(Object element) { + return null; + } + + @Override + public String getText(Object element) { + if (element instanceof EClassifier) { + return ((EClassifier) element).getName(); + } else { + return element.toString(); + } + } + +} diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/operations/CompositeWorkspaceModifyOperation.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/operations/CompositeWorkspaceModifyOperation.java index b4a10814..0046b535 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/operations/CompositeWorkspaceModifyOperation.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/operations/CompositeWorkspaceModifyOperation.java @@ -20,24 +20,23 @@ public class CompositeWorkspaceModifyOperation extends WorkspaceModifyOperation { - WorkspaceModifyOperation[] operations; - private String description; - - public CompositeWorkspaceModifyOperation( - WorkspaceModifyOperation[] operations, String description) { - super(); - this.operations = operations; - this.description = description; - } - - @Override - protected void execute(IProgressMonitor monitor) throws CoreException, - InvocationTargetException, InterruptedException { - monitor.beginTask(description, 10 * operations.length); - for (WorkspaceModifyOperation op : operations) { - op.run(new SubProgressMonitor(monitor, 10)); - } - monitor.done(); - } + WorkspaceModifyOperation[] operations; + private String description; + + public CompositeWorkspaceModifyOperation(WorkspaceModifyOperation[] operations, String description) { + super(); + this.operations = operations; + this.description = description; + } + + @Override + protected void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException, + InterruptedException { + monitor.beginTask(description, 10 * operations.length); + for (WorkspaceModifyOperation op : operations) { + op.run(new SubProgressMonitor(monitor, 10)); + } + monitor.done(); + } } diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/operations/CreateGenmodelOperation.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/operations/CreateGenmodelOperation.java index de288bd5..91614cbc 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/operations/CreateGenmodelOperation.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/operations/CreateGenmodelOperation.java @@ -33,46 +33,40 @@ import org.eclipse.xtext.ui.resource.IResourceSetProvider; import org.eclipse.xtext.util.StringInputStream; -public class CreateGenmodelOperation extends - WorkspaceModifyOperation { - private final IProject project; - private final List genmodels; - private final IEiqGenmodelProvider genmodelProvider; - private final IResourceSetProvider resourceSetProvider; +public class CreateGenmodelOperation extends WorkspaceModifyOperation { + private final IProject project; + private final List genmodels; + private final IEiqGenmodelProvider genmodelProvider; + private final IResourceSetProvider resourceSetProvider; - public CreateGenmodelOperation(IProject project, - List genmodels, IEiqGenmodelProvider genmodelProvider, IResourceSetProvider resourceSetProvider) { - this.project = project; - this.genmodels = genmodels; - this.genmodelProvider = genmodelProvider; - this.resourceSetProvider = resourceSetProvider; - } + public CreateGenmodelOperation(IProject project, List genmodels, IEiqGenmodelProvider genmodelProvider, + IResourceSetProvider resourceSetProvider) { + this.project = project; + this.genmodels = genmodels; + this.genmodelProvider = genmodelProvider; + this.resourceSetProvider = resourceSetProvider; + } - @Override - protected void execute(IProgressMonitor monitor) - throws CoreException { - try { - IncQueryGeneratorModel generatorModel = genmodelProvider - .getGeneratorModel(project, - resourceSetProvider.get(project)); - EList genmodelRefs = generatorModel - .getGenmodels(); - for (GenModel ecoreGenmodel : genmodels) { - GeneratorModelReference ref = GeneratorModelFactory.eINSTANCE - .createGeneratorModelReference(); - ref.setGenmodel(ecoreGenmodel); - genmodelRefs.add(ref); - } - if (genmodelRefs.isEmpty()) { - IFile file = project.getFile(IncQueryNature.IQGENMODEL); - file.create(new StringInputStream(""), false, new SubProgressMonitor(monitor, 1)); - } else { - genmodelProvider.saveGeneratorModel(project, generatorModel); - } - } catch (IOException e) { - throw new CoreException(new Status(IStatus.ERROR, - IncQueryGUIPlugin.PLUGIN_ID, - "Cannot create generator model: " + e.getMessage(), e)); - } - } + @Override + protected void execute(IProgressMonitor monitor) throws CoreException { + try { + IncQueryGeneratorModel generatorModel = genmodelProvider.getGeneratorModel(project, + resourceSetProvider.get(project)); + EList genmodelRefs = generatorModel.getGenmodels(); + for (GenModel ecoreGenmodel : genmodels) { + GeneratorModelReference ref = GeneratorModelFactory.eINSTANCE.createGeneratorModelReference(); + ref.setGenmodel(ecoreGenmodel); + genmodelRefs.add(ref); + } + if (genmodelRefs.isEmpty()) { + IFile file = project.getFile(IncQueryNature.IQGENMODEL); + file.create(new StringInputStream(""), false, new SubProgressMonitor(monitor, 1)); + } else { + genmodelProvider.saveGeneratorModel(project, generatorModel); + } + } catch (IOException e) { + throw new CoreException(new Status(IStatus.ERROR, IncQueryGUIPlugin.PLUGIN_ID, + "Cannot create generator model: " + e.getMessage(), e)); + } + } } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/operations/CreateProjectOperation.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/operations/CreateProjectOperation.java index 02a9dd52..f06c89e1 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/operations/CreateProjectOperation.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/operations/CreateProjectOperation.java @@ -20,22 +20,18 @@ import org.eclipse.incquery.tooling.core.project.ProjectGenerationHelper; import org.eclipse.ui.actions.WorkspaceModifyOperation; -public class CreateProjectOperation extends - WorkspaceModifyOperation { - private final IProject projectHandle; - private final IProjectDescription description; - private final List dependencies; +public class CreateProjectOperation extends WorkspaceModifyOperation { + private final IProject projectHandle; + private final IProjectDescription description; + private final List dependencies; - public CreateProjectOperation(IProject projectHandle, - IProjectDescription description, List dependencies) { - this.projectHandle = projectHandle; - this.description = description; - this.dependencies = dependencies; - } + public CreateProjectOperation(IProject projectHandle, IProjectDescription description, List dependencies) { + this.projectHandle = projectHandle; + this.description = description; + this.dependencies = dependencies; + } - protected void execute(IProgressMonitor monitor) - throws CoreException { - ProjectGenerationHelper.createProject(description, - projectHandle, dependencies, monitor); - } + protected void execute(IProgressMonitor monitor) throws CoreException { + ProjectGenerationHelper.createProject(description, projectHandle, dependencies, monitor); + } } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/operations/EnsureProjectDependencies.java b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/operations/EnsureProjectDependencies.java index 22595040..851a16c5 100644 --- a/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/operations/EnsureProjectDependencies.java +++ b/plugins/org.eclipse.incquery.tooling.ui/src/org/eclipse/incquery/tooling/ui/wizards/internal/operations/EnsureProjectDependencies.java @@ -19,19 +19,16 @@ import org.eclipse.incquery.tooling.core.project.ProjectGenerationHelper; import org.eclipse.ui.actions.WorkspaceModifyOperation; -public class EnsureProjectDependencies extends - WorkspaceModifyOperation { - private final IProject project; - private final List dependencies; +public class EnsureProjectDependencies extends WorkspaceModifyOperation { + private final IProject project; + private final List dependencies; - public EnsureProjectDependencies(IProject project, - List dependencies) { - this.project = project; - this.dependencies = dependencies; - } + public EnsureProjectDependencies(IProject project, List dependencies) { + this.project = project; + this.dependencies = dependencies; + } - protected void execute(IProgressMonitor monitor) - throws CoreException { - ProjectGenerationHelper.ensureBundleDependencies(project, dependencies); - } + protected void execute(IProgressMonitor monitor) throws CoreException { + ProjectGenerationHelper.ensureBundleDependencies(project, dependencies); + } } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.validation.runtime.ui/src/org/eclipse/incquery/validation/runtime/ui/ValidationInitUtil.java b/plugins/org.eclipse.incquery.validation.runtime.ui/src/org/eclipse/incquery/validation/runtime/ui/ValidationInitUtil.java index 002b9454..dbe5896f 100644 --- a/plugins/org.eclipse.incquery.validation.runtime.ui/src/org/eclipse/incquery/validation/runtime/ui/ValidationInitUtil.java +++ b/plugins/org.eclipse.incquery.validation.runtime.ui/src/org/eclipse/incquery/validation/runtime/ui/ValidationInitUtil.java @@ -16,12 +16,12 @@ import org.eclipse.ui.IEditorPart; public class ValidationInitUtil { - + /** * Constructor hidden for utility class */ private ValidationInitUtil() { - + } public static void initializeAdapters(IEditorPart activeEditor, Notifier root) throws IncQueryException { diff --git a/plugins/org.eclipse.incquery.validation.runtime/src/org/eclipse/incquery/validation/runtime/Constraint.java b/plugins/org.eclipse.incquery.validation.runtime/src/org/eclipse/incquery/validation/runtime/Constraint.java index a07aaa14..65da21f0 100644 --- a/plugins/org.eclipse.incquery.validation.runtime/src/org/eclipse/incquery/validation/runtime/Constraint.java +++ b/plugins/org.eclipse.incquery.validation.runtime/src/org/eclipse/incquery/validation/runtime/Constraint.java @@ -9,28 +9,28 @@ * Zoltan Ujhelyi, Abel Hegedus, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.validation.runtime; - +package org.eclipse.incquery.validation.runtime; + import org.eclipse.emf.ecore.EObject; import org.eclipse.incquery.runtime.api.IPatternMatch; import org.eclipse.incquery.runtime.api.impl.BaseGeneratedMatcher; import org.eclipse.incquery.runtime.api.impl.BaseGeneratedMatcherFactory; - -public abstract class Constraint { - - public abstract String getMessage(); - - public abstract EObject getLocationObject(T signature); - - public String prettyPrintSignature(T signature) { - return signature.prettyPrint(); - } - - public Object[] extractAffectedElements(T signature) { - return signature.toArray(); - } - - public abstract int getSeverity(); - - public abstract BaseGeneratedMatcherFactory> getMatcherFactory(); -} + +public abstract class Constraint { + + public abstract String getMessage(); + + public abstract EObject getLocationObject(T signature); + + public String prettyPrintSignature(T signature) { + return signature.prettyPrint(); + } + + public Object[] extractAffectedElements(T signature) { + return signature.toArray(); + } + + public abstract int getSeverity(); + + public abstract BaseGeneratedMatcherFactory> getMatcherFactory(); +} diff --git a/plugins/org.eclipse.incquery.validation.runtime/src/org/eclipse/incquery/validation/runtime/ConstraintAdapter.java b/plugins/org.eclipse.incquery.validation.runtime/src/org/eclipse/incquery/validation/runtime/ConstraintAdapter.java index 5d2fa2b5..64fec14e 100644 --- a/plugins/org.eclipse.incquery.validation.runtime/src/org/eclipse/incquery/validation/runtime/ConstraintAdapter.java +++ b/plugins/org.eclipse.incquery.validation.runtime/src/org/eclipse/incquery/validation/runtime/ConstraintAdapter.java @@ -9,8 +9,8 @@ * Zoltan Ujhelyi, Abel Hegedus, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.validation.runtime; - +package org.eclipse.incquery.validation.runtime; + import java.util.HashMap; import java.util.Map; @@ -27,55 +27,55 @@ import org.eclipse.ui.IEditorPart; /** - * The constraint adapter class is used to collect the constraints and deal with their - * maintenance for a given EMF instance model. If the validation framework is - * initialized an instance of this class will be created which handles the creation - * of the appropriate rules and their jobs. - * + * The constraint adapter class is used to collect the constraints and deal with their maintenance for a given EMF + * instance model. If the validation framework is initialized an instance of this class will be created which handles + * the creation of the appropriate rules and their jobs. + * * @author Tamas Szabo - */ + */ public class ConstraintAdapter { - - private Map markerMap; - private IAgenda agenda; - - public ConstraintAdapter(IEditorPart editorPart, Notifier notifier, Logger logger) { - this.markerMap = new HashMap(); - - this.agenda = RuleEngine.getInstance().getOrCreateAgenda(notifier); - - for (Constraint constraint : ValidationUtil.getConstraintsForEditorId(editorPart.getSite().getId())) { - IRule rule = agenda.createRule(constraint.getMatcherFactory(), true, true); - rule.setStateChangeProcessor(ActivationState.APPEARED, new MarkerPlacerJob(this, constraint, logger)); - rule.setStateChangeProcessor(ActivationState.DISAPPEARED, new MarkerEraserJob(this, logger)); - rule.setStateChangeProcessor(ActivationState.UPDATED, new MarkerUpdaterJob(this, constraint, logger)); - } - - AutomaticFiringStrategy firingStrategy = new AutomaticFiringStrategy(agenda.newActivationMonitor(true)); - agenda.addUpdateCompleteListener(firingStrategy, true); - } - - public void dispose() { - for (IMarker marker : markerMap.values()) { - try { - marker.delete(); - } - catch (CoreException e) { - agenda.getLogger().error(String.format("Exception occured when removing a marker on dispose: %s", e.getMessage()), e); - } - } - agenda.dispose(); - } - - public IMarker getMarker(IPatternMatch match) { - return this.markerMap.get(match); - } - - public IMarker addMarker(IPatternMatch match, IMarker marker) { - return this.markerMap.put(match, marker); - } - - public IMarker removeMarker(IPatternMatch match) { - return this.markerMap.remove(match); - } -} + + private Map markerMap; + private IAgenda agenda; + + public ConstraintAdapter(IEditorPart editorPart, Notifier notifier, Logger logger) { + this.markerMap = new HashMap(); + + this.agenda = RuleEngine.getInstance().getOrCreateAgenda(notifier); + + for (Constraint constraint : ValidationUtil.getConstraintsForEditorId(editorPart.getSite() + .getId())) { + IRule rule = agenda.createRule(constraint.getMatcherFactory(), true, true); + rule.setStateChangeProcessor(ActivationState.APPEARED, new MarkerPlacerJob(this, constraint, logger)); + rule.setStateChangeProcessor(ActivationState.DISAPPEARED, new MarkerEraserJob(this, logger)); + rule.setStateChangeProcessor(ActivationState.UPDATED, new MarkerUpdaterJob(this, constraint, logger)); + } + + AutomaticFiringStrategy firingStrategy = new AutomaticFiringStrategy(agenda.newActivationMonitor(true)); + agenda.addUpdateCompleteListener(firingStrategy, true); + } + + public void dispose() { + for (IMarker marker : markerMap.values()) { + try { + marker.delete(); + } catch (CoreException e) { + agenda.getLogger().error( + String.format("Exception occured when removing a marker on dispose: %s", e.getMessage()), e); + } + } + agenda.dispose(); + } + + public IMarker getMarker(IPatternMatch match) { + return this.markerMap.get(match); + } + + public IMarker addMarker(IPatternMatch match, IMarker marker) { + return this.markerMap.put(match, marker); + } + + public IMarker removeMarker(IPatternMatch match) { + return this.markerMap.remove(match); + } +} diff --git a/plugins/org.eclipse.incquery.validation.runtime/src/org/eclipse/incquery/validation/runtime/MarkerEraserJob.java b/plugins/org.eclipse.incquery.validation.runtime/src/org/eclipse/incquery/validation/runtime/MarkerEraserJob.java index c3a18116..066ffd2f 100644 --- a/plugins/org.eclipse.incquery.validation.runtime/src/org/eclipse/incquery/validation/runtime/MarkerEraserJob.java +++ b/plugins/org.eclipse.incquery.validation.runtime/src/org/eclipse/incquery/validation/runtime/MarkerEraserJob.java @@ -18,32 +18,31 @@ import org.eclipse.incquery.runtime.api.IPatternMatch; /** - * The job is used to remove a problem marker from the Problems View of Eclipse - * when the constraint violation is no longer present. - * It is associated to the rule that is created for the constraint. + * The job is used to remove a problem marker from the Problems View of Eclipse when the constraint violation is no + * longer present. It is associated to the rule that is created for the constraint. * * @author Tamas Szabo - * + * */ public class MarkerEraserJob implements IMatchProcessor { - private Logger logger; - private ConstraintAdapter adapter; - - public MarkerEraserJob(ConstraintAdapter adapter, Logger logger) { - this.logger = logger; - this.adapter = adapter; - } - - @Override - public void process(IPatternMatch match) { - IMarker marker = adapter.removeMarker(match); - if (marker != null) { - try { - marker.delete(); - } catch (CoreException e) { - logger.error("Could not delete marker!", e); - } - } - } + private Logger logger; + private ConstraintAdapter adapter; + + public MarkerEraserJob(ConstraintAdapter adapter, Logger logger) { + this.logger = logger; + this.adapter = adapter; + } + + @Override + public void process(IPatternMatch match) { + IMarker marker = adapter.removeMarker(match); + if (marker != null) { + try { + marker.delete(); + } catch (CoreException e) { + logger.error("Could not delete marker!", e); + } + } + } } diff --git a/plugins/org.eclipse.incquery.validation.runtime/src/org/eclipse/incquery/validation/runtime/MarkerPlacerJob.java b/plugins/org.eclipse.incquery.validation.runtime/src/org/eclipse/incquery/validation/runtime/MarkerPlacerJob.java index 67a1c509..a4e74e82 100644 --- a/plugins/org.eclipse.incquery.validation.runtime/src/org/eclipse/incquery/validation/runtime/MarkerPlacerJob.java +++ b/plugins/org.eclipse.incquery.validation.runtime/src/org/eclipse/incquery/validation/runtime/MarkerPlacerJob.java @@ -26,45 +26,44 @@ import org.eclipse.incquery.runtime.api.impl.BasePatternMatch; /** - * The job is used to create a problem marker in the Problems View of Eclipse - * upon constraint violation. - * It is associated to the rule that is created for the constraint. + * The job is used to create a problem marker in the Problems View of Eclipse upon constraint violation. It is + * associated to the rule that is created for the constraint. * * @author Tamas Szabo - * + * */ public class MarkerPlacerJob implements IMatchProcessor { - private Constraint constraint; - private Logger logger; - ConstraintAdapter adapter; - - public MarkerPlacerJob(ConstraintAdapter adapter, Constraint constraint, Logger logger) { - this.constraint = constraint; - this.logger = logger; - this.adapter = adapter; - } - - @Override - public void process(IPatternMatch match) { - EObject location = constraint.getLocationObject(match); - if (location != null && location.eResource() != null) { - URI uri = location.eResource().getURI(); - String platformString = uri.toPlatformString(true); - IResource markerLoc = ResourcesPlugin.getWorkspace().getRoot().findMember(platformString); - try { - IMarker marker = markerLoc.createMarker(EValidator.MARKER); - marker.setAttribute(IMarker.SEVERITY, constraint.getSeverity()); - marker.setAttribute(IMarker.TRANSIENT, true); - String locationString = String.format("%1$s %2$s", location.eClass().getName(), BasePatternMatch.prettyPrintValue(location)); - marker.setAttribute(IMarker.LOCATION, locationString); - marker.setAttribute(EValidator.URI_ATTRIBUTE, EcoreUtil.getURI(location).toString()); - marker.setAttribute(IMarker.MESSAGE, DatabindingAdapterUtil.getMessage(match, constraint.getMessage())); - adapter.addMarker(match, marker); - } - catch (CoreException e) { - logger.error("Error during marker initialization!", e); - } - } - } + private Constraint constraint; + private Logger logger; + ConstraintAdapter adapter; + + public MarkerPlacerJob(ConstraintAdapter adapter, Constraint constraint, Logger logger) { + this.constraint = constraint; + this.logger = logger; + this.adapter = adapter; + } + + @Override + public void process(IPatternMatch match) { + EObject location = constraint.getLocationObject(match); + if (location != null && location.eResource() != null) { + URI uri = location.eResource().getURI(); + String platformString = uri.toPlatformString(true); + IResource markerLoc = ResourcesPlugin.getWorkspace().getRoot().findMember(platformString); + try { + IMarker marker = markerLoc.createMarker(EValidator.MARKER); + marker.setAttribute(IMarker.SEVERITY, constraint.getSeverity()); + marker.setAttribute(IMarker.TRANSIENT, true); + String locationString = String.format("%1$s %2$s", location.eClass().getName(), + BasePatternMatch.prettyPrintValue(location)); + marker.setAttribute(IMarker.LOCATION, locationString); + marker.setAttribute(EValidator.URI_ATTRIBUTE, EcoreUtil.getURI(location).toString()); + marker.setAttribute(IMarker.MESSAGE, DatabindingAdapterUtil.getMessage(match, constraint.getMessage())); + adapter.addMarker(match, marker); + } catch (CoreException e) { + logger.error("Error during marker initialization!", e); + } + } + } } \ No newline at end of file diff --git a/plugins/org.eclipse.incquery.validation.runtime/src/org/eclipse/incquery/validation/runtime/MarkerUpdaterJob.java b/plugins/org.eclipse.incquery.validation.runtime/src/org/eclipse/incquery/validation/runtime/MarkerUpdaterJob.java index efc3efde..abdb9aea 100644 --- a/plugins/org.eclipse.incquery.validation.runtime/src/org/eclipse/incquery/validation/runtime/MarkerUpdaterJob.java +++ b/plugins/org.eclipse.incquery.validation.runtime/src/org/eclipse/incquery/validation/runtime/MarkerUpdaterJob.java @@ -19,34 +19,33 @@ import org.eclipse.incquery.runtime.api.IPatternMatch; /** - * The job is used to update a problem marker in the Problems View of Eclipse. - * It is associated to the rule that is created for the constraint. + * The job is used to update a problem marker in the Problems View of Eclipse. It is associated to the rule that is + * created for the constraint. * * @author Tamas Szabo - * + * */ public class MarkerUpdaterJob implements IMatchProcessor { - private Constraint constraint; - private Logger logger; - private ConstraintAdapter adapter; - - public MarkerUpdaterJob(ConstraintAdapter adapter, Constraint constraint, Logger logger) { - this.constraint = constraint; - this.logger = logger; - this.adapter = adapter; - } - - @Override - public void process(IPatternMatch match) { - IMarker marker = adapter.getMarker(match); - if (marker != null) { - try { - marker.setAttribute(IMarker.MESSAGE, DatabindingAdapterUtil.getMessage(match, constraint.getMessage())); - } - catch (CoreException e) { - logger.error("Error during marker update!", e); - } - } - } + private Constraint constraint; + private Logger logger; + private ConstraintAdapter adapter; + + public MarkerUpdaterJob(ConstraintAdapter adapter, Constraint constraint, Logger logger) { + this.constraint = constraint; + this.logger = logger; + this.adapter = adapter; + } + + @Override + public void process(IPatternMatch match) { + IMarker marker = adapter.getMarker(match); + if (marker != null) { + try { + marker.setAttribute(IMarker.MESSAGE, DatabindingAdapterUtil.getMessage(match, constraint.getMessage())); + } catch (CoreException e) { + logger.error("Error during marker update!", e); + } + } + } } diff --git a/plugins/org.eclipse.incquery.validation.runtime/src/org/eclipse/incquery/validation/runtime/ValidationPartListener.java b/plugins/org.eclipse.incquery.validation.runtime/src/org/eclipse/incquery/validation/runtime/ValidationPartListener.java index d16f22c5..b7c1af84 100644 --- a/plugins/org.eclipse.incquery.validation.runtime/src/org/eclipse/incquery/validation/runtime/ValidationPartListener.java +++ b/plugins/org.eclipse.incquery.validation.runtime/src/org/eclipse/incquery/validation/runtime/ValidationPartListener.java @@ -9,62 +9,62 @@ * Zoltan Ujhelyi, Abel Hegedus, Tamas Szabo - initial API and implementation *******************************************************************************/ -package org.eclipse.incquery.validation.runtime; - +package org.eclipse.incquery.validation.runtime; + import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IPartListener; import org.eclipse.ui.IWorkbenchPart; - -/** - * The PartListener is used to observe EditorPart close actions. - * - * @author Tamas Szabo - * - */ -public class ValidationPartListener implements IPartListener { - - private static ValidationPartListener instance; - - public static ValidationPartListener getInstance() { - if (instance == null) { - instance = new ValidationPartListener(); - } - return instance; - } - - protected ValidationPartListener() { - - } - - @Override - public void partActivated(IWorkbenchPart part) { - - } - - @Override - public void partBroughtToTop(IWorkbenchPart part) { - - } - - @Override - public void partClosed(IWorkbenchPart part) { - if (part instanceof IEditorPart) { - IEditorPart closedEditor = (IEditorPart) part; - ConstraintAdapter adapter = ValidationUtil.getAdapterMap().remove(part); - if (adapter != null) { - adapter.dispose(); - } - ValidationUtil.unregisterEditorPart(closedEditor); - } - } - - @Override - public void partDeactivated(IWorkbenchPart part) { - - } - - @Override - public void partOpened(IWorkbenchPart part) { - - } -} + +/** + * The PartListener is used to observe EditorPart close actions. + * + * @author Tamas Szabo + * + */ +public class ValidationPartListener implements IPartListener { + + private static ValidationPartListener instance; + + public static ValidationPartListener getInstance() { + if (instance == null) { + instance = new ValidationPartListener(); + } + return instance; + } + + protected ValidationPartListener() { + + } + + @Override + public void partActivated(IWorkbenchPart part) { + + } + + @Override + public void partBroughtToTop(IWorkbenchPart part) { + + } + + @Override + public void partClosed(IWorkbenchPart part) { + if (part instanceof IEditorPart) { + IEditorPart closedEditor = (IEditorPart) part; + ConstraintAdapter adapter = ValidationUtil.getAdapterMap().remove(part); + if (adapter != null) { + adapter.dispose(); + } + ValidationUtil.unregisterEditorPart(closedEditor); + } + } + + @Override + public void partDeactivated(IWorkbenchPart part) { + + } + + @Override + public void partOpened(IWorkbenchPart part) { + + } +} diff --git a/plugins/org.eclipse.incquery.validation.runtime/src/org/eclipse/incquery/validation/runtime/ValidationUtil.java b/plugins/org.eclipse.incquery.validation.runtime/src/org/eclipse/incquery/validation/runtime/ValidationUtil.java index 2fe64c5e..5f570bcb 100644 --- a/plugins/org.eclipse.incquery.validation.runtime/src/org/eclipse/incquery/validation/runtime/ValidationUtil.java +++ b/plugins/org.eclipse.incquery.validation.runtime/src/org/eclipse/incquery/validation/runtime/ValidationUtil.java @@ -37,140 +37,141 @@ import com.google.common.collect.Sets; public class ValidationUtil { - + /** * Constructor hidden for utility class */ private ValidationUtil() { - + + } + + private static Logger logger = Logger.getLogger(ValidationUtil.class); + + private static Map> pageMap = new HashMap>(); + + private static Set genericEditorIds = Sets.newHashSet( + "org.eclipse.emf.ecore.presentation.XMLReflectiveEditorID", + "org.eclipse.emf.ecore.presentation.ReflectiveEditorID", "org.eclipse.emf.genericEditor"); + + private static Map adapterMap = new HashMap(); + + public static synchronized Map getAdapterMap() { + return adapterMap; } + private static Multimap> editorConstraintMap; + + public static synchronized Multimap> getEditorConstraintMap() { + if (editorConstraintMap == null) { + editorConstraintMap = loadConstraintsFromExtensions(); + } + return editorConstraintMap; + } + + /** + * Returns the appropriate IMarker enum value of severity for the given literal + * + * @param severity + * the literal of the severity + * @return the IMarker severity enum value (info is the default) + */ + public static int getSeverity(String severity) { + if (severity != null) { + if (severity.matches("error")) { + return IMarker.SEVERITY_ERROR; + } else if (severity.matches("warning")) { + return IMarker.SEVERITY_WARNING; + } + } + return IMarker.SEVERITY_INFO; + } - private static Logger logger = Logger.getLogger(ValidationUtil.class); - - private static Map> pageMap = new HashMap>(); - - private static Set genericEditorIds = Sets.newHashSet("org.eclipse.emf.ecore.presentation.XMLReflectiveEditorID", - "org.eclipse.emf.ecore.presentation.ReflectiveEditorID", "org.eclipse.emf.genericEditor"); - - private static Map adapterMap = new HashMap(); - public static synchronized Map getAdapterMap() { - return adapterMap; - } - - private static Multimap> editorConstraintMap; - public static synchronized Multimap> getEditorConstraintMap() { - if(editorConstraintMap == null) { - editorConstraintMap = loadConstraintsFromExtensions(); - } - return editorConstraintMap; - } - - /** - * Returns the appropriate IMarker enum value of severity for the given - * literal - * - * @param severity - * the literal of the severity - * @return the IMarker severity enum value (info is the default) - */ - public static int getSeverity(String severity) { - if (severity != null) { - if (severity.matches("error")) { - return IMarker.SEVERITY_ERROR; - } else if (severity.matches("warning")) { - return IMarker.SEVERITY_WARNING; - } - } - return IMarker.SEVERITY_INFO; - } - - public static synchronized boolean isConstraintsRegisteredForEditorId(String editorId) { - return getEditorConstraintMap().containsKey(editorId); - } - - public static synchronized Set> getConstraintsForEditorId(String editorId) { - if(genericEditorIds.contains(editorId)) { + public static synchronized boolean isConstraintsRegisteredForEditorId(String editorId) { + return getEditorConstraintMap().containsKey(editorId); + } + + public static synchronized Set> getConstraintsForEditorId(String editorId) { + if (genericEditorIds.contains(editorId)) { return ImmutableSet.copyOf(getEditorConstraintMap().values()); } - Set> set = new HashSet>(getEditorConstraintMap().get(editorId)); - set.addAll(getEditorConstraintMap().get("*")); - return set; - } - - private static synchronized Multimap> loadConstraintsFromExtensions() { - Multimap> result = HashMultimap.create(); - - IExtensionRegistry reg = Platform.getExtensionRegistry(); - IExtensionPoint ep = reg.getExtensionPoint("org.eclipse.incquery.validation.runtime.constraint"); - - for (IExtension extension : ep.getExtensions()) { - for (IConfigurationElement ce : extension.getConfigurationElements()) { - if (ce.getName().equals("constraint")) { - processConstraintConfigurationElement(result, ce); - } - } - } - return result; - } + Set> set = new HashSet>(getEditorConstraintMap().get( + editorId)); + set.addAll(getEditorConstraintMap().get("*")); + return set; + } + + private static synchronized Multimap> loadConstraintsFromExtensions() { + Multimap> result = HashMultimap.create(); + + IExtensionRegistry reg = Platform.getExtensionRegistry(); + IExtensionPoint ep = reg.getExtensionPoint("org.eclipse.incquery.validation.runtime.constraint"); + + for (IExtension extension : ep.getExtensions()) { + for (IConfigurationElement ce : extension.getConfigurationElements()) { + if (ce.getName().equals("constraint")) { + processConstraintConfigurationElement(result, ce); + } + } + } + return result; + } /** * @param result * @param ce */ - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") private static void processConstraintConfigurationElement(Multimap> result, IConfigurationElement ce) { try { - List ids = new ArrayList(); - for (IConfigurationElement child : ce.getChildren()) { - if (child.getName().equals("enabledForEditor")) { - String id = child.getAttribute("editorId"); - if (id != null && !id.equals("")) { - ids.add(id); - } - } - } - - Object o = ce.createExecutableExtension("class"); - if (o instanceof Constraint) { - if (ids.isEmpty()) { - ids.add("*"); - } - for (String id : ids) { - result.put(id, (Constraint) o); - } - } + List ids = new ArrayList(); + for (IConfigurationElement child : ce.getChildren()) { + if (child.getName().equals("enabledForEditor")) { + String id = child.getAttribute("editorId"); + if (id != null && !id.equals("")) { + ids.add(id); + } + } + } + + Object o = ce.createExecutableExtension("class"); + if (o instanceof Constraint) { + if (ids.isEmpty()) { + ids.add("*"); + } + for (String id : ids) { + result.put(id, (Constraint) o); + } + } } catch (CoreException e) { - logger.error("Error loading EMF-IncQuery Validation Constraint", e); + logger.error("Error loading EMF-IncQuery Validation Constraint", e); } } - public static synchronized void addNotifier(IEditorPart editorPart, Notifier notifier) { - adapterMap.put(editorPart, new ConstraintAdapter(editorPart, notifier, logger)); - } - - public static void registerEditorPart(IEditorPart editorPart) { - IWorkbenchPage page = editorPart.getSite().getPage(); - if (pageMap.containsKey(page)) { - pageMap.get(page).add(editorPart); - } - else { - Set editorParts = new HashSet(); - editorParts.add(editorPart); - pageMap.put(page, editorParts); - page.addPartListener(ValidationPartListener.getInstance()); - } - } - - public static void unregisterEditorPart(IEditorPart editorPart) { - IWorkbenchPage page = editorPart.getSite().getPage(); - if (pageMap.containsKey(page)) { - pageMap.get(page).remove(editorPart); - if (pageMap.get(page).size() == 0) { - pageMap.remove(page); - page.removePartListener(ValidationPartListener.getInstance()); - } - } - } + public static synchronized void addNotifier(IEditorPart editorPart, Notifier notifier) { + adapterMap.put(editorPart, new ConstraintAdapter(editorPart, notifier, logger)); + } + + public static void registerEditorPart(IEditorPart editorPart) { + IWorkbenchPage page = editorPart.getSite().getPage(); + if (pageMap.containsKey(page)) { + pageMap.get(page).add(editorPart); + } else { + Set editorParts = new HashSet(); + editorParts.add(editorPart); + pageMap.put(page, editorParts); + page.addPartListener(ValidationPartListener.getInstance()); + } + } + + public static void unregisterEditorPart(IEditorPart editorPart) { + IWorkbenchPage page = editorPart.getSite().getPage(); + if (pageMap.containsKey(page)) { + pageMap.get(page).remove(editorPart); + if (pageMap.get(page).size() == 0) { + pageMap.remove(page); + page.removePartListener(ValidationPartListener.getInstance()); + } + } + } }