blob: eb5cb7b299ee8a086444f89500223fc329891032 [file] [log] [blame]
/**********************************************************************
* Copyright (c) 2005, 2010 IBM Corporation.
* 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 API and implementation
*******************************************************************************/
package org.eclipse.ptp.pldt.common;
/**
* Artifact Visitor - Generic - for delta or full build
* @author Beth Tibbitts
*
*/
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.ui.texteditor.MarkerUtilities;
/**
* Processes an <code>IResource</code> or an <code>IResourceDelta</code> to set Artifact Markers on the files
* and populate the data model used for the Artifact view(s).
*/
public class ArtifactMarkingVisitor implements IResourceDeltaVisitor, IResourceVisitor
{
private static final boolean traceOn = false;
protected String markerID_;
protected ArtifactManager artifactManager_;
private boolean removeMarkers;
/**
* Construction that allows specification of whether or not to removed old
* markers on this resource before creating new ones
* @param markerId
* @param removeMarkers
*/
public ArtifactMarkingVisitor(String markerId, boolean removeMarkers)
{
this.markerID_ = markerId;
this.removeMarkers=removeMarkers;
this.artifactManager_=ArtifactManager.getManager(markerID_);
if(artifactManager_==null){
System.out.println("no manager yet!"); //$NON-NLS-1$
}
}
/**
* Constructor that uses the default behavior that WILL remove old markers
* on the resource before creating new ones. (This is the former behavior,
* now the default behavior)
* @param markerID
*/
public ArtifactMarkingVisitor(String markerID)
{
this(markerID, true);
}
/**
* Generic visiting of a file, to presumably add markers. This version is called from a build.
*
* @param resource
* @return
* @author Beth Tibbitts
*/
public boolean visitFile(IResource resource)
{
// System.out.println("filename="+resource.getLocation().toString());
Artifact[] artifacts = getPIs(resource);
return visitFile(resource, artifacts);
}
/**
* Generic version to put markers on a file, given the file(resource) and the list of artifacts
*
* @param resource
* @param artifacts list of artifact objects
* @return
*/
public boolean visitFile(IResource resource, Artifact[] artifacts)
{
try {
if (traceOn) System.out.println("ArtifactMarkingVisitor.visitFile: " + resource.getName()); //$NON-NLS-1$
// first clear existing markers (not: not doing anything ArtifactManager now.)
if(removeMarkers) {
removeMarkers(resource, this.markerID_);
}
int numArtifacts=artifactManager_.getArtifacts().length;
if(traceOn)System.out.println("numArtifacts: "+numArtifacts); //$NON-NLS-1$
String fn = resource.getProjectRelativePath().toString();
if (artifacts != null) {
createMarkers(resource, fn, artifacts);
}
} catch (CoreException e) {
e.printStackTrace();
}
return true;
}
public boolean visitFile(IResource resource, List<Artifact> artifacts)
{
Artifact[] artifactArray = new Artifact[artifacts.size()];
int i = 0;
for (Iterator<Artifact> iter = artifacts.iterator(); iter.hasNext();) {
Artifact element = (Artifact) iter.next();
artifactArray[i] = element;
i++;
}
return visitFile(resource, artifactArray);
}
/**
* Create markers for a file. This method creates a marker for each artifact. It also populates/refreshes the
* views.
*
* @param resource assumed to be a file, resource upon which to place the marker(s)
* @param fn - filename
* @param artifacts - array of Artifact objects for which to create markers.
* @throws CoreException
*/
protected void createMarkers(IResource resource, String fn, Artifact[] artifacts) throws CoreException
{
if (traceOn) System.out.println("ArtifactMarkingVisitor.createMarkers: " + resource.getName() + " #artifacts=" + artifacts.length); //$NON-NLS-1$ //$NON-NLS-2$
for (int i = 0; i < artifacts.length; i++) {
Artifact artifact = artifacts[i];
// artifactMarker 'inherits' from textMarker(see plugin.xml)
// If it also inherited from ProblemMarker, it would automagically show in more views (e.g. Problems view)
if (artifact != null) {
// 1. make marker for main Artifact
// Get correct filename for include files
// Actual file containing artifact may be an include file, so use it
// instead of the original file being analyzed
String filename = artifact.getFileName();
IResource f = resource;
// If artifact is not on same file being analyzed, correct it
// and get the actual file. E.G. an include file
// (don't create another resource object if we don't need to)
// System.out.println("resLocn="+resource.getRawLocation().toString());
// if (!resLocn.equals(filename))
// f = MpiPlugin.getWorkspace().getRoot().getFileForLocation(
// new Path(pifn));
//
int index=filename.lastIndexOf('/');
if(index==-1){
index=filename.lastIndexOf('\\');
}
if(index!=-1){
// BRT note: if contains both / and \ this won't work
// trucate to last portion of path
// this shd probably be a user preference, if this is truncated or not
String tmp2=filename.substring(index+1);
filename=tmp2;
}
createArtifactMarker(f, artifact, filename);
// If making other views, e.g. tree view, add to model tree for view here..
} else {
if (traceOn)
System.out.println("*** artifact for " + fn + "is null! ********"); //$NON-NLS-1$ //$NON-NLS-2$
else {
}
}
// now refresh the tree view!!
// MPITree.getTree().refresh();
}
}
/**
* create the marker for the artifact, and add it to
* the repository (ArtifactManager)
* @param resource
* @param artifact
* @param fn
* @throws CoreException
*/
protected void createArtifactMarker(IResource resource, Artifact artifact, String fn) throws CoreException
{
if (traceOn) System.out.println("Artifact desc=" + artifact.getShortName() + " fn=" + fn); //$NON-NLS-1$ //$NON-NLS-2$
Map<String, Object> attrs = createCommonMarkerAttrs(resource, artifact, fn);
// message attribute will be used for hover over editor location
attrs.put(IMarker.MESSAGE, artifact.getShortName());
// create the marker all at once, so get ONLY a single resourceChange event.
MarkerUtilities.createMarker(resource, attrs, this.markerID_); // 154
if (traceOn)
System.out.println("marker created: for " + fn + " - " + artifact.getShortName() + " line " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ artifact.getLine() + " start " + artifact.getSourceInfo().getStart() + " end " //$NON-NLS-1$ //$NON-NLS-2$
+ artifact.getSourceInfo().getEnd());
artifactManager_.addArtifactToHash(artifact);
}
/**
* Create marker attributes with common information shared by everyone
*
* @param resource File on which analysis was run
* @param artifact the artifact object
* @param fn project relative path of the resource
* @return
*
* Note we are not creating the marker here; we do it all at once after attributes are calculated, so that a single
* resourceChange event gets triggered
*/
protected Map<String, Object> createCommonMarkerAttrs(IResource resource, Artifact artifact, String fn)
{
Map<String, Object> attrs = new HashMap<String, Object>();
attrs.put(IMarker.PRIORITY, new Integer(IMarker.PRIORITY_NORMAL));
attrs.put(IMarker.LINE_NUMBER, new Integer(artifact.getLine()));
// use filename from the artifact, not the base file being analysed,
// because the artifact may be a result of reporting on e.g. an include file
attrs.put(IMarker.LOCATION, artifact.getFileName());
attrs.put(IDs.FILENAME, fn); // fn being processed
attrs.put(IDs.NAME, artifact.getShortName());
attrs.put(IDs.DESCRIPTION, artifact.getDescription());
// java5
// // trying setting the marker to more precise location
// attrs.put(IMarker.CHAR_START, artifact.getSourceInfo_().getStart());
// attrs.put(IMarker.CHAR_END, artifact.getSourceInfo_().getEnd());
//
// // adding construct type, i.e. func call, constants, ect.
// attrs.put(IDs.CONSTRUCT_TYPE, artifact.getSourceInfo_().getConstructType());
// trying setting the marker to more precise location
attrs.put(IMarker.CHAR_START, new Integer(artifact.getSourceInfo().getStart()));
attrs.put(IMarker.CHAR_END, new Integer(artifact.getSourceInfo().getEnd()));
// adding construct type, i.e. func call, constants, ect.
attrs.put(IDs.CONSTRUCT_TYPE, new Integer(artifact.getSourceInfo().getConstructType()));
String id = ((Artifact) artifact).getId();
attrs.put(IDs.ID, id); // used to look up to get artifact from marker later
attrs.put(IDs.LINE, Integer.toString(artifact.getLine()));
if (traceOn)
System.out.println("marker created: for " + fn + " - " + artifact.getDescription() + " line " + artifact.getLine()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
return attrs;
}
/**
* Get Artifacts for a given resource. e.g. could reads XML file that is presumed to be in same folder as
* resource file.
*
* @param r The resource (file assumed) for which to look for artifacts
* @return a list of artifacts
*/
public static Artifact[] getPIs(IResource r)
{
System.out.println("*UNIMPLEMENTED** ArtifactMarkingVisitor.getPIs: " + r.getName()); //$NON-NLS-1$
return null;
}
/**
* Remove the markers currently set on a resource.
*
* @param resource
*/
private void removeMarkers(IResource resource, String markerID)
{
if (traceOn) System.out.println("ArtifactMarkingVisitor.removeMarkers: " + resource.getName()); //$NON-NLS-1$
try {
resource.deleteMarkers(markerID, false, IResource.DEPTH_INFINITE);
// also sync up tree view
// MPITree.getTree().removeIssues(resource);
} catch (CoreException e) {
System.out.println(e);
System.out.println(e.toString());
System.out.println("Problem deleting markers on " + resource.getProjectRelativePath()); //$NON-NLS-1$
}
}
/**
* Implemented for IResourceDeltaVisitor Required implementation of the visit method. The
* <code>IResourceDelta</code> is processed by providing it a visitor using the <code>accept()</code> method and
* using this method in the visitor to process any events of interest.
*
* Processing continues as long as this method returns true or when the end of the <code>IResourceDelta</code> has
* been reached.
*/
public boolean visit(IResourceDelta delta) throws CoreException
{
// if (traceOn)System.out.println("ArtifactMarkingVisitor.visit(resourceDelta)...");
IResource resource = delta.getResource();
int type = resource.getType();
if ((delta.getKind() != IResourceDelta.REMOVED) && (type == IResource.FILE)) {
// System.out.println("delta visitor visits FILE: " +
// resource.getProjectRelativePath());
visitFile(resource);
}
return true; // carry on
}
/**
* Implemented for IResourceVisitor
*/
public boolean visit(IResource resource)
{
if (resource.getType() == IResource.FILE) {
// if (traceOn)System.out.println("FULL visitor visits FILE: " +
// resource.getProjectRelativePath());
visitFile(resource);
}
return true; // carry on
}
/**
* Show an artifact object - print for debugging/tracing purposes
*
* @param artifact the Artifact Object
*/
public static void showArtifact(Artifact artifact)
{
System.out.println("Artifact name: " + artifact.getShortName()); //$NON-NLS-1$
System.out.println(" Description: " + artifact.getDescription()); //$NON-NLS-1$
System.out.println(" Filename: " + artifact.getFileName()); //$NON-NLS-1$
}
}