View | Details | Raw Unified | Return to bug 233643 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/pde/api/tools/internal/builder/IncrementalApiBuilder.java (-27 / +13 lines)
Lines 31-37 Link Here
31
import org.eclipse.jdt.core.IType;
31
import org.eclipse.jdt.core.IType;
32
import org.eclipse.jdt.core.JavaCore;
32
import org.eclipse.jdt.core.JavaCore;
33
import org.eclipse.jdt.core.JavaModelException;
33
import org.eclipse.jdt.core.JavaModelException;
34
import org.eclipse.jdt.internal.core.JavaModelManager;
35
import org.eclipse.jdt.internal.core.builder.ReferenceCollection;
34
import org.eclipse.jdt.internal.core.builder.ReferenceCollection;
36
import org.eclipse.jdt.internal.core.builder.State;
35
import org.eclipse.jdt.internal.core.builder.State;
37
import org.eclipse.jdt.internal.core.builder.StringSet;
36
import org.eclipse.jdt.internal.core.builder.StringSet;
Lines 117-136 Link Here
117
	 * Incrementally builds using the {@link org.eclipse.pde.api.tools.internal.provisional.builder.IApiAnalyzer}
116
	 * Incrementally builds using the {@link org.eclipse.pde.api.tools.internal.provisional.builder.IApiAnalyzer}
118
	 * from the given {@link ApiAnalysisBuilder}
117
	 * from the given {@link ApiAnalysisBuilder}
119
	 * 
118
	 * 
120
	 * @param baseline
119
	 * @param baseline the baseline to compare with
121
	 * @param deltas
120
	 * @param wbaseline the workspace baseline
121
	 * @param deltas the deltas to be built
122
	 * @param state the current JDT build state
123
	 * @param buildstate the current API tools build state
122
	 * @param monitor
124
	 * @param monitor
123
	 * @throws CoreException
125
	 * @throws CoreException
124
	 */
126
	 */
