### Eclipse Workspace Patch 1.0 #P org.eclipse.pde.api.tools Index: src/org/eclipse/pde/api/tools/internal/builder/IncrementalApiBuilder.java =================================================================== RCS file: /cvsroot/eclipse/pde/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/builder/IncrementalApiBuilder.java,v retrieving revision 1.5 diff -u -r1.5 IncrementalApiBuilder.java --- src/org/eclipse/pde/api/tools/internal/builder/IncrementalApiBuilder.java 6 Apr 2009 19:10:33 -0000 1.5 +++ src/org/eclipse/pde/api/tools/internal/builder/IncrementalApiBuilder.java 6 Apr 2009 21:17:06 -0000 @@ -31,7 +31,6 @@ import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; -import org.eclipse.jdt.internal.core.JavaModelManager; import org.eclipse.jdt.internal.core.builder.ReferenceCollection; import org.eclipse.jdt.internal.core.builder.State; import org.eclipse.jdt.internal.core.builder.StringSet; @@ -117,20 +116,18 @@ * Incrementally builds using the {@link org.eclipse.pde.api.tools.internal.provisional.builder.IApiAnalyzer} * from the given {@link ApiAnalysisBuilder} * - * @param baseline - * @param deltas + * @param baseline the baseline to compare with + * @param wbaseline the workspace baseline + * @param deltas the deltas to be built + * @param state the current JDT build state + * @param buildstate the current API tools build state * @param monitor * @throws CoreException */ - public void build(IApiBaseline baseline, IResourceDelta[] deltas, BuildState buildstate, IProgressMonitor monitor) throws CoreException { + public void build(IApiBaseline baseline, IApiBaseline wbaseline, IResourceDelta[] deltas, State state, BuildState buildstate, IProgressMonitor monitor) throws CoreException { IProject project = this.builder.getProject(); SubMonitor localmonitor = SubMonitor.convert(monitor, NLS.bind(BuilderMessages.IncrementalBuilder_builder_for_project, project.getName()), 10); try { - State state = (State)JavaModelManager.getJavaModelManager().getLastBuiltState(project, localmonitor.newChild(1)); - if(state == null) { - this.builder.buildAll(baseline, localmonitor); - return; - } String[] projectNames = buildstate.getReexportedComponents(); HashSet depprojects = null; if (projectNames.length != 0) { @@ -151,7 +148,7 @@ for (int i = 0; i < deltas.length; i++) { deltas[i].accept(visitor); } - build(project, state, baseline, buildstate, localmonitor.newChild(1)); + build(project, baseline, wbaseline, state, buildstate, localmonitor.newChild(1)); } finally { if(!localmonitor.isCanceled()) { @@ -167,15 +164,14 @@ /** * Builds an API delta using the default profile (from the workspace settings and the current * @param project - * workspace profile - * @param state + * @param baseline the baseline to compare to + * @param wbaseline the current workspace baseline + * @param state the current JDT build state + * @param buildstate the current API tools build state * @param monitor */ - void build(final IProject project, final State state, IApiBaseline baseline, BuildState buildstate, IProgressMonitor monitor) throws CoreException { - IApiBaseline wsprofile = null; + void build(final IProject project, IApiBaseline baseline, IApiBaseline wbaseline, final State state, BuildState buildstate, IProgressMonitor monitor) throws CoreException { try { - // clear the old state so a full build will occur if this one is cancelled or terminates prematurely - this.builder.clearLastState(); SubMonitor localmonitor = SubMonitor.convert(monitor, BuilderMessages.api_analysis_on_0, 1); collectAffectedSourceFiles(project, state, this.changedtypes); int typesize = this.changedtypes.size(); @@ -186,15 +182,8 @@ if (typesize != 0) { IPluginModelBase currentModel = this.builder.getCurrentModel(); if (currentModel != null) { - wsprofile = this.builder.getWorkspaceProfile(); - if (wsprofile == null) { - if (ApiAnalysisBuilder.DEBUG) { - System.err.println("Could not retrieve a workspace profile"); //$NON-NLS-1$ - } - return; - } String id = currentModel.getBundleDescription().getSymbolicName(); - IApiComponent comp = wsprofile.getApiComponent(id); + IApiComponent comp = wbaseline.getApiComponent(id); if(comp == null) { return; } @@ -217,9 +206,6 @@ } } finally { - if(wsprofile != null) { - wsprofile.close(); - } if(monitor != null) { monitor.done(); } Index: src/org/eclipse/pde/api/tools/internal/builder/BaseApiAnalyzer.java =================================================================== RCS file: /cvsroot/eclipse/pde/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/builder/BaseApiAnalyzer.java,v retrieving revision 1.94 diff -u -r1.94 BaseApiAnalyzer.java --- src/org/eclipse/pde/api/tools/internal/builder/BaseApiAnalyzer.java 3 Apr 2009 17:37:47 -0000 1.94 +++ src/org/eclipse/pde/api/tools/internal/builder/BaseApiAnalyzer.java 6 Apr 2009 21:17:06 -0000 @@ -488,7 +488,7 @@ return new BuildState(); } try { - BuildState state = ApiAnalysisBuilder.getLastBuiltState(project); + BuildState state = BuildState.getLastBuiltState(project); if(state != null) { return state; } Index: src/org/eclipse/pde/api/tools/internal/builder/BuildState.java =================================================================== RCS file: /cvsroot/eclipse/pde/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/builder/BuildState.java,v retrieving revision 1.12 diff -u -r1.12 BuildState.java --- src/org/eclipse/pde/api/tools/internal/builder/BuildState.java 24 Mar 2009 18:50:44 -0000 1.12 +++ src/org/eclipse/pde/api/tools/internal/builder/BuildState.java 6 Apr 2009 21:17:06 -0000 @@ -10,8 +10,13 @@ *******************************************************************************/ package org.eclipse.pde.api.tools.internal.builder; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; @@ -22,12 +27,25 @@ import java.util.Map; import java.util.Set; +import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.osgi.util.NLS; import org.eclipse.pde.api.tools.internal.comparator.Delta; import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin; import org.eclipse.pde.api.tools.internal.provisional.comparator.IDelta; import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent; +import org.eclipse.pde.api.tools.internal.util.Util; +/** + * The API tools build state + * + * @since 1.0.1 + */ public class BuildState { private static final IDelta[] EMPTY_DELTAS = new IDelta[0]; private static final String[] NO_REEXPORTED_COMPONENTS = new String[0]; @@ -38,13 +56,29 @@ private String[] reexportedComponents; private Set apiToolingDependentProjects; - public static BuildState read(DataInputStream in) throws IOException { + /** + * Constructor + */ + BuildState() { + this.compatibleChanges = new HashMap(); + this.breakingChanges = new HashMap(); + } + + /** + * Reads the build state from an input stream + * @param in + * @return the {@link BuildState} from the given input stream + * @throws IOException + */ + public static BuildState read(DataInputStream in) throws IOException { String pluginID= in.readUTF(); - if (!pluginID.equals(ApiPlugin.PLUGIN_ID)) - throw new IOException(BuilderMessages.build_wrongFileFormat); + if (!pluginID.equals(ApiPlugin.PLUGIN_ID)) { + throw new IOException(BuilderMessages.build_wrongFileFormat); + } String kind= in.readUTF(); - if (!kind.equals("STATE")) //$NON-NLS-1$ - throw new IOException(BuilderMessages.build_wrongFileFormat); + if (!kind.equals("STATE")) {//$NON-NLS-1$ + throw new IOException(BuilderMessages.build_wrongFileFormat); + } if (in.readInt() != VERSION) { // this is an old build state - a full build is required return null; @@ -77,6 +111,13 @@ } return null; } + + /** + * Writes the given {@link BuildState} to the given output stream + * @param state + * @param out + * @throws IOException + */ public static void write(BuildState state, DataOutputStream out) throws IOException { out.writeUTF(ApiPlugin.PLUGIN_ID); out.writeUTF("STATE"); //$NON-NLS-1$ @@ -107,6 +148,13 @@ out.writeUTF((String) iterator.next()); } } + + /** + * Read the {@link IDelta} from the build state (input stream) + * @param in the input stream to read the {@link IDelta} from + * @return a reconstructed {@link IDelta} from the build state + * @throws IOException + */ private static IDelta readDelta(DataInputStream in) throws IOException { // decode the delta from the build state boolean hasComponentID = in.readBoolean(); @@ -136,6 +184,13 @@ int newModifiers = modifiers >>> Delta.NEW_MODIFIERS_OFFSET; return new Delta(componentID, elementType, kind, flags, restrictions, oldModifiers, newModifiers, typeName, key, datas); } + + /** + * Writes a given {@link IDelta} to the build state (the output stream) + * @param delta the delta to write + * @param out the stream to write to + * @throws IOException + */ private static void writeDelta(IDelta delta, DataOutputStream out) throws IOException { // encode a delta into the build state // int elementType, int kind, int flags, int restrictions, int modifiers, String typeName, String key, Object data @@ -161,10 +216,11 @@ } } - BuildState() { - this.compatibleChanges = new HashMap(); - this.breakingChanges = new HashMap(); - } + /** + * Adds an {@link IDelta} for a compatible compatibility change to the current state + * + * @param delta the {@link IDelta} to add to the state + */ public void addCompatibleChange(IDelta delta) { String typeName = delta.getTypeName(); Set object = (Set) this.compatibleChanges.get(typeName); @@ -177,6 +233,11 @@ } } + /** + * Add an {@link IDelta} for an incompatible compatibility change to the current state + * + * @param delta the {@link IDelta} to add to the state + */ public void addBreakingChange(IDelta delta) { String typeName = delta.getTypeName(); Set object = (Set) this.breakingChanges.get(typeName); @@ -221,12 +282,16 @@ return (IDelta[]) collector.toArray(new IDelta[collector.size()]); } + /** + * @return the complete list of re-exported {@link IApiComponent}s + */ public String[] getReexportedComponents() { if (this.reexportedComponents == null) { return NO_REEXPORTED_COMPONENTS; } return this.reexportedComponents; } + /** * Remove all entries for the given type name. * @@ -235,11 +300,17 @@ public void cleanup(String typeName) { this.breakingChanges.remove(typeName); this.compatibleChanges.remove(typeName); - this.reexportedComponents = null;; + this.reexportedComponents = null; } + /** + * Sets the current list if re-exported {@link IApiComponent}s for this build state + * @param components + */ public void setReexportedComponents(IApiComponent[] components) { - if (components == null) return; + if (components == null) { + return; + } try { if (this.reexportedComponents == null) { final int length = components.length; @@ -254,6 +325,10 @@ } } + /** + * Adds a dependent project to the listing of dependent projects + * @param projectName + */ public void addApiToolingDependentProject(String projectName) { if (this.apiToolingDependentProjects == null) { this.apiToolingDependentProjects = new HashSet(3); @@ -261,7 +336,137 @@ this.apiToolingDependentProjects.add(projectName); } + /** + * @return the complete listing of dependent projects + */ public Set getApiToolingDependentProjects() { return this.apiToolingDependentProjects == null ? Collections.EMPTY_SET : this.apiToolingDependentProjects; } + /** + * Return the last built state for the given project, or null if none + */ + public static BuildState getLastBuiltState(IProject project) throws CoreException { + if (!Util.isApiProject(project)) { + // should never be requested on non-Java projects + return null; + } + return readState(project); + } + + /** + * Reads the build state for the relevant project. + * @return the current {@link BuildState} for the given project or null if there is not one + */ + static BuildState readState(IProject project) throws CoreException { + File file = getSerializationFile(project); + if (file != null && file.exists()) { + try { + DataInputStream in= new DataInputStream(new BufferedInputStream(new FileInputStream(file))); + try { + return read(in); + } finally { + if (ApiAnalysisBuilder.DEBUG) { + System.out.println("Saved state thinks last build failed for " + project.getName()); //$NON-NLS-1$ + } + in.close(); + } + } catch (Exception e) { + e.printStackTrace(); + throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, Platform.PLUGIN_ERROR, "Error reading last build state for project "+ project.getName(), e)); //$NON-NLS-1$ + } + } else if (ApiAnalysisBuilder.DEBUG) { + if (file == null) { + System.out.println("Project does not exist: " + project); //$NON-NLS-1$ + } else { + System.out.println("Build state file " + file.getPath() + " does not exist"); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + return null; + } + + /** + * Sets the last built state for the given project, or null to reset it. + * + * @param project the project to set a state for + * @param state the {@link BuildState} to set as the last state + */ + public static void setLastBuiltState(IProject project, BuildState state) throws CoreException { + if (Util.isApiProject(project)) { + // should never be requested on non-Java projects + if (state != null) { + saveBuiltState(project, state); + } else { + try { + File file = getSerializationFile(project); + if (file != null && file.exists()) { + file.delete(); + } + } catch(SecurityException se) { + // could not delete file: cannot do much more + } + } + } + } + + /** + * Returns the {@link File} to use for saving and restoring the last built state for the given project. + * + * @param project gets the saved state file for the given project + * @return the {@link File} to use for saving and restoring the last built state for the given project. + */ + static File getSerializationFile(IProject project) { + if (!project.exists()) { + return null; + } + IPath workingLocation = project.getWorkingLocation(ApiPlugin.PLUGIN_ID); + return workingLocation.append("state.dat").toFile(); //$NON-NLS-1$ + } + + /** + * Saves the current build state + * @param project + * @param state + * @throws CoreException + */ + static void saveBuiltState(IProject project, BuildState state) throws CoreException { + if (ApiAnalysisBuilder.DEBUG) { + System.out.println("Saving build state for project: "+project.getName()); //$NON-NLS-1$ + } + File file = BuildState.getSerializationFile(project); + if (file == null) return; + long t = 0; + if (ApiAnalysisBuilder.DEBUG) { + t = System.currentTimeMillis(); + } + try { + DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file))); + try { + write(state, out); + } finally { + out.close(); + } + } catch (RuntimeException e) { + try { + file.delete(); + } catch(SecurityException se) { + // could not delete file: cannot do much more + } + throw new CoreException( + new Status(IStatus.ERROR, ApiPlugin.PLUGIN_ID, Platform.PLUGIN_ERROR, + NLS.bind(BuilderMessages.build_cannotSaveState, project.getName()), e)); + } catch (IOException e) { + try { + file.delete(); + } catch(SecurityException se) { + // could not delete file: cannot do much more + } + throw new CoreException( + new Status(IStatus.ERROR, ApiPlugin.PLUGIN_ID, Platform.PLUGIN_ERROR, + NLS.bind(BuilderMessages.build_cannotSaveState, project.getName()), e)); + } + if (ApiAnalysisBuilder.DEBUG) { + t = System.currentTimeMillis() - t; + System.out.println(NLS.bind(BuilderMessages.build_saveStateComplete, String.valueOf(t))); + } + } } Index: src/org/eclipse/pde/api/tools/internal/builder/ApiAnalysisBuilder.java =================================================================== RCS file: /cvsroot/eclipse/pde/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/builder/ApiAnalysisBuilder.java,v retrieving revision 1.100 diff -u -r1.100 ApiAnalysisBuilder.java --- src/org/eclipse/pde/api/tools/internal/builder/ApiAnalysisBuilder.java 6 Apr 2009 19:10:33 -0000 1.100 +++ src/org/eclipse/pde/api/tools/internal/builder/ApiAnalysisBuilder.java 6 Apr 2009 21:17:05 -0000 @@ -10,14 +10,6 @@ *******************************************************************************/ package org.eclipse.pde.api.tools.internal.builder; -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; @@ -39,14 +31,14 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubMonitor; import org.eclipse.jdt.core.IClasspathAttribute; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.internal.core.JavaModelManager; +import org.eclipse.jdt.internal.core.builder.State; import org.eclipse.osgi.service.resolver.BundleDescription; import org.eclipse.osgi.util.NLS; import org.eclipse.pde.api.tools.internal.ApiDescriptionManager; @@ -214,51 +206,67 @@ SubMonitor localMonitor = SubMonitor.convert(monitor, BuilderMessages.api_analysis_builder, 2); final IProject[] projects = getRequiredProjects(true); IApiBaseline baseline = ApiPlugin.getDefault().getApiBaselineManager().getDefaultApiBaseline(); + IApiBaseline wbaseline = ApiPlugin.getDefault().getApiBaselineManager().getWorkspaceBaseline(); + if (wbaseline == null) { + if (DEBUG) { + System.err.println("Could not retrieve a workspace profile"); //$NON-NLS-1$ + } + return NO_PROJECTS; + } try { switch(kind) { case FULL_BUILD : { if (DEBUG) { System.out.println("Performing full build as requested by user"); //$NON-NLS-1$ } - buildAll(baseline, localMonitor.newChild(1)); + buildAll(baseline, wbaseline, localMonitor.newChild(1)); break; } case AUTO_BUILD : case INCREMENTAL_BUILD : { - this.buildstate = getLastBuiltState(currentproject); + this.buildstate = BuildState.getLastBuiltState(currentproject); if (this.buildstate == null) { - buildAll(baseline, localMonitor.newChild(1)); + buildAll(baseline, wbaseline, localMonitor.newChild(1)); break; } else if(worthDoingFullBuild(projects)) { - buildAll(baseline, localMonitor.newChild(1)); - } - IResourceDelta[] deltas = getDeltas(projects); - if(deltas.length < 1) { - buildAll(baseline, localMonitor.newChild(1)); + buildAll(baseline, wbaseline, localMonitor.newChild(1)); + break; } - else { - IResourceDelta manifest = null; - IResourceDelta filters = null; - for (int i = 0; i < deltas.length; i++) { - manifest = deltas[i].findMember(MANIFEST_PATH); - if(manifest != null) { - break; + else { + IResourceDelta[] deltas = getDeltas(projects); + if(deltas.length < 1) { + buildAll(baseline, wbaseline, localMonitor.newChild(1)); + } + else { + IResourceDelta manifest = null; + IResourceDelta filters = null; + for (int i = 0; i < deltas.length; i++) { + manifest = deltas[i].findMember(MANIFEST_PATH); + if(manifest != null) { + break; + } + filters = deltas[i].findMember(FILTER_PATH); + if(filters != null){ + break; + } } - filters = deltas[i].findMember(FILTER_PATH); - if(filters != null){ - break; + if (manifest != null || filters != null) { + if (DEBUG) { + System.out.println("Performing full build since MANIFEST.MF or .api_filters was modified"); //$NON-NLS-1$ + } + buildAll(baseline, wbaseline, localMonitor.newChild(1)); + } + else { + State state = (State)JavaModelManager.getJavaModelManager().getLastBuiltState(this.currentproject, localMonitor.newChild(1)); + if(state == null) { + buildAll(baseline, wbaseline, localMonitor.newChild(1)); + break; + } + BuildState.setLastBuiltState(this.currentproject, null); + IncrementalApiBuilder builder = new IncrementalApiBuilder(this); + builder.build(baseline, wbaseline, deltas, state, this.buildstate, localMonitor.newChild(1)); } - } - if (manifest != null || filters != null) { - if (DEBUG) { - System.out.println("Performing full build since MANIFEST.MF or .api_filters was modified"); //$NON-NLS-1$ - } - buildAll(baseline, localMonitor.newChild(1)); - } - else { - IncrementalApiBuilder builder = new IncrementalApiBuilder(this); - builder.build(baseline, deltas, this.buildstate, localMonitor.newChild(1)); } } } @@ -279,6 +287,7 @@ if(baseline != null) { baseline.close(); } + wbaseline.close(); if(monitor != null) { monitor.done(); } @@ -289,7 +298,7 @@ this.buildstate.addApiToolingDependentProject(project.getName()); } } - saveBuiltState(this.currentproject, this.buildstate); + BuildState.saveBuiltState(this.currentproject, this.buildstate); this.buildstate = null; } } @@ -299,7 +308,12 @@ return projects; } - private boolean worthDoingFullBuild(IProject[] projects) { + /** + * if its worth doing a full build considering the given set if projects + * @param projects projects to check the build state for + * @return true if a full build should take place, false otherwise + */ + boolean worthDoingFullBuild(IProject[] projects) { Set apiToolingDependentProjects = this.buildstate.getApiToolingDependentProjects(); for (int i = 0, max = projects.length; i < max; i++) { IProject currentProject = projects[i]; @@ -317,12 +331,13 @@ /** * Performs a full build for the project + * @param baseline the default baseline + * @param wbaseline the workspace baseline * @param monitor */ - void buildAll(IApiBaseline baseline, IProgressMonitor monitor) throws CoreException { - IApiBaseline wsprofile = null; + void buildAll(IApiBaseline baseline, IApiBaseline wbaseline, IProgressMonitor monitor) throws CoreException { try { - clearLastState(); + BuildState.setLastBuiltState(this.currentproject, null); this.buildstate = new BuildState(); SubMonitor localMonitor = SubMonitor.convert(monitor, BuilderMessages.api_analysis_on_0, 4); localMonitor.subTask(NLS.bind(BuilderMessages.ApiAnalysisBuilder_initializing_analyzer, currentproject.getName())); @@ -330,17 +345,10 @@ IPluginModelBase currentModel = getCurrentModel(); if (currentModel != null) { localMonitor.subTask(BuilderMessages.building_workspace_profile); - wsprofile = getWorkspaceProfile(); updateMonitor(localMonitor, 1); - if (wsprofile == null) { - if (DEBUG) { - System.err.println("Could not retrieve a workspace profile"); //$NON-NLS-1$ - } - return; - } String id = currentModel.getBundleDescription().getSymbolicName(); // Compatibility checks - IApiComponent apiComponent = wsprofile.getApiComponent(id); + IApiComponent apiComponent = wbaseline.getApiComponent(id); if(apiComponent != null) { getAnalyzer().analyzeComponent(this.buildstate, null, null, baseline, apiComponent, null, null, localMonitor.newChild(1)); updateMonitor(localMonitor, 1); @@ -350,9 +358,6 @@ } } finally { - if(wsprofile != null) { - wsprofile.close(); - } if(monitor != null) { monitor.done(); } @@ -393,10 +398,11 @@ /** * Returns the {@link IApiMarkerConstants} problem type given the * problem category - * @param category + * @param category the problem category - see {@link IApiProblem} for problem categories + * @param kind the kind of the problem - see {@link IApiProblem} for problem kinds * @return the problem type or null */ - private String getProblemTypeFromCategory(int category, int kind) { + String getProblemTypeFromCategory(int category, int kind) { switch(category) { case IApiProblem.CATEGORY_API_COMPONENT_RESOLUTION : { return IApiMarkerConstants.API_COMPONENT_RESOLUTION_PROBLEM_MARKER; @@ -430,9 +436,11 @@ * Creates an {@link IMarker} on the resource specified * in the problem (via its path) with the given problem * attributes + * @param category the category of the problem - see {@link IApiProblem} for categories + * @param type the marker type to create - see {@link IApiMarkerConstants} for types * @param problem the problem to create a marker from */ - private void createMarkerForProblem(int category, String type, IApiProblem problem) { + void createMarkerForProblem(int category, String type, IApiProblem problem) { IResource resource = resolveResource(problem); if(resource == null) { return; @@ -498,7 +506,7 @@ * @param problem the problem to get the resource for * @return the resource or null */ - private IResource resolveResource(IApiProblem problem) { + IResource resolveResource(IApiProblem problem) { String resourcePath = problem.getResourcePath(); if (resourcePath == null) { return null; @@ -519,7 +527,7 @@ * @param args * @return a single string attribute from an array or arguments */ - private String createArgAttribute(String[] args) { + String createArgAttribute(String[] args) { StringBuffer buff = new StringBuffer(); for(int i = 0; i < args.length; i++) { buff.append(args[i]); @@ -564,7 +572,7 @@ updateMonitor(localmonitor, 1); } finally { - clearLastState(); + BuildState.setLastBuiltState(this.currentproject, null); localmonitor.done(); } } @@ -573,7 +581,7 @@ * Cleans the .api_settings file for the given project * @param project */ - private void cleanupApiDescription(IProject project) { + void cleanupApiDescription(IProject project) { if(project != null && project.exists()) { ApiDescriptionManager.getDefault().clean(JavaCore.create(project), true, true); } @@ -608,7 +616,7 @@ * @param projects * @return */ - private IResourceDelta[] getDeltas(IProject[] projects) { + IResourceDelta[] getDeltas(IProject[] projects) { if(DEBUG) { System.out.println("Searching for deltas for build of project: "+this.currentproject.getName()); //$NON-NLS-1$ } @@ -646,10 +654,10 @@ /** * Returns the complete listing of required projects from the classpath of the backing project * @param includeBinaryPrerequisites - * @return + * @return the list of projects required * @throws CoreException */ - private IProject[] getRequiredProjects(boolean includebinaries) throws CoreException { + IProject[] getRequiredProjects(boolean includebinaries) throws CoreException { IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); if (this.currentproject == null || workspaceRoot == null) { return new IProject[0]; @@ -719,13 +727,6 @@ projects.toArray(result); return result; } - - /** - * @return the workspace {@link IApiProfile} - */ - IApiBaseline getWorkspaceProfile() throws CoreException { - return ApiPlugin.getDefault().getApiBaselineManager().getWorkspaceBaseline(); - } /** * Returns the output paths of the given project or null if none have been computed @@ -741,7 +742,7 @@ * @param entry * @return true if the specified {@link IClasspathEntry} is optional, false otherwise */ - private boolean isOptional(IClasspathEntry entry) { + boolean isOptional(IClasspathEntry entry) { IClasspathAttribute[] attribs = entry.getExtraAttributes(); for (int i = 0, length = attribs.length; i < length; i++) { IClasspathAttribute attribute = attribs[i]; @@ -757,133 +758,4 @@ public String toString() { return NLS.bind(BuilderMessages.ApiAnalysisBuilder_builder_for_project, this.currentproject.getName()); } - - /** - * Return the last built state for the given project, or null if none - */ - public static BuildState getLastBuiltState(IProject project) throws CoreException { - if (!Util.isApiProject(project)) { - // should never be requested on non-Java projects - return null; - } - return readState(project); - } - - /** - * Reads the build state for the relevant project. - */ - static BuildState readState(IProject project) throws CoreException { - File file = getSerializationFile(project); - if (file != null && file.exists()) { - try { - DataInputStream in= new DataInputStream(new BufferedInputStream(new FileInputStream(file))); - try { - return BuildState.read(in); - } finally { - if (DEBUG) { - System.out.println("Saved state thinks last build failed for " + project.getName()); //$NON-NLS-1$ - } - in.close(); - } - } catch (Exception e) { - e.printStackTrace(); - throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, Platform.PLUGIN_ERROR, "Error reading last build state for project "+ project.getName(), e)); //$NON-NLS-1$ - } - } else if (DEBUG) { - if (file == null) { - System.out.println("Project does not exist: " + project); //$NON-NLS-1$ - } else { - System.out.println("Build state file " + file.getPath() + " does not exist"); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - return null; - } - - /** - * Sets the last built state for the given project, or null to reset it. - */ - public static void setLastBuiltState(IProject project, BuildState state) throws CoreException { - if (Util.isApiProject(project)) { - // should never be requested on non-Java projects - if (state != null) { - saveBuiltState(project, state); - } else { - try { - File file = getSerializationFile(project); - if (file != null && file.exists()) { - file.delete(); - } - } catch(SecurityException se) { - // could not delete file: cannot do much more - } - } - } - } - - /** - * Returns the File to use for saving and restoring the last built state for the given project. - */ - static File getSerializationFile(IProject project) { - if (!project.exists()) { - return null; - } - IPath workingLocation = project.getWorkingLocation(ApiPlugin.PLUGIN_ID); - return workingLocation.append("state.dat").toFile(); //$NON-NLS-1$ - } - - /** - * Saves the current build state - * @param project - * @param state - * @throws CoreException - */ - static void saveBuiltState(IProject project, BuildState state) throws CoreException { - if (DEBUG) { - System.out.println("Saving build state for project: "+project.getName()); //$NON-NLS-1$ - } - File file = getSerializationFile(project); - if (file == null) return; - long t = 0; - if (DEBUG) { - t = System.currentTimeMillis(); - } - try { - DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file))); - try { - BuildState.write(state, out); - } finally { - out.close(); - } - } catch (RuntimeException e) { - try { - file.delete(); - } catch(SecurityException se) { - // could not delete file: cannot do much more - } - throw new CoreException( - new Status(IStatus.ERROR, ApiPlugin.PLUGIN_ID, Platform.PLUGIN_ERROR, - NLS.bind(BuilderMessages.build_cannotSaveState, project.getName()), e)); - } catch (IOException e) { - try { - file.delete(); - } catch(SecurityException se) { - // could not delete file: cannot do much more - } - throw new CoreException( - new Status(IStatus.ERROR, ApiPlugin.PLUGIN_ID, Platform.PLUGIN_ERROR, - NLS.bind(BuilderMessages.build_cannotSaveState, project.getName()), e)); - } - if (DEBUG) { - t = System.currentTimeMillis() - t; - System.out.println(NLS.bind(BuilderMessages.build_saveStateComplete, String.valueOf(t))); - } - } - - /** - * Clears the last build state by setting it to null - * @throws CoreException - */ - void clearLastState() throws CoreException { - setLastBuiltState(this.currentproject, null); - } } Index: buildnotes_api_tools.html =================================================================== RCS file: /cvsroot/eclipse/pde/apitools/org.eclipse.pde.api.tools/buildnotes_api_tools.html,v retrieving revision 1.441 diff -u -r1.441 buildnotes_api_tools.html --- buildnotes_api_tools.html 3 Apr 2009 17:52:06 -0000 1.441 +++ buildnotes_api_tools.html 6 Apr 2009 21:17:05 -0000 @@ -14,6 +14,7 @@

