/******************************************************************************* * Copyright 2005-2006, CHISEL Group, University of Victoria, Victoria, BC, Canada. * 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: * The Chisel Group, University of Victoria *******************************************************************************/ package net.sourceforge.tagsea.java.resources.internal; import java.lang.reflect.InvocationTargetException; import java.util.List; import net.sourceforge.tagsea.TagSEAModelException; import net.sourceforge.tagsea.TagSEAPlugin; import net.sourceforge.tagsea.core.IWaypoint; import net.sourceforge.tagsea.java.IJavaWaypointsConstants; import net.sourceforge.tagsea.java.JavaTagsPlugin; import net.sourceforge.tagsea.java.documents.internal.FileWaypointExtractor; import net.sourceforge.tagsea.java.waypoints.JavaWaypointDelegate; import net.sourceforge.tagsea.java.waypoints.parser.IParsedJavaWaypointInfo; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.core.runtime.jobs.ISchedulingRule; /** * Refreshes the waypoints for a list of files. * @author Del Myers */ //@tag tagsea.bug.171 : this job can cause deadlock if a thread that has a lock on the workspace tries to access the waypoint/tags model. public class FileWaypointRefreshJob extends JavaWaypointDelegate.InternalOperation { private List<IFile> files; private class FileRefreshOperation extends JavaWaypointDelegate.InternalOperation { private IFile file; public FileRefreshOperation(IFile file) { this.file = file; } @Override public IStatus run(IProgressMonitor monitor) throws InvocationTargetException { monitor.beginTask(Messages.getString("FileWaypointRefreshJob.refreshWaypoints") + file.getFullPath(), 300); //$NON-NLS-1$ if (!file.exists()) { //remove the waypoints from the file. return removeWaypointsForFile(file); } IMarker[] problems; MultiStatus status = new MultiStatus(JavaTagsPlugin.PLUGIN_ID, 0, "", null); //$NON-NLS-1$ try { problems = file.findMarkers(IJavaWaypointsConstants.WAYPOINT_PROBLEM_MARKER, true, IResource.DEPTH_ZERO); } catch (CoreException e) { status.merge(e.getStatus()); problems = new IMarker[0]; } for (IMarker problem : problems) { try { problem.delete(); } catch (CoreException e) { status.merge(e.getStatus()); } } IMarker[] markers; try { markers = file.findMarkers(IJavaWaypointsConstants.WAYPOINT_MARKER, true, IResource.DEPTH_ZERO); } catch (CoreException e) { status.merge(e.getStatus()); markers = new IMarker[0]; } // This process is started by a resource change event, so we have to delete the markers later; otherwise the process will hang. for (IMarker marker : markers) { try { marker.delete(); } catch (CoreException e) { status.merge(e.getStatus()); } } monitor.subTask(Messages.getString("FileWaypointRefreshJob.findWaypoints")); //$NON-NLS-1$ IParsedJavaWaypointInfo[] toCreate = FileWaypointExtractor.findWaypoints(file); monitor.worked(300); monitor.subTask(Messages.getString("FileWaypointRefreshJob.refreshWaypoints")); //$NON-NLS-1$ status.merge(removeWaypointsForFile(file)); status.merge(createWaypoints(toCreate, file)); monitor.done(); return status; } /** * @param file2 * @throws TagSEAModelException */ private IStatus removeWaypointsForFile(IFile file) { IWaypoint[] toDelete = JavaTagsPlugin.getJavaWaypointsForFile(file); MultiStatus status = new MultiStatus(JavaTagsPlugin.PLUGIN_ID, 0, "", null); //$NON-NLS-1$ for (IWaypoint wp : toDelete) { status.merge(TagSEAPlugin.getWaypointsModel().removeWaypoint(wp).getStatus()); } return status; } private IStatus createWaypoints(IParsedJavaWaypointInfo[] toCreate, IFile file) { MultiStatus s = new MultiStatus(JavaTagsPlugin.PLUGIN_ID, IStatus.OK, "", null); //$NON-NLS-1$ for (IParsedJavaWaypointInfo info : toCreate) { IWaypoint wp = WaypointResourceUtil.createWaypointForInfo(info, file); if (wp == null) { s.add( new Status( IStatus.WARNING, JavaTagsPlugin.PLUGIN_ID, IStatus.WARNING, Messages.getString("FileWaypointRefreshJob.error.noWaypointCreate" + ": " + file.getName()), //$NON-NLS-1$ null ) ); } } return s; } } public FileWaypointRefreshJob(List<IFile> files) { super(Messages.getString("FileWaypointRefreshJob.jobName")); //$NON-NLS-1$ this.files = files; } @Override public ISchedulingRule getRule() { return ResourcesPlugin.getWorkspace().getRuleFactory().buildRule(); } /* (non-Javadoc) * @see net.sourceforge.tagsea.core.TagSEAOperation#run(org.eclipse.core.runtime.IProgressMonitor) */ @Override public IStatus run(IProgressMonitor monitor) throws InvocationTargetException { monitor.beginTask(Messages.getString("FileWaypointRefreshJob.refreshFiles"), 100*files.size()); //$NON-NLS-1$ MultiStatus status = new MultiStatus(JavaTagsPlugin.PLUGIN_ID, 0, "", null); //$NON-NLS-1$ for (IFile file : files) { if (file == null) continue; FileRefreshOperation operation = new FileRefreshOperation(file); status.merge(TagSEAPlugin.syncRun(operation, new SubProgressMonitor(monitor, 100))); } monitor.done(); return status; } }