blob: c1f4a31541156b1e9c8bbaf5b47bf434b9e8c147 [file] [log] [blame]
//------------------------------------------------------------------------------
// Copyright (c) 2005, 2008 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 Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.library.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
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.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.epf.common.utils.RestartableJob;
import org.eclipse.epf.library.ILibraryManager;
import org.eclipse.epf.library.ILibraryService;
import org.eclipse.epf.library.LibraryPlugin;
import org.eclipse.epf.library.LibraryResources;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.LibraryServiceListener;
import org.eclipse.epf.library.LibraryServiceUtil;
import org.eclipse.epf.library.events.ILibraryChangeListener;
import org.eclipse.epf.services.ILibraryPersister;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.MethodPlugin;
/**
* The class for monitor library problems.
*
* @author Weiping Lu
* @since 1.5
*/
public class LibraryProblemMonitor extends RestartableJob implements ILibraryChangeListener {
public static final String UnresolvedBasedPluginMARKER_ID = LibraryPlugin.getDefault().getId() + ".unresolvedBasePlugins"; //$NON-NLS-1$
public static final String Name = "name"; //$NON-NLS-1$
public static final String Guid = "guid"; //$NON-NLS-1$
public static final String UnresolvedBaseGuids = "unresolvedBaseGuids"; //$NON-NLS-1$
private long delay = 30000L;
private long restartDelay = 1000L;
private boolean hasChange = false;
private Thread monitorThread;
private boolean stopMonitor = false;
private MethodLibrary library;
private Map<MethodPlugin, IMarker> pluginMarkerMap = new HashMap<MethodPlugin, IMarker>();
public LibraryProblemMonitor() {
super(LibraryResources.libraryProblemMonitor);
LibraryServiceListener libServiceListener = new LibraryServiceListener() {
public void librarySet(MethodLibrary lib) {
ILibraryService libService = LibraryService.getInstance();
if (library != null && library != lib) {
ILibraryManager libMgr = libService.getLibraryManager(library);
if (libMgr != null) {
libMgr.removeListener(LibraryProblemMonitor.this);
}
}
if (lib != null && lib != library) {
ILibraryManager libMgr = libService.getLibraryManager(lib);
if (libMgr != null) {
libMgr.addListener(LibraryProblemMonitor.this);
}
kickToRun();
}
library = lib;
}
};
LibraryService.getInstance().addListener(libServiceListener);
startMonitor();
}
public void startMonitor() {
Runnable runnable = new Runnable() {
public void run() {
while (! stopMonitor) {
try {
Thread.sleep(delay);
} catch (Exception e) {
LibraryPlugin.getDefault().getLogger().logError(e);
return;
}
if (hasChange) {
hasChange = false;
guardedSchedule(0L);
}
}
}
};
stopMonitor = false;
if (monitorThread == null) {
monitorThread = new Thread(runnable);
}
monitorThread.start();
}
public void stopMonitor() {
stopMonitor = true;
}
public void libraryChanged(int option, Collection<Object> changedItems) {
if (changedItems != null && changedItems.size() > 0) {
hasChange = true;
enableToRestart();
}
}
// Update will abort and re-schedule a job if new change detected
private void update() throws RestartInterruptException {
if (localDebug) {
System.out.println("LD> update"); //$NON-NLS-1$
}
MethodLibrary lib = getLibrary();
if (lib == null) {
return;
}
checkRestartInterruptException(restartDelay);
cleanUp();
List<MethodPlugin> plugins = new ArrayList<MethodPlugin>();
plugins.addAll(lib.getMethodPlugins());
Set<MethodPlugin> pluginSet = new HashSet<MethodPlugin>(plugins);
for (MethodPlugin plugin: plugins) {
checkRestartInterruptException(restartDelay);
List<MethodPlugin> baseList = plugin.getBases();
boolean missing = false;
for (MethodPlugin base: baseList) {
checkRestartInterruptException(restartDelay);
if (! pluginSet.contains(base)) {
if (! missing) {
if (localDebug) {
System.out.println("LD> plugin: " + plugin); //$NON-NLS-1$
System.out.println("LD> " + plugin.getName() + " references unresolved bases:"); //$NON-NLS-1$ //$NON-NLS-2$
}
missing = true;
}
if (localDebug) {
System.out.println("LD> base: " + base); //$NON-NLS-1$
}
addMissingBasePluginError(plugin, base);
}
}
if (missing) {
System.out.println(""); //$NON-NLS-1$
}
}
}
private void addMissingBasePluginError(MethodPlugin plugin, MethodPlugin base) {
IMarker marker = pluginMarkerMap.get(plugin);
if (marker == null) {
Resource res = plugin.eResource();
if (res == null) {
return;
}
URI containerURI = res.getURI();
IWorkspace workspace = ResourcesPlugin.getWorkspace();
IPath path = new Path(containerURI.toFileString());
IFile file = workspace.getRoot().getFileForLocation(path);
if (file == null) {
return;
}
String location = containerURI != null ? containerURI
.toFileString() : ""; //$NON-NLS-1$
try {
marker = file.createMarker(UnresolvedBasedPluginMARKER_ID);
marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
marker.setAttribute(Name, plugin.getName());
marker.setAttribute(Guid, plugin.getGuid());
marker.setAttribute(IMarker.LOCATION, location);
marker.setAttribute(Guid, plugin.getGuid());
} catch (Exception e) {
LibraryPlugin.getDefault().getLogger().logError(e);
}
if (marker == null) {
return;
}
if (localDebug) {
System.out.println("LD> marker: " + marker); //$NON-NLS-1$
}
pluginMarkerMap.put(plugin, marker);
}
String unresolvedBaseGuidsValue = null;
try {
String errMsg = plugin.getName() + " references unresolved base "; //$NON-NLS-1$
unresolvedBaseGuidsValue = (String) marker.getAttribute(UnresolvedBaseGuids);
if (unresolvedBaseGuidsValue == null || unresolvedBaseGuidsValue.length() == 0) {
unresolvedBaseGuidsValue = base.getGuid();
errMsg += "plugin: "; //$NON-NLS-1$
} else if (unresolvedBaseGuidsValue.indexOf(base.getGuid()) < 0) {
unresolvedBaseGuidsValue += ", " + base.getGuid(); //$NON-NLS-1$
errMsg += "plugins: "; //$NON-NLS-1$
}
errMsg += unresolvedBaseGuidsValue;
marker.setAttribute(IMarker.MESSAGE, errMsg);
marker.setAttribute(UnresolvedBaseGuids, unresolvedBaseGuidsValue);
} catch (Exception e) {
LibraryPlugin.getDefault().getLogger().logError(e);
}
}
protected IStatus restartableRun(IProgressMonitor monitor) throws RestartInterruptException {
update();
return Status.OK_STATUS;
}
protected void resetToRestart() {
if (localDebug) {
System.out.println("LD> resetToRestart"); //$NON-NLS-1$
}
cleanUp();
}
private void cleanUp() {
if (pluginMarkerMap.isEmpty()) {
return;
}
for (IMarker marker: pluginMarkerMap.values()) {
try {
marker.delete();
} catch (Exception e) {
LibraryPlugin.getDefault().getLogger().logError(e);
}
}
pluginMarkerMap = new HashMap<MethodPlugin, IMarker>();
}
public void kickToRun() {
if (localDebug) {
System.out.println("LD> kickToRun"); //$NON-NLS-1$
}
enableToRestart();
guardedSchedule(0L);
}
//To do: allow a cached data to pased and return -> optimize fix of similar problems
public void fixProblem(IMarker marker) {
try {
if (marker.getType() != UnresolvedBasedPluginMARKER_ID) {
return;
}
MethodLibrary lib = getLibrary();
if (lib == null) {
return;
}
Map<String, MethodPlugin> guidToPluginMap = new HashMap<String, MethodPlugin>();
for (MethodPlugin plugin : lib.getMethodPlugins()) {
guidToPluginMap.put(plugin.getGuid(), plugin);
}
String guid = (String) marker.getAttribute(Guid); //$NON-NLS-1$
MethodPlugin plugin = guidToPluginMap.get(guid);
if (plugin == null || plugin.eResource() == null) {
return;
}
if (localDebug) {
System.out.println("LD> fixProblem, plugin: " + plugin); //$NON-NLS-1$
}
List<MethodPlugin> bases = new ArrayList<MethodPlugin>();
bases.addAll(plugin.getBases());
boolean modified = false;
for (MethodPlugin base : bases) {
if (! guidToPluginMap.containsKey(base.getGuid())) {
modified = true;
plugin.getBases().remove(base);
}
}
if (! modified) {
return;
}
Resource resource = plugin.eResource();
ILibraryPersister.FailSafeMethodLibraryPersister persister = LibraryServiceUtil
.getPersisterFor(resource).getFailSafePersister();
try {
persister.save(resource);
persister.commit();
}
catch(Exception e) {
LibraryPlugin.getDefault().getLogger().logError(e);
persister.rollback();
}
kickToRun();
} catch (Exception e) {
LibraryPlugin.getDefault().getLogger().logError(e);
}
}
public void dispose() {
stopMonitor();
cleanUp();
}
public MethodLibrary getLibrary() {
return library;
}
public void setLibrary(MethodLibrary library) {
this.library = library;
}
}