summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Rennie2012-12-20 17:45:09 (EST)
committer Curtis Windatt2012-12-20 17:45:09 (EST)
commit17e890b63cb6edbae2612ebbeefca79754f141fc (patch)
tree0fdc9b6c0456a497ece4688db7dbe14760de4d56
parent3f9ffa6aaa32747e6c38963ef089ae1d9fdc10f5 (diff)
downloadeclipse.pde.ui-17e890b63cb6edbae2612ebbeefca79754f141fc.zip
eclipse.pde.ui-17e890b63cb6edbae2612ebbeefca79754f141fc.tar.gz
eclipse.pde.ui-17e890b63cb6edbae2612ebbeefca79754f141fc.tar.bz2
Bug 332772 - Support problem filters for API Use Scan Task
-rw-r--r--apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/ApiFilterStore.java215
-rw-r--r--apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/CoreMessages.java1
-rw-r--r--apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/FilterStore.java420
-rw-r--r--apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/IApiXmlConstants.java2
-rw-r--r--apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/coremessages.properties1
-rw-r--r--apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/model/BundleComponent.java40
-rw-r--r--apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/search/UseSearchRequestor.java48
-rw-r--r--apitools/org.eclipse.pde.api.tools/src_ant/org/eclipse/pde/api/tools/internal/tasks/APIToolsAnalysisTask.java297
-rw-r--r--apitools/org.eclipse.pde.api.tools/src_ant/org/eclipse/pde/api/tools/internal/tasks/AntFilterStore.java104
-rw-r--r--apitools/org.eclipse.pde.api.tools/src_ant/org/eclipse/pde/api/tools/internal/tasks/ApiUseTask.java26
10 files changed, 643 insertions, 511 deletions
diff --git a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/ApiFilterStore.java b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/ApiFilterStore.java
index 0b6bafe..2c300a1 100644
--- a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/ApiFilterStore.java
+++ b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/ApiFilterStore.java
@@ -23,18 +23,17 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-
-import org.eclipse.pde.api.tools.internal.problems.ApiProblemFactory;
-import org.eclipse.pde.api.tools.internal.problems.ApiProblemFilter;
-import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
-import org.eclipse.pde.api.tools.internal.provisional.IApiFilterStore;
-import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblem;
-import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblemFilter;
-import org.eclipse.pde.api.tools.internal.util.Util;
-
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
+import org.eclipse.core.resources.ProjectScope;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
@@ -47,47 +46,21 @@ import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.core.runtime.preferences.InstanceScope;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceChangeEvent;
-import org.eclipse.core.resources.IResourceChangeListener;
-import org.eclipse.core.resources.IResourceDelta;
-import org.eclipse.core.resources.IncrementalProjectBuilder;
-import org.eclipse.core.resources.ProjectScope;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.resources.WorkspaceJob;
-
import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.pde.api.tools.internal.problems.ApiProblemFilter;
+import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
+import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblem;
+import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblemFilter;
+import org.eclipse.pde.api.tools.internal.util.Util;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
/**
* Base implementation of a filter store for API components
*
* @since 1.0.0
*/
-public class ApiFilterStore implements IApiFilterStore, IResourceChangeListener {
-
- /**
- * Constant representing the name of the .settings folder
- */
- private static final String SETTINGS_FOLDER = ".settings"; //$NON-NLS-1$
- public static final String GLOBAL = "!global!"; //$NON-NLS-1$
- public static final int CURRENT_STORE_VERSION = 2;
-
- /**
- * Represents no filters
- */
- private static IApiProblemFilter[] NO_FILTERS = new IApiProblemFilter[0];
-
- /**
- * The mapping of filters for this store.
- * <pre>
- * HashMap<IResource, HashSet<IApiProblemFilter>>
- * </pre>
- */
- private HashMap fFilterMap = null;
+public class ApiFilterStore extends FilterStore implements IResourceChangeListener {
/**
* Map used to collect unused {@link IApiProblemFilter}s
@@ -154,8 +127,9 @@ public class ApiFilterStore implements IApiFilterStore, IResourceChangeListener
}
String lineDelimiter= getLineDelimiterPreference(file);
String lineSeparator= System.getProperty("line.separator"); //$NON-NLS-1$
- if (lineDelimiter != null && !lineDelimiter.equals(lineSeparator))
+ if (lineDelimiter != null && !lineDelimiter.equals(lineSeparator)) {
xml= xml.replaceAll(lineSeparator, lineDelimiter);
+ }
InputStream xstream = Util.getInputStreamFromString(xml);
if(xstream == null) {
return Status.CANCEL_STATUS;
@@ -255,7 +229,8 @@ public class ApiFilterStore implements IApiFilterStore, IResourceChangeListener
return;
}
initializeApiFilters();
- internalAddFilters(problems, null, true);
+ internalAddFilters(problems, null);
+ persistApiFilters();
}
/* (non-Javadoc)
@@ -265,7 +240,7 @@ public class ApiFilterStore implements IApiFilterStore, IResourceChangeListener
initializeApiFilters();
Map pTypeNames = (Map) fFilterMap.get(resource);
if(pTypeNames == null) {
- return NO_FILTERS;
+ return FilterStore.NO_FILTERS;
}
List allFilters = new ArrayList();
for (Iterator iterator = pTypeNames.values().iterator(); iterator.hasNext(); ) {
@@ -525,11 +500,10 @@ public class ApiFilterStore implements IApiFilterStore, IResourceChangeListener
return Util.serializeDocument(document);
}
- /**
- * Initializes the backing filter map for this store from the .api_filters file. Does nothing if the filter store has already been
- * initialized.
+ /* (non-Javadoc)
+ * @see org.eclipse.pde.api.tools.internal.FilterStore#initializeApiFilters()
*/
- private synchronized void initializeApiFilters() {
+ protected synchronized void initializeApiFilters() {
if(fFilterMap != null) {
return;
}
@@ -545,13 +519,12 @@ public class ApiFilterStore implements IApiFilterStore, IResourceChangeListener
}
return;
}
- String xml = null;
InputStream contents = null;
try {
IFile filterFile = (IFile)file;
if (filterFile.exists()) {
contents = filterFile.getContents();
- xml = new String(Util.getInputStreamAsCharArray(contents, -1, IApiCoreConstants.UTF_8));
+ readFilterFile(contents);
}
}
catch(CoreException e) {
@@ -569,101 +542,15 @@ public class ApiFilterStore implements IApiFilterStore, IResourceChangeListener
}
}
}
- if(xml == null) {
- return;
- }
- Element root = null;
- try {
- root = Util.parseDocument(xml);
- }
- catch(CoreException ce) {
- ApiPlugin.log(ce);
- }
- if (root == null) {
- return;
- }
- if (!root.getNodeName().equals(IApiXmlConstants.ELEMENT_COMPONENT)) {
- return;
- }
- String component = root.getAttribute(IApiXmlConstants.ATTR_ID);
- if(component.length() == 0) {
- return;
- }
- String versionValue = root.getAttribute(IApiXmlConstants.ATTR_VERSION);
- int currentVersion = Integer.parseInt(IApiXmlConstants.API_FILTER_STORE_CURRENT_VERSION);
- int version = 0;
- if(versionValue.length() != 0) {
- try {
- version = Integer.parseInt(versionValue);
- } catch (NumberFormatException e) {
- // ignore
- }
- }
- if (version != currentVersion) {
- // we discard all filters since there is no way to retrieve the type name
- fNeedsSaving = true;
- persistApiFilters();
- return;
- }
- NodeList resources = root.getElementsByTagName(IApiXmlConstants.ELEMENT_RESOURCE);
- ArrayList newfilters = new ArrayList();
- ArrayList comments = new ArrayList();
- for(int i = 0; i < resources.getLength(); i++) {
- Element element = (Element) resources.item(i);
- String path = element.getAttribute(IApiXmlConstants.ATTR_PATH);
- if(path.length() == 0) {
- continue;
- }
- String typeName = element.getAttribute(IApiXmlConstants.ATTR_TYPE);
- if (typeName.length() == 0) {
- typeName = null;
- }
- IProject project = (IProject) ResourcesPlugin.getWorkspace().getRoot().findMember(component);
- if(project == null) {
- continue;
- }
- IResource resource = project.findMember(new Path(path));
- if(resource == null) {
- continue;
- }
- NodeList filters = element.getElementsByTagName(IApiXmlConstants.ELEMENT_FILTER);
- for(int j = 0; j < filters.getLength(); j++) {
- element = (Element) filters.item(j);
- int id = loadIntegerAttribute(element, IApiXmlConstants.ATTR_ID);
- if(id <= 0) {
- continue;
- }
- String[] messageargs = null;
- NodeList elements = element.getElementsByTagName(IApiXmlConstants.ELEMENT_PROBLEM_MESSAGE_ARGUMENTS);
- if (elements.getLength() != 1) continue;
- Element messageArguments = (Element) elements.item(0);
- NodeList arguments = messageArguments.getElementsByTagName(IApiXmlConstants.ELEMENT_PROBLEM_MESSAGE_ARGUMENT);
- int length = arguments.getLength();
- messageargs = new String[length];
- for (int k = 0; k < length; k++) {
- Element messageArgument = (Element) arguments.item(k);
- messageargs[k] = messageArgument.getAttribute(IApiXmlConstants.ATTR_VALUE);
- }
- String comment = element.getAttribute(IApiXmlConstants.ATTR_COMMENT);
- comments.add((comment.length() < 1 ? null : comment));
- newfilters.add(ApiProblemFactory.newApiProblem(resource.getProjectRelativePath().toPortableString(),
- typeName,
- messageargs, null, null, -1, -1, -1, id));
- }
- }
- internalAddFilters((IApiProblem[]) newfilters.toArray(new IApiProblem[newfilters.size()]),
- (String[]) comments.toArray(new String[comments.size()]),
- false);
- newfilters.clear();
+ //need to reset the flag during initialization if we are not going to persist
+ //the filters, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=309635
+ fNeedsSaving = false;
}
- /**
- * Internal use method that allows auto-persisting of the filter file to be turned on or off
- * @param problems the problems to add the the store
- * @param comments the comments associated with each problem
- * @param persist if the filters should be auto-persisted after they are added
+ /* (non-Javadoc)
+ * @see org.eclipse.pde.api.tools.internal.FilterStore#internalAddFilters(org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblem[], java.lang.String[])
*/
- private synchronized void internalAddFilters(IApiProblem[] problems, String[] comments, boolean persist) {
+ protected synchronized void internalAddFilters(IApiProblem[] problems, String[] comments) {
Set filters = null;
for(int i = 0; i < problems.length; i++) {
IApiProblem problem = problems[i];
@@ -695,14 +582,6 @@ public class ApiFilterStore implements IApiFilterStore, IResourceChangeListener
}
fNeedsSaving |= filters.add(filter);
}
- if(persist) {
- persistApiFilters();
- }
- else {
- //need to reset the flag during initialization if we are not going to persist
- //the filters, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=309635
- fNeedsSaving = false;
- }
}
/**
@@ -715,32 +594,14 @@ public class ApiFilterStore implements IApiFilterStore, IResourceChangeListener
}
/**
- * Loads the specified integer attribute from the given xml element
- * @param element
- * @param name
- * @return
- */
- private static int loadIntegerAttribute(Element element, String name) {
- String value = element.getAttribute(name);
- if(value.length() == 0) {
- return -1;
- }
- try {
- int number = Integer.parseInt(value);
- return number;
- }
- catch(NumberFormatException nfe) {}
- return -1;
- }
- /**
* @return the {@link IPath} to the filters file
*/
IPath getFilterFilePath(boolean includeproject) {
if(includeproject) {
IPath path = fProject.getPath();
- return path.append(SETTINGS_FOLDER).append(IApiCoreConstants.API_FILTERS_XML_NAME);
+ return path.append(FilterStore.SETTINGS_FOLDER).append(IApiCoreConstants.API_FILTERS_XML_NAME);
}
- return new Path(SETTINGS_FOLDER).append(IApiCoreConstants.API_FILTERS_XML_NAME);
+ return new Path(FilterStore.SETTINGS_FOLDER).append(IApiCoreConstants.API_FILTERS_XML_NAME);
}
static String getLineDelimiterPreference(IFile file) {
@@ -841,11 +702,11 @@ public class ApiFilterStore implements IApiFilterStore, IResourceChangeListener
}
int size = unused.size();
if (size == 0) {
- return NO_FILTERS;
+ return FilterStore.NO_FILTERS;
}
return (IApiProblemFilter[]) unused.toArray(new IApiProblemFilter[size]);
}
- return NO_FILTERS;
+ return FilterStore.NO_FILTERS;
}
/**
diff --git a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/CoreMessages.java b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/CoreMessages.java
index d6ce2b6..176aafd 100644
--- a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/CoreMessages.java
+++ b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/CoreMessages.java
@@ -23,6 +23,7 @@ public class CoreMessages extends NLS {
public static String ApiBaseline_4;
public static String ApiBaseline_5;
public static String ApiBaseline_6;
+ public static String FilterStore_0;
public static String ProjectComponent_could_not_locate_model;
static {
// initialize resource bundle
diff --git a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/FilterStore.java b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/FilterStore.java
new file mode 100644
index 0000000..20d65e9
--- /dev/null
+++ b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/FilterStore.java
@@ -0,0 +1,420 @@
+/*******************************************************************************
+ * Copyright (c) 2012 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 API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.api.tools.internal;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.pde.api.tools.internal.model.BundleComponent;
+import org.eclipse.pde.api.tools.internal.problems.ApiProblemFactory;
+import org.eclipse.pde.api.tools.internal.problems.ApiProblemFilter;
+import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
+import org.eclipse.pde.api.tools.internal.provisional.IApiFilterStore;
+import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblem;
+import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblemFilter;
+import org.eclipse.pde.api.tools.internal.util.Util;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+/**
+ * A generic {@link IApiFilterStore} that does not depend on workspace resources
+ * to filter {@link IApiProblem}s.
+ * <br>
+ * This filter store can have filters added and removed from it, but those changes
+ * are not saved.
+ */
+public class FilterStore implements IApiFilterStore {
+
+ public static final String GLOBAL = "!global!"; //$NON-NLS-1$
+ /**
+ * Represents no filters
+ */
+ public static IApiProblemFilter[] NO_FILTERS = new IApiProblemFilter[0];
+ /**
+ * The current version of this filter store file format
+ */
+ public static final int CURRENT_STORE_VERSION = 2;
+ /**
+ * Constant representing the name of the .settings folder
+ */
+ static final String SETTINGS_FOLDER = ".settings"; //$NON-NLS-1$
+ /**
+ * The mapping of filters for this store.
+ */
+ protected HashMap fFilterMap = null;
+ /**
+ * The bundle component backing this store
+ */
+ private BundleComponent fComponent = null;
+
+ /**
+ * Constructor
+ */
+ public FilterStore() {}
+
+ /**
+ * Constructor
+ * @param component
+ */
+ public FilterStore(BundleComponent component) {
+ fComponent = component;
+ initializeApiFilters();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.pde.api.tools.internal.provisional.IApiFilterStore#addFilters(org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblemFilter[])
+ */
+ public void addFilters(IApiProblemFilter[] filters) {
+ if(filters != null && filters.length > 0) {
+ initializeApiFilters();
+ for (int i = 0; i < filters.length; i++) {
+ fFilterMap.put(filters[i].getComponentId(), filters[i]);
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.pde.api.tools.internal.provisional.IApiFilterStore#addFiltersFor(org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblem[])
+ */
+ public void addFiltersFor(IApiProblem[] problems) {
+ if(problems != null && problems.length > 0) {
+ initializeApiFilters();
+ internalAddFilters(problems, null);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.pde.api.tools.internal.provisional.IApiFilterStore#getFilters(org.eclipse.core.resources.IResource)
+ */
+ public IApiProblemFilter[] getFilters(IResource resource) {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.pde.api.tools.internal.provisional.IApiFilterStore#getResources()
+ */
+ public IResource[] getResources() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.pde.api.tools.internal.provisional.IApiFilterStore#removeFilters(org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblemFilter[])
+ */
+ public boolean removeFilters(IApiProblemFilter[] filters) {
+ if(filters != null && filters.length > 0) {
+ initializeApiFilters();
+ boolean removed = true;
+ for(int i = 0; i < filters.length; i++) {
+ removed &= (fFilterMap.remove(filters[i].getComponentId()) != null);
+ }
+ return removed;
+ }
+ return false;
+ }
+
+ /**
+ * Loads the filters from the .api_filters file
+ */
+ protected synchronized void initializeApiFilters() {
+ if(fFilterMap == null) {
+ fFilterMap = new HashMap(5);
+ ZipFile jarFile = null;
+ InputStream filterstream = null;
+ File loc = new File(fComponent.getLocation());
+ String extension = new Path(loc.getName()).getFileExtension();
+ try {
+ if (extension != null && extension.equals("jar") && loc.isFile()) { //$NON-NLS-1$
+ jarFile = new ZipFile(loc, ZipFile.OPEN_READ);
+ ZipEntry filterfile = jarFile.getEntry(IApiCoreConstants.API_FILTERS_XML_NAME);
+ if (filterfile != null) {
+ filterstream = jarFile.getInputStream(filterfile);
+ }
+ } else {
+ File file = new File(loc, SETTINGS_FOLDER+File.separator+IApiCoreConstants.API_FILTERS_XML_NAME);
+ if (file.exists()) {
+ filterstream = new FileInputStream(file);
+ }
+ }
+ if (filterstream == null) {
+ return;
+ }
+ readFilterFile(filterstream);
+
+ } catch (IOException e) {
+ ApiPlugin.log(e);
+ } finally {
+ fComponent.closingZipFileAndStream(filterstream, jarFile);
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.pde.api.tools.internal.provisional.IApiFilterStore#isFiltered(org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblem)
+ */
+ public boolean isFiltered(IApiProblem problem) {
+ if (fFilterMap == null || fFilterMap.isEmpty()) {
+ return false;
+ }
+ String typeName = problem.getTypeName();
+ if (typeName == null || typeName.length() == 0) {
+ typeName = GLOBAL;
+ }
+ Set filters = (Set) fFilterMap.get(typeName);
+ if (filters == null) {
+ return false;
+ }
+ for (Iterator iterator = filters.iterator(); iterator.hasNext();) {
+ IApiProblemFilter filter = (IApiProblemFilter) iterator.next();
+ if (problemsMatch(filter.getUnderlyingProblem(), problem)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns <code>true</code> if the attributes of the problems match, <code>false</code> otherwise
+ *
+ * @param filterProblem the problem from the filter store
+ * @param problem the problem from the builder
+ * @return <code>true</code> if the problems match, <code>false</code> otherwise
+ */
+ protected boolean problemsMatch(IApiProblem filterProblem, IApiProblem problem) {
+ if (problem.getId() == filterProblem.getId()) {
+ // check arguments
+// String problemPath = problem.getResourcePath();
+// String filterProblemPath = filterProblem.getResourcePath();
+// if (problemPath == null) {
+// if (filterProblemPath != null) {
+// return false;
+// }
+// } else if (filterProblemPath == null) {
+// return false;
+// } else if (!new Path(problemPath).equals(new Path(filterProblemPath))) {
+// return false;
+// }
+ String problemTypeName = problem.getTypeName();
+ String filterProblemTypeName = filterProblem.getTypeName();
+ if (problemTypeName == null) {
+ if (filterProblemTypeName != null) {
+ return false;
+ }
+ } else if (filterProblemTypeName == null) {
+ return false;
+ } else if (!problemTypeName.equals(filterProblemTypeName)) {
+ return false;
+ }
+ return argumentsEquals(problem.getMessageArguments(), filterProblem.getMessageArguments());
+ }
+ return false;
+ }
+
+ /**
+ * Returns if the arrays of message arguments are equal.
+ * <br>
+ * The arrays are considered equal iff:
+ * <ul>
+ * <li>both are <code>null</code></li>
+ * <li>both are the same length</li>
+ * <li>both have equal elements at equal positions in the array</li>
+ * </ul>
+ * @param problemMessageArguments
+ * @param filterProblemMessageArguments
+ * @return <code>true</code> if the arrays are equal, <code>false</code> otherwise
+ */
+ private boolean argumentsEquals(String[] problemMessageArguments, String[] filterProblemMessageArguments) {
+ // filter problems message arguments are always simple name
+ // problem message arguments are fully qualified name outside the IDE
+ int length = problemMessageArguments.length;
+ if (length == filterProblemMessageArguments.length) {
+ for (int i = 0; i < length; i++) {
+ String problemMessageArgument = problemMessageArguments[i];
+ String filterProblemMessageArgument = filterProblemMessageArguments[i];
+ if (problemMessageArgument.equals(filterProblemMessageArgument)) {
+ continue;
+ }
+ int index = problemMessageArgument.lastIndexOf('.');
+ int filterProblemIndex = filterProblemMessageArgument.lastIndexOf('.');
+ if (index == -1) {
+ if (filterProblemIndex == -1) {
+ return false; // simple names should match
+ }
+ if (filterProblemMessageArgument.substring(filterProblemIndex + 1).equals(problemMessageArgument)) {
+ continue;
+ } else {
+ return false;
+ }
+ } else if (filterProblemIndex != -1) {
+ return false; // fully qualified name should match
+ } else {
+ if (problemMessageArgument.substring(index + 1).equals(filterProblemMessageArgument)) {
+ continue;
+ } else {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.pde.api.tools.internal.provisional.IApiFilterStore#dispose()
+ */
+ public void dispose() {
+ if(fFilterMap != null) {
+ fFilterMap.clear();
+ fFilterMap = null;
+ }
+ }
+
+ /**
+ * Reads the API problem filter file and calls back to {@link #addFilters(IApiProblemFilter[])}
+ * to store the filters.
+ * <br>
+ * This method will not close the given input stream when done reading it.
+ *
+ * @param contents the {@link InputStream} for the contents of the filter file, <code>null</code> is not allowed.
+ * @throws IOException if the stream cannot be read or fails
+ */
+ protected void readFilterFile(InputStream contents) throws IOException {
+ if(contents == null) {
+ throw new IOException(CoreMessages.FilterStore_0);
+ }
+ String xml = new String(Util.getInputStreamAsCharArray(contents, -1, IApiCoreConstants.UTF_8));
+ Element root = null;
+ try {
+ root = Util.parseDocument(xml);
+ }
+ catch(CoreException ce) {
+ ApiPlugin.log(ce);
+ }
+ if (root == null) {
+ return;
+ }
+ if (!root.getNodeName().equals(IApiXmlConstants.ELEMENT_COMPONENT)) {
+ return;
+ }
+ String component = root.getAttribute(IApiXmlConstants.ATTR_ID);
+ if(component.length() == 0) {
+ return;
+ }
+ String versionValue = root.getAttribute(IApiXmlConstants.ATTR_VERSION);
+ int currentVersion = Integer.parseInt(IApiXmlConstants.API_FILTER_STORE_CURRENT_VERSION);
+ int version = 0;
+ if(versionValue.length() != 0) {
+ try {
+ version = Integer.parseInt(versionValue);
+ } catch (NumberFormatException e) {
+ // ignore
+ }
+ }
+ if (version != currentVersion) {
+ return;
+ }
+ NodeList resources = root.getElementsByTagName(IApiXmlConstants.ELEMENT_RESOURCE);
+ ArrayList newfilters = new ArrayList();
+ ArrayList comments = new ArrayList();
+ for(int i = 0; i < resources.getLength(); i++) {
+ Element element = (Element) resources.item(i);
+ String typeName = element.getAttribute(IApiXmlConstants.ATTR_TYPE);
+ if (typeName.length() == 0) {
+ // if there is no type attribute, an empty string is returned
+ typeName = null;
+ }
+ String path = element.getAttribute(IApiXmlConstants.ATTR_PATH);
+ NodeList filters = element.getElementsByTagName(IApiXmlConstants.ELEMENT_FILTER);
+ for(int j = 0; j < filters.getLength(); j++) {
+ element = (Element) filters.item(j);
+ int id = loadIntegerAttribute(element, IApiXmlConstants.ATTR_ID);
+ if(id <= 0) {
+ continue;
+ }
+ String[] messageargs = null;
+ NodeList elements = element.getElementsByTagName(IApiXmlConstants.ELEMENT_PROBLEM_MESSAGE_ARGUMENTS);
+ if (elements.getLength() != 1) continue;
+ Element messageArguments = (Element) elements.item(0);
+ NodeList arguments = messageArguments.getElementsByTagName(IApiXmlConstants.ELEMENT_PROBLEM_MESSAGE_ARGUMENT);
+ int length = arguments.getLength();
+ messageargs = new String[length];
+ String comment = element.getAttribute(IApiXmlConstants.ATTR_COMMENT);
+ comments.add((comment.length() < 1 ? null : comment));
+ for (int k = 0; k < length; k++) {
+ Element messageArgument = (Element) arguments.item(k);
+ messageargs[k] = messageArgument.getAttribute(IApiXmlConstants.ATTR_VALUE);
+ }
+ newfilters.add(ApiProblemFactory.newApiProblem(path, typeName, messageargs, null, null, -1, -1, -1, id));
+ }
+ }
+ internalAddFilters(
+ (IApiProblem[]) newfilters.toArray(new IApiProblem[newfilters.size()]),
+ (String[]) comments.toArray(new String[comments.size()]));
+ newfilters.clear();
+ }
+
+ /**
+ * Internal use method that allows auto-persisting of the filter file to be turned on or off
+ * @param problems the problems to add the the store
+ * @param persist if the filters should be auto-persisted after they are added
+ */
+ protected void internalAddFilters(IApiProblem[] problems, String[] comments) {
+ if(problems == null) {
+ return;
+ }
+ for(int i = 0; i < problems.length; i++) {
+ IApiProblem problem = problems[i];
+ IApiProblemFilter filter = new ApiProblemFilter(fComponent.getSymbolicName(), problem, comments[i]);
+ String typeName = problem.getTypeName();
+ if (typeName == null) {
+ typeName = GLOBAL;
+ }
+ Set filters = (Set) fFilterMap.get(typeName);
+ if(filters == null) {
+ filters = new HashSet();
+ fFilterMap.put(typeName, filters);
+ }
+ filters.add(filter);
+ }
+ }
+
+ /**
+ * Loads the specified integer attribute from the given XML element
+ * @param element the XML element
+ * @param name the name of the attribute
+ * @return the specified value in XML or -1
+ */
+ protected int loadIntegerAttribute(Element element, String name) {
+ String value = element.getAttribute(name);
+ if(value.length() == 0) {
+ return -1;
+ }
+ try {
+ int number = Integer.parseInt(value);
+ return number;
+ }
+ catch(NumberFormatException nfe) {}
+ return -1;
+ }
+
+}
diff --git a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/IApiXmlConstants.java b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/IApiXmlConstants.java
index 0e7b931..bc8bb9a 100644
--- a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/IApiXmlConstants.java
+++ b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/IApiXmlConstants.java
@@ -25,7 +25,7 @@ public interface IApiXmlConstants {
/**
* Constant representing the current version for API filter store files
*/
- public static final String API_FILTER_STORE_CURRENT_VERSION = Integer.toString(ApiFilterStore.CURRENT_STORE_VERSION);
+ public static final String API_FILTER_STORE_CURRENT_VERSION = Integer.toString(FilterStore.CURRENT_STORE_VERSION);
/**
* Constant representing the current version for API profile files
*/
diff --git a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/coremessages.properties b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/coremessages.properties
index 8053c0e..8cd2a78 100644
--- a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/coremessages.properties
+++ b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/coremessages.properties
@@ -15,4 +15,5 @@ ApiBaseline_2=Error occurred while binding execution environment
ApiBaseline_4=Baseline has bundles requiring unavailable execution environments
ApiBaseline_5={0} is unavailable
ApiBaseline_6=Baseline not bound - there are no installed VMs compatible with the required execution environments
+FilterStore_0=Cannot read API problem filters from a null stream
ProjectComponent_could_not_locate_model=Could not locate the plugin model base for project: {0}
diff --git a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/model/BundleComponent.java b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/model/BundleComponent.java
index a1525a3..c47ceac 100644
--- a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/model/BundleComponent.java
+++ b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/model/BundleComponent.java
@@ -28,7 +28,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.jar.JarFile;
-import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@@ -55,6 +54,7 @@ import org.eclipse.pde.api.tools.internal.ApiDescription;
import org.eclipse.pde.api.tools.internal.ApiDescriptionProcessor;
import org.eclipse.pde.api.tools.internal.BundleVersionRange;
import org.eclipse.pde.api.tools.internal.CompositeApiDescription;
+import org.eclipse.pde.api.tools.internal.FilterStore;
import org.eclipse.pde.api.tools.internal.IApiCoreConstants;
import org.eclipse.pde.api.tools.internal.RequiredComponentDescription;
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
@@ -529,8 +529,7 @@ public class BundleComponent extends Component {
* @see org.eclipse.pde.api.tools.internal.AbstractApiComponent#createApiFilterStore()
*/
protected IApiFilterStore createApiFilterStore() throws CoreException {
- //always return a new empty store since we do not support filtering from bundles
- return null;
+ return new FilterStore(this);
}
/**
@@ -814,41 +813,8 @@ public class BundleComponent extends Component {
}
return null;
}
-
- /**
- * Reads and returns this bunlde's manifest in a Manifest object.
- * The bundle may be in a jar or in a directory at the specified location.
- *
- * @param bundleLocation root location of the bundle
- * @return manifest or <code>null</code> if not present
- * @throws IOException if unable to parse
- */
- protected Manifest readManifest(File bundleLocation) throws IOException {
- ZipFile jarFile = null;
- InputStream manifestStream = null;
- try {
- String extension = new Path(bundleLocation.getName()).getFileExtension();
- if (extension != null && extension.equals("jar") && bundleLocation.isFile()) { //$NON-NLS-1$
- jarFile = new ZipFile(bundleLocation, ZipFile.OPEN_READ);
- ZipEntry manifestEntry = jarFile.getEntry(JarFile.MANIFEST_NAME);
- if (manifestEntry != null) {
- manifestStream = jarFile.getInputStream(manifestEntry);
- }
- } else {
- File file = new File(bundleLocation, JarFile.MANIFEST_NAME);
- if (file.exists())
- manifestStream = new FileInputStream(file);
- }
- if (manifestStream == null) {
- return null;
- }
- return new Manifest(manifestStream);
- } finally {
- closingZipFileAndStream(manifestStream, jarFile);
- }
- }
- void closingZipFileAndStream(InputStream stream, ZipFile jarFile) {
+ public void closingZipFileAndStream(InputStream stream, ZipFile jarFile) {
try {
if (stream != null) {
stream.close();
diff --git a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/search/UseSearchRequestor.java b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/search/UseSearchRequestor.java
index 967c17a..68de9d0 100644
--- a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/search/UseSearchRequestor.java
+++ b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/search/UseSearchRequestor.java
@@ -19,6 +19,7 @@ import org.eclipse.pde.api.tools.internal.builder.Reference;
import org.eclipse.pde.api.tools.internal.builder.ReferenceAnalyzer;
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
import org.eclipse.pde.api.tools.internal.provisional.IApiAnnotations;
+import org.eclipse.pde.api.tools.internal.provisional.IApiFilterStore;
import org.eclipse.pde.api.tools.internal.provisional.VisibilityModifiers;
import org.eclipse.pde.api.tools.internal.provisional.builder.IApiProblemDetector;
import org.eclipse.pde.api.tools.internal.provisional.builder.IReference;
@@ -29,6 +30,7 @@ import org.eclipse.pde.api.tools.internal.provisional.model.IApiMember;
import org.eclipse.pde.api.tools.internal.provisional.model.IApiScope;
import org.eclipse.pde.api.tools.internal.provisional.model.IApiType;
import org.eclipse.pde.api.tools.internal.provisional.model.IApiTypeContainer;
+import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblem;
import org.eclipse.pde.api.tools.internal.provisional.search.IApiSearchRequestor;
/**
@@ -47,6 +49,18 @@ public class UseSearchRequestor implements IApiSearchRequestor {
private Set fComponentIds = null;
/**
+ * The current {@link IApiFilterStore} from the current {@link IApiComponent} context we are visiting
+ */
+ private IApiFilterStore currentStore = null;
+
+ /**
+ * An {@link IApiFilterStore} that was set from an external source
+ *
+ * @see #setGlobalFilterStore
+ */
+ private IApiFilterStore globalStore = null;
+
+ /**
* The mask to use while searching
*/
private int fSearchMask = 0;
@@ -94,12 +108,14 @@ public class UseSearchRequestor implements IApiSearchRequestor {
if(includesIllegalUse()) {
fAnalyzer.buildProblemDetectors(component, ProblemDetectorBuilder.K_USE, null);
}
+ currentStore = component.getFilterStore();
return true;
}
}
catch(CoreException ce) {
//do nothing, return false
}
+ currentStore = null;
return false;
}
@@ -195,7 +211,19 @@ public class UseSearchRequestor implements IApiSearchRequestor {
Reference ref = (Reference) reference;
ref.setFlags(IReference.F_ILLEGAL);
try {
- ref.addProblems(((AbstractProblemDetector)detectors[i]).createProblem(reference));
+ IApiProblem pb = ((AbstractProblemDetector)detectors[i]).createProblem(reference);
+ if(!isFiltered(pb)) {
+ ref.addProblems(pb);
+ } else {
+
+
+ // TODO CWindatt - Remove tracing
+ System.out.println("332772 - Problem filtered");
+
+
+
+
+ }
} catch (CoreException e) {
ApiPlugin.log(e);
}
@@ -205,6 +233,16 @@ public class UseSearchRequestor implements IApiSearchRequestor {
return false;
}
+ /**
+ * Returns if the given problem is filtered
+ * @param problem
+ * @return <code>true</code> is filtered, false otherwise
+ */
+ boolean isFiltered(IApiProblem problem) throws CoreException {
+ return (currentStore != null && currentStore.isFiltered(problem)) ||
+ (globalStore != null && globalStore.isFiltered(problem));
+ }
+
/* (non-Javadoc)
* @see org.eclipse.pde.api.tools.internal.provisional.search.IApiSearchRequestor#getReferenceKinds()
*/
@@ -260,4 +298,12 @@ public class UseSearchRequestor implements IApiSearchRequestor {
public void setJarPatterns(String[] patterns) {
jarPatterns = patterns;
}
+
+ /**
+ * Allows a global {@link IApiFilterStore} to be used to filter all references found during the scan
+ * @param store the store to set or <code>null</code> to remove the store
+ */
+ public void setGlobalFilterStore(IApiFilterStore store) {
+ globalStore = store;
+ }
}
diff --git a/apitools/org.eclipse.pde.api.tools/src_ant/org/eclipse/pde/api/tools/internal/tasks/APIToolsAnalysisTask.java b/apitools/org.eclipse.pde.api.tools/src_ant/org/eclipse/pde/api/tools/internal/tasks/APIToolsAnalysisTask.java
index ef4a5ab..7b3e81e 100644
--- a/apitools/org.eclipse.pde.api.tools/src_ant/org/eclipse/pde/api/tools/internal/tasks/APIToolsAnalysisTask.java
+++ b/apitools/org.eclipse.pde.api.tools/src_ant/org/eclipse/pde/api/tools/internal/tasks/APIToolsAnalysisTask.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2011 IBM Corporation and others.
+ * Copyright (c) 2008, 2012 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
@@ -14,7 +14,6 @@ import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
@@ -29,18 +28,14 @@ import java.util.Properties;
import java.util.Set;
import org.apache.tools.ant.BuildException;
-import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.Path;
import org.eclipse.osgi.util.NLS;
-import org.eclipse.pde.api.tools.internal.IApiCoreConstants;
import org.eclipse.pde.api.tools.internal.IApiXmlConstants;
import org.eclipse.pde.api.tools.internal.builder.BaseApiAnalyzer;
import org.eclipse.pde.api.tools.internal.builder.BuildContext;
import org.eclipse.pde.api.tools.internal.model.StubApiComponent;
import org.eclipse.pde.api.tools.internal.problems.ApiProblemFactory;
-import org.eclipse.pde.api.tools.internal.problems.ApiProblemFilter;
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
import org.eclipse.pde.api.tools.internal.provisional.IApiFilterStore;
import org.eclipse.pde.api.tools.internal.provisional.IApiMarkerConstants;
@@ -48,305 +43,17 @@ import org.eclipse.pde.api.tools.internal.provisional.comparator.IDelta;
import org.eclipse.pde.api.tools.internal.provisional.model.IApiBaseline;
import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent;
import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblem;
-import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblemFilter;
import org.eclipse.pde.api.tools.internal.util.FilteredElements;
import org.eclipse.pde.api.tools.internal.util.Util;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
/**
* Ant task to run the API tool verification during Eclipse build.
*/
public class APIToolsAnalysisTask extends CommonUtilsTask {
- /**
- * This filter store is only used to filter problem using existing filters.
- * It doesn't add or remove any filters.
- */
- private static class AntFilterStore implements IApiFilterStore {
- private static final String GLOBAL = "!global!"; //$NON-NLS-1$
- private static int loadIntegerAttribute(Element element, String name) {
- String value = element.getAttribute(name);
- if(value.length() == 0) {
- return -1;
- }
- try {
- int number = Integer.parseInt(value);
- return number;
- }
- catch(NumberFormatException nfe) {}
- return -1;
- }
- private boolean debug;
-
- private Map fFilterMap;
-
- public AntFilterStore(boolean debug, String filtersRoot, String componentID) {
- this.initialize(filtersRoot, componentID);
- }
-
- public void addFiltersFor(IApiProblem[] problems) {
- // do nothing
- }
-
- public void addFilters(IApiProblemFilter[] filters) {
- // do nothing
- }
-
- private boolean argumentsEquals(String[] problemMessageArguments,
- String[] filterProblemMessageArguments) {
- // filter problems message arguments are always simple name
- // problem message arguments are fully qualified name outside the IDE
- int length = problemMessageArguments.length;
- if (length == filterProblemMessageArguments.length) {
- for (int i = 0; i < length; i++) {
- String problemMessageArgument = problemMessageArguments[i];
- String filterProblemMessageArgument = filterProblemMessageArguments[i];
- if (problemMessageArgument.equals(filterProblemMessageArgument)) {
- continue;
- }
- int index = problemMessageArgument.lastIndexOf('.');
- int filterProblemIndex = filterProblemMessageArgument.lastIndexOf('.');
- if (index == -1) {
- if (filterProblemIndex == -1) {
- return false; // simple names should match
- }
- if (filterProblemMessageArgument.substring(filterProblemIndex + 1).equals(problemMessageArgument)) {
- continue;
- } else {
- return false;
- }
- } else if (filterProblemIndex != -1) {
- return false; // fully qualified name should match
- } else {
- if (problemMessageArgument.substring(index + 1).equals(filterProblemMessageArgument)) {
- continue;
- } else {
- return false;
- }
- }
- }
- return true;
- }
- return false;
- }
-
- public void dispose() {
- // do nothing
- }
-
- public IApiProblemFilter[] getFilters(IResource resource) {
- return null;
- }
-
- public IResource[] getResources() {
- return null;
- }
-
- /**
- * Initialize the filter store using the given component id
- */
- private void initialize(String filtersRoot, String componentID) {
- if(fFilterMap != null) {
- return;
- }
- if(this.debug) {
- System.out.println("null filter map, creating a new one"); //$NON-NLS-1$
- }
- fFilterMap = new HashMap(5);
- String xml = null;
- InputStream contents = null;
- try {
- File filterFileParent = new File(filtersRoot, componentID);
- if (!filterFileParent.exists()) {
- return;
- }
- contents = new BufferedInputStream(new FileInputStream(new File(filterFileParent, IApiCoreConstants.API_FILTERS_XML_NAME)));
- xml = new String(Util.getInputStreamAsCharArray(contents, -1, IApiCoreConstants.UTF_8));
- }
- catch(IOException ioe) {}
- finally {
- if (contents != null) {
- try {
- contents.close();
- } catch(IOException e) {
- // ignore
- }
- }
- }
- if(xml == null) {
- return;
- }
- Element root = null;
- try {
- root = Util.parseDocument(xml);
- }
- catch(CoreException ce) {
- ApiPlugin.log(ce);
- }
- if (root == null) {
- return;
- }
- if (!root.getNodeName().equals(IApiXmlConstants.ELEMENT_COMPONENT)) {
- return;
- }
- String component = root.getAttribute(IApiXmlConstants.ATTR_ID);
- if(component.length() == 0) {
- return;
- }
- String versionValue = root.getAttribute(IApiXmlConstants.ATTR_VERSION);
- int version = 0;
- if(versionValue.length() != 0) {
- try {
- version = Integer.parseInt(versionValue);
- } catch (NumberFormatException e) {
- // ignore
- }
- }
- if (version < 2) {
- // we discard all filters since there is no way to retrieve the type name
- return;
- }
- NodeList resources = root.getElementsByTagName(IApiXmlConstants.ELEMENT_RESOURCE);
- ArrayList newfilters = new ArrayList();
- ArrayList comments = new ArrayList();
- for(int i = 0; i < resources.getLength(); i++) {
- Element element = (Element) resources.item(i);
- String typeName = element.getAttribute(IApiXmlConstants.ATTR_TYPE);
- if (typeName.length() == 0) {
- // if there is no type attribute, an empty string is returned
- typeName = null;
- }
- String path = element.getAttribute(IApiXmlConstants.ATTR_PATH);
- NodeList filters = element.getElementsByTagName(IApiXmlConstants.ELEMENT_FILTER);
- for(int j = 0; j < filters.getLength(); j++) {
- element = (Element) filters.item(j);
- int id = loadIntegerAttribute(element, IApiXmlConstants.ATTR_ID);
- if(id <= 0) {
- continue;
- }
- String[] messageargs = null;
- NodeList elements = element.getElementsByTagName(IApiXmlConstants.ELEMENT_PROBLEM_MESSAGE_ARGUMENTS);
- if (elements.getLength() != 1) continue;
- Element messageArguments = (Element) elements.item(0);
- NodeList arguments = messageArguments.getElementsByTagName(IApiXmlConstants.ELEMENT_PROBLEM_MESSAGE_ARGUMENT);
- int length = arguments.getLength();
- messageargs = new String[length];
- String comment = element.getAttribute(IApiXmlConstants.ATTR_COMMENT);
- comments.add((comment.length() < 1 ? null : comment));
- for (int k = 0; k < length; k++) {
- Element messageArgument = (Element) arguments.item(k);
- messageargs[k] = messageArgument.getAttribute(IApiXmlConstants.ATTR_VALUE);
- }
- newfilters.add(ApiProblemFactory.newApiProblem(path, typeName, messageargs, null, null, -1, -1, -1, id));
- }
- }
- internalAddFilters(componentID, (IApiProblem[]) newfilters.toArray(new IApiProblem[newfilters.size()]),
- (String[]) comments.toArray(new String[comments.size()]));
- newfilters.clear();
- }
-
- /**
- * Internal use method that allows auto-persisting of the filter file to be turned on or off
- * @param problems the problems to add the the store
- * @param persist if the filters should be auto-persisted after they are added
- */
- private void internalAddFilters(String componentID, IApiProblem[] problems, String[] comments) {
- if(problems == null) {
- if(this.debug) {
- System.out.println("null problems array not addding filters"); //$NON-NLS-1$
- }
- return;
- }
- for(int i = 0; i < problems.length; i++) {
- IApiProblem problem = problems[i];
- IApiProblemFilter filter = new ApiProblemFilter(componentID, problem, comments[i]);
- String typeName = problem.getTypeName();
- if (typeName == null) {
- typeName = GLOBAL;
- }
- Set filters = (Set) fFilterMap.get(typeName);
- if(filters == null) {
- filters = new HashSet();
- fFilterMap.put(typeName, filters);
- }
- filters.add(filter);
- }
- }
-
- public boolean isFiltered(IApiProblem problem) {
- if (this.fFilterMap == null || this.fFilterMap.isEmpty()) return false;
- String typeName = problem.getTypeName();
- if (typeName == null || typeName.length() == 0) {
- typeName = GLOBAL;
- }
- Set filters = (Set) this.fFilterMap.get(typeName);
- if (filters == null) {
- return false;
- }
- for (Iterator iterator = filters.iterator(); iterator.hasNext();) {
- IApiProblemFilter filter = (IApiProblemFilter) iterator.next();
- if (problem.getCategory() == IApiProblem.CATEGORY_USAGE) {
- // write our own matching implementation
- return matchUsageProblem(filter.getUnderlyingProblem(), problem);
- } else if (matchFilters(filter.getUnderlyingProblem(), problem)) {
- return true;
- }
- }
- return false;
- }
-
- private boolean matchFilters(IApiProblem filterProblem, IApiProblem problem) {
- if (problem.getId() == filterProblem.getId() && argumentsEquals(problem.getMessageArguments(), filterProblem.getMessageArguments())) {
- String typeName = problem.getTypeName();
- String filteredProblemTypeName = filterProblem.getTypeName();
- if (typeName == null) {
- if (filteredProblemTypeName != null) {
- return false;
- }
- return true;
- } else if (filteredProblemTypeName == null) {
- return false;
- }
- return typeName.equals(filteredProblemTypeName);
- }
- return false;
- }
-
- private boolean matchUsageProblem(IApiProblem filterProblem, IApiProblem problem) {
- if (problem.getId() == filterProblem.getId()) {
- // check arguments
- String problemPath = problem.getResourcePath();
- String filterProblemPath = filterProblem.getResourcePath();
- if (problemPath == null) {
- if (filterProblemPath != null) {
- return false;
- }
- } else if (filterProblemPath == null) {
- return false;
- } else if (!new Path(problemPath).equals(new Path(filterProblemPath))) {
- return false;
- }
- String problemTypeName = problem.getTypeName();
- String filterProblemTypeName = filterProblem.getTypeName();
- if (problemTypeName == null) {
- if (filterProblemTypeName != null) {
- return false;
- }
- } else if (filterProblemTypeName == null) {
- return false;
- } else if (!problemTypeName.equals(filterProblemTypeName)) {
- return false;
- }
- return argumentsEquals(problem.getMessageArguments(), filterProblem.getMessageArguments());
- }
- return false;
- }
- public boolean removeFilters(IApiProblemFilter[] filters) {
- return false;
- }
- }
+
private static class Summary {
List apiBundleVersionProblems = new ArrayList();
List apiCompatibilityProblems = new ArrayList();
diff --git a/apitools/org.eclipse.pde.api.tools/src_ant/org/eclipse/pde/api/tools/internal/tasks/AntFilterStore.java b/apitools/org.eclipse.pde.api.tools/src_ant/org/eclipse/pde/api/tools/internal/tasks/AntFilterStore.java
new file mode 100644
index 0000000..a4c5e32
--- /dev/null
+++ b/apitools/org.eclipse.pde.api.tools/src_ant/org/eclipse/pde/api/tools/internal/tasks/AntFilterStore.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2012 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 API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.api.tools.internal.tasks;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.pde.api.tools.internal.FilterStore;
+import org.eclipse.pde.api.tools.internal.IApiCoreConstants;
+import org.eclipse.pde.api.tools.internal.problems.ApiProblemFilter;
+import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblem;
+import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblemFilter;
+
+/**
+ * This filter store is only used to filter problem using existing filters.
+ * It doesn't add or remove any filters.
+ */
+public class AntFilterStore extends FilterStore {
+
+ private boolean debug;
+ String fComponentId = null;
+ String fFiltersRoot = null;
+
+ /**
+ * Constructor
+ * @param debug
+ * @param filtersRoot
+ * @param componentID
+ */
+ public AntFilterStore(boolean debug, String filtersRoot, String componentID) {
+ fComponentId = componentID;
+ fFiltersRoot = filtersRoot;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.pde.api.tools.internal.FilterStore#initializeApiFilters()
+ */
+ protected synchronized void initializeApiFilters() {
+ if(fFilterMap != null) {
+ return;
+ }
+ if(this.debug) {
+ System.out.println("null filter map, creating a new one"); //$NON-NLS-1$
+ }
+ fFilterMap = new HashMap(5);
+ InputStream contents = null;
+ try {
+ File filterFileParent = new File(fFiltersRoot, fComponentId);
+ if (!filterFileParent.exists()) {
+ return;
+ }
+ contents = new BufferedInputStream(new FileInputStream(new File(filterFileParent, IApiCoreConstants.API_FILTERS_XML_NAME)));
+ readFilterFile(contents);
+ }
+ catch(IOException ioe) {
+ }
+ finally {
+ if (contents != null) {
+ try {
+ contents.close();
+ } catch(IOException e) {
+ // ignore
+ }
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.pde.api.tools.internal.FilterStore#internalAddFilters(org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblem[], java.lang.String[])
+ */
+ protected void internalAddFilters(IApiProblem[] problems, String[] comments) {
+ if(problems == null) {
+ return;
+ }
+ for(int i = 0; i < problems.length; i++) {
+ IApiProblem problem = problems[i];
+ IApiProblemFilter filter = new ApiProblemFilter(fComponentId, problem, comments[i]);
+ String typeName = problem.getTypeName();
+ if (typeName == null) {
+ typeName = GLOBAL;
+ }
+ Set filters = (Set) fFilterMap.get(typeName);
+ if(filters == null) {
+ filters = new HashSet();
+ fFilterMap.put(typeName, filters);
+ }
+ filters.add(filter);
+ }
+ }
+} \ No newline at end of file
diff --git a/apitools/org.eclipse.pde.api.tools/src_ant/org/eclipse/pde/api/tools/internal/tasks/ApiUseTask.java b/apitools/org.eclipse.pde.api.tools/src_ant/org/eclipse/pde/api/tools/internal/tasks/ApiUseTask.java
index aa958be..92266f9 100644
--- a/apitools/org.eclipse.pde.api.tools/src_ant/org/eclipse/pde/api/tools/internal/tasks/ApiUseTask.java
+++ b/apitools/org.eclipse.pde.api.tools/src_ant/org/eclipse/pde/api/tools/internal/tasks/ApiUseTask.java
@@ -25,6 +25,7 @@ import org.eclipse.core.runtime.CoreException;
import org.eclipse.osgi.service.resolver.ResolverError;
import org.eclipse.osgi.util.NLS;
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
+import org.eclipse.pde.api.tools.internal.provisional.IApiFilterStore;
import org.eclipse.pde.api.tools.internal.provisional.model.IApiBaseline;
import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent;
import org.eclipse.pde.api.tools.internal.provisional.model.IApiElement;
@@ -97,6 +98,10 @@ public final class ApiUseTask extends CommonUtilsTask {
* </pre>
*/
private String[] archivePatterns = null;
+ /**
+ * Absolute file paths to the filter files to use
+ */
+ private String[] filterPaths = null;
/**
* List of elements excluded from the scope
@@ -238,6 +243,14 @@ public final class ApiUseTask extends CommonUtilsTask {
}
/**
+ * Sets the paths of the filter files to use
+ * @param paths
+ */
+ public void setFilterPaths(String paths) {
+ filterPaths = parsePatterns(paths);
+ }
+
+ /**
* @see org.eclipse.pde.api.tools.internal.tasks.UseTask#assertParameters()
*/
protected void assertParameters() throws BuildException {
@@ -298,6 +311,7 @@ public final class ApiUseTask extends CommonUtilsTask {
(IApiElement[]) scope.toArray(new IApiElement[scope.size()]),
getSearchFlags());
requestor.setJarPatterns(archivePatterns);
+ requestor.setGlobalFilterStore(getFilterStore(ids));
// override API descriptions as required
if (apiPatterns != null || internalPatterns != null) {
// modify API descriptions
@@ -461,6 +475,18 @@ public final class ApiUseTask extends CommonUtilsTask {
}
/**
+ * Create a global filter store from a group of filter files
+ *
+ * @return the new {@link IApiFilterStore} or <code>null</code>
+ */
+ protected IApiFilterStore getFilterStore(Set ids) {
+ if(filterPaths != null && !ids.isEmpty()) {
+ //TODO we need to create the filter store
+ }
+ return null;
+ }
+
+ /**
* Cleans the report location specified by the parameter {@link CommonUtilsTask#reportLocation}
*/
protected void cleanReportLocation() {