/******************************************************************************* * Copyright (c) 2010-2015 Henshin developers. 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: * TU Berlin, University of Luxembourg, SES S.A. *******************************************************************************/ package de.tub.tfs.muvitor.ui; import java.util.HashMap; import java.util.List; import org.eclipse.emf.common.util.TreeIterator; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.emf.ecore.xmi.XMLResource; import de.tub.tfs.muvitor.ui.utils.EMFModelManager; import de.tub.tfs.muvitor.ui.utils.GenericUtils; /** * This purely static utility class encapsulates and manages the access to * EObject models via their unique IDs (assigned by their XMLResource) and keeps * track of the {@link MuvitorTreeEditor}s showing those models. It is used * properly by {@link MuvitorTreeEditor}s and should not be needed elsewhere, * except for {@link #getIDForModel(EObject)} and possibly * {@link #getRealURIFragment(EObject)}. * * @author Tony Modica * */ public final class IDUtil { /** * A map storing all running editors associated with their model root URIs. */ final private static HashMap<String, MuvitorTreeEditor> modelURI2editor = new HashMap<String, MuvitorTreeEditor>(); /** * Method for getting the editor that hosts an EObject model (or rather its * root container). * * @param model * the model to find the hosting editor for * @return the editor whose model root is the root container of the passed * model */ static public final MuvitorTreeEditor getHostEditor(final EObject model) { // register the model root's ID with the editor if (model==null) return null; final EObject rootContainer = EcoreUtil.getRootContainer(model); final String uri = EcoreUtil.getURI(rootContainer).toString(); final MuvitorTreeEditor editor = modelURI2editor.get(uri); if (editor == null) { //MuvitorActivator.logError("Model '" + model + "' has no hosting editor (yet)!", null); } return editor; } /** * Convenience method for retrieving the unique ID this model has in its * {@link XMLResource}. * * @param model * The model to get an ID for * @return The unique EObject ID for the model * * @see #getModelForID(String) */ static public final String getIDForModel(final EObject model) { final XMLResource res = (XMLResource) model.eResource(); final String id = res.getID(model); return id; } /** * This method resolves an ID to an EObject model searching the models of * all running {@link MuvitorTreeEditor}s. * * @param id * an ID that has been retrieved before * @return the EObject that has the id */ static public final EObject getModelForID(final String id) { // look in all running editors for (final MuvitorTreeEditor editor : modelURI2editor.values()) { final List<EObject> modelRoots = editor.getModelRoots(); // look through all model roots for (final EObject modelRoot : modelRoots) { final XMLResource res = (XMLResource) modelRoot.eResource(); if (res == null) return null; final EObject model = res.getEObject(id); if (model != null) { return model; } } } return null; } /** * Convenience method the get the real URI fragment for an EObject model. * Because we set XMLResource to use unique IDs for its models (see * {@link EMFModelManager}) it will return these IDs if asked for the * URIFragment. To get the real URIFragment we have to set the ID to null * temporarily, which does this method. * * @param model * the model element to get the URI fragment from * @return the real URI fragment of the model rather than its ID */ static public final String getRealURIFragment(final EObject model) { final XMLResource res = (XMLResource) model.eResource(); if (res == null) { return null; } // store id of the model final String id = res.getID(model); // set id of model to null to get real uriFragment, XMLResource just // works like this res.setID(model, null); final String uriFragment = res.getURIFragment(model); // restore model id res.setID(model, id); return uriFragment; } /** * Sets newly generated IDs for all EObject contained in the passed model * root. root. * * @param model */ static public final void refreshIDs(final EObject modelRoot) { final XMLResource res = (XMLResource) modelRoot.eResource(); res.setID(modelRoot, EcoreUtil.generateUUID()); for (final TreeIterator<EObject> it = modelRoot.eAllContents(); it.hasNext();) { res.setID(it.next(), EcoreUtil.generateUUID()); } } /** * Deregisters a {@link MuvitorTreeEditor}. * * @param editor * the editor to be deregistered */ static final void deregisterEditor(final MuvitorTreeEditor editor) { GenericUtils.deleteValueFromMap(modelURI2editor, editor, false); } /** * Associates the URI of the model roots with the hosting editor. * * @param editor */ static public final void registerEditor(final MuvitorTreeEditor editor) { // remove a possible registration deregisterEditor(editor); // register the model roots' ID with the editor final List<EObject> models = editor.getModelRoots(); for (final EObject model : models) { final String uri = EcoreUtil.getURI(model).toString(); modelURI2editor.put(uri, editor); } } }