%date%

Problem Reports Fixed

+Bug 271110: "The minor version should be incremented" stays on MANIFEST.MF after removing all problems
Bug 233883: [api tooling] Reports wrong error on correct @since 3.4 tag
Bug 270992: Unable to add EE descriptions from repository
Bug 270857: unused import in manifest
#P org.eclipse.pde.api.tools.tests Index: src/org/eclipse/pde/api/tools/builder/tests/tags/TagTest.java =================================================================== RCS file: /cvsroot/eclipse/pde/apitools/org.eclipse.pde.api.tools.tests/src/org/eclipse/pde/api/tools/builder/tests/tags/TagTest.java,v retrieving revision 1.8 diff -u -r1.8 TagTest.java --- src/org/eclipse/pde/api/tools/builder/tests/tags/TagTest.java 27 Feb 2009 19:20:43 -0000 1.8 +++ src/org/eclipse/pde/api/tools/builder/tests/tags/TagTest.java 6 Apr 2009 21:17:07 -0000 @@ -18,6 +18,8 @@ import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.tests.junit.extension.TestCase; import org.eclipse.pde.api.tools.builder.tests.ApiBuilderTest; import org.eclipse.pde.api.tools.builder.tests.ApiTestingEnvironment; @@ -195,4 +197,40 @@ protected String getTestingProjectName() { return "tagtest"; } + + /** + * Deploys a full build test for API Javadoc tags using the given source file in the specified package, + * looking for problems specified from {@link #getExpectedProblemIds()()} + * @param packagename + * @param sourcename + * @param expectingproblems + * @param buildtype the type of build to perform. One of: + *
    + *
  1. IncrementalProjectBuilder#FULL_BUILD
  2. + *
  3. IncrementalProjectBuilder#INCREMENTAL_BUILD
  4. + *
  5. IncrementalProjectBuilder#CLEAN_BUILD
  6. + *
