blob: 10bef72e28b0120512f5120cd01cf6b210f8c467 [file] [log] [blame]
package org.eclipse.jdt.internal.core.builder.impl;
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.internal.core.builder.*;
import java.util.*;
public class ReportCardImpl implements IReportCard {
private StateImpl fState;
private ImageContextImpl fImageContext;
public ReportCardImpl(StateImpl state, IImageContext context) {
fState = state;
fImageContext = (ImageContextImpl)context;
}
public IPath[] changedPaths(IReportCard previous) {
Hashtable myProblemTable = problemTableFrom(getLeafProblemsFor(null));
Hashtable prevProblemTable = problemTableFrom(previous.getLeafProblemsFor(null));
Hashtable changed = new Hashtable();
/* do for all problems in the new table */
for (Enumeration e = myProblemTable.keys(); e.hasMoreElements();) {
IPath path = (IPath) e.nextElement();
Hashtable myProblems = (Hashtable) myProblemTable.get(path);
Hashtable prevProblems = (Hashtable) prevProblemTable.remove(path);
if (prevProblems == null || !setCompare(myProblems, prevProblems)) {
changed.put(path, path);
}
}
/* pick up all problems that are only in the old table */
for (Enumeration e = prevProblemTable.keys(); e.hasMoreElements();) {
IPath path = (IPath) e.nextElement();
changed.put(path, path);
}
/* convert results to array */
IPath[] results = new IPath[changed.size()];
int i = 0;
for (Enumeration e = changed.keys(); e.hasMoreElements();i++) {
results[i] = (IPath) e.nextElement();
}
return results;
}
/**
* Returns all the problems for this state
*/
private void getAllProblems(Vector results) {
/* iterate through problems in the problem table */
for (Enumeration e = fState.getProblemReporter().getAllProblems(); e.hasMoreElements();) {
results.addElement(e.nextElement());
}
/* go through all problems attached to the image itself */
for (Enumeration e = fState.getProblems(); e.hasMoreElements();) {
results.addElement(e.nextElement());
}
}
public IImageContext getImageContext() {
return fImageContext;
}
public IProblemDetail[] getLeafProblemsFor(IPath path) {
Vector vResults = new Vector();
/* if we want all problems */
if (path == null) {
getAllProblems(vResults);
}
else {
getProblemsForPath(path, vResults);
}
/* convert to array */
IProblemDetail[] results = new IProblemDetail[vResults.size()];
vResults.copyInto(results);
return results;
}
public IPath[] getProblemPaths(IPath path) {
Hashtable set = new Hashtable();
/* build set of all element IDs */
IProblemDetail[] problems = getLeafProblemsFor(path);
for (int i = 0; i < problems.length; i++) {
IPath problemPath = ((ProblemDetailImpl) problems[i]).getSourceEntry().getPath();
set.put(problemPath, problemPath);
}
/* convert set to array */
IPath[] results = new IPath[set.size()];
int i = 0;
for (Enumeration e = set.keys(); e.hasMoreElements();) {
results[i++] = (IPath) e.nextElement();
}
return results;
}
private void getProblemsForPath(IPath path, Vector vResults) {
for (Enumeration e = fState.getProblemReporter().getProblemKeys(); e.hasMoreElements();) {
SourceEntry sEntry = (SourceEntry)e.nextElement();
IPath sEntryPath = sEntry.getPath();
if (path.isPrefixOf(sEntryPath)) {
String extension = sEntryPath.getFileExtension();
// test most frequent cases first
if (extension != null && (extension.toLowerCase().equals("java"/*nonNLS*/) || extension.toLowerCase().equals("class"/*nonNLS*/))) {
getProblemsForSourceEntry(sEntry, vResults);
} else {
if (fState.isZipElement(sEntryPath)) {
getProblemsForZip(sEntryPath, vResults);
}
}
}
}
}
private void getProblemsForSourceEntry(SourceEntry sEntry, Vector results) {
IProblemReporter pbReporter = fState.getProblemReporter();
if (pbReporter.hasProblems(sEntry)) {
// Only check image context if there are really problems with this element
IPackage pkg = fState.getPathMap().packageHandleFromPath(sEntry.getPath().removeLastSegments(1));
if (fImageContext == null || fImageContext.containsPackage(pkg)) {
for (Enumeration e = pbReporter.getProblems(sEntry); e.hasMoreElements();) {
results.addElement(e.nextElement());
}
}
}
}
protected void getProblemsForZip(IPath zipPath, Vector results) {
// avoid iterating over all entries in the zip file
IProblemReporter pbReporter = fState.getProblemReporter();
for (Enumeration e = pbReporter.getAllProblems(); e.hasMoreElements();) {
ProblemDetailImpl problem = (ProblemDetailImpl) e.nextElement();
SourceEntry sEntry = problem.getSourceEntry();
if (sEntry.fZipEntryFileName != null && sEntry.getPath().equals(zipPath)) {
// Check image context.
if (fImageContext == null || fImageContext.containsPackage(fState.packageFromSourceEntry(sEntry))) {
results.addElement(problem);
}
}
}
}
public IState getState() {
return fState;
}
public boolean hasLeafProblems(IPath path) {
return getLeafProblemsFor(path).length > 0;
}
/**
* Returns a dictionary of problems keyed by their path.
* Each entry in the dictionary is a set of problems. The set is implemented as a
* hashtable with identical keys and values. Problems with no path are not
* included in the result.
*/
private Hashtable problemTableFrom(IProblemDetail[] problems) {
Hashtable table = new Hashtable(25);
for (int i = 0; i < problems.length; i++) {
IPath path = ((ProblemDetailImpl) problems[i]).getPath();
if (path != null) {
Hashtable entry = (Hashtable) table.get(path);
if (entry == null) {
entry = new Hashtable(10);
table.put(path,entry);
}
entry.put(problems[i], problems[i]);
}
}
return table;
}
/**
* Returns true if the two sets of problems are the same, false otherwise.
* Don't use ProblemDetail.equals() because it doesn't consider source
* positions or severity
*/
private boolean setCompare(Hashtable myProblems, Hashtable prevProblems) {
if (myProblems.size() != prevProblems.size()) {
return false;
}
/* iterate through both tables */
for (Enumeration e = myProblems.keys(); e.hasMoreElements();) {
ProblemDetailImpl a = (ProblemDetailImpl) myProblems.get(e.nextElement());
ProblemDetailImpl b = (ProblemDetailImpl) prevProblems.get(a);
if (b == null) {
/* problem is not in prevProblems */
return false;
}
}
for (Enumeration e = prevProblems.keys(); e.hasMoreElements();) {
ProblemDetailImpl a = (ProblemDetailImpl) prevProblems.get(e.nextElement());
ProblemDetailImpl b = (ProblemDetailImpl) myProblems.get(a);
if (b == null) {
/* problem is not in myProblems */
return false;
}
}
return true;
}
}