/******************************************************************************* * Copyright (c) 2006-2012 * Software Technology Group, Dresden University of Technology * DevBoost GmbH, Berlin, Amtsgericht Charlottenburg, HRB 140026 * * 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: * Software Technology Group - TU Dresden, Germany; * DevBoost GmbH - Berlin, Germany * - initial API and implementation ******************************************************************************/ package org.reuseware.coconut.resource.gmf; import java.util.Iterator; import java.util.Map; import org.eclipse.core.resources.IFile; 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.util.EcoreUtil; import org.eclipse.emf.ecore.xmi.XMLResource; import org.eclipse.emf.workspace.util.WorkspaceSynchronizer; import org.eclipse.gmf.runtime.notation.Diagram; import org.eclipse.ui.IEditorDescriptor; import org.eclipse.ui.PlatformUI; import org.reuseware.coconut.compositionprogram.resource.CompositionProblemReporter; import org.reuseware.coconut.fragment.Fragment; import org.reuseware.coconut.resource.ReuseResources; /** * Problem reporter that can annotate GMF diagrams with markers * that are shown on visual elements in the diagrams. */ public class GMFCompositionProblemReporter implements CompositionProblemReporter { private EObject findNotationFor(EObject problemSource) { Resource resource = problemSource.eResource(); if (resource == null || !resource.getURI().isPlatformResource()) { return null; } ResourceSet resourceSet = resource.getResourceSet(); if (resourceSet != null) { Fragment fragment = ReuseResources.INSTANCE.getFragment(ReuseResources.INSTANCE.getID(resource.getURI()), resourceSet); if (fragment != null) { // make sure fragment.contents is resolved EcoreUtil.resolveAll(fragment); for (EObject diagramRoot : fragment.getDiagrams()) { if (diagramRoot instanceof Diagram) { Iterator<EObject> i = diagramRoot.eResource().getAllContents(); while (i.hasNext()) { EObject next = i.next(); for (EObject crossRef : next.eCrossReferences()) { if (problemSource.equals(crossRef)) { return next; } } } } } } } return null; } /** * Returns the GMF diagram file that is associated * with the model containing the problem's source element. * * @param problemSource the EObject causing the problem * * @return file with GMF diagram */ public IFile getFile(EObject problemSource) { EObject notation = findNotationFor(problemSource); if (notation == null) { return null; } IFile file = WorkspaceSynchronizer.getFile(notation.eResource()); return file; } /** * GMF generates an individual marker type for each editor. * This method computes this marker type based on the class * name of the GMF editor for the given type of model. * * @param problemSource the EObject causing the problem * * @return individual GMF marker type */ public String getMarkerType(EObject problemSource) { EObject notation = findNotationFor(problemSource); Resource resource = notation.eResource(); IEditorDescriptor gmfEditorDescriptor = PlatformUI.getWorkbench().getEditorRegistry().getDefaultEditor( resource.getURI().lastSegment()); if (gmfEditorDescriptor == null) { return null; } // this guesses the marker ID based on the editor ID according to GMF's defaults String markerID = gmfEditorDescriptor.getId(); markerID = markerID.substring(0, markerID.lastIndexOf(".")); markerID = markerID.substring(0, markerID.lastIndexOf(".")); markerID = markerID + ".diagnostic"; return markerID; } /** * Sets the <code>elementId</code> attribute to the * <code>XMLResource.getID()</code> for the notation element * associated with the given problem source element. This * information can be used by GMF to annotate the notation * element in the diagram editor. * * @param problemSource the EObject causing the problem * @param attributes the attributes for the marker that can be extended by this methods */ public void getAttributes(EObject problemSource, Map<String, Object> attributes) { EObject notation = findNotationFor(problemSource); Resource resource = notation.eResource(); if (resource instanceof XMLResource) { String elementId = ((XMLResource) resource).getID(notation); attributes.put("elementId", elementId); } } }