[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[henshin-dev] Interpreter API draft
|
Hi,
I created a first draft for the new API -- see the attached interfaces.
We should now discuss the details and design decisions. I'm keen to hear
your ideas :).
A few comments up-front:
- all classes are meant to be reusable (for multiple executions)
- all objects are supposed to be created using a factory
- the engine has 2 jobs now: (1) find matches, (2) create a model changes
- options are directly stored in the engine (no TransformationOption class)
- the engine internally keeps the reference to the JavaScript engine
(the reason for keeping the engine separately)
- matches are computed on-the-fly in an iterator
- for applying a rule either a partial match (e.g. an empty one) or a
complete match can be specified. Partial matches are completed
automatically if no complete match is defined explicitly.
If you don't understand something, please ask. The API should be
powerful, user-friendly, minimal and allow to build efficient
implementations.
Please make suggestions for (and *briefly* say why):
- Names of interfaces / methods etc.
- Functionality that you think should be moved, added, deleted,
- Any other ideas you have ;)
Cheers,
Christian
package org.eclipse.emf.henshin.interpreter;
import org.eclipse.emf.henshin.model.Parameter;
import org.eclipse.emf.henshin.model.TransformationUnit;
/**
* Parameter assignment interface for storing parameter values.
* @author Christian Krause
*/
public interface Assignment {
/**
* Get the unit that this assignment refers to.
* @return The transformation unit.
*/
TransformationUnit getUnit();
/**
* Set the unit that this assignment refers to.
* @param unit The transformation unit.
*/
void setUnit(TransformationUnit unit);
/**
* Get the value assigned to a parameter.
* @param param The parameter.
* @return The assigned value or <code>null</code>.
*/
Object getParameterValue(Parameter param);
/**
* Set the assigned value for a parameter.
* @param param The parameter.
* @param value The value to be assigned with the parameter.
*/
void setParameterValue(Parameter param, Object value);
/**
* Clear this assignment.
*/
void clear();
}
package org.eclipse.emf.henshin.interpreter;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.change.ChangeDescription;
/**
* Change descriptions for {@link EGraph}.
* Created objects are stored in {@link #getObjectsToAttach()}.
* Deleted objects are stored in {@link #getObjectsToDetach()}.
*
* @author Christian Krause
*
*/
public interface EChange extends ChangeDescription {
/**
* Set the {@link EGraph} this change refers to.
* @param graph The {@link EGraph}.
*/
void setEGraph(EGraph graph);
/**
* Helper method for adding a reference change.
* @param object Object to be changed.
* @param reference Reference to be changed.
* @param value Object that should be added to or deleted from the reference.
* @param delete Flag indicating whether the reference should be deleted.
*/
void addReferenceChange(EObject object, EReference reference, EObject value, boolean delete);
/**
* Helper method for adding an attribute change.
* @param object Object to be changed.
* @param attribute Attribute to be changed.
* @param value New value for the attribute.
* @param delete Flag indicating whether the value should be deleted.
*/
void addAttributeChange(EObject object, EAttribute attribute, String value, boolean delete);
}
package org.eclipse.emf.henshin.interpreter;
import java.util.Set;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
/**
* EGraph interface for storing object graphs.
* @author Christian Krause
*/
public interface EGraph extends Set<EObject> {
/**
* Adds an {@link EObject} and all its children to this graph.
* @param root The root object of the tree.
* @return <code>true</code> if an object was added.
*/
boolean addTree(EObject root);
/**
* Removes an {@link EObject} and all its children from this graph.
* @param root The root object of the tree.
* @return <code>true</code> if any object was removed.
*/
boolean removeTree(EObject root);
/**
* Get all {@link EObject}s of this graph which are compatible with the given type.
* @param type The type of the objects.
* @param strict Whether subtypes are excluded from the result.
* @return A set of {@link EObject}s compatible with the type.
*/
Set<EObject> getDomain(EClass type, boolean strict);
/**
* Check whether the domain for a type is empty. This is the case if and only
* if {@link #getDomain(EClass, boolean)} returns an empty list.
* @param type The type.
* @param strict Whether subtypes are excluded.
* @return <code>true</code> if the domain is empty.
*/
boolean isDomainEmpty(EClass type, boolean strict);
/**
* Get the cross reference adapter of this graph.
* @return The cross reference adapter.
*/
ECrossReferenceAdapter getCrossReferenceAdapter();
}
/*******************************************************************************
* Copyright (c) 2010 CWI Amsterdam, Technical University Berlin,
* Philipps-University Marburg and others. All rights reserved.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Technical University Berlin - initial API and implementation
*******************************************************************************/
package org.eclipse.emf.henshin.interpreter;
import java.util.Map;
import org.eclipse.emf.henshin.model.Rule;
/**
* Engine interface for the Henshin interpreter.
*/
public interface Engine {
/**
* Option for general injective rule matching.
*/
String OPTION_INJECTIVE_MATCHING = "INJECTIVE_MATCHING";
/**
* Option for general checks for dangling edges.
*/
String OPTION_CHECK_DANGLING = "CHECK_DANGLING";
/**
* Option for general deterministic engine behavior.
*/
String OPTION_DETERMINISTIC = "DETERMINISTIC";
/**
* Find matches for a {@link Rule} in an {@link EGraph}.
* @param rule Rule to be matched.
* @param graph Graph where the match should be found.
* @param partialMatch Partial match (can be empty or <code>null</code>).
* @return An iterable list of matches.
*/
Iterable<Match> findMatches(Rule rule, EGraph graph, Match partialMatch);
/**
* Create an {@link EChange} for applying a rule
* @param rule Rule to be applied.
* @param graph Graph where the rule should be applied.
* @param completeMatch A <b>complete</b> match for the rule in the graph.
* @return An {@link EChange} object that can be used to apply the rule
*/
EChange createChange(Rule rule, EGraph graph, Match completeMatch);
/**
* Get or set the options for this engine.
* @return Options map.
*/
Map<?,?> getOptions();
}
package org.eclipse.emf.henshin.interpreter;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.henshin.interpreter.impl.InterpreterFactoryImpl;
import org.eclipse.emf.henshin.model.Rule;
import org.eclipse.emf.henshin.model.TransformationUnit;
/**
* Factory interface for the Henshin interpreter.
* @author Christian Krause
*/
public interface InterpreterFactory {
/**
* Static factory instance.
*/
final static InterpreterFactory INSTANCE = new InterpreterFactoryImpl();
/**
* Create a new {@link EGraph} object.
* @return A new {@link EGraph}.
*/
EGraph createEGraph();
/**
* Create a new {@link EGraph} object.
* @param root A root object to be used in the graph.
* @return A new {@link EGraph}.
*/
EGraph createEGraph(EObject root);
/**
* Create a new {@link EGraph} object.
* @param resource A resource whose content shall be used in the graph.
* @return A new {@link EGraph}.
*/
EGraph createEGraph(Resource resource);
/**
* Create an {@link Assignment} object.
* @param unit Target {@link TransformationUnit}.
* @return A new {@link Assignment}.
*/
Assignment createAssignment(TransformationUnit unit);
/**
* Create a {@link Match} object.
* @param Rule to be matched.
* @return A new {@link Match}.
*/
Match createMatch(Rule rule);
/**
* Create an {@link Engine} object. For engines create with this
* factory method, it is always ensured that fresh {@link Match}s
* and {@link EChange}s are created.
* @return A new {@link Engine}.
*/
Engine createEngine();
/**
* Create a new minimal {@link Engine} object. Minimal engines
* save memory by reusing {@link Match}s and {@link EChange}s.
* @return A new minimal {@link Engine}.
*/
Engine createMinimalEngine();
/**
* Create a new {@link UnitApplication}.
* @param unit {@link TransformationUnit} to be applied.
* @param graph {@link EGraph} the unit should be applied to.
* @param engine {@link Engine} to be used.
* @return A new {@link UnitApplication}.
*/
UnitApplication createUnitApplication(TransformationUnit unit, EGraph graph, Engine engine);
/**
* Create a new {@link RuleApplication}.
* @param unit {@link Rule} to be applied.
* @param graph {@link EGraph} the rule should be applied to.
* @param engine {@link Engine} to be used.
* @return A new {@link RuleApplication}.
*/
RuleApplication createRuleApplication(Rule rule, EGraph graph, Engine engine);
}
package org.eclipse.emf.henshin.interpreter;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.henshin.model.Node;
import org.eclipse.emf.henshin.model.Rule;
/**
* Match interface for mapping {@link Node}s to {@link EObject} and
* assigning parameter values by extending {@link Assignment}.
* @author Christian Krause
*/
public interface Match extends Assignment {
/**
* Get the rule that this match is used for.
* @return The rule.
*/
Rule getRule();
/**
* Set the rule that this match is used for.
* @param rule The rule.
*/
void setRule(Rule rule);
/**
* Get the match target for a node.
* @param node The node.
* @return The matched target object.
*/
EObject getNodeTarget(Node node);
/**
* Set the match target for a node.
* @param node The node.
* @param target The match target.
*/
void setNodeTarget(Node node, EObject target);
/**
* Get the nested matches for a multi-rule.
* @param multiRule The multi-rule.
* @return List of matches.
*/
EList<Match> getNestedMatches(Rule multiRule);
/**
* Checks whether this match overlaps with another match.
* The second match can be from a different rule.
* @param match A second match to check against.
* @return <code>true</code> if both matches have common targets.
*/
boolean overlapsWith(Match match);
/**
* Checks if all nodes have a target and all nested matches are also complete.
* @return <code>true</code> if all nodes are matched.
*/
boolean isComplete();
/**
* Checks whether this match is complete, whether the typing of the matched
* objects is correct with respect to the node types, and whether all edges
* are present.
* @return <code>true</code> if the match is valid.
*/
boolean isValid();
/**
* Checks whether this is a comatch.
* @return <code>true</code> if it is a comatch.
*/
boolean isCoMatch();
/**
* Decide whether this is a comatch.
* @param isCoMatch <code>true</code> if it is a comatch.
*/
void setIsCoMatch(boolean isCoMatch);
}
package org.eclipse.emf.henshin.interpreter;
import org.eclipse.emf.henshin.model.Rule;
/**
* Rule application interface for executing a {@link Rule}.
*
* @author Christian Krause
*/
public interface RuleApplication extends UnitApplication {
/**
* Get the rule to be applied.
* @return The rule to be applied.
*/
Rule getRule();
/**
* Set the rule to be applied.
* @param rule The rule to be applied.
*/
void setRule(Rule rule);
/**
* Get the partial match to be used.
* @return The partial match.
*/
Match getPartialMatch();
/**
* Set the partial match to be used.
* @param partialMatch The partial match.
*/
void setPartialMatch(Match partialMatch);
/**
* Get the complete match to be used.
* @return The complete match.
*/
Match getCompleteMatch();
/**
* Set the complete match to be used.
* @param completeMatch The complete match.
*/
void setCompleteMatch(Match completeMatch);
/**
* Get the used comatch.
* @return The comatch.
*/
Match getCoMatch();
}
package org.eclipse.emf.henshin.interpreter;
import org.eclipse.emf.henshin.model.TransformationUnit;
/**
* Unit application interface for executing a {@link TransformationUnit}.
* If you want to execute a transformation rule, use {@link RuleApplication}
* instead.
*
* @author Christian Krause
*/
public interface UnitApplication {
/**
* Get the unit to be applied.
* @return The transformation unit.
*/
TransformationUnit getUnit();
/**
* Set the unit to be applied.
* @param unit The transformation unit.
*/
void setUnit(TransformationUnit unit);
/**
* Get the parameter assignment to be used.
* @return The parameter assignment.
*/
Assignment getAssignment();
/**
* Set the parameter assignment to be used.
* @param assignment The parameter assignment.
*/
void setAssignment(Assignment assignment);
/**
* Execute this unit application.
* @return <code>true</code> if the unit was successfully applied.
*/
boolean execute();
/**
* Undo this unit application. This restores the original model as
* it was before calling {@link #execute()}.
*/
void undo();
/**
* Redo this unit application. This method can be invoked after
* {@link #undo()} has been invoked. The effect is that the
* unit is executed again.
*/
void redo();
}