/**
* <copyright>
*
* Copyright (c) 2010 Eclipse Modeling Project 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:
* E.D.Willink - initial API and implementation
*
* </copyright>
*
* $Id: ProblemIndicationManager.java,v 1.1 2010/03/13 13:16:11 ewillink Exp $
*/
package org.eclipse.ocl.examples.editor.ui.common;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.ui.MarkerHelper;
import org.eclipse.emf.common.ui.editor.ProblemEditorPart;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EContentAdapter;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.ui.util.EditUIMarkerHelper;
import org.eclipse.ocl.examples.editor.ui.OCLExamplesEditorPlugin;
import org.eclipse.ui.IEditorPart;
/**
* ProblemIndicationManager manages the problems associated with the resources
* of an editor using a ResourceSet.
* <p>
* The code is based on the auto-generated EcoreEditor code and is separated out
* to support re-use in single and multi-page editors.
*/
public abstract class ProblemIndicationManager extends EContentAdapter
{
/**
* This looks up a string in the plugin's plugin.properties file.
*/
protected static String getString(String key)
{
return OCLExamplesEditorPlugin.INSTANCE.getString(key);
}
/**
* This looks up a string in plugin.properties, making a substitution.
*/
protected static String getString(String key, Object s1)
{
return OCLExamplesEditorPlugin.INSTANCE.getString(key, new Object [] { s1 });
}
private final class UpdateProblemIndicationRunnable implements Runnable
{
public void run()
{
updateProblemIndication();
}
}
/**
* Map to store the diagnostic associated with a resource.
*/
protected Map<Resource, Diagnostic> resourceToDiagnosticMap = new LinkedHashMap<Resource, Diagnostic>();
/**
* Controls whether the problem indication should be updated.
*/
protected boolean updateProblemIndication = true;
/**
* The MarkerHelper is responsible for creating workspace resource markers presented
* in Eclipse's Problems View.
*/
protected MarkerHelper markerHelper = new EditUIMarkerHelper();
/**
* Returns a diagnostic describing the errors and warnings listed in the resource
* and the specified exception (if any).
*/
public Diagnostic analyzeResourceProblems(Resource resource, Exception exception)
{
if (!resource.getErrors().isEmpty() || !resource.getWarnings().isEmpty())
{
BasicDiagnostic basicDiagnostic = new BasicDiagnostic
(Diagnostic.ERROR, "org.eclipse.emf.ecore.editor", 0,
getString("_UI_CreateModelError_message", resource.getURI()),
new Object [] { exception == null ? (Object)resource : exception });
basicDiagnostic.merge(EcoreUtil.computeDiagnostic(resource, true));
return basicDiagnostic;
}
else if (exception != null)
{
return new BasicDiagnostic
(Diagnostic.ERROR, "org.eclipse.emf.ecore.editor", 0,
getString("_UI_CreateModelError_message", resource.getURI()),
new Object[] { exception });
}
else
return Diagnostic.OK_INSTANCE;
}
protected abstract void asyncExec(Runnable runnable);
protected abstract void createProblemEditor(BasicDiagnostic diagnostic);
protected abstract ProblemEditorPart getProblemEditor();
protected abstract ResourceSet getResourceSet();
public List<?> getTargetObjects(Object object, IMarker marker) {
return markerHelper.getTargetObjects(object, marker);
}
public void handleResourceException(Resource resource, Exception exception, boolean forceUpdate) {
if (forceUpdate || !resourceToDiagnosticMap.containsKey(resource))
{
resourceToDiagnosticMap.put(resource, analyzeResourceProblems(resource, exception));
}
}
public void initializeProblemIndication(Resource resource, Exception exception) {
Diagnostic diagnostic = analyzeResourceProblems(resource, exception);
if (diagnostic.getSeverity() != Diagnostic.OK) {
resourceToDiagnosticMap.put(resource, diagnostic);
}
getResourceSet().eAdapters().add(this);
updateProblemIndication();
}
@Override
public void notifyChanged(Notification notification)
{
if (notification.getNotifier() instanceof Resource)
{
switch (notification.getFeatureID(Resource.class))
{
case Resource.RESOURCE__IS_LOADED:
case Resource.RESOURCE__ERRORS:
case Resource.RESOURCE__WARNINGS:
{
Resource resource = (Resource)notification.getNotifier();
Diagnostic diagnostic = analyzeResourceProblems(resource, null);
if (diagnostic.getSeverity() != Diagnostic.OK)
resourceToDiagnosticMap.put(resource, diagnostic);
else
resourceToDiagnosticMap.remove(resource);
if (updateProblemIndication) {
asyncExec(new UpdateProblemIndicationRunnable());
}
break;
}
}
}
else
{
super.notifyChanged(notification);
}
}
protected void refreshMarkers(BasicDiagnostic diagnostic) {
ResourceSet resourceSet = getResourceSet();
if (markerHelper.hasMarkers(resourceSet))
{
markerHelper.deleteMarkers(resourceSet);
if (diagnostic.getSeverity() != Diagnostic.OK)
{
try
{
markerHelper.createMarkers(diagnostic);
}
catch (CoreException exception)
{
OCLExamplesEditorPlugin.INSTANCE.log(exception);
}
}
}
}
public void resumeProblemIndicationUpdate() {
updateProblemIndication = true;
updateProblemIndication();
}
protected abstract void setActiveEditor(IEditorPart editor);
@Override
protected void setTarget(Resource target)
{
basicSetTarget(target);
}
public void suspendProblemIndicationUpdate() {
updateProblemIndication = false;
}
@Override
protected void unsetTarget(Resource target)
{
basicUnsetTarget(target);
}
/**
* Updates the problems indication with the information described in the specified diagnostic.
*/
public void updateProblemIndication()
{
if (updateProblemIndication)
{
BasicDiagnostic diagnostic = new BasicDiagnostic
(Diagnostic.OK, "org.eclipse.emf.ecore.editor", 0, null,
new Object [] { getResourceSet() });
for (Diagnostic childDiagnostic : resourceToDiagnosticMap.values()) {
if (childDiagnostic.getSeverity() != Diagnostic.OK) {
diagnostic.add(childDiagnostic);
}
}
ProblemEditorPart problemEditor = getProblemEditor();
if (problemEditor != null) {
problemEditor.setDiagnostic(diagnostic);
if (diagnostic.getSeverity() != Diagnostic.OK) {
setActiveEditor(problemEditor);
}
}
else if (diagnostic.getSeverity() != Diagnostic.OK) {
createProblemEditor(diagnostic);
}
refreshMarkers(diagnostic);
}
}
}