/*******************************************************************************
* 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.compositionprogram.resource;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
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.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.workspace.util.WorkspaceSynchronizer;
/**
* Utility class for marking resources that cause errors in a UCL composition programs.
* This are not only UCL files but also diagrams for UCL files and other files from
* which UCL files are derived.
* <p>
* This class manages the extension point:
* <i>org.reuseware.coconut.compositionprogram.resource.ucl.reporter</i>.
*/
public final class UCLMarkerHelper {
private UCLMarkerHelper() { }
/**
* Extension point ID:
* <i>org.reuseware.coconut.compositionprogram.resource.ucl.reporter</i>.
*/
public static final String REPORTER_EP_ID =
"org.reuseware.coconut.compositionprogram.resource.ucl.reporter";
/**
* Constant used as UCPI attribute in markers.
*/
public static final String UNIQUE_COMPOSITION_PROGRAM_IDENTIFIER =
"UNIQUE_COMPOSITION_PROGRAM_IDENTIFIER";
private static final class ExistingMarker {
private ExistingMarker() { }
private String type;
@SuppressWarnings("rawtypes")
private Map attributes;
}
private static List<CompositionProblemReporter> reporterList = null;
private static void init() {
if (reporterList == null) {
reporterList = new ArrayList<CompositionProblemReporter>();
if (Platform.isRunning()) {
IExtensionPoint reporterEP =
Platform.getExtensionRegistry().getExtensionPoint(REPORTER_EP_ID);
IConfigurationElement[] entries = reporterEP.getConfigurationElements();
for (int i = 0; i < entries.length; i++) {
try {
CompositionProblemReporter reporter =
(CompositionProblemReporter) entries[i].createExecutableExtension("class");
reporterList.add(reporter);
} catch (CoreException e) {
e.printStackTrace();
}
}
}
reporterList.add(new DefaultCompositionProblemReporter());
}
}
/**
* Register a new reporter.
*
* @param reporter the reporter to register
*/
public static void addReporter(CompositionProblemReporter reporter) {
init();
reporterList.add(0, reporter);
}
/**
* @return list of all registered reporters
*/
public static List<CompositionProblemReporter> getReporter() {
init();
return reporterList;
}
/**
* Create a marker based on the given diagnostic.
*
* @param diagnostic diagnostic holding the issue
* @param ucpi UCPI of the composition diagram causing the issue
*/
public static void mark(UCLDiagnostic diagnostic, List<String> ucpi) {
if (!Platform.isRunning()) {
return;
}
init();
for (EObject problemSource : diagnostic.getElements()) {
Set<IFile> markedFiles = new LinkedHashSet<IFile>();
for (CompositionProblemReporter reporter : UCLMarkerHelper.getReporter()) {
IFile file = reporter.getFile(problemSource);
if (file != null && !markedFiles.contains(file)) {
String markerType = reporter.getMarkerType(problemSource);
Map<String, Object> attributes = new LinkedHashMap<String, Object>();
reporter.getAttributes(problemSource, attributes);
createNewMarker(file, diagnostic, markerType, attributes, ucpi);
markedFiles.add(file);
}
}
}
}
/**
* Removes all markers from the given resource that were caused by the
* indicated composition program.
*
* @param resource resource from which to remove markers
* @param ucpi UCPI of the composition program causing the issue
*/
public static void unmark(Resource resource, List<String> ucpi) {
init();
if (!Platform.isRunning()) {
return;
}
IFile file = WorkspaceSynchronizer.getFile(resource);
if (file != null) {
try {
List<ExistingMarker> markerMemory = new ArrayList<ExistingMarker>();
boolean needsClean = false;
for (IMarker existingMarker : file.findMarkers(null, false, IResource.DEPTH_ZERO)) {
if (!ucpi.toString().equals(existingMarker.getAttribute(UNIQUE_COMPOSITION_PROGRAM_IDENTIFIER))) {
Map<?, ?> markerAttributes = existingMarker.getAttributes();
if (markerAttributes != null) {
ExistingMarker m = new ExistingMarker();
m.type = existingMarker.getType();
m.attributes = markerAttributes;
markerMemory.add(m);
}
} else {
needsClean = true;
}
}
if (needsClean) {
file.deleteMarkers(null, false, IResource.DEPTH_ZERO);
for (ExistingMarker m : markerMemory) {
IMarker marker = file.createMarker(m.type);
marker.setAttributes(m.attributes);
}
}
} catch (Exception ce) {
if (ce.getMessage().matches("Marker.*not found.")) {
// ignore
} else if (ce.getMessage().matches("Resource.*does not exist.")) {
// ignore
} else {
ce.printStackTrace();
}
}
}
}
private static void createNewMarker(
IFile file, UCLDiagnostic diagnostic, String markerType, Map<String, Object> attributes, List<String> ucpi) {
try {
IMarker marker = file.createMarker(markerType);
attributes.put(IMarker.MESSAGE, diagnostic.getMessage());
if (diagnostic.getSeverity() == org.eclipse.emf.common.util.Diagnostic.ERROR) {
attributes.put(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
} else if (diagnostic.getSeverity() == org.eclipse.emf.common.util.Diagnostic.INFO) {
attributes.put(IMarker.SEVERITY, IMarker.SEVERITY_INFO);
} else {
attributes.put(IMarker.SEVERITY, IMarker.SEVERITY_WARNING);
}
attributes.put(UNIQUE_COMPOSITION_PROGRAM_IDENTIFIER, ucpi.toString());
marker.setAttributes(attributes);
} catch (org.eclipse.core.runtime.CoreException ce) {
if (ce.getMessage().matches("Marker.*not found.")) {
// ignore
} else {
ce.printStackTrace();
}
}
}
}