package school.base.test.util; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.emf.common.notify.Notifier; import org.eclipse.emf.common.util.TreeIterator; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl; import org.eclipse.emf.transaction.TransactionalEditingDomain; import school.SchoolPackage; /** * Utility class to access persisted and dynamic EMF instance models and * demand create {@link TransactionalEditingDomain}s for these models. * * @author Tamas Szabo (itemis AG) * */ public class ModelManager { private static ResourceSet cachedModel = null; private static EObject cachedDynamicModel = null; /** * Returns a {@link ResourceSet} consisting of the persisted * model/school1.school and model/school2.school instance models (as two {@link Resource}s). * Consecutive calls return the same cached {@link ResourceSet} instance. * * @return the persisted instance model */ public static ResourceSet getModel() { if (cachedModel == null) { cachedModel = new ResourceSetImpl(); SchoolPackage.eINSTANCE.eClass(); Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE; Map<String, Object> m = reg.getExtensionToFactoryMap(); m.put("school", new XMIResourceFactoryImpl()); cachedModel.getResource(URI.createFileURI(new File("model/school1.school").getAbsolutePath()), true); cachedModel.getResource(URI.createFileURI(new File("model/school2.school").getAbsolutePath()), true); } return cachedModel; } /** * Returns the root (School instance) of the dynamic instance model which is populated * with similar objects as the persisted model. * Consecutive calls return the same cached {@link EObject} instance. * * @return the dynamic instance model */ public static EObject getDynamicModel() { if (cachedDynamicModel == null) { cachedDynamicModel = new DynamicResourceModel().school; } return cachedDynamicModel; } /** * Returns all contents of the given {@link Notifier} instance as a {@link List} of {@link EObject}s. * * @param notifier the notifier instance * @return the list of contents */ public static List<EObject> getAllContents(Notifier notifier) { List<EObject> contents = new ArrayList<EObject>(); if (notifier instanceof EObject) { getAllContents(contents, ((EObject) notifier).eAllContents()); } else if (notifier instanceof Resource) { getAllContents(contents, ((Resource) notifier).getAllContents()); } else { for (Resource resource : ((ResourceSet) notifier).getResources()) { getAllContents(contents, resource.getAllContents()); } } return contents; } private static void getAllContents(List<EObject> contents, TreeIterator<EObject> iterator) { while (iterator.hasNext()) { contents.add(iterator.next()); } } private static Map<ResourceSet, TransactionalEditingDomain> editingDomainMap = new HashMap<ResourceSet, TransactionalEditingDomain>(); private static Map<Notifier, ResourceSet> resourceSetMap = new HashMap<Notifier, ResourceSet>(); /** * Demand creates a {@link TransactionalEditingDomain} for the given {@link Notifier}. * First a {@link ResourceSet} instance will be demand created for the {@link Notifier} and this one will * be used to create the editing domain. * Consecutive calls return the same {@link TransactionalEditingDomain} instance for the given {@link Notifier}. * * @param notifier the notifier instance * @return the transactional editing domain */ public static TransactionalEditingDomain demandCreateTransactionalEditingDomain(Notifier notifier) { ResourceSet resSet = demandCreateResourceSet(notifier); if (editingDomainMap.containsKey(resSet)) { return editingDomainMap.get(resSet); } else { TransactionalEditingDomain editingDomain = TransactionalEditingDomain.Factory.INSTANCE.createEditingDomain(resSet); editingDomainMap.put(resSet, editingDomain); return editingDomain; } } private static ResourceSet demandCreateResourceSet(Notifier notifier) { if (resourceSetMap.containsKey(notifier)) { return resourceSetMap.get(notifier); } else { ResourceSet resSet = null; if (notifier instanceof EObject) { if (((EObject) notifier).eResource() == null) { resSet = new ResourceSetImpl(); Resource resource = resSet.createResource(URI.createURI("test")); resource.getContents().add((EObject) notifier); } else { if (((EObject) notifier).eResource().getResourceSet() == null) { resSet = new ResourceSetImpl(); resSet.getResources().add(((EObject) notifier).eResource()); } else { resSet = ((EObject) notifier).eResource().getResourceSet(); } } } else if (notifier instanceof Resource) { if (((Resource) notifier).getResourceSet() != null) { resSet = ((Resource) notifier).getResourceSet(); } else { resSet = new ResourceSetImpl(); resSet.getResources().add(((Resource) notifier)); } } else if (notifier instanceof ResourceSet) { resSet = (ResourceSet) notifier; } resourceSetMap.put(notifier, resSet); return resSet; } } }