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

Collapse All | Expand All

(-)plugin.xml (+5 lines)
Lines 224-229 Link Here
224
          library="lib/apitooling-ant.jar"
224
          library="lib/apitooling-ant.jar"
225
          name="apitooling.analysis_reportconversion">
225
          name="apitooling.analysis_reportconversion">
226
    </antTask>
226
    </antTask>
227
        <antTask
228
          class="org.eclipse.pde.api.tools.internal.tasks.APIUseScanTask"
229
          library="lib/apitooling-ant.jar"
230
          name="apitooling.apiusescan">
231
    </antTask>
227
    <antTask
232
    <antTask
228
          class="org.eclipse.pde.api.tools.internal.tasks.ApiUseTask"
233
          class="org.eclipse.pde.api.tools.internal.tasks.ApiUseTask"
229
          library="lib/apitooling-ant.jar"
234
          library="lib/apitooling-ant.jar"
(-)src/org/eclipse/pde/api/tools/internal/builder/BaseApiAnalyzer.java (-43 / +62 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2008, 2010 IBM Corporation and others.
2
 * Copyright (c) 2008, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 280-286 Link Here
280
			Util.updateMonitor(localMonitor);
280
			Util.updateMonitor(localMonitor);
281
			
281
			
282
			if (component instanceof ProjectComponent) {
282
			if (component instanceof ProjectComponent) {
283
				checkExternalDependencies(component, bcontext, localMonitor.newChild(1));
283
				checkExternalDependencies(component, bcontext, null, localMonitor.newChild(1));
284
			}
284
			}
285
		} catch(CoreException e) {
285
		} catch(CoreException e) {
286
			ApiPlugin.log(e);
286
			ApiPlugin.log(e);
Lines 305-314 Link Here
305
	 * @param monitor
305
	 * @param monitor
306
	 * @throws CoreException
306
	 * @throws CoreException
307
	 */
307
	 */
308
	void checkExternalDependencies(IApiComponent apiComponent, IBuildContext bcontext, IProgressMonitor monitor) throws CoreException {
308
	public void checkExternalDependencies(IApiComponent apiComponent, IBuildContext bcontext, Properties properties, IProgressMonitor monitor) throws CoreException {
309
		if (!isSeverityEnabled()) {
309
		if (!isSeverityEnabled(properties)) {
310
			return;
310
			return;
311
		}
311
		}		
312
		String[] apiUseTypes = getApiUseTypes(bcontext);
312
		String[] apiUseTypes = getApiUseTypes(bcontext);
313
		if (DEBUG) {
313
		if (DEBUG) {
314
			System.out.println("Fetching external dependencies for the types : " + Arrays.asList(apiUseTypes)); //$NON-NLS-1$
314
			System.out.println("Fetching external dependencies for the types : " + Arrays.asList(apiUseTypes)); //$NON-NLS-1$
Lines 367-385 Link Here
367
		}
367
		}
368
	}
368
	}
369
369
370
	public boolean isSeverityEnabled() {
370
	public boolean isSeverityEnabled(Properties properties) {
371
		IEclipsePreferences node = (new InstanceScope()).getNode(ApiPlugin.PLUGIN_ID);
371
		IEclipsePreferences node = InstanceScope.INSTANCE.getNode(ApiPlugin.PLUGIN_ID);
372
372
		if (properties == null) {
373
		if (!node.get(IApiProblemTypes.API_USE_SCAN_TYPE_SEVERITY, ApiPlugin.VALUE_IGNORE).equalsIgnoreCase(ApiPlugin.VALUE_IGNORE)) {
373
			if (!isIgnore(node.get(IApiProblemTypes.API_USE_SCAN_TYPE_SEVERITY, ApiPlugin.VALUE_IGNORE)))
374
			return true;
374
				return true;
375
		}
375
			if (!isIgnore(node.get(IApiProblemTypes.API_USE_SCAN_METHOD_SEVERITY, ApiPlugin.VALUE_IGNORE)))
376
		if (!node.get(IApiProblemTypes.API_USE_SCAN_METHOD_SEVERITY, ApiPlugin.VALUE_IGNORE).equalsIgnoreCase(ApiPlugin.VALUE_IGNORE)) {
376
				return true;
377
			return true;
377
			if (isIgnore(node.get(IApiProblemTypes.API_USE_SCAN_FIELD_SEVERITY, ApiPlugin.VALUE_IGNORE)))
378
				return true;
379
			return false;
380
		} else {
381
			if (properties.isEmpty())
382
				return true; // preferences parameter not provided
383
			if (!isIgnore(properties.get(IApiProblemTypes.API_USE_SCAN_TYPE_SEVERITY))) 
384
				return true;
385
			if (!isIgnore(properties.get(IApiProblemTypes.API_USE_SCAN_METHOD_SEVERITY))) 
386
				return true;
387
			if (!isIgnore(properties.get(IApiProblemTypes.API_USE_SCAN_FIELD_SEVERITY))) 
388
				return true;
389
			return false;
378
		}
390
		}
379
		if (!node.get(IApiProblemTypes.API_USE_SCAN_FIELD_SEVERITY, ApiPlugin.VALUE_IGNORE).equalsIgnoreCase(ApiPlugin.VALUE_IGNORE)) {
391
	}
380
			return true;
392
393
	private boolean isIgnore(Object value) {
394
		if (value != null && (value.toString().equalsIgnoreCase(ApiPlugin.VALUE_ERROR) || value.toString().equalsIgnoreCase(ApiPlugin.VALUE_WARNING))) {
395
			return false;
381
		}
396
		}
382
		return false;
397
		return true;
383
	}
398
	}
384
	
399
	
385
	/**
400
	/**
Lines 395-427 Link Here
395
	 */
410
	 */
396
	protected IApiProblem createExternalDependenciesProblem(HashMap problems, IReferenceDescriptor dependency, String referenceTypeName, IMemberDescriptor referencedMember, int elementType, int flag) {	
411
	protected IApiProblem createExternalDependenciesProblem(HashMap problems, IReferenceDescriptor dependency, String referenceTypeName, IMemberDescriptor referencedMember, int elementType, int flag) {	
397
		String resource = referenceTypeName;
412
		String resource = referenceTypeName;
398
		String primaryTypeName = referenceTypeName.replace('$', '.');
413
		String primaryTypeName = referenceTypeName.replace('$', '.');		
399
		int charStart = -1, charEnd = -1, lineNumber = -1; 
414
		int charStart = -1, charEnd = -1, lineNumber = -1; 
400
		try {
415
		if (fJavaProject != null) {
401
			IType type = fJavaProject.findType(primaryTypeName);
416
			try {
402
			IResource res = Util.getResource(fJavaProject.getProject(), type);
417
				
403
			if(res == null) {
418
				IType type = fJavaProject.findType(primaryTypeName);
404
				return null;
419
				IResource res = Util.getResource(fJavaProject.getProject(), type);
405
			}
420
				if(res == null) {
406
			if(!Util.isManifest(res.getProjectRelativePath())) {
421
					return null;
407
				resource = res.getProjectRelativePath().toString();
422
				}
408
			}
423
				if(!Util.isManifest(res.getProjectRelativePath())) {
409
			else {
424
					resource = res.getProjectRelativePath().toString();
410
				resource = "."; //$NON-NLS-1$
425
				}
411
			}
426
				else {
412
			if (type != null) {
427
					resource = "."; //$NON-NLS-1$
413
				ISourceRange range = type.getNameRange();
428
				}
414
				charStart = range.getOffset();
429
				if (type != null) {
415
				charEnd = charStart + range.getLength();
430
					ISourceRange range = type.getNameRange();
416
				try {
431
					charStart = range.getOffset();
417
					IDocument document = Util.getDocument(type.getCompilationUnit());
432
					charEnd = charStart + range.getLength();
418
					lineNumber = document.getLineOfOffset(charStart);
433
					try {
419
				} catch (BadLocationException e) {
434
						IDocument document = Util.getDocument(type.getCompilationUnit());
420
					// ignore
435
						lineNumber = document.getLineOfOffset(charStart);
421
				}			
436
					} catch (BadLocationException e) {
422
				catch (CoreException ce) {}
437
						// ignore
423
			}
438
					}			
424
		} catch (JavaModelException e) {}
439
					catch (CoreException ce) {}
440
				}
441
			} catch (JavaModelException e) {}
442
		}
425
		String[] msgArgs = new String[] {referenceTypeName, referencedMember.getName(), dependency.getComponent().getId()};
443
		String[] msgArgs = new String[] {referenceTypeName, referencedMember.getName(), dependency.getComponent().getId()};
426
		int kind = 0;
444
		int kind = 0;
427
		switch (elementType) {
445
		switch (elementType) {
Lines 441-447 Link Here
441
		}
459
		}
442
		
460
		
443
		int dependencyNameIndex = 2;	// the comma separated list of dependent plugins 
461
		int dependencyNameIndex = 2;	// the comma separated list of dependent plugins 
444
		String problemKey = referenceTypeName +  resource + dependency.getReferenceKind() + elementType + kind + flag;
462
		int problemId = ApiProblemFactory.createProblemId(IApiProblem.CATEGORY_API_USE_SCAN_PROBLEM, elementType, kind, flag);
463
		String problemKey = referenceTypeName +  problemId;
445
		IApiProblem similarProblem =  (IApiProblem) problems.get(problemKey);
464
		IApiProblem similarProblem =  (IApiProblem) problems.get(problemKey);
446
		if (similarProblem != null) {
465
		if (similarProblem != null) {
447
			String[] existingMsgArgs = similarProblem.getMessageArguments()[dependencyNameIndex].split(", "); //$NON-NLS-1$
466
			String[] existingMsgArgs = similarProblem.getMessageArguments()[dependencyNameIndex].split(", "); //$NON-NLS-1$
(-)src_ant/org/eclipse/pde/api/tools/internal/tasks/APIUseScanTask.java (+688 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.pde.api.tools.internal.tasks;
12
13
import java.io.BufferedInputStream;
14
import java.io.File;
15
import java.io.FileInputStream;
16
import java.io.IOException;
17
import java.io.PrintWriter;
18
import java.io.StringWriter;
19
import java.util.ArrayList;
20
import java.util.Arrays;
21
import java.util.Collections;
22
import java.util.Comparator;
23
import java.util.HashMap;
24
import java.util.HashSet;
25
import java.util.Iterator;
26
import java.util.List;
27
import java.util.Map;
28
import java.util.Properties;
29
import java.util.Set;
30
31
import org.apache.tools.ant.BuildException;
32
import org.eclipse.core.runtime.CoreException;
33
import org.eclipse.core.runtime.NullProgressMonitor;
34
import org.eclipse.osgi.util.NLS;
35
import org.eclipse.pde.api.tools.internal.IApiXmlConstants;
36
import org.eclipse.pde.api.tools.internal.builder.BaseApiAnalyzer;
37
import org.eclipse.pde.api.tools.internal.builder.BuildContext;
38
import org.eclipse.pde.api.tools.internal.model.StubApiComponent;
39
import org.eclipse.pde.api.tools.internal.problems.ApiProblemFactory;
40
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
41
import org.eclipse.pde.api.tools.internal.provisional.model.IApiBaseline;
42
import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent;
43
import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblem;
44
import org.eclipse.pde.api.tools.internal.search.UseScanManager;
45
import org.eclipse.pde.api.tools.internal.util.FilteredElements;
46
import org.eclipse.pde.api.tools.internal.util.Util;
47
import org.w3c.dom.DOMException;
48
import org.w3c.dom.Document;
49
import org.w3c.dom.Element;
50
51
/**
52
 * Ant task to headlessly run the API Analysis builder and generate a report of missing
53
 * references in the API Use Scans
54
 */
55
public class APIUseScanTask extends CommonUtilsTask {
56
57
	private FilteredElements fExcludedElements;
58
	private FilteredElements fIncludedElements;
59
	private String fFilters;
60
	private String[] fAPIUseScans;
61
	private Properties fProperties = new Properties();
62
63
//	public static final String BUNDLE_VERSION = "bundleVersion"; //$NON-NLS-1$
64
	public static final String COMPATIBILITY = "compatibility"; //$NON-NLS-1$
65
//	public static final String USAGE = "usage"; //$NON-NLS-1$
66
67
	private static final Summary[] NO_SUMMARIES = new Summary[0];
68
69
	private static class Summary {
70
//		List apiBundleVersionProblems = new ArrayList();
71
//		List apiCompatibilityProblems = new ArrayList();
72
//		List apiUsageProblems = new ArrayList();
73
		String fComponentID;
74
		List fApiProblems;
75
		
76
		public Summary(String componentID, IApiProblem[] apiProblems) {
77
			fComponentID = componentID;
78
			fApiProblems = Arrays.asList(apiProblems);
79
//			for (int i = 0, max = apiProblems.length; i < max; i++) {
80
//				IApiProblem problem = apiProblems[i];
81
//				switch (problem.getCategory()) {
82
//					case IApiProblem.CATEGORY_COMPATIBILITY :
83
//						apiCompatibilityProblems.add(problem);
84
//						break;
85
//					case IApiProblem.CATEGORY_USAGE :
86
//						apiUsageProblems.add(problem);
87
//						break;
88
//					case IApiProblem.CATEGORY_VERSION :
89
//						apiBundleVersionProblems.add(problem);
90
//				}
91
//			}
92
		}
93
94
		private void dumpProblems(String title, PrintWriter printWriter) {
95
			printWriter.println(title);
96
			if (fApiProblems.size() != 0) {
97
				for (Iterator iterator = fApiProblems.iterator(); iterator.hasNext();) {
98
					IApiProblem problem = (IApiProblem) iterator.next();
99
					printWriter.println(problem.getMessage());
100
				}
101
			} else {
102
				printWriter.println("None"); //$NON-NLS-1$
103
			}
104
		}
105
106
		public String getDetails() {
107
			StringWriter writer = new StringWriter();
108
			PrintWriter printWriter = new PrintWriter(writer);
109
110
			printWriter.println("=================================================================================="); //$NON-NLS-1$
111
			printWriter.println("Details for " + fComponentID + ":"); //$NON-NLS-1$//$NON-NLS-2$
112
			printWriter.println("=================================================================================="); //$NON-NLS-1$
113
			dumpProblems("All Problems",printWriter); //$NON-NLS-1$
114
			printWriter.println("=================================================================================="); //$NON-NLS-1$
115
			printWriter.flush();
116
			printWriter.close();
117
			return String.valueOf(writer.getBuffer());
118
		}
119
120
		public String getTitle() {
121
			StringWriter writer = new StringWriter();
122
			PrintWriter printWriter = new PrintWriter(writer);
123
			printTitle(printWriter);
124
125
			printWriter.flush();
126
			printWriter.close();
127
			return String.valueOf(writer.getBuffer());
128
		}
129
130
		private void printTitle(PrintWriter printWriter) {
131
			printWriter.print("Results for " + fComponentID + " : "); //$NON-NLS-1$ //$NON-NLS-2$
132
			printWriter.print('(');
133
			printWriter.print("total: "); //$NON-NLS-1$
134
			printWriter.print(fApiProblems.size());
135
			printWriter.println(')');
136
		}
137
138
		public String toString() {
139
			StringWriter writer = new StringWriter();
140
			PrintWriter printWriter = new PrintWriter(writer);
141
			printTitle(printWriter);
142
143
			dumpProblems("All Problems",printWriter); //$NON-NLS-1$
144
145
			printWriter.flush();
146
			printWriter.close();
147
			return String.valueOf(writer.getBuffer());
148
		}
149
	}
150
151
	/**
152
	 * Run the api tools verification task
153
	 * 
154
	 * @throws BuildException exception is thrown if anything goes wrong during the verification
155
	 */
156
	public void execute() throws BuildException {
157
		if (super.currentBaselineLocation == null || super.reportLocation == null) {
158
			StringWriter out = new StringWriter();
159
			PrintWriter writer = new PrintWriter(out);
160
			writer.println(NLS.bind(Messages.printArguments, // TODO put new message
161
					new String[] {super.currentBaselineLocation, super.reportLocation,}));
162
			writer.flush();
163
			writer.close();
164
			throw new BuildException(String.valueOf(out.getBuffer()));
165
		}
166
		if (super.debug) {
167
			System.out.println("profile to compare : " + super.currentBaselineLocation); //$NON-NLS-1$
168
			System.out.println("report location : " + super.reportLocation); //$NON-NLS-1$
169
			if (this.fFilters != null) {
170
				System.out.println("filter store : " + this.fFilters); //$NON-NLS-1$
171
			} else {
172
				System.out.println("No filter store"); //$NON-NLS-1$
173
			}
174
			if (super.excludeListLocation != null) {
175
				System.out.println("exclude list location : " + super.excludeListLocation); //$NON-NLS-1$
176
			} else {
177
				System.out.println("No exclude list location"); //$NON-NLS-1$
178
			}
179
			if (super.includeListLocation != null) {
180
				System.out.println("include list location : " + super.includeListLocation); //$NON-NLS-1$
181
			} else {
182
				System.out.println("No include list location"); //$NON-NLS-1$
183
			}
184
		}
185
		// unzip profile
186
		long time = 0;
187
		if (super.debug) {
188
			time = System.currentTimeMillis();
189
		}
190
191
		File baselineInstallDir = extractSDK(CURRENT, super.currentBaselineLocation);
192
		if (super.debug) {
193
			System.out.println("Preparation of profile installation : " + (System.currentTimeMillis() - time) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
194
			time = System.currentTimeMillis();
195
		}
196
		// run the comparison
197
		// create baseline for the reference
198
		IApiBaseline currentBaseline = createBaseline(CURRENT_BASELINE_NAME, baselineInstallDir.getAbsolutePath(), super.eeFileLocation);
199
		if (super.debug) { //TODO
200
			System.out.println("Creation of baseline : " + (System.currentTimeMillis() - time) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
201
			time = System.currentTimeMillis();
202
		}
203
204
		if (this.excludeListLocation != null) {
205
			this.fExcludedElements = CommonUtilsTask.initializeFilteredElements(this.excludeListLocation, currentBaseline, super.debug);
206
			if (super.debug) {
207
				System.out.println("===================================================================================="); //$NON-NLS-1$
208
				System.out.println("Excluded elements list:"); //$NON-NLS-1$
209
				System.out.println(this.fExcludedElements);
210
			}
211
		}
212
		if (this.includeListLocation != null) {
213
			this.fIncludedElements = CommonUtilsTask.initializeFilteredElements(this.includeListLocation, currentBaseline, super.debug);
214
			if (super.debug) {
215
				System.out.println("===================================================================================="); //$NON-NLS-1$
216
				System.out.println("Included elements list:"); //$NON-NLS-1$
217
				System.out.println(this.fIncludedElements);
218
			}
219
		}
220
221
		UseScanManager.getInstance().setReportLocations(fAPIUseScans);
222
		
223
		if (super.debug) {
224
			System.out.println("===================================================================================="); //$NON-NLS-1$
225
			System.out.println("API Use Scan locations:"); //$NON-NLS-1$
226
			for (int i = 0; i < fAPIUseScans.length; i++) {
227
				System.out.println("Location " + i + " : " + fAPIUseScans[i]); //$NON-NLS-1$ //$NON-NLS-2$
228
			}
229
		}
230
231
		Map allProblems = new HashMap();
232
		List allNonApiBundles = new ArrayList();
233
		List allApiBundles = new ArrayList();
234
		try {
235
			IApiComponent[] apiComponents = currentBaseline.getApiComponents();
236
			int length = apiComponents.length;
237
			Set visitedApiComponentNames = new HashSet();
238
			for (int i = 0; i < length; i++) {
239
				IApiComponent apiComponent = apiComponents[i];
240
				String name = apiComponent.getSymbolicName();
241
				visitedApiComponentNames.add(name);
242
				if (apiComponent.isSystemComponent()) {
243
					continue;
244
				}
245
				if (!Util.isApiToolsComponent(apiComponent)) {
246
					allNonApiBundles.add(name);
247
					continue;
248
				}
249
				
250
				allApiBundles.add(name);
251
				BaseApiAnalyzer analyzer = new BaseApiAnalyzer();
252
				try {
253
					BaseApiAnalyzer.setDebug(super.debug);
254
					analyzer.checkExternalDependencies(apiComponent, new BuildContext(), this.fProperties, new NullProgressMonitor());
255
					IApiProblem[] problems = analyzer.getProblems();
256
					if (problems.length != 0) {
257
						allProblems.put(name, problems);
258
					}
259
				} catch (RuntimeException e) {
260
					ApiPlugin.log(e);
261
					throw e;
262
				} catch (CoreException e) {
263
					ApiPlugin.log(e);
264
				} finally {
265
					analyzer.dispose();
266
				}
267
			}
268
			if (super.debug) {
269
				System.out.println("Total number of components in current baseline :" + length); //$NON-NLS-1$
270
				System.out.println("Total number of api tools components in current baseline :" + allApiBundles.size()); //$NON-NLS-1$
271
				System.out.println("Details:"); //$NON-NLS-1$
272
				Collections.sort(allApiBundles);
273
				for (Iterator iterator = allApiBundles.iterator(); iterator.hasNext();) {
274
					System.out.println(iterator.next());
275
				}
276
				System.out.println("=============================================================================="); //$NON-NLS-1$
277
				System.out.println("Total number of non-api tools components in current baseline :" + allNonApiBundles.size()); //$NON-NLS-1$
278
				System.out.println("Details:"); //$NON-NLS-1$
279
				Collections.sort(allNonApiBundles);
280
				for (Iterator iterator = allNonApiBundles.iterator(); iterator.hasNext();) {
281
					System.out.println(iterator.next());
282
				}
283
			}
284
		} finally {
285
			if (super.debug) {
286
				System.out.println("API tools verification check : " + (System.currentTimeMillis() - time) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
287
				time = System.currentTimeMillis();
288
			}
289
			currentBaseline.dispose();
290
			StubApiComponent.disposeAllCaches();
291
			deleteBaseline(super.currentBaselineLocation, baselineInstallDir);
292
			if (super.debug) {
293
				System.out.println("Cleanup : " + (System.currentTimeMillis() - time) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
294
			}
295
		}
296
		Summary[] summaries = createAllSummaries(allProblems);
297
298
		try {
299
			dumpReport(summaries, allNonApiBundles);
300
		} catch (RuntimeException e) {
301
			ApiPlugin.log(e);
302
			throw e;
303
		}
304
	}
305
306
	private Summary[] createAllSummaries(Map allProblems) {
307
		Set entrySet = allProblems.entrySet();
308
		int size = entrySet.size();
309
		if (size == 0) {
310
			return NO_SUMMARIES;
311
		}
312
		List allEntries = new ArrayList();
313
		allEntries.addAll(entrySet);
314
		Collections.sort(allEntries, new Comparator() {
315
			public int compare(Object o1, Object o2) {
316
				Map.Entry entry1 = (Map.Entry) o1;
317
				Map.Entry entry2 = (Map.Entry) o2;
318
				return ((String) entry1.getKey()).compareTo((String) entry2.getKey());
319
			}
320
		});
321
		Summary[] summaries = new Summary[size];
322
		int i = 0;
323
		for (Iterator iterator = allEntries.iterator(); iterator.hasNext();) {
324
			Map.Entry entry = (Map.Entry) iterator.next();
325
			summaries[i++] = new Summary((String) entry.getKey(), (IApiProblem[]) entry.getValue());
326
		}
327
		if (super.debug) {
328
			dumpSummaries(summaries);
329
		}
330
		return summaries;
331
	}
332
333
	private void dumpReport(Summary[] summaries, List bundlesNames) {
334
		for (int i = 0, max = summaries.length; i < max; i++) {
335
			Summary summary = summaries[i];
336
			String contents = null;
337
			String componentID = summary.fComponentID;
338
			if (this.fExcludedElements != null && (this.fExcludedElements.containsExactMatch(componentID) || this.fExcludedElements.containsPartialMatch(componentID))) {
339
				continue;
340
			}
341
			if (this.fIncludedElements != null && !this.fIncludedElements.isEmpty() && !(this.fIncludedElements.containsExactMatch(componentID) || this.fIncludedElements.containsPartialMatch(componentID))) {
342
				continue;
343
			}
344
			try {
345
				Document document = Util.newDocument();
346
				Element report = document.createElement(IApiXmlConstants.ELEMENT_API_TOOL_REPORT);
347
				report.setAttribute(IApiXmlConstants.ATTR_VERSION, IApiXmlConstants.API_REPORT_CURRENT_VERSION);
348
				report.setAttribute(IApiXmlConstants.ATTR_COMPONENT_ID, componentID);
349
				document.appendChild(report);
350
351
				Element category = document.createElement(IApiXmlConstants.ATTR_CATEGORY);
352
				category.setAttribute(IApiXmlConstants.ATTR_KEY, Integer.toString(IApiProblem.CATEGORY_API_USE_SCAN_PROBLEM));
353
				category.setAttribute(IApiXmlConstants.ATTR_VALUE, COMPATIBILITY);
354
				insertAPIProblems(category, document, summary.fApiProblems);
355
				report.appendChild(category);
356
357
				contents = Util.serializeDocument(document);
358
			} catch (DOMException e) {
359
				throw new BuildException(e);
360
			} catch (CoreException e) {
361
				throw new BuildException(e);
362
			}
363
			if (contents != null) {
364
				saveReport(componentID, contents, "report.xml"); //$NON-NLS-1$
365
			}
366
		}
367
		if (bundlesNames != null && bundlesNames.size() != 0) {
368
			String contents = null;
369
			try {
370
				Document document = Util.newDocument();
371
				Element report = document.createElement(IApiXmlConstants.ELEMENT_API_TOOL_REPORT);
372
				report.setAttribute(IApiXmlConstants.ATTR_VERSION, IApiXmlConstants.API_REPORT_CURRENT_VERSION);
373
				document.appendChild(report);
374
375
				for (Iterator iterator = bundlesNames.iterator(); iterator.hasNext();) {
376
					String bundleName = (String) iterator.next();
377
					if (this.fExcludedElements == null || !this.fExcludedElements.containsPartialMatch(bundleName) && (this.fIncludedElements == null || this.fIncludedElements.isEmpty() || this.fIncludedElements.containsPartialMatch(bundleName))) {
378
						Element bundle = document.createElement(IApiXmlConstants.ELEMENT_BUNDLE);
379
						bundle.setAttribute(IApiXmlConstants.ATTR_NAME, bundleName);
380
						report.appendChild(bundle);
381
					}
382
				}
383
				contents = Util.serializeDocument(document);
384
			} catch (DOMException e) {
385
				throw new BuildException(e);
386
			} catch (CoreException e) {
387
				throw new BuildException(e);
388
			}
389
			if (contents != null) {
390
				saveReport("allNonApiBundles", contents, "report.xml"); //$NON-NLS-1$ //$NON-NLS-2$
391
			}
392
		}
393
	}
394
395
	private void dumpSummaries(Summary[] summaries) {
396
		System.out.println("=================================================================================="); //$NON-NLS-1$);
397
		System.out.println("Summaries"); //$NON-NLS-1$
398
		for (int i = 0, max = summaries.length; i < max; i++) {
399
			System.out.println(summaries[i].getTitle());
400
		}
401
		for (int i = 0, max = summaries.length; i < max; i++) {
402
			System.out.println(summaries[i].getDetails());
403
		}
404
		System.out.println("=================================================================================="); //$NON-NLS-1$);
405
	}
406
407
	/**
408
	 * Returns an element that contains all the api problem nodes.
409
	 *
410
	 * @param document the given xml document
411
	 * @param problems the given problem to dump into the document
412
	 * @return an element that contains all the api problem nodes or null if an error occured
413
	 */
414
	private void insertAPIProblems(Element root, Document document, List problems) throws CoreException {
415
		Element apiProblems = document.createElement(IApiXmlConstants.ELEMENT_API_PROBLEMS);
416
		root.appendChild(apiProblems);
417
		Element element = null;
418
		// sort the problem by type name
419
		Collections.sort(problems, new Comparator() {
420
			public int compare(Object o1, Object o2) {
421
				IApiProblem p1 = (IApiProblem) o1;
422
				IApiProblem p2 = (IApiProblem) o2;
423
				return p1.getTypeName().compareTo(p2.getTypeName());
424
			}
425
		});
426
		for (Iterator iterator = problems.iterator(); iterator.hasNext();) {
427
			IApiProblem problem = (IApiProblem) iterator.next();
428
			element = document.createElement(IApiXmlConstants.ELEMENT_API_PROBLEM);
429
			element.setAttribute(IApiXmlConstants.ATTR_TYPE_NAME, String.valueOf(problem.getTypeName()));
430
			element.setAttribute(IApiXmlConstants.ATTR_ID, Integer.toString(problem.getId()));
431
			element.setAttribute(IApiXmlConstants.ATTR_LINE_NUMBER, Integer.toString(problem.getLineNumber()));
432
			element.setAttribute(IApiXmlConstants.ATTR_CHAR_START, Integer.toString(problem.getCharStart()));
433
			element.setAttribute(IApiXmlConstants.ATTR_CHAR_END, Integer.toString(problem.getCharEnd()));
434
			element.setAttribute(IApiXmlConstants.ATTR_ELEMENT_KIND, Integer.toString(problem.getElementKind()));
435
			element.setAttribute(IApiXmlConstants.ATTR_SEVERITY, Integer.toString(getSeverity(problem)));
436
			element.setAttribute(IApiXmlConstants.ATTR_KIND, Integer.toString(problem.getKind()));
437
			element.setAttribute(IApiXmlConstants.ATTR_FLAGS, Integer.toString(problem.getFlags()));
438
			element.setAttribute(IApiXmlConstants.ATTR_MESSAGE, problem.getMessage());
439
			String[] extraMarkerAttributeIds = problem.getExtraMarkerAttributeIds();
440
			if (extraMarkerAttributeIds != null && extraMarkerAttributeIds.length != 0) {
441
				int length = extraMarkerAttributeIds.length;
442
				Object[] extraMarkerAttributeValues = problem.getExtraMarkerAttributeValues();
443
				Element extraArgumentsElement = document.createElement(IApiXmlConstants.ELEMENT_PROBLEM_EXTRA_ARGUMENTS);
444
				for (int j = 0; j < length; j++) {
445
					Element extraArgumentElement = document.createElement(IApiXmlConstants.ELEMENT_PROBLEM_EXTRA_ARGUMENT);
446
					extraArgumentElement.setAttribute(IApiXmlConstants.ATTR_ID, extraMarkerAttributeIds[j]);
447
					extraArgumentElement.setAttribute(IApiXmlConstants.ATTR_VALUE, String.valueOf(extraMarkerAttributeValues[j]));
448
					extraArgumentsElement.appendChild(extraArgumentElement);
449
				}
450
				element.appendChild(extraArgumentsElement);
451
			}
452
			String[] messageArguments = problem.getMessageArguments();
453
			if (messageArguments != null && messageArguments.length != 0) {
454
				int length = messageArguments.length;
455
				Element messageArgumentsElement = document.createElement(IApiXmlConstants.ELEMENT_PROBLEM_MESSAGE_ARGUMENTS);
456
				for (int j = 0; j < length; j++) {
457
					Element messageArgumentElement = document.createElement(IApiXmlConstants.ELEMENT_PROBLEM_MESSAGE_ARGUMENT);
458
					messageArgumentElement.setAttribute(IApiXmlConstants.ATTR_VALUE, String.valueOf(messageArguments[j]));
459
					messageArgumentsElement.appendChild(messageArgumentElement);
460
				}
461
				element.appendChild(messageArgumentsElement);
462
			}
463
			apiProblems.appendChild(element);
464
		}
465
	}
466
467
	/**
468
	 * By default, we return a warning severity.
469
	 * @param problem the given problem
470
	 * @return the problem's severity
471
	 */
472
	private int getSeverity(IApiProblem problem) {
473
		if (this.fProperties != null) {
474
			String key = ApiProblemFactory.getProblemSeverityId(problem);
475
			if (key != null) {
476
				String value = this.fProperties.getProperty(key, null);
477
				if (value != null) {
478
					if (ApiPlugin.VALUE_ERROR.equals(value)) {
479
						return ApiPlugin.SEVERITY_ERROR;
480
					}
481
				}
482
			}
483
		}
484
		return ApiPlugin.SEVERITY_WARNING;
485
	}
486
487
	/**
488
	 * Set the debug value.
489
	 * <p>The possible values are: <code>true</code>, <code>false</code></p>
490
	 * <p>Default is <code>false</code>.</p>
491
	 *
492
	 * @param debugValue the given debug value
493
	 */
494
	public void setDebug(String debugValue) {
495
		super.debug = Boolean.toString(true).equals(debugValue);
496
	}
497
498
	/**
499
	 * Set the execution environment file to use.
500
	 * <p>By default, an execution environment file corresponding to a JavaSE-1.6 execution environment
501
	 * is used.</p>
502
	 * <p>The file is specified using an absolute path. This is optional.</p> 
503
	 *
504
	 * @param eeFileLocation the given execution environment file
505
	 */
506
	public void setEEFile(String eeFileLocation) {
507
		this.eeFileLocation = eeFileLocation;
508
	}
509
510
	/**
511
	 * Set the exclude list location.
512
	 * 
513
	 * <p>The exclude list is used to know what bundles should excluded from the xml report generated by the task
514
	 * execution. Lines starting with '#' are ignored from the excluded elements.</p>
515
	 * <p>The format of the exclude list file looks like this:</p>
516
	 * <pre>
517
	 * # DOC BUNDLES
518
	 * org.eclipse.jdt.doc.isv
519
	 * org.eclipse.jdt.doc.user
520
	 * org.eclipse.pde.doc.user
521
	 * org.eclipse.platform.doc.isv
522
	 * org.eclipse.platform.doc.user
523
	 * # NON-ECLIPSE BUNDLES
524
	 * com.ibm.icu
525
	 * com.jcraft.jsch
526
	 * javax.servlet
527
	 * javax.servlet.jsp
528
	 * ...
529
	 * </pre>
530
	 * <p>The location is set using an absolute path.</p>
531
	 *
532
	 * @param excludeListLocation the given location for the excluded list file
533
	 */
534
	public void setExcludeList(String excludeListLocation) {
535
		this.excludeListLocation = excludeListLocation;
536
	}
537
538
	/**
539
	 * Set the include list location.
540
	 * 
541
	 * <p>The include list is used to know what bundles should included from the xml report generated by the task
542
	 * execution. Lines starting with '#' are ignored from the included elements.</p>
543
	 * <p>The format of the include list file looks like this:</p>
544
	 * <pre>
545
	 * # DOC BUNDLES
546
	 * org.eclipse.jdt.doc.isv
547
	 * org.eclipse.jdt.doc.user
548
	 * org.eclipse.pde.doc.user
549
	 * org.eclipse.platform.doc.isv
550
	 * org.eclipse.platform.doc.user
551
	 * # NON-ECLIPSE BUNDLES
552
	 * com.ibm.icu
553
	 * com.jcraft.jsch
554
	 * javax.servlet
555
	 * javax.servlet.jsp
556
	 * ...
557
	 * </pre>
558
	 * <p>The location is set using an absolute path.</p>
559
	 *
560
	 * @param includeListLocation the given location for the included list file
561
	 */
562
	public void setIncludeList(String includeListLocation) {
563
		this.includeListLocation = includeListLocation;
564
	}
565
566
	/**
567
	 * Set the root directory of API fFilters to use during the analysis.
568
	 * 
569
	 * <p>The argument is the root directory of the .api_filters files that should be used to filter potential
570
	 * problems created by the api tooling analysis. The root needs to contain the following structure:</p>
571
	 * <pre>
572
	 * root
573
	 *  |
574
	 *  +-- component name (i.e. org.eclipse.jface)
575
	 *         |
576
	 *         +--- .api_filters
577
	 * </pre>
578
	 *
579
	 * @param fFilters the root of the .api_filters files
580
	 */
581
	public void setFilters(String filters) {
582
		this.fFilters = filters;
583
	}
584
585
	/**
586
	 * Set the preferences for the task.
587
	 * 
588
	 * <p>The preferences are used to configure problem severities. Problem severities have
589
	 * three possible values: Ignore, Warning, or Error. The set of problems detected is defined
590
	 * by corresponding problem preference keys in API tools.</p>
591
	 * <p>If the given location doesn't exist, the preferences won't be set.</p>
592
	 * <p>Lines starting with '#' are ignored. The format of the preferences file looks like this:</p>
593
	 * <pre>
594
	 * #Thu Jan 11 17:03:09 IST 2011
595
	 * API_USE_SCAN_TYPE_SEVERITY=Error
596
	 * API_USE_SCAN_METHOD_SEVERITY=Ignore
597
	 * API_USE_SCAN_FIELD_SEVERITY=Ignore
598
	 * </pre>
599
	 * <p>The keys can be found in {@link org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblemTypes}.</p>
600
	 * <p>The location is set using an absolute path.</p>
601
	 *
602
	 * @param preferencesLocation the location of the preference file
603
	 */
604
	public void setPreferences(String preferencesLocation) {
605
		File preferencesFile = new File(preferencesLocation);
606
		if (!preferencesFile.exists()) {
607
			return;
608
		}
609
		BufferedInputStream inputStream = null;
610
		try {
611
			inputStream = new BufferedInputStream(new FileInputStream(preferencesFile));
612
			Properties temp = new Properties();
613
			temp.load(inputStream);
614
			this.fProperties = temp;
615
		} catch (IOException e) {
616
			// ignore
617
		} finally {
618
			if (inputStream != null) {
619
				try {
620
					inputStream.close();
621
				} catch (IOException e) {
622
					// ignore
623
				}
624
			}
625
		}
626
	}
627
628
	/**
629
	 * Set the location of the current product or baseline that you want to compare against
630
	 * the reference baseline.
631
	 * 
632
	 * <p>It can be a .zip, .jar, .tgz, .tar.gz file, or a directory that corresponds to 
633
	 * the Eclipse installation folder. This is the directory is which you can find the 
634
	 * Eclipse executable.
635
	 * </p>
636
	 *
637
	 * @param baselineLocation the given location for the baseline to analyze
638
	 */
639
	public void setProfile(String baselineLocation) {
640
		this.currentBaselineLocation = baselineLocation;
641
	}
642
643
	/**
644
	 * Comma-separated list of the locations of the API Use Scans that you want to check against
645
	 * the reference baseline.
646
	 * 
647
	 * <p>It can be a .zip, .jar, .tgz, .tar.gz file, or a directory that corresponds to 
648
	 * the API Use Scan report. This is the directory is which you can find the 
649
	 * XML folder.
650
	 * </p>
651
	 *
652
	 * @param baselineLocation the given location for the baseline to analyze
653
	 */
654
	public void setAPIUseScans(String apiUseScans) {
655
		fAPIUseScans = apiUseScans.split(";"); //$NON-NLS-1$		
656
	}
657
658
	/*	*//**
659
			* Set the location of the reference baseline.
660
			* 
661
			* <p>It can be a .zip, .jar, .tgz, .tar.gz file, or a directory that corresponds to 
662
			* the Eclipse installation folder. This is the directory is which you can find the 
663
			* Eclipse executable.
664
			* </p>
665
			* <p>The location is set using an absolute path.</p>
666
			*
667
			* @param baselineLocation the given location for the reference baseline to analyze
668
			*/
669
	/*
670
	public void setBaseline(String baselineLocation) {
671
	this.referenceBaselineLocation = baselineLocation;
672
	}*/
673
	/**
674
	 * Set the output location where the reports will be generated.
675
	 * 
676
	 * <p>Once the task is completed, reports are available in this directory using a structure
677
	 * similar to the filter root. A sub-folder is created for each component that has problems
678
	 * to be reported. Each sub-folder contains a file called "report.xml". </p>
679
	 * 
680
	 * <p>A special folder called "allNonApiBundles" is also created in this folder that contains a xml file called
681
	 * "report.xml". This file lists all the bundles that are not using the api tooling nature.</p>
682
	 * 
683
	 * @param baselineLocation the given location for the reference baseline to analyze
684
	 */
685
	public void setReport(String reportLocation) {
686
		this.reportLocation = reportLocation;
687
	}
688
}

Return to bug 332763