+ * @param buildworkspace true if the workspace should be built, false if the created project should be built + */ + protected void deployTagTest(String packagename, String sourcename, boolean expectingproblems, int buildtype, boolean buildworkspace) { + try { + IPath path = assertProject(sourcename, packagename); + doBuild(buildtype, (buildworkspace ? null : path)); + expectingNoJDTProblems(); + IJavaProject jproject = getEnv().getJavaProject(path); + IType type = jproject.findType(packagename, sourcename); + assertNotNull("The type "+sourcename+" from package "+packagename+" must exist", type); + IPath sourcepath = type.getPath(); + if(expectingproblems) { + expectingOnlySpecificProblemsFor(sourcepath, getExpectedProblemIds()); + assertProblems(getEnv().getProblems()); + } + else { + expectingNoProblemsFor(sourcepath); + } + } + catch(Exception e) { + fail(e.getMessage()); + } + } } Index: src/org/eclipse/pde/api/tools/builder/tests/ApiBuilderTest.java =================================================================== RCS file: /cvsroot/eclipse/pde/apitools/org.eclipse.pde.api.tools.tests/src/org/eclipse/pde/api/tools/builder/tests/ApiBuilderTest.java,v retrieving revision 1.27 diff -u -r1.27 ApiBuilderTest.java --- src/org/eclipse/pde/api/tools/builder/tests/ApiBuilderTest.java 24 Mar 2009 21:14:12 -0000 1.27 +++ src/org/eclipse/pde/api/tools/builder/tests/ApiBuilderTest.java 6 Apr 2009 21:17:07 -0000 @@ -412,83 +412,6 @@ } /** - * Deploys a standard API usage test with the test project being created and the given source is imported in the testing project - * into the given project. - * - * This method assumes that the reference and testing project have been imported into the workspace already. - * - * @param packagename - * @param sourcename - * @param expectingproblems - * @param buildtype the type of build to perform. One of: - *
    - *
  1. IncrementalProjectBuilder#FULL_BUILD
  2. - *
  3. IncrementalProjectBuilder#INCREMENTAL_BUILD
  4. - *
  5. IncrementalProjectBuilder#CLEAN_BUILD
  6. - *
- * @param buildworkspace - */ - protected void deployUsageTest(String packagename, String sourcename, boolean expectingproblems, int buildtype, boolean buildworkspace) { - try { - IProject project = getEnv().getProject(getTestingProjectName()); - assertNotNull("the testing project "+getTestingProjectName()+" must be in the workspace", project); - assertSource(project, packagename, sourcename); - doBuild(buildtype, (buildworkspace ? null : project.getFullPath())); - expectingNoJDTProblems(); - IJavaProject jproject = getEnv().getJavaProject(getTestingProjectName()); - IType type = jproject.findType(packagename, sourcename); - assertNotNull("The type "+sourcename+" from package "+packagename+" must exist", type); - IPath sourcepath = type.getPath(); - if(expectingproblems) { - expectingOnlySpecificProblemsFor(sourcepath, getExpectedProblemIds()); - assertProblems(getEnv().getProblems()); - } - else { - expectingNoProblemsFor(sourcepath); - } - } - catch(Exception e) { - fail(e.getMessage()); - } - } - - /** - * Deploys a full build test for API Javadoc tags using the given source file in the specified package, - * looking for problems specified from {@link #getExpectedProblemIds()()} - * @param packagename - * @param sourcename - * @param expectingproblems - * @param buildtype the type of build to perform. One of: - *
    - *
  1. IncrementalProjectBuilder#FULL_BUILD
  2. - *
  3. IncrementalProjectBuilder#INCREMENTAL_BUILD
  4. - *
  5. IncrementalProjectBuilder#CLEAN_BUILD
  6. - *
- * @param buildworkspace true if the workspace should be built, false if the created project should be built - */ - protected void deployTagTest(String packagename, String sourcename, boolean expectingproblems, int buildtype, boolean buildworkspace) { - try { - IPath path = assertProject(sourcename, packagename); - doBuild(buildtype, (buildworkspace ? null : path)); - expectingNoJDTProblems(); - IJavaProject jproject = getEnv().getJavaProject(path); - IType type = jproject.findType(packagename, sourcename); - assertNotNull("The type "+sourcename+" from package "+packagename+" must exist", type); - IPath sourcepath = type.getPath(); - if(expectingproblems) { - expectingOnlySpecificProblemsFor(sourcepath, getExpectedProblemIds()); - assertProblems(getEnv().getProblems()); - } - else { - expectingNoProblemsFor(sourcepath); - } - } - catch(Exception e) { - fail(e.getMessage()); - } - } - - /** * Sets up the project for a given test using the specified source. * The listing of source names and package names must be equal in size, as each source name will be * placed in the the corresponding package listed in packagenames Index: src/org/eclipse/pde/api/tools/builder/tests/usage/UsageTest.java =================================================================== RCS file: /cvsroot/eclipse/pde/apitools/org.eclipse.pde.api.tools.tests/src/org/eclipse/pde/api/tools/builder/tests/usage/UsageTest.java,v retrieving revision 1.9 diff -u -r1.9 UsageTest.java --- src/org/eclipse/pde/api/tools/builder/tests/usage/UsageTest.java 24 Mar 2009 21:14:12 -0000 1.9 +++ src/org/eclipse/pde/api/tools/builder/tests/usage/UsageTest.java 6 Apr 2009 21:17:07 -0000 @@ -21,6 +21,8 @@ import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.tests.junit.extension.TestCase; import org.eclipse.pde.api.tools.builder.tests.ApiBuilderTest; import org.eclipse.pde.api.tools.model.tests.TestSuiteHelper; @@ -172,6 +174,47 @@ } /** + * Deploys a standard API usage test with the test project being created and the given source is imported in the testing project + * into the given project. + * + * This method assumes that the reference and testing project have been imported into the workspace already. + * + * @param packagename + * @param sourcename + * @param expectingproblems + * @param buildtype the type of build to perform. One of: + *
    + *
  1. IncrementalProjectBuilder#FULL_BUILD
  2. + *
  3. IncrementalProjectBuilder#INCREMENTAL_BUILD
  4. + *
  5. IncrementalProjectBuilder#CLEAN_BUILD
  6. + *
+ * @param buildworkspace + */ + protected void deployUsageTest(String packagename, String sourcename, boolean expectingproblems, int buildtype, boolean buildworkspace) { + try { + IProject project = getEnv().getProject(getTestingProjectName()); + assertNotNull("the testing project "+getTestingProjectName()+" must be in the workspace", project); + assertSource(project, packagename, sourcename); + doBuild(buildtype, (buildworkspace ? null : project.getFullPath())); + expectingNoJDTProblems(); + IJavaProject jproject = getEnv().getJavaProject(getTestingProjectName()); + IType type = jproject.findType(packagename, sourcename); + assertNotNull("The type "+sourcename+" from package "+packagename+" must exist", type); + IPath sourcepath = type.getPath(); + if(expectingproblems) { + expectingOnlySpecificProblemsFor(sourcepath, getExpectedProblemIds()); + assertProblems(getEnv().getProblems()); + } + else { + expectingNoProblemsFor(sourcepath); + } + } + catch(Exception e) { + fail(e.getMessage()); + } + } + + /** * @return all of the child test classes of this class */ private static Class[] getAllTestClasses() { #P org.eclipse.pde.api.tools.ui Index: src/org/eclipse/pde/api/tools/ui/internal/wizards/ProjectUpdateChange.java =================================================================== RCS file: /cvsroot/eclipse/pde/apitools/org.eclipse.pde.api.tools.ui/src/org/eclipse/pde/api/tools/ui/internal/wizards/ProjectUpdateChange.java,v retrieving revision 1.3 diff -u -r1.3 ProjectUpdateChange.java --- src/org/eclipse/pde/api/tools/ui/internal/wizards/ProjectUpdateChange.java 24 Mar 2009 18:50:45 -0000 1.3 +++ src/org/eclipse/pde/api/tools/ui/internal/wizards/ProjectUpdateChange.java 6 Apr 2009 21:17:08 -0000 @@ -23,7 +23,7 @@ import org.eclipse.ltk.core.refactoring.Change; import org.eclipse.ltk.core.refactoring.RefactoringStatus; import org.eclipse.pde.api.tools.internal.ApiDescriptionManager; -import org.eclipse.pde.api.tools.internal.builder.ApiAnalysisBuilder; +import org.eclipse.pde.api.tools.internal.builder.BuildState; import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin; import org.eclipse.pde.api.tools.internal.util.Util; import org.eclipse.pde.api.tools.ui.internal.IApiToolsConstants; @@ -101,7 +101,7 @@ * If autobuild is off, clear the last build state to force a full build of * this project on the next build. */ - ApiAnalysisBuilder.setLastBuiltState(this.fProject, null); + BuildState.setLastBuiltState(this.fProject, null); } if(!pm.isCanceled()) { pm.worked(1);