/** * Copyright (c) 2006 IBM Corporation and others. * 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: * IBM - Initial API and implementation */ package org.eclipse.emf.edit.ui.util; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.emf.common.ui.CommonUIPlugin; import org.eclipse.emf.common.ui.MarkerHelper; import org.eclipse.emf.common.util.BasicDiagnostic; import org.eclipse.emf.common.util.Diagnostic; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EValidator; 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.edit.domain.AdapterFactoryEditingDomain; import org.eclipse.emf.edit.domain.EditingDomain; import org.eclipse.emf.edit.ui.EMFEditUIPlugin; /** * Extension of {@link MarkerHelper} that provides extra functionalities useful when * using EMF classes such as {@link Resource}. * * @since 2.2.0 */ public class EditUIMarkerHelper extends MarkerHelper { @Override protected IFile getFile(Object datum) { if (datum instanceof Resource) { Resource resource = (Resource)datum; URI uri = resource.getURI(); if (uri == null) { return null; } else { ResourceSet resourceSet = resource.getResourceSet(); if (resourceSet != null) { uri = resourceSet.getURIConverter().normalize(uri); } return getFile(uri); } } else if (datum instanceof EObject) { return getFile(((EObject)datum).eResource()); } else if (datum instanceof Resource.Diagnostic) { String location = ((Resource.Diagnostic)datum).getLocation(); if (location != null) { return getFile(URI.createURI(location)); } } return super.getFile(datum); } @Override protected void adjustMarker(IMarker marker, Diagnostic diagnostic, Diagnostic parentDiagnostic) throws CoreException { if (!adjustMarker(marker, diagnostic) && parentDiagnostic != null) { adjustMarker(marker, parentDiagnostic); } } protected boolean adjustMarker(IMarker marker, Diagnostic diagnostic) throws CoreException { if (diagnostic.getData() != null) { for (Object element : diagnostic.getData()) { if (element instanceof Resource.Diagnostic) { Resource.Diagnostic resourceDiagnostic = (Resource.Diagnostic)element; if (resourceDiagnostic.getLocation() != null) { marker.setAttribute (IMarker.LOCATION, EMFEditUIPlugin.getPlugin().getString ("_UI_MarkerLocation", new String[] { Integer.toString(resourceDiagnostic.getLine()), Integer.toString(resourceDiagnostic.getColumn()) })); marker.setAttribute(IMarker.LINE_NUMBER, resourceDiagnostic.getLine()); try { Method getObjectMethod = resourceDiagnostic.getClass().getMethod("getObject"); Object object = getObjectMethod.invoke(resourceDiagnostic); if (object instanceof EObject) { marker.setAttribute(EValidator.URI_ATTRIBUTE, EcoreUtil.getURI((EObject)object).toString()); Method getFeatureMethod = resourceDiagnostic.getClass().getMethod("getFeature"); Object feature = getFeatureMethod.invoke(resourceDiagnostic); if (feature instanceof EObject) { marker.setAttribute(EValidator.RELATED_URIS_ATTRIBUTE, EcoreUtil.getURI((EObject)feature).toString()); } } } catch (Throwable throwable) { // Ignore. } return true; } } } } return false; } @Override public boolean hasMarkers(Object object, boolean includeSubtypes, int depth) { if (object instanceof ResourceSet) { ResourceSet resourceSet = (ResourceSet)object; List<Resource> resources = resourceSet.getResources(); for (int i=0, size=resources.size(); i<size; i++) { if (hasMarkers(resources.get(i), includeSubtypes, depth)) { return true; } } return false; } else if (object instanceof Diagnostic) { List<?> data = ((Diagnostic)object).getData(); if (data != null) { for (Object datum : data) { if (datum instanceof ResourceSet) { return hasMarkers(datum, includeSubtypes, depth); } } } } return super.hasMarkers(object, includeSubtypes, depth); } @Override public void deleteMarkers(Object object, boolean includeSubtypes, int depth) { if (object instanceof ResourceSet) { ResourceSet resourceSet = (ResourceSet)object; List<Resource> resources = resourceSet.getResources(); for (int i=0, size=resources.size(); i<size; i++) { deleteMarkers(resources.get(i), includeSubtypes, depth); } } else if (object instanceof Diagnostic) { List<?> data = ((Diagnostic)object).getData(); if (data != null) { for (Object datum : data) { if (datum instanceof ResourceSet) { deleteMarkers(datum, includeSubtypes, depth); return; } } } } super.deleteMarkers(object, includeSubtypes, depth); } /** * @since 2.11 */ @Override public List<?> getTargetObjects(Object object, IMarker marker, boolean wrap) { if (object instanceof AdapterFactoryEditingDomain) { ArrayList<Object> result = new ArrayList<Object>(); AdapterFactoryEditingDomain editingDomain = (AdapterFactoryEditingDomain)object; String uriAttribute = marker.getAttribute(EValidator.URI_ATTRIBUTE, null); if (uriAttribute == null) { uriAttribute = marker.getAttribute("URI_KEY", null); } if (uriAttribute != null) { URI uri = URI.createURI(uriAttribute); try { EObject eObject = editingDomain.getResourceSet().getEObject(uri, true); if (eObject != null) { result.add(wrap ? editingDomain.getWrapper(eObject) : eObject); } } catch (Throwable throwable) { // Ignore if we can resolve the object. } } String relatedURIsAttribute = marker.getAttribute(EValidator.RELATED_URIS_ATTRIBUTE, null); if (relatedURIsAttribute != null) { for (String relatedURI : relatedURIsAttribute.split(" ")) { URI uri = URI.createURI(URI.decode(relatedURI)); try { EObject eObject = editingDomain.getResourceSet().getEObject(uri, true); if (eObject != null) { result.add(wrap ? editingDomain.getWrapper(eObject) : eObject); } } catch (Throwable throwable) { // Ignore if we can't resolve the object. } } } else { relatedURIsAttribute = marker.getAttribute("DATA_KEY", null); if (relatedURIsAttribute != null) { int start = 0; int length = relatedURIsAttribute.length(); for (int index = relatedURIsAttribute.indexOf(':'); start < length; index = relatedURIsAttribute.indexOf(':', start)) { int itemLength = Integer.parseInt(relatedURIsAttribute.substring(start, index == -1 ? length : index)); start = index + itemLength + 1; String uriLiteral = relatedURIsAttribute.substring(index + 1, start); try { URI uri = URI.createURI(uriLiteral); if (uri.hasFragment()) { EObject eObject = editingDomain.getResourceSet().getEObject(uri, true); if (eObject != null) { result.add(wrap ? editingDomain.getWrapper(eObject) : eObject); } } } catch (Throwable throwable) { // Ignore if it's not a URI or we can't load the object. } } } } return result; } else { return super.getTargetObjects(object, marker, wrap); } } /** * @since 2.11 */ @Override public Diagnostic getMarkerDiagnostics(Object object, IFile file, boolean wrap) { if (file == null) { file = getFile(object); } if (object instanceof Resource) { Resource resource = (Resource)object; EditingDomain editingDomain = AdapterFactoryEditingDomain.getEditingDomainFor(resource.getResourceSet()); BasicDiagnostic diagnostic = new BasicDiagnostic(getDiagnosticSource(), 0, null, new Object[] { resource }); if (file != null && file.isAccessible()) { try { for (IMarker marker : file.findMarkers(null, true, IResource.DEPTH_ZERO)) { String message = marker.getAttribute(IMarker.MESSAGE, ""); int severity = marker.getAttribute(IMarker.SEVERITY, IMarker.SEVERITY_INFO); String sourceID = marker.getAttribute(IMarker.SOURCE_ID, ""); List<?> data = wrap ? getTargetObjects(editingDomain, marker) : getTargetObjects(editingDomain, marker, false); diagnostic.add (new BasicDiagnostic (severity == IMarker.SEVERITY_ERROR ? Diagnostic.ERROR : severity == IMarker.SEVERITY_WARNING ? Diagnostic.WARNING : Diagnostic.INFO, sourceID, 0, message, data.toArray(new Object[data.size()]))); } } catch (CoreException exception) { CommonUIPlugin.INSTANCE.log(exception); } } for (Diagnostic intrinsicDiagnostic : getInstrinciDiagnostics(resource, wrap)) { diagnostic.add(intrinsicDiagnostic); } return diagnostic; } else { return super.getMarkerDiagnostics(object, file, wrap); } } @Override public List<? extends Diagnostic> getInstrinciDiagnostics(Object object, boolean wrap) { if (object instanceof Resource) { Resource resource = (Resource)object; List<Diagnostic> diagnostics = new ArrayList<Diagnostic>(); for (Resource.Diagnostic resourceDiagnostic : resource.getWarnings()) { diagnostics.add(new BasicDiagnostic(Diagnostic.WARNING, null, 0, resourceDiagnostic.getMessage(), getDiagnosticData(resource, resourceDiagnostic, wrap))); } for (Resource.Diagnostic resourceDiagnostic : resource.getErrors()) { diagnostics.add(new BasicDiagnostic(Diagnostic.ERROR, null, 0, resourceDiagnostic.getMessage(), getDiagnosticData(resource, resourceDiagnostic, wrap))); } return diagnostics; } else { return super.getInstrinciDiagnostics(object, wrap); } } /** * @since 2.13 */ protected Object[] getDiagnosticData(Resource resource, Resource.Diagnostic resourceDiagnostic, boolean wrap) { List<Object> result = new ArrayList<Object>(); EditingDomain editingDomain = AdapterFactoryEditingDomain.getEditingDomainFor(resource.getResourceSet()); try { Method getObjectMethod = resourceDiagnostic.getClass().getMethod("getObject"); Object object = getObjectMethod.invoke(resourceDiagnostic); if (object instanceof EObject) { result.add(wrap && editingDomain instanceof AdapterFactoryEditingDomain ? ((AdapterFactoryEditingDomain)editingDomain).getWrapper(object) : object); Method getFeatureMethod = resourceDiagnostic.getClass().getMethod("getFeature"); Object feature = getFeatureMethod.invoke(resourceDiagnostic); if (feature instanceof EObject) { result.add(wrap && editingDomain instanceof AdapterFactoryEditingDomain ? ((AdapterFactoryEditingDomain)editingDomain).getWrapper(feature) : feature); result.add(feature); } } } catch (Throwable throwable) { // Ignore. } return result.isEmpty() ? new Object[] { resource } : result.toArray(); } }