blob: b793970a24889102921c82d994e40202d98c8c27 [file] [log] [blame]
import java.util.ArrayList;
import java.util.List;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.edapt.migration.CustomMigration;
import org.eclipse.emf.edapt.migration.MigrationException;
import org.eclipse.emf.edapt.spi.migration.Instance;
import org.eclipse.emf.edapt.spi.migration.Metamodel;
import org.eclipse.emf.edapt.spi.migration.Model;
import org.eclipse.emf.edapt.spi.migration.ModelResource;
public class ExtractStates extends CustomMigration {
@Override
public void migrateBefore(Model model, Metamodel metamodel)
throws MigrationException {
PrintTime.start = System.currentTimeMillis();
}
@Override
public void migrateAfter(Model model, Metamodel metamodel)
throws MigrationException {
Instance stateMachine = createStateMachine(model);
createStates(model, stateMachine);
}
/** Create the state machine. */
private Instance createStateMachine(Model model) {
ModelResource resource = createResultResource(model);
Instance stateMachine = model.newInstance("statemachine.StateMachine");
resource.getRootInstances().add(stateMachine);
return stateMachine;
}
/** Create the resource to store the state machine in. */
private ModelResource createResultResource(Model model) {
URI uri = model.getResources().get(0).getUri();
URI resultUri = uri
.trimSegments(1)
.appendSegment(uri.trimFileExtension().lastSegment() + "result")
.appendFileExtension(uri.fileExtension());
return model.newResource(resultUri);
}
/** Create the states. */
private void createStates(Model model, Instance stateMachine) {
Instance stateClass = getStateClass(model);
for (Instance subClass : getAllSubClasses(stateClass)) {
if (!isAbstract(subClass)) {
Instance state = model.newInstance("statemachine.State");
state.set("name", subClass.get("name"));
stateMachine.add("states", state);
state.set("class", subClass);
}
}
}
/** Get the class that is super class of all classes representing states. */
private Instance getStateClass(Model model) {
for (Instance c : model.getAllInstances("classifiers.Class")) {
if ("State".equals(c.get("name"))) {
return c;
}
}
return null;
}
/** Get all direct and indirect sub classes of a class. */
private List<Instance> getAllSubClasses(Instance c) {
List<Instance> subTypes = new ArrayList<Instance>();
for (Instance subType : getSubClasses(c)) {
if (!subTypes.contains(subType)) {
subTypes.add(subType);
}
subTypes.addAll(getAllSubClasses(subType));
}
return subTypes;
}
/** Get all direct sub classes of a class. */
private List<Instance> getSubClasses(Instance c) {
List<Instance> subClasses = new ArrayList<Instance>();
List<Instance> classifierReferences = c
.getInverse("types.ClassifierReference.target");
for (Instance classifierReference : classifierReferences) {
Instance container = classifierReference.getContainer()
.getContainer();
if (container.instanceOf("classifiers.Class")) {
subClasses.add(container);
}
}
return subClasses;
}
/** Check whether a class is abstract. */
private boolean isAbstract(Instance c) {
for (Instance modifier : c.getLinks("annotationsAndModifiers")) {
if (modifier.instanceOf("modifiers.Abstract")) {
return true;
}
}
return false;
}
}