package de.hub.emffrag.fragmentation; import junit.framework.Assert; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.util.EcoreUtil; import de.hub.emffrag.EmfFragActivator; import de.hub.emffrag.model.emffrag.EmfFragPackage; import de.hub.emffrag.util.EMFFragUtil; import de.hub.emffrag.util.EMFFragUtil.FragmentationType; public class IndexBasedIdSemantics implements IdSemantics { public enum IdBehaviour { strict, preliminary, defaultModel }; private static String preliminaryID = "PRELIMINARY_ID"; private static boolean isPreliminary(String id) { return preliminaryID.equals(id); } private final IdBehaviour idBehavior; public IndexBasedIdSemantics(IdBehaviour behavior) { this.idBehavior = behavior; } String getId(FInternalObjectImpl internalObject, boolean issueIfNecessary) { if (internalObject.eIsProxy()) { EcoreUtil.resolve(internalObject, internalObject.getFragmentation()); } String id = internalObject.getId(); if (id != null) { if (internalObject.hasDefaultModelId) { FragmentedModel fragmentedModel = internalObject.getFragmentation(); if (fragmentedModel != null) { fragmentedModel.getIdIndex().updateObjectURI(id, internalObject); } internalObject.hasDefaultModelId = false; } return id; } else { if (issueIfNecessary) { FragmentedModel fragmentedModel = internalObject.getFragmentation(); if (fragmentedModel != null) { id = fragmentedModel.getIdIndex().issueId(internalObject); fragmentedModel.getIdIndex().updateObjectURI(id, internalObject); internalObject.setId(id); internalObject.hasPriliminaryId = false; return id; } else if (internalObject.hasPriliminaryId) { return preliminaryID; } else if (idBehavior == IdBehaviour.preliminary) { internalObject.hasPriliminaryId = true; return preliminaryID; } else if (idBehavior == IdBehaviour.defaultModel) { id = EmfFragActivator.instance.defaultModel.getIdIndex().issueId(internalObject); internalObject.hasDefaultModelId = true; internalObject.setId(id); return id; } else { throw new NotInAFragmentedModelException( "Could not issue an ID because the object is not part of a fragmented model."); } } else if (internalObject.hasPriliminaryId) { FragmentedModel fragmentedModel = internalObject.getFragmentation(); if (fragmentedModel != null) { id = fragmentedModel.getIdIndex().issueId(internalObject); internalObject.setId(id); internalObject.hasPriliminaryId = false; } else { return preliminaryID; } } } return null; } /** * Some objects need to have an IDs. These are objects with indexed value * sets, or indexed class instances. */ public void onRequiredId(FInternalObjectImpl internalObject) { if (internalObject.getFragmentation() != null && getId(internalObject, false) == null) { boolean idIsRequired = false; idIsRequired |= ReflectiveMetaModelRegistry.instance.getInternalClass(EmfFragPackage.eINSTANCE.getIndexedMap()) .isInstance(this); for (EStructuralFeature feature : internalObject.eClass().getEAllStructuralFeatures()) { if (feature instanceof EReference) { FragmentationType fragmentationType = EMFFragUtil.getFragmentationType(feature); idIsRequired |= fragmentationType == FragmentationType.FragmentsIndexedContainment || fragmentationType == FragmentationType.IndexedReferences; } } if (idIsRequired) { getId(internalObject, true); } } } public void onObjectAsReferenced(FInternalObjectImpl internalObject) { getId(internalObject, true); } public URI getURI(FInternalObjectImpl internalObject, FragmentedModel model, boolean forceIssue, SaveURI saveURI) { String id = getId(internalObject, forceIssue); if (id == null || isPreliminary(id)) { return null; } return model.getIdIndex().createIdUri(id); } public String getPrefixID(FInternalObjectImpl object) { String id = getId(object, true); if (isPreliminary(id)) { throw new NotInAFragmentedModelException("Indexed reference owner have to be added to a fragmented model before the indexed reference can be used."); } return id; } public void onObjectSaved(FInternalObjectImpl fInternalObject) { getId(fInternalObject, false); } @Override public void onContainerChange(FInternalObjectImpl object, FragmentedModel model) { String id = object.getId(); if (id != null) { model.getIdIndex().updateObjectURI(id, object); object.hasDefaultModelId = false; } } @Override public FInternalObject resolveURI(URI uri, FragmentedModel model) { return (FInternalObject)model.getInternalResourceSet().getEObject(model.getIdIndex().getObjectUriForIdUri(uri), true); } void assertHasPreliminary(FInternalObjectImpl fInternalObject) { Assert.assertTrue("Object has not a preliminary id.", isPreliminary(getId(fInternalObject, false))); } void assertHasNotPreliminary(FInternalObjectImpl fInternalObject) { boolean preliminaryId = isPreliminary(getId(fInternalObject, false)); Assert.assertFalse("Object has a preliminary id.", preliminaryId); } }