| 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; |
| } |
| } |