125
	public void build(IApiBaseline baseline, IResourceDelta[] deltas, BuildState buildstate, IProgressMonitor monitor) throws CoreException {
127
	public void build(IApiBaseline baseline, IApiBaseline wbaseline, IResourceDelta[] deltas, State state, BuildState buildstate, IProgressMonitor monitor) throws CoreException {
126
		IProject project = this.builder.getProject();
128
		IProject project = this.builder.getProject();
127
		SubMonitor localmonitor = SubMonitor.convert(monitor, NLS.bind(BuilderMessages.IncrementalBuilder_builder_for_project, project.getName()), 10);
129
		SubMonitor localmonitor = SubMonitor.convert(monitor, NLS.bind(BuilderMessages.IncrementalBuilder_builder_for_project, project.getName()), 10);
128
		try {
130
		try {
129
			State state = (State)JavaModelManager.getJavaModelManager().getLastBuiltState(project, localmonitor.newChild(1));
130
			if(state == null) {
131
				this.builder.buildAll(baseline, localmonitor);
132
				return;
133
			}
134
			String[] projectNames = buildstate.getReexportedComponents();
131
			String[] projectNames = buildstate.getReexportedComponents();
135
			HashSet depprojects = null;
132
			HashSet depprojects = null;
136
			if (projectNames.length != 0) {
133
			if (projectNames.length != 0) {
Lines 151-157 Link Here
151
			for (int i = 0; i < deltas.length; i++) {
148
			for (int i = 0; i < deltas.length; i++) {
152
				deltas[i].accept(visitor);
149
				deltas[i].accept(visitor);
153
			}
150
			}
154
			build(project, state, baseline, buildstate, localmonitor.newChild(1));
151
			build(project, baseline, wbaseline, state, buildstate, localmonitor.newChild(1));
155
		}
152
		}
156
		finally {
153
		finally {
157
			if(!localmonitor.isCanceled()) {
154
			if(!localmonitor.isCanceled()) {
Lines 167-181 Link Here
167
	/**
164
	/**
168
	 * Builds an API delta using the default profile (from the workspace settings and the current
165
	 * Builds an API delta using the default profile (from the workspace settings and the current
169
	 * @param project
166
	 * @param project
170
	 * workspace profile
167
	 * @param baseline the baseline to compare to
171
	 * @param state
168
	 * @param wbaseline the current workspace baseline
169
	 * @param state the current JDT build state
170
	 * @param buildstate the current API tools build state
172
	 * @param monitor
171
	 * @param monitor
173
	 */
172
	 */
174
	void build(final IProject project, final State state, IApiBaseline baseline, BuildState buildstate, IProgressMonitor monitor) throws CoreException {
173
	void build(final IProject project, IApiBaseline baseline, IApiBaseline wbaseline, final State state, BuildState buildstate, IProgressMonitor monitor) throws CoreException {
175
		IApiBaseline wsprofile = null;
176
		try {
174
		try {
177
			// clear the old state so a full build will occur if this one is cancelled or terminates prematurely
178
			this.builder.clearLastState();
179
			SubMonitor localmonitor = SubMonitor.convert(monitor, BuilderMessages.api_analysis_on_0, 1);
175
			SubMonitor localmonitor = SubMonitor.convert(monitor, BuilderMessages.api_analysis_on_0, 1);
180
			collectAffectedSourceFiles(project, state, this.changedtypes);
176
			collectAffectedSourceFiles(project, state, this.changedtypes);
181
			int typesize = this.changedtypes.size();
177
			int typesize = this.changedtypes.size();
Lines 186-200 Link Here
186
			if (typesize != 0) {
182
			if (typesize != 0) {
187
				IPluginModelBase currentModel = this.builder.getCurrentModel();
183
				IPluginModelBase currentModel = this.builder.getCurrentModel();
188
				if (currentModel != null) {
184
				if (currentModel != null) {
189
					wsprofile = this.builder.getWorkspaceProfile();
190
					if (wsprofile == null) {
191
						if (ApiAnalysisBuilder.DEBUG) {
192
							System.err.println("Could not retrieve a workspace profile"); //$NON-NLS-1$
193
						}
194
						return;
195
					}
196
					String id = currentModel.getBundleDescription().getSymbolicName();
185
					String id = currentModel.getBundleDescription().getSymbolicName();
197
					IApiComponent comp = wsprofile.getApiComponent(id);
186
					IApiComponent comp = wbaseline.getApiComponent(id);
198
					if(comp == null) {
187
					if(comp == null) {
199
						return;
188
						return;
200
					}
189
					}
Lines 217-225 Link Here
217
			}
206
			}
218
		}
207
		}
219
		finally {
208
		finally {
220
			if(wsprofile != null) {
221
				wsprofile.close();
222
			}
223
			if(monitor != null) {
209
			if(monitor != null) {
224
				monitor.done();
210
				monitor.done();
225
			}
211
			}
(-)src/org/eclipse/pde/api/tools/internal/builder/BaseApiAnalyzer.java (-1 / +1 lines)
Lines 488-494 Link Here
488
			return new BuildState();
488
			return new BuildState();
489
		}
489
		}
490
		try {
490
		try {
491
			BuildState state = ApiAnalysisBuilder.getLastBuiltState(project);
491
			BuildState state = BuildState.getLastBuiltState(project);
492
			if(state != null) {
492
			if(state != null) {
493
				return state;
493
				return state;
494
			}
494
			}
(-)src/org/eclipse/pde/api/tools/internal/builder/BuildState.java (-11 / +216 lines)
Lines 10-17 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.pde.api.tools.internal.builder;
11
package org.eclipse.pde.api.tools.internal.builder;
12
12
13
import java.io.BufferedInputStream;
14
import java.io.BufferedOutputStream;
13
import java.io.DataInputStream;
15
import java.io.DataInputStream;
14
import java.io.DataOutputStream;
16
import java.io.DataOutputStream;
17
import java.io.File;
18
import java.io.FileInputStream;
19
import java.io.FileOutputStream;
15
import java.io.IOException;
20
import java.io.IOException;
16
import java.util.ArrayList;
21
import java.util.ArrayList;
17
import java.util.Collection;
22
import java.util.Collection;
Lines 22-33 Link Here
22
import java.util.Map;
27
import java.util.Map;
23
import java.util.Set;
28
import java.util.Set;
24
29
30
import org.eclipse.core.resources.IProject;
25
import org.eclipse.core.runtime.CoreException;
31
import org.eclipse.core.runtime.CoreException;
32
import org.eclipse.core.runtime.IPath;
33
import org.eclipse.core.runtime.IStatus;
34
import org.eclipse.core.runtime.Platform;
35
import org.eclipse.core.runtime.Status;
36
import org.eclipse.jdt.core.JavaCore;
37
import org.eclipse.osgi.util.NLS;
26
import org.eclipse.pde.api.tools.internal.comparator.Delta;
38
import org.eclipse.pde.api.tools.internal.comparator.Delta;
27
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
39
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
28
import org.eclipse.pde.api.tools.internal.provisional.comparator.IDelta;
40
import org.eclipse.pde.api.tools.internal.provisional.comparator.IDelta;
29
import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent;
41
import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent;
42
import org.eclipse.pde.api.tools.internal.util.Util;
30
43
44
/**
45
 * The API tools build state
46
 * 
47
 * @since 1.0.1
48
 */
31
public class BuildState {
49
public class BuildState {
32
	private static final IDelta[] EMPTY_DELTAS = new IDelta[0];
50
	private static final IDelta[] EMPTY_DELTAS = new IDelta[0];
33
	private static final String[] NO_REEXPORTED_COMPONENTS = new String[0];
51
	private static final String[] NO_REEXPORTED_COMPONENTS = new String[0];
Lines 38-50 Link Here
38
	private String[] reexportedComponents;
56
	private String[] reexportedComponents;
39
	private Set apiToolingDependentProjects;
57
	private Set apiToolingDependentProjects;
40
	
58
	
41
	public static BuildState read(DataInputStream in) throws IOException {
59
	/**
60
	 * Constructor
61
	 */
62
	BuildState() {
63
		this.compatibleChanges = new HashMap();
64
		this.breakingChanges = new HashMap();
65
	}
66
	
67
	/**
68
	 * Reads the build state from an input stream
69
	 * @param in
70
	 * @return the {@link BuildState} from the given input stream
71
	 * @throws IOException
72
	 */
73
	 public static BuildState read(DataInputStream in) throws IOException {
42
		String pluginID= in.readUTF();
74
		String pluginID= in.readUTF();
43
		if (!pluginID.equals(ApiPlugin.PLUGIN_ID))
75
		if (!pluginID.equals(ApiPlugin.PLUGIN_ID)) {
44
			throw new IOException(BuilderMessages.build_wrongFileFormat); 
76
			throw new IOException(BuilderMessages.build_wrongFileFormat);
77
		}
45
		String kind= in.readUTF();
78
		String kind= in.readUTF();
46
		if (!kind.equals("STATE")) //$NON-NLS-1$
79
		if (!kind.equals("STATE")) {//$NON-NLS-1$
47
			throw new IOException(BuilderMessages.build_wrongFileFormat); 
80
			throw new IOException(BuilderMessages.build_wrongFileFormat);
81
		}
48
		if (in.readInt() != VERSION) {
82
		if (in.readInt() != VERSION) {
49
			// this is an old build state - a full build is required
83
			// this is an old build state - a full build is required
50
			return null;
84
			return null;
Lines 77-82 Link Here
77
		}
111
		}
78
		return null;
112
		return null;
79
	}
113
	}
114
	 
115
	/**
116
	 * Writes the given {@link BuildState} to the given output stream
117
	 * @param state
118
	 * @param out
119
	 * @throws IOException
120
	 */
80
	public static void write(BuildState state, DataOutputStream out) throws IOException {
121
	public static void write(BuildState state, DataOutputStream out) throws IOException {
81
		out.writeUTF(ApiPlugin.PLUGIN_ID);
122
		out.writeUTF(ApiPlugin.PLUGIN_ID);
82
		out.writeUTF("STATE"); //$NON-NLS-1$
123
		out.writeUTF("STATE"); //$NON-NLS-1$
Lines 107-112 Link Here
107
			out.writeUTF((String) iterator.next());
148
			out.writeUTF((String) iterator.next());
108
		}
149
		}
109
	}
150
	}
151
	
152
	/**
153
	 * Read the {@link IDelta} from the build state (input stream)
154
	 * @param in the input stream to read the {@link IDelta} from
155
	 * @return a reconstructed {@link IDelta} from the build state
156
	 * @throws IOException
157
	 */
110
	private static IDelta readDelta(DataInputStream in) throws IOException {
158
	private static IDelta readDelta(DataInputStream in) throws IOException {
111
		// decode the delta from the build state
159
		// decode the delta from the build state
112
		boolean hasComponentID = in.readBoolean();
160
		boolean hasComponentID = in.readBoolean();
Lines 136-141 Link Here
136
		int newModifiers = modifiers >>> Delta.NEW_MODIFIERS_OFFSET;
184
		int newModifiers = modifiers >>> Delta.NEW_MODIFIERS_OFFSET;
137
		return new Delta(componentID, elementType, kind, flags, restrictions, oldModifiers, newModifiers, typeName, key, datas);
185
		return new Delta(componentID, elementType, kind, flags, restrictions, oldModifiers, newModifiers, typeName, key, datas);
138
	}
186
	}
187
	
188
	/**
189
	 * Writes a given {@link IDelta} to the build state (the output stream)
190
	 * @param delta the delta to write
191
	 * @param out the stream to write to
192
	 * @throws IOException
193
	 */
139
	private static void writeDelta(IDelta delta, DataOutputStream out) throws IOException {
194
	private static void writeDelta(IDelta delta, DataOutputStream out) throws IOException {
140
		// encode a delta into the build state
195
		// encode a delta into the build state
141
		// int elementType, int kind, int flags, int restrictions, int modifiers, String typeName, String key, Object data
196
		// int elementType, int kind, int flags, int restrictions, int modifiers, String typeName, String key, Object data
Lines 161-170 Link Here
161
		}
216
		}
162
	}
217
	}
163
218
164
	BuildState() {
219
	/**
165
		this.compatibleChanges = new HashMap();
220
	 * Adds an {@link IDelta} for a compatible compatibility change to the current state
166
		this.breakingChanges = new HashMap();
221
	 * 
167
	}
222
	 * @param delta the {@link IDelta} to add to the state
223
	 */
168
	public void addCompatibleChange(IDelta delta) {
224
	public void addCompatibleChange(IDelta delta) {
169
		String typeName = delta.getTypeName();
225
		String typeName = delta.getTypeName();
170
		Set object = (Set) this.compatibleChanges.get(typeName);
226
		Set object = (Set) this.compatibleChanges.get(typeName);
Lines 177-182 Link Here
177
		}
233
		}
178
	}
234
	}
179
235
236
	/**
237
	 * Add an {@link IDelta} for an incompatible compatibility change to the current state
238
	 * 
239
	 * @param delta the {@link IDelta} to add to the state
240
	 */
180
	public void addBreakingChange(IDelta delta) {
241
	public void addBreakingChange(IDelta delta) {
181
		String typeName = delta.getTypeName();
242
		String typeName = delta.getTypeName();
182
		Set object = (Set) this.breakingChanges.get(typeName);
243
		Set object = (Set) this.breakingChanges.get(typeName);
Lines 221-232 Link Here
221
		return (IDelta[]) collector.toArray(new IDelta[collector.size()]);
282
		return (IDelta[]) collector.toArray(new IDelta[collector.size()]);
222
	}
283
	}
223
284
285
	/**
286
	 * @return the complete list of re-exported {@link IApiComponent}s
287
	 */
224
	public String[] getReexportedComponents() {
288
	public String[] getReexportedComponents() {
225
		if (this.reexportedComponents == null) {
289
		if (this.reexportedComponents == null) {
226
			return NO_REEXPORTED_COMPONENTS;
290
			return NO_REEXPORTED_COMPONENTS;
227
		}
291
		}
228
		return this.reexportedComponents;
292
		return this.reexportedComponents;
229
	}
293
	}
294
	
230
	/**
295
	/**
231
	 * Remove all entries for the given type name.
296
	 * Remove all entries for the given type name.
232
	 *
297
	 *
Lines 235-245 Link Here
235
	public void cleanup(String typeName) {
300
	public void cleanup(String typeName) {
236
		this.breakingChanges.remove(typeName);
301
		this.breakingChanges.remove(typeName);
237
		this.compatibleChanges.remove(typeName);
302
		this.compatibleChanges.remove(typeName);
238
		this.reexportedComponents = null;;
303
		this.reexportedComponents = null;
239
	}
304
	}
240
305
306
	/**
307
	 * Sets the current list if re-exported {@link IApiComponent}s for this build state
308
	 * @param components
309
	 */
241
	public void setReexportedComponents(IApiComponent[] components) {
310
	public void setReexportedComponents(IApiComponent[] components) {
242
		if (components == null) return;
311
		if (components == null) {
312
			return;
313
		}
243
		try {
314
		try {
244
			if (this.reexportedComponents == null) {
315
			if (this.reexportedComponents == null) {
245
				final int length = components.length;
316
				final int length = components.length;
Lines 254-259 Link Here
254
		}
325
		}
255
	}
326
	}
256
327
328
	/**
329
	 * Adds a dependent project to the listing of dependent projects
330
	 * @param projectName
331
	 */
257
	public void addApiToolingDependentProject(String projectName) {
332
	public void addApiToolingDependentProject(String projectName) {
258
		if (this.apiToolingDependentProjects == null) {
333
		if (this.apiToolingDependentProjects == null) {
259
			this.apiToolingDependentProjects = new HashSet(3);
334
			this.apiToolingDependentProjects = new HashSet(3);
Lines 261-267 Link Here
261
		this.apiToolingDependentProjects.add(projectName);
336
		this.apiToolingDependentProjects.add(projectName);
262
	}
337
	}
263
	
338
	
339
	/**
340
	 * @return the complete listing of dependent projects
341
	 */
264
	public Set getApiToolingDependentProjects() {
342
	public Set getApiToolingDependentProjects() {
265
		return this.apiToolingDependentProjects == null ? Collections.EMPTY_SET : this.apiToolingDependentProjects;
343
		return this.apiToolingDependentProjects == null ? Collections.EMPTY_SET : this.apiToolingDependentProjects;
266
	}
344
	}
345
	/**
346
	 * Return the last built state for the given project, or null if none
347
	 */
348
	public static BuildState getLastBuiltState(IProject project) throws CoreException {
349
		if (!Util.isApiProject(project)) {
350
			// should never be requested on non-Java projects
351
			return null;
352
		}
353
		return readState(project);
354
	}
355
	
356
	/**
357
	 * Reads the build state for the relevant project.
358
	 * @return the current {@link BuildState} for the given project or <code>null</code> if there is not one
359
	 */
360
	static BuildState readState(IProject project) throws CoreException {
361
		File file = getSerializationFile(project);
362
		if (file != null && file.exists()) {
363
			try {
364
				DataInputStream in= new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
365
				try {
366
					return read(in);
367
				} finally {
368
					if (ApiAnalysisBuilder.DEBUG) {
369
						System.out.println("Saved state thinks last build failed for " + project.getName()); //$NON-NLS-1$
370
					}
371
					in.close();
372
				}
373
			} catch (Exception e) {
374
				e.printStackTrace();
375
				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$
376
			}
377
		} else if (ApiAnalysisBuilder.DEBUG) {
378
			if (file == null) {
379
				System.out.println("Project does not exist: " + project); //$NON-NLS-1$
380
			} else {
381
				System.out.println("Build state file " + file.getPath() + " does not exist"); //$NON-NLS-1$ //$NON-NLS-2$
382
			}
383
		}
384
		return null;
385
	}
386
	
387
	/**
388
	 * Sets the last built state for the given project, or null to reset it.
389
	 * 
390
	 * @param project the project to set a state for
391
	 * @param state the {@link BuildState} to set as the last state
392
	 */
393
	public static void setLastBuiltState(IProject project, BuildState state) throws CoreException {
394
		if (Util.isApiProject(project)) {
395
			// should never be requested on non-Java projects
396
			if (state != null) {
397
				saveBuiltState(project, state);
398
			} else {
399
				try {
400
					File file = getSerializationFile(project);
401
					if (file != null && file.exists()) {
402
						file.delete();
403
					}
404
				} catch(SecurityException se) {
405
					// could not delete file: cannot do much more
406
				}
407
			}
408
		}
409
	}
410
	
411
	/**
412
	 * Returns the {@link File} to use for saving and restoring the last built state for the given project.
413
	 * 
414
	 * @param project gets the saved state file for the given project
415
	 * @return the {@link File} to use for saving and restoring the last built state for the given project.
416
	 */
417
	static File getSerializationFile(IProject project) {
418
		if (!project.exists()) {
419
			return null;
420
		}
421
		IPath workingLocation = project.getWorkingLocation(ApiPlugin.PLUGIN_ID);
422
		return workingLocation.append("state.dat").toFile(); //$NON-NLS-1$
423
	}
424
	
425
	/**
426
	 * Saves the current build state
427
	 * @param project
428
	 * @param state
429
	 * @throws CoreException
430
	 */
431
	static void saveBuiltState(IProject project, BuildState state) throws CoreException {
432
		if (ApiAnalysisBuilder.DEBUG) {
433
			System.out.println("Saving build state for project: "+project.getName()); //$NON-NLS-1$
434
		}
435
		File file = BuildState.getSerializationFile(project);
436
		if (file == null) return;
437
		long t = 0;
438
		if (ApiAnalysisBuilder.DEBUG) {
439
			t = System.currentTimeMillis();
440
		}
441
		try {
442
			DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
443
			try {
444
				write(state, out);
445
			} finally {
446
				out.close();
447
			}
448
		} catch (RuntimeException e) {
449
			try {
450
				file.delete();
451
			} catch(SecurityException se) {
452
				// could not delete file: cannot do much more
453
			}
454
			throw new CoreException(
455
				new Status(IStatus.ERROR, ApiPlugin.PLUGIN_ID, Platform.PLUGIN_ERROR,
456
					NLS.bind(BuilderMessages.build_cannotSaveState, project.getName()), e)); 
457
		} catch (IOException e) {
458
			try {
459
				file.delete();
460
			} catch(SecurityException se) {
461
				// could not delete file: cannot do much more
462
			}
463
			throw new CoreException(
464
				new Status(IStatus.ERROR, ApiPlugin.PLUGIN_ID, Platform.PLUGIN_ERROR,
465
					NLS.bind(BuilderMessages.build_cannotSaveState, project.getName()), e)); 
466
		}
467
		if (ApiAnalysisBuilder.DEBUG) {
468
			t = System.currentTimeMillis() - t;
469
			System.out.println(NLS.bind(BuilderMessages.build_saveStateComplete, String.valueOf(t))); 
470
		}
471
	}
267
}
472
}
(-)src/org/eclipse/pde/api/tools/internal/builder/ApiAnalysisBuilder.java (-201 / +73 lines)
Lines 10-23 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.pde.api.tools.internal.builder;
11
package org.eclipse.pde.api.tools.internal.builder;
12
12
13
import java.io.BufferedInputStream;
14
import java.io.BufferedOutputStream;
15
import java.io.DataInputStream;
16
import java.io.DataOutputStream;
17
import java.io.File;
18
import java.io.FileInputStream;
19
import java.io.FileOutputStream;
20
import java.io.IOException;
21
import java.util.ArrayList;
13
import java.util.ArrayList;
22
import java.util.Date;
14
import java.util.Date;
23
import java.util.HashMap;
15
import java.util.HashMap;
Lines 39-52 Link Here
39
import org.eclipse.core.runtime.IStatus;
31
import org.eclipse.core.runtime.IStatus;
40
import org.eclipse.core.runtime.OperationCanceledException;
32
import org.eclipse.core.runtime.OperationCanceledException;
41
import org.eclipse.core.runtime.Path;
33
import org.eclipse.core.runtime.Path;
42
import org.eclipse.core.runtime.Platform;
43
import org.eclipse.core.runtime.Status;
44
import org.eclipse.core.runtime.SubMonitor;
34
import org.eclipse.core.runtime.SubMonitor;
45
import org.eclipse.jdt.core.IClasspathAttribute;
35
import org.eclipse.jdt.core.IClasspathAttribute;
46
import org.eclipse.jdt.core.IClasspathEntry;
36
import org.eclipse.jdt.core.IClasspathEntry;
47
import org.eclipse.jdt.core.IJavaProject;
37
import org.eclipse.jdt.core.IJavaProject;
48
import org.eclipse.jdt.core.JavaCore;
38
import org.eclipse.jdt.core.JavaCore;
49
import org.eclipse.jdt.core.JavaModelException;
39
import org.eclipse.jdt.core.JavaModelException;
40
import org.eclipse.jdt.internal.core.JavaModelManager;
41
import org.eclipse.jdt.internal.core.builder.State;
50
import org.eclipse.osgi.service.resolver.BundleDescription;
42
import org.eclipse.osgi.service.resolver.BundleDescription;
51
import org.eclipse.osgi.util.NLS;
43
import org.eclipse.osgi.util.NLS;
52
import org.eclipse.pde.api.tools.internal.ApiDescriptionManager;
44
import org.eclipse.pde.api.tools.internal.ApiDescriptionManager;
Lines 214-264 Link Here
214
		SubMonitor localMonitor = SubMonitor.convert(monitor, BuilderMessages.api_analysis_builder, 2);
206
		SubMonitor localMonitor = SubMonitor.convert(monitor, BuilderMessages.api_analysis_builder, 2);
215
		final IProject[] projects = getRequiredProjects(true);
207
		final IProject[] projects = getRequiredProjects(true);
216
		IApiBaseline baseline = ApiPlugin.getDefault().getApiBaselineManager().getDefaultApiBaseline();
208
		IApiBaseline baseline = ApiPlugin.getDefault().getApiBaselineManager().getDefaultApiBaseline();
209
		IApiBaseline wbaseline = ApiPlugin.getDefault().getApiBaselineManager().getWorkspaceBaseline();
210
		if (wbaseline == null) {
211
			if (DEBUG) {
212
				System.err.println("Could not retrieve a workspace profile"); //$NON-NLS-1$
213
			}
214
			return NO_PROJECTS;
215
		}
217
		try {
216
		try {
218
			switch(kind) {
217
			switch(kind) {
219
				case FULL_BUILD : {
218
				case FULL_BUILD : {
220
					if (DEBUG) {
219
					if (DEBUG) {
221
						System.out.println("Performing full build as requested by user"); //$NON-NLS-1$
220
						System.out.println("Performing full build as requested by user"); //$NON-NLS-1$
222
					}
221
					}
223
					buildAll(baseline, localMonitor.newChild(1));
222
					buildAll(baseline, wbaseline, localMonitor.newChild(1));
224
					break;
223
					break;
225
				}
224
				}
226
				case AUTO_BUILD :
225
				case AUTO_BUILD :
227
				case INCREMENTAL_BUILD : {
226
				case INCREMENTAL_BUILD : {
228
					this.buildstate = getLastBuiltState(currentproject);
227
					this.buildstate = BuildState.getLastBuiltState(currentproject);
229
					if (this.buildstate == null) {
228
					if (this.buildstate == null) {
230
						buildAll(baseline, localMonitor.newChild(1));
229
						buildAll(baseline, wbaseline, localMonitor.newChild(1));
231
						break;
230
						break;
232
					}
231
					}
233
					else if(worthDoingFullBuild(projects)) {
232
					else if(worthDoingFullBuild(projects)) {
234
						buildAll(baseline, localMonitor.newChild(1));
233
						buildAll(baseline, wbaseline, localMonitor.newChild(1));
235
					}
234
						break;
236
					IResourceDelta[] deltas = getDeltas(projects);
237
					if(deltas.length < 1) {
238
						buildAll(baseline, localMonitor.newChild(1));
239
					}
235
					}
240
					else {	
236
					else {
241
						IResourceDelta manifest = null;
237
						IResourceDelta[] deltas = getDeltas(projects);
242
						IResourceDelta filters = null;
238
						if(deltas.length < 1) {
243
						for (int i = 0; i < deltas.length; i++) {
239
							buildAll(baseline, wbaseline, localMonitor.newChild(1));
244
							manifest = deltas[i].findMember(MANIFEST_PATH);
240
						}
245
							if(manifest != null) {
241
						else {	
246
								break;
242
							IResourceDelta manifest = null;
243
							IResourceDelta filters = null;
244
							for (int i = 0; i < deltas.length; i++) {
245
								manifest = deltas[i].findMember(MANIFEST_PATH);
246
								if(manifest != null) {
247
									break;
248
								}
249
								filters = deltas[i].findMember(FILTER_PATH);
250
								if(filters != null){
251
									break;
252
								}
247
							}
253
							}
248
							filters = deltas[i].findMember(FILTER_PATH);
254
							if (manifest != null || filters != null) {
249
							if(filters != null){
255
								if (DEBUG) {
250
								break;
256
									System.out.println("Performing full build since MANIFEST.MF or .api_filters was modified"); //$NON-NLS-1$
257
		 						}
258
								buildAll(baseline, wbaseline, localMonitor.newChild(1));
259
							}
260
							else {
261
								State state = (State)JavaModelManager.getJavaModelManager().getLastBuiltState(this.currentproject, localMonitor.newChild(1));
262
								if(state == null) {
263
									buildAll(baseline, wbaseline, localMonitor.newChild(1));
264
									break;
265
								}
266
								BuildState.setLastBuiltState(this.currentproject, null);
267
								IncrementalApiBuilder builder = new IncrementalApiBuilder(this);
268
								builder.build(baseline, wbaseline, deltas, state, this.buildstate, localMonitor.newChild(1));
251
							}
269
							}
252
						}
253
						if (manifest != null || filters != null) {
254
							if (DEBUG) {
255
								System.out.println("Performing full build since MANIFEST.MF or .api_filters was modified"); //$NON-NLS-1$
256
	 						}
257
							buildAll(baseline, localMonitor.newChild(1));
258
						}
259
						else {
260
							IncrementalApiBuilder builder = new IncrementalApiBuilder(this);
261
							builder.build(baseline, deltas, this.buildstate, localMonitor.newChild(1));
262
						}
270
						}
263
					}
271
					}
264
				}	
272
				}	
Lines 279-284 Link Here
279
			if(baseline != null) {
287
			if(baseline != null) {
280
				baseline.close();
288
				baseline.close();
281
			}
289
			}
290
			wbaseline.close();
282
			if(monitor != null) {
291
			if(monitor != null) {
283
				monitor.done();
292
				monitor.done();
284
			}
293
			}
Lines 289-295 Link Here
289
						this.buildstate.addApiToolingDependentProject(project.getName());
298
						this.buildstate.addApiToolingDependentProject(project.getName());
290
					}
299
					}
291
				}
300
				}
292
				saveBuiltState(this.currentproject, this.buildstate);
301
				BuildState.saveBuiltState(this.currentproject, this.buildstate);
293
				this.buildstate = null;
302
				this.buildstate = null;
294
			}
303
			}
295
		}
304
		}
Lines 299-305 Link Here
299
		return projects;
308
		return projects;
300
	}
309
	}
301
	
310
	
302
	private boolean worthDoingFullBuild(IProject[] projects) {
311
	/**
312
	 * if its worth doing a full build considering the given set if projects
313
	 * @param projects projects to check the build state for
314
	 * @return true if a full build should take place, false otherwise
315
	 */
316
	boolean worthDoingFullBuild(IProject[] projects) {
303
		Set apiToolingDependentProjects = this.buildstate.getApiToolingDependentProjects();
317
		Set apiToolingDependentProjects = this.buildstate.getApiToolingDependentProjects();
304
		for (int i = 0, max = projects.length; i < max; i++) {
318
		for (int i = 0, max = projects.length; i < max; i++) {
305
			IProject currentProject = projects[i];
319
			IProject currentProject = projects[i];
Lines 317-328 Link Here
317
	
331
	
318
	/**
332
	/**
319
	 * Performs a full build for the project
333
	 * Performs a full build for the project
334
	 * @param baseline the default baseline 
335
	 * @param wbaseline the workspace baseline
320
	 * @param monitor
336
	 * @param monitor
321
	 */
337
	 */
322
	void buildAll(IApiBaseline baseline, IProgressMonitor monitor) throws CoreException {
338
	void buildAll(IApiBaseline baseline, IApiBaseline wbaseline, IProgressMonitor monitor) throws CoreException {
323
		IApiBaseline wsprofile = null;
324
		try {
339
		try {
325
			clearLastState();
340
			BuildState.setLastBuiltState(this.currentproject, null);
326
			this.buildstate = new BuildState();
341
			this.buildstate = new BuildState();
327
			SubMonitor localMonitor = SubMonitor.convert(monitor, BuilderMessages.api_analysis_on_0, 4);
342
			SubMonitor localMonitor = SubMonitor.convert(monitor, BuilderMessages.api_analysis_on_0, 4);
328
			localMonitor.subTask(NLS.bind(BuilderMessages.ApiAnalysisBuilder_initializing_analyzer, currentproject.getName()));
343
			localMonitor.subTask(NLS.bind(BuilderMessages.ApiAnalysisBuilder_initializing_analyzer, currentproject.getName()));
Lines 330-346 Link Here
330
			IPluginModelBase currentModel = getCurrentModel();
345
			IPluginModelBase currentModel = getCurrentModel();
331
			if (currentModel != null) {
346
			if (currentModel != null) {
332
				localMonitor.subTask(BuilderMessages.building_workspace_profile);
347
				localMonitor.subTask(BuilderMessages.building_workspace_profile);
333
				wsprofile = getWorkspaceProfile();
334
				updateMonitor(localMonitor, 1);
348
				updateMonitor(localMonitor, 1);
335
				if (wsprofile == null) {
336
					if (DEBUG) {
337
						System.err.println("Could not retrieve a workspace profile"); //$NON-NLS-1$
338
					}
339
					return;
340
				}
341
				String id = currentModel.getBundleDescription().getSymbolicName();
349
				String id = currentModel.getBundleDescription().getSymbolicName();
342
				// Compatibility checks
350
				// Compatibility checks
343
				IApiComponent apiComponent = wsprofile.getApiComponent(id);
351
				IApiComponent apiComponent = wbaseline.getApiComponent(id);
344
				if(apiComponent != null) {
352
				if(apiComponent != null) {
345
					getAnalyzer().analyzeComponent(this.buildstate, null, null, baseline, apiComponent, null, null, localMonitor.newChild(1));
353
					getAnalyzer().analyzeComponent(this.buildstate, null, null, baseline, apiComponent, null, null, localMonitor.newChild(1));
346
					updateMonitor(localMonitor, 1);
354
					updateMonitor(localMonitor, 1);
Lines 350-358 Link Here
350
			}
358
			}
351
		}
359
		}
352
		finally {
360
		finally {
353
			if(wsprofile != null) {
354
				wsprofile.close();
355
			}
356
			if(monitor != null) {
361
			if(monitor != null) {
357
				monitor.done();
362
				monitor.done();
358
			}
363
			}
Lines 393-402 Link Here
393
	/**
398
	/**
394
	 * Returns the {@link IApiMarkerConstants} problem type given the 
399
	 * Returns the {@link IApiMarkerConstants} problem type given the 
395
	 * problem category
400
	 * problem category
396
	 * @param category
401
	 * @param category the problem category - see {@link IApiProblem} for problem categories
402
	 * @param kind the kind of the problem - see {@link IApiProblem} for problem kinds
397
	 * @return the problem type or <code>null</code>
403
	 * @return the problem type or <code>null</code>
398
	 */
404
	 */
399
	private String getProblemTypeFromCategory(int category, int kind) {
405
	String getProblemTypeFromCategory(int category, int kind) {
400
		switch(category) {
406
		switch(category) {
401
			case IApiProblem.CATEGORY_API_COMPONENT_RESOLUTION : {
407
			case IApiProblem.CATEGORY_API_COMPONENT_RESOLUTION : {
402
				return IApiMarkerConstants.API_COMPONENT_RESOLUTION_PROBLEM_MARKER;
408
				return IApiMarkerConstants.API_COMPONENT_RESOLUTION_PROBLEM_MARKER;
Lines 430-438 Link Here
430
	 * Creates an {@link IMarker} on the resource specified
436
	 * Creates an {@link IMarker} on the resource specified
431
	 * in the problem (via its path) with the given problem
437
	 * in the problem (via its path) with the given problem
432
	 * attributes
438
	 * attributes
439
	 * @param category the category of the problem - see {@link IApiProblem} for categories
440
	 * @param type the marker type to create - see {@link IApiMarkerConstants} for types
433
	 * @param problem the problem to create a marker from
441
	 * @param problem the problem to create a marker from
434
	 */
442
	 */
435
	private void createMarkerForProblem(int category, String type, IApiProblem problem) {
443
	void createMarkerForProblem(int category, String type, IApiProblem problem) {
436
		IResource resource = resolveResource(problem);
444
		IResource resource = resolveResource(problem);
437
		if(resource == null) {
445
		if(resource == null) {
438
			return;
446
			return;
Lines 498-504 Link Here
498
	 * @param problem the problem to get the resource for
506
	 * @param problem the problem to get the resource for
499
	 * @return the resource or <code>null</code>
507
	 * @return the resource or <code>null</code>
500
	 */
508
	 */
501
	private IResource resolveResource(IApiProblem problem) {
509
	IResource resolveResource(IApiProblem problem) {
502
		String resourcePath = problem.getResourcePath();
510
		String resourcePath = problem.getResourcePath();
503
		if (resourcePath == null) {
511
		if (resourcePath == null) {
504
			return null;
512
			return null;
Lines 519-525 Link Here
519
	 * @param args
527
	 * @param args
520
	 * @return a single string attribute from an array or arguments
528
	 * @return a single string attribute from an array or arguments
521
	 */
529
	 */
522
	private String createArgAttribute(String[] args) {
530
	String createArgAttribute(String[] args) {
523
		StringBuffer buff = new StringBuffer();
531
		StringBuffer buff = new StringBuffer();
524
		for(int i = 0; i < args.length; i++) {
532
		for(int i = 0; i < args.length; i++) {
525
			buff.append(args[i]);
533
			buff.append(args[i]);
Lines 564-570 Link Here
564
			updateMonitor(localmonitor, 1);
572
			updateMonitor(localmonitor, 1);
565
		}
573
		}
566
		finally {
574
		finally {
567
			clearLastState();
575
			BuildState.setLastBuiltState(this.currentproject, null);
568
			localmonitor.done();
576
			localmonitor.done();
569
		}
577
		}
570
	}
578
	}
Lines 573-579 Link Here
573
	 * Cleans the .api_settings file for the given project
581
	 * Cleans the .api_settings file for the given project
574
	 * @param project
582
	 * @param project
575
	 */
583
	 */
576
	private void cleanupApiDescription(IProject project) {
584
	void cleanupApiDescription(IProject project) {
577
		if(project != null && project.exists()) {
585
		if(project != null && project.exists()) {
578
			ApiDescriptionManager.getDefault().clean(JavaCore.create(project), true, true);
586
			ApiDescriptionManager.getDefault().clean(JavaCore.create(project), true, true);
579
		}
587
		}
Lines 608-614 Link Here
608
	 * @param projects
616
	 * @param projects
609
	 * @return
617
	 * @return
610
	 */
618
	 */
611
	private IResourceDelta[] getDeltas(IProject[] projects) {
619
	IResourceDelta[] getDeltas(IProject[] projects) {
612
		if(DEBUG) {
620
		if(DEBUG) {
613
			System.out.println("Searching for deltas for build of project: "+this.currentproject.getName()); //$NON-NLS-1$
621
			System.out.println("Searching for deltas for build of project: "+this.currentproject.getName()); //$NON-NLS-1$
614
		}
622
		}
Lines 646-655 Link Here
646
	/**
654
	/**
647
	 * Returns the complete listing of required projects from the classpath of the backing project
655
	 * Returns the complete listing of required projects from the classpath of the backing project
648
	 * @param includeBinaryPrerequisites
656
	 * @param includeBinaryPrerequisites
649
	 * @return
657
	 * @return the list of projects required 
650
	 * @throws CoreException
658
	 * @throws CoreException
651
	 */
659
	 */
652
	private IProject[] getRequiredProjects(boolean includebinaries) throws CoreException {
660
	IProject[] getRequiredProjects(boolean includebinaries) throws CoreException {
653
		IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
661
		IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
654
		if (this.currentproject == null || workspaceRoot == null) { 
662
		if (this.currentproject == null || workspaceRoot == null) { 
655
			return new IProject[0];
663
			return new IProject[0];
Lines 719-731 Link Here
719
		projects.toArray(result);
727
		projects.toArray(result);
720
		return result;
728
		return result;
721
	}
729
	}
722
723
	/**
724
	 * @return the workspace {@link IApiProfile}
725
	 */
726
	IApiBaseline getWorkspaceProfile() throws CoreException {
727
		return ApiPlugin.getDefault().getApiBaselineManager().getWorkspaceBaseline();
728
	}
729
	
730
	
730
	/**
731
	/**
731
	 * Returns the output paths of the given project or <code>null</code> if none have been computed
732
	 * Returns the output paths of the given project or <code>null</code> if none have been computed
Lines 741-747 Link Here
741
	 * @param entry
742
	 * @param entry
742
	 * @return true if the specified {@link IClasspathEntry} is optional, false otherwise
743
	 * @return true if the specified {@link IClasspathEntry} is optional, false otherwise
743
	 */
744
	 */
744
	private boolean isOptional(IClasspathEntry entry) {
745
	boolean isOptional(IClasspathEntry entry) {
745
		IClasspathAttribute[] attribs = entry.getExtraAttributes();
746
		IClasspathAttribute[] attribs = entry.getExtraAttributes();
746
		for (int i = 0, length = attribs.length; i < length; i++) {
747
		for (int i = 0, length = attribs.length; i < length; i++) {
747
			IClasspathAttribute attribute = attribs[i];
748
			IClasspathAttribute attribute = attribs[i];
Lines 757-889 Link Here
757
	public String toString() {
758
	public String toString() {
758
		return NLS.bind(BuilderMessages.ApiAnalysisBuilder_builder_for_project, this.currentproject.getName());
759
		return NLS.bind(BuilderMessages.ApiAnalysisBuilder_builder_for_project, this.currentproject.getName());
759
	}
760
	}
760
	
761
	/**
762
	 * Return the last built state for the given project, or null if none
763
	 */
764
	public static BuildState getLastBuiltState(IProject project) throws CoreException {
765
		if (!Util.isApiProject(project)) {
766
			// should never be requested on non-Java projects
767
			return null;
768
		}
769
		return readState(project);
770
	}
771
	
772
	/**
773
	 * Reads the build state for the relevant project.
774
	 */
775
	static BuildState readState(IProject project) throws CoreException {
776
		File file = getSerializationFile(project);
777
		if (file != null && file.exists()) {
778
			try {
779
				DataInputStream in= new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
780
				try {
781
					return BuildState.read(in);
782
				} finally {
783
					if (DEBUG) {
784
						System.out.println("Saved state thinks last build failed for " + project.getName()); //$NON-NLS-1$
785
					}
786
					in.close();
787
				}
788
			} catch (Exception e) {
789
				e.printStackTrace();
790
				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$
791
			}
792
		} else if (DEBUG) {
793
			if (file == null) {
794
				System.out.println("Project does not exist: " + project); //$NON-NLS-1$
795
			} else {
796
				System.out.println("Build state file " + file.getPath() + " does not exist"); //$NON-NLS-1$ //$NON-NLS-2$
797
			}
798
		}
799
		return null;
800
	}
801
802
	/**
803
	 * Sets the last built state for the given project, or null to reset it.
804
	 */
805
	public static void setLastBuiltState(IProject project, BuildState state) throws CoreException {
806
		if (Util.isApiProject(project)) {
807
			// should never be requested on non-Java projects
808
			if (state != null) {
809
				saveBuiltState(project, state);
810
			} else {
811
				try {
812
					File file = getSerializationFile(project);
813
					if (file != null && file.exists()) {
814
						file.delete();
815
					}
816
				} catch(SecurityException se) {
817
					// could not delete file: cannot do much more
818
				}
819
			}
820
		}
821
	}	
822
823
	/**
824
	 * Returns the File to use for saving and restoring the last built state for the given project.
825
	 */
826
	static File getSerializationFile(IProject project) {
827
		if (!project.exists()) {
828
			return null;
829
		}
830
		IPath workingLocation = project.getWorkingLocation(ApiPlugin.PLUGIN_ID);
831
		return workingLocation.append("state.dat").toFile(); //$NON-NLS-1$
832
	}
833
834
	/**
835
	 * Saves the current build state
836
	 * @param project
837
	 * @param state
838
	 * @throws CoreException
839
	 */
840
	static void saveBuiltState(IProject project, BuildState state) throws CoreException {
841
		if (DEBUG) {
842
			System.out.println("Saving build state for project: "+project.getName()); //$NON-NLS-1$
843
		}
844
		File file = getSerializationFile(project);
845
		if (file == null) return;
846
		long t = 0;
847
		if (DEBUG) {
848
			t = System.currentTimeMillis();
849
		}
850
		try {
851
			DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
852
			try {
853
				BuildState.write(state, out);
854
			} finally {
855
				out.close();
856
			}
857
		} catch (RuntimeException e) {
858
			try {
859
				file.delete();
860
			} catch(SecurityException se) {
861
				// could not delete file: cannot do much more
862
			}
863
			throw new CoreException(
864
				new Status(IStatus.ERROR, ApiPlugin.PLUGIN_ID, Platform.PLUGIN_ERROR,
865
					NLS.bind(BuilderMessages.build_cannotSaveState, project.getName()), e)); 
866
		} catch (IOException e) {
867
			try {
868
				file.delete();
869
			} catch(SecurityException se) {
870
				// could not delete file: cannot do much more
871
			}
872
			throw new CoreException(
873
				new Status(IStatus.ERROR, ApiPlugin.PLUGIN_ID, Platform.PLUGIN_ERROR,
874
					NLS.bind(BuilderMessages.build_cannotSaveState, project.getName()), e)); 
875
		}
876
		if (DEBUG) {
877
			t = System.currentTimeMillis() - t;
878
			System.out.println(NLS.bind(BuilderMessages.build_saveStateComplete, String.valueOf(t))); 
879
		}
880
	}
881
882
	/**
883
	 * Clears the last build state by setting it to <code>null</code>
884
	 * @throws CoreException
885
	 */
886
	void clearLastState() throws CoreException {
887
		setLastBuiltState(this.currentproject, null);
888
	}
889
}
761
}
(-)buildnotes_api_tools.html (+1 lines)
Lines 14-19 Link Here
14
<!-- NEW -->
14
<!-- NEW -->
15
<h2>%date%</h2>
15
<h2>%date%</h2>
16
<h3>Problem Reports Fixed</h3>
16
<h3>Problem Reports Fixed</h3>
17
<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=271110">Bug 271110</a>: &quot;The minor version should be incremented&quot; stays on MANIFEST.MF after removing all problems<br>
17
<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=233883">Bug 233883</a>: [api tooling] Reports wrong error on correct @since 3.4 tag<br>
18
<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=233883">Bug 233883</a>: [api tooling] Reports wrong error on correct @since 3.4 tag<br>
18
<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=270992">Bug 270992</a>: Unable to add EE descriptions from repository<br>
19
<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=270992">Bug 270992</a>: Unable to add EE descriptions from repository<br>
19
<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=270857">Bug 270857</a>: unused import in manifest<br>
20
<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=270857">Bug 270857</a>: unused import in manifest<br>
(-)src/org/eclipse/pde/api/tools/builder/tests/tags/TagTest.java (+38 lines)
Lines 18-23 Link Here
18
18
19
import org.eclipse.core.runtime.IPath;
19
import org.eclipse.core.runtime.IPath;
20
import org.eclipse.core.runtime.Path;
20
import org.eclipse.core.runtime.Path;
21
import org.eclipse.jdt.core.IJavaProject;
22
import org.eclipse.jdt.core.IType;
21
import org.eclipse.jdt.core.tests.junit.extension.TestCase;
23
import org.eclipse.jdt.core.tests.junit.extension.TestCase;
22
import org.eclipse.pde.api.tools.builder.tests.ApiBuilderTest;
24
import org.eclipse.pde.api.tools.builder.tests.ApiBuilderTest;
23
import org.eclipse.pde.api.tools.builder.tests.ApiTestingEnvironment;
25
import org.eclipse.pde.api.tools.builder.tests.ApiTestingEnvironment;
Lines 195-198 Link Here
195
	protected String getTestingProjectName() {
197
	protected String getTestingProjectName() {
196
		return "tagtest";
198
		return "tagtest";
197
	}
199
	}
200
	
201
	/**
202
	 * Deploys a full build test for API Javadoc tags using the given source file in the specified package,
203
	 * looking for problems specified from {@link #getExpectedProblemIds()()}
204
	 * @param packagename
205
	 * @param sourcename
206
	 * @param expectingproblems
207
	 * @param buildtype the type of build to perform. One of:
208
	 * <ol>
209
	 * <li>IncrementalProjectBuilder#FULL_BUILD</li>
210
	 * <li>IncrementalProjectBuilder#INCREMENTAL_BUILD</li>
211
	 * <li>IncrementalProjectBuilder#CLEAN_BUILD</li>
212
	 * </ol>
213
	 * @param buildworkspace true if the workspace should be built, false if the created project should be built
214
	 */
215
	protected void deployTagTest(String packagename, String sourcename, boolean expectingproblems, int buildtype, boolean buildworkspace) {
216
		try {
217
			IPath path = assertProject(sourcename, packagename);
218
			doBuild(buildtype, (buildworkspace ? null : path));
219
			expectingNoJDTProblems();
220
			IJavaProject jproject = getEnv().getJavaProject(path);
221
			IType type = jproject.findType(packagename, sourcename);
222
			assertNotNull("The type "+sourcename+" from package "+packagename+" must exist", type);
223
			IPath sourcepath = type.getPath();
224
			if(expectingproblems) {
225
				expectingOnlySpecificProblemsFor(sourcepath, getExpectedProblemIds());
226
				assertProblems(getEnv().getProblems());
227
			}
228
			else {
229
				expectingNoProblemsFor(sourcepath);
230
			}
231
		}
232
		catch(Exception e) {
233
			fail(e.getMessage());
234
		}
235
	}
198
}
236
}
(-)src/org/eclipse/pde/api/tools/builder/tests/ApiBuilderTest.java (-77 lines)
Lines 412-494 Link Here
412
	}
412
	}
413
	
413
	
414
	/**
414
	/**
415
	 * Deploys a standard API usage test with the test project being created and the given source is imported in the testing project
416
	 * into the given project.
417
	 * 
418
	 * This method assumes that the reference and testing project have been imported into the workspace already.
419
	 * 
420
	 * @param packagename
421
	 * @param sourcename
422
	 * @param expectingproblems
423
	 * @param buildtype the type of build to perform. One of:
424
	 * <ol>
425
	 * <li>IncrementalProjectBuilder#FULL_BUILD</li>
426
	 * <li>IncrementalProjectBuilder#INCREMENTAL_BUILD</li>
427
	 * <li>IncrementalProjectBuilder#CLEAN_BUILD</li>
428
	 * </ol>
429
	 * @param buildworkspace
430
	 */
431
	protected void deployUsageTest(String packagename, String sourcename, boolean expectingproblems, int buildtype, boolean buildworkspace) {
432
		try {
433
			IProject project = getEnv().getProject(getTestingProjectName());
434
			assertNotNull("the testing project "+getTestingProjectName()+" must be in the workspace", project);
435
			assertSource(project, packagename, sourcename);
436
			doBuild(buildtype, (buildworkspace ? null : project.getFullPath()));
437
			expectingNoJDTProblems();
438
			IJavaProject jproject = getEnv().getJavaProject(getTestingProjectName());
439
			IType type = jproject.findType(packagename, sourcename);
440
			assertNotNull("The type "+sourcename+" from package "+packagename+" must exist", type);
441
			IPath sourcepath = type.getPath();
442
			if(expectingproblems) {
443
				expectingOnlySpecificProblemsFor(sourcepath, getExpectedProblemIds());
444
				assertProblems(getEnv().getProblems());
445
			}
446
			else {
447
				expectingNoProblemsFor(sourcepath);
448
			}
449
		}
450
		catch(Exception e) {
451
			fail(e.getMessage());
452
		}
453
	}
454
	
455
	/**
456
	 * Deploys a full build test for API Javadoc tags using the given source file in the specified package,
457
	 * looking for problems specified from {@link #getExpectedProblemIds()()}
458
	 * @param packagename
459
	 * @param sourcename
460
	 * @param expectingproblems
461
	 * @param buildtype the type of build to perform. One of:
462
	 * <ol>
463
	 * <li>IncrementalProjectBuilder#FULL_BUILD</li>
464
	 * <li>IncrementalProjectBuilder#INCREMENTAL_BUILD</li>
465
	 * <li>IncrementalProjectBuilder#CLEAN_BUILD</li>
466
	 * </ol>
467
	 * @param buildworkspace true if the workspace should be built, false if the created project should be built
468
	 */
469
	protected void deployTagTest(String packagename, String sourcename, boolean expectingproblems, int buildtype, boolean buildworkspace) {
470
		try {
471
			IPath path = assertProject(sourcename, packagename);
472
			doBuild(buildtype, (buildworkspace ? null : path));
473
			expectingNoJDTProblems();
474
			IJavaProject jproject = getEnv().getJavaProject(path);
475
			IType type = jproject.findType(packagename, sourcename);
476
			assertNotNull("The type "+sourcename+" from package "+packagename+" must exist", type);
477
			IPath sourcepath = type.getPath();
478
			if(expectingproblems) {
479
				expectingOnlySpecificProblemsFor(sourcepath, getExpectedProblemIds());
480
				assertProblems(getEnv().getProblems());
481
			}
482
			else {
483
				expectingNoProblemsFor(sourcepath);
484
			}
485
		}
486
		catch(Exception e) {
487
			fail(e.getMessage());
488
		}
489
	}
490
	
491
	/**
492
	 * Sets up the project for a given test using the specified source.
415
	 * Sets up the project for a given test using the specified source.
493
	 * The listing of source names and package names must be equal in size, as each source name will be
416
	 * The listing of source names and package names must be equal in size, as each source name will be
494
	 * placed in the the corresponding package listed in packagenames
417
	 * placed in the the corresponding package listed in packagenames
(-)src/org/eclipse/pde/api/tools/builder/tests/usage/UsageTest.java (+43 lines)
Lines 21-26 Link Here
21
import org.eclipse.core.resources.IncrementalProjectBuilder;
21
import org.eclipse.core.resources.IncrementalProjectBuilder;
22
import org.eclipse.core.runtime.IPath;
22
import org.eclipse.core.runtime.IPath;
23
import org.eclipse.core.runtime.Path;
23
import org.eclipse.core.runtime.Path;
24
import org.eclipse.jdt.core.IJavaProject;
25
import org.eclipse.jdt.core.IType;
24
import org.eclipse.jdt.core.tests.junit.extension.TestCase;
26
import org.eclipse.jdt.core.tests.junit.extension.TestCase;
25
import org.eclipse.pde.api.tools.builder.tests.ApiBuilderTest;
27
import org.eclipse.pde.api.tools.builder.tests.ApiBuilderTest;
26
import org.eclipse.pde.api.tools.model.tests.TestSuiteHelper;
28
import org.eclipse.pde.api.tools.model.tests.TestSuiteHelper;
Lines 172-177 Link Here
172
	}
174
	}
173
	
175
	
174
	/**
176
	/**
177
	 * Deploys a standard API usage test with the test project being created and the given source is imported in the testing project
178
	 * into the given project.
179
	 * 
180
	 * This method assumes that the reference and testing project have been imported into the workspace already.
181
	 * 
182
	 * @param packagename
183
	 * @param sourcename
184
	 * @param expectingproblems
185
	 * @param buildtype the type of build to perform. One of:
186
	 * <ol>
187
	 * <li>IncrementalProjectBuilder#FULL_BUILD</li>
188
	 * <li>IncrementalProjectBuilder#INCREMENTAL_BUILD</li>
189
	 * <li>IncrementalProjectBuilder#CLEAN_BUILD</li>
190
	 * </ol>
191
	 * @param buildworkspace
192
	 */
193
	protected void deployUsageTest(String packagename, String sourcename, boolean expectingproblems, int buildtype, boolean buildworkspace) {
194
		try {
195
			IProject project = getEnv().getProject(getTestingProjectName());
196
			assertNotNull("the testing project "+getTestingProjectName()+" must be in the workspace", project);
197
			assertSource(project, packagename, sourcename);
198
			doBuild(buildtype, (buildworkspace ? null : project.getFullPath()));
199
			expectingNoJDTProblems();
200
			IJavaProject jproject = getEnv().getJavaProject(getTestingProjectName());
201
			IType type = jproject.findType(packagename, sourcename);
202
			assertNotNull("The type "+sourcename+" from package "+packagename+" must exist", type);
203
			IPath sourcepath = type.getPath();
204
			if(expectingproblems) {
205
				expectingOnlySpecificProblemsFor(sourcepath, getExpectedProblemIds());
206
				assertProblems(getEnv().getProblems());
207
			}
208
			else {
209
				expectingNoProblemsFor(sourcepath);
210
			}
211
		}
212
		catch(Exception e) {
213
			fail(e.getMessage());
214
		}
215
	}
216
	
217
	/**
175
	 * @return all of the child test classes of this class
218
	 * @return all of the child test classes of this class
176
	 */
219
	 */
177
	private static Class[] getAllTestClasses() {
220
	private static Class[] getAllTestClasses() {
(-)src/org/eclipse/pde/api/tools/ui/internal/wizards/ProjectUpdateChange.java (-2 / +2 lines)
Lines 23-29 Link Here
23
import org.eclipse.ltk.core.refactoring.Change;
23
import org.eclipse.ltk.core.refactoring.Change;
24
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
24
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
25
import org.eclipse.pde.api.tools.internal.ApiDescriptionManager;
25
import org.eclipse.pde.api.tools.internal.ApiDescriptionManager;
26
import org.eclipse.pde.api.tools.internal.builder.ApiAnalysisBuilder;
26
import org.eclipse.pde.api.tools.internal.builder.BuildState;
27
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
27
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
28
import org.eclipse.pde.api.tools.internal.util.Util;
28
import org.eclipse.pde.api.tools.internal.util.Util;
29
import org.eclipse.pde.api.tools.ui.internal.IApiToolsConstants;
29
import org.eclipse.pde.api.tools.ui.internal.IApiToolsConstants;
Lines 101-107 Link Here
101
			 * If autobuild is off, clear the last build state to force a full build of
101
			 * If autobuild is off, clear the last build state to force a full build of
102
			 * this project on the next build.
102
			 * this project on the next build.
103
			 */
103
			 */
104
			ApiAnalysisBuilder.setLastBuiltState(this.fProject, null);
104
			BuildState.setLastBuiltState(this.fProject, null);
105
		}
105
		}
106
		if(!pm.isCanceled()) {
106
		if(!pm.isCanceled()) {
107
			pm.worked(1);
107
			pm.worked(1);

Return to bug 233643