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

Collapse All | Expand All

(-)src/org/eclipse/pde/api/tools/internal/ApiBaselineManager.java (-7 / +15 lines)
Lines 23-28 Link Here
23
import java.util.HashSet;
23
import java.util.HashSet;
24
import java.util.Iterator;
24
import java.util.Iterator;
25
import java.util.List;
25
import java.util.List;
26
import java.util.Set;
26
27
27
import javax.xml.parsers.DocumentBuilder;
28
import javax.xml.parsers.DocumentBuilder;
28
import javax.xml.parsers.DocumentBuilderFactory;
29
import javax.xml.parsers.DocumentBuilderFactory;
Lines 59-64 Link Here
59
import org.eclipse.pde.api.tools.internal.model.ApiModelCache;
60
import org.eclipse.pde.api.tools.internal.model.ApiModelCache;
60
import org.eclipse.pde.api.tools.internal.model.ApiModelFactory;
61
import org.eclipse.pde.api.tools.internal.model.ApiModelFactory;
61
import org.eclipse.pde.api.tools.internal.model.StubApiComponent;
62
import org.eclipse.pde.api.tools.internal.model.StubApiComponent;
63
import org.eclipse.pde.api.tools.internal.model.WorkspaceBaseline;
62
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
64
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
63
import org.eclipse.pde.api.tools.internal.provisional.IApiBaselineManager;
65
import org.eclipse.pde.api.tools.internal.provisional.IApiBaselineManager;
64
import org.eclipse.pde.api.tools.internal.provisional.model.IApiBaseline;
66
import org.eclipse.pde.api.tools.internal.provisional.model.IApiBaseline;
Lines 66-71 Link Here
66
import org.eclipse.pde.api.tools.internal.util.Util;
68
import org.eclipse.pde.api.tools.internal.util.Util;
67
import org.eclipse.pde.core.plugin.IPluginModelBase;
69
import org.eclipse.pde.core.plugin.IPluginModelBase;
68
import org.eclipse.pde.core.plugin.PluginRegistry;
70
import org.eclipse.pde.core.plugin.PluginRegistry;
71
import org.eclipse.pde.internal.core.DependencyManager;
69
import org.w3c.dom.Document;
72
import org.w3c.dom.Document;
70
import org.w3c.dom.Element;
73
import org.w3c.dom.Element;
71
import org.w3c.dom.NodeList;
74
import org.w3c.dom.NodeList;
Lines 403-409 Link Here
403
			IApiComponent comp = components[i];
406
			IApiComponent comp = components[i];
404
			if (!comp.isSystemComponent()) {
407
			if (!comp.isSystemComponent()) {
405
				celement = document.createElement(IApiXmlConstants.ELEMENT_APICOMPONENT);
408
				celement = document.createElement(IApiXmlConstants.ELEMENT_APICOMPONENT);
406
				celement.setAttribute(IApiXmlConstants.ATTR_ID, comp.getId());
409
				celement.setAttribute(IApiXmlConstants.ATTR_ID, comp.getSymbolicName());
407
				celement.setAttribute(IApiXmlConstants.ATTR_VERSION, comp.getVersion());
410
				celement.setAttribute(IApiXmlConstants.ATTR_VERSION, comp.getVersion());
408
				celement.setAttribute(IApiXmlConstants.ATTR_LOCATION, new Path(comp.getLocation()).toPortableString());
411
				celement.setAttribute(IApiXmlConstants.ATTR_LOCATION, new Path(comp.getLocation()).toPortableString());
409
				root.appendChild(celement);
412
				root.appendChild(celement);
Lines 665-678 Link Here
665
		long time = System.currentTimeMillis();
668
		long time = System.currentTimeMillis();
666
		IApiBaseline baseline = null; 
669
		IApiBaseline baseline = null; 
667
		try {
670
		try {
668
			baseline = ApiModelFactory.newApiBaseline(ApiBaselineManager.WORKSPACE_API_BASELINE_ID);
671
			baseline = new WorkspaceBaseline();
669
			// populate it with only projects that are API aware
672
			// populate it with only projects that are API aware
670
			IPluginModelBase[] models = PluginRegistry.getActiveModels();
673
			Set ids = DependencyManager.getSelfandDependencies(PluginRegistry.getWorkspaceModels(), null);
671
			List componentsList = new ArrayList(models.length);
674
			List componentsList = new ArrayList(ids.size());
672
			IApiComponent apiComponent = null;
675
			IApiComponent apiComponent = null;
673
			for (int i = 0, length = models.length; i < length; i++) {
676
			IPluginModelBase model = null;
677
			for (Iterator iter = ids.iterator(); iter.hasNext();) {
678
				model = PluginRegistry.findModel((String) iter.next());
679
				if(model == null) {
680
					continue;
681
				}
674
				try {
682
				try {
675
					apiComponent = ApiModelFactory.newApiComponent(baseline, models[i]);
683
					apiComponent = ApiModelFactory.newApiComponent(baseline, model);
676
					if (apiComponent != null) {
684
					if (apiComponent != null) {
677
						componentsList.add(apiComponent);
685
						componentsList.add(apiComponent);
678
					}
686
					}
Lines 683-689 Link Here
683
			baseline.addApiComponents((IApiComponent[]) componentsList.toArray(new IApiComponent[componentsList.size()]));
691
			baseline.addApiComponents((IApiComponent[]) componentsList.toArray(new IApiComponent[componentsList.size()]));
684
		} finally {
692
		} finally {
685
			if (DEBUG) {
693
			if (DEBUG) {
686
				System.out.println("Time to create a workspace profile : " + (System.currentTimeMillis() - time) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
694
				System.out.println("Time to create a workspace baseline : " + (System.currentTimeMillis() - time) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
687
			}
695
			}
688
		}
696
		}
689
		return baseline;
697
		return baseline;
(-)src/org/eclipse/pde/api/tools/internal/ApiDescriptionManager.java (-2 / +2 lines)
Lines 41-47 Link Here
41
import org.eclipse.pde.api.tools.internal.ApiDescription.ManifestNode;
41
import org.eclipse.pde.api.tools.internal.ApiDescription.ManifestNode;
42
import org.eclipse.pde.api.tools.internal.ProjectApiDescription.TypeNode;
42
import org.eclipse.pde.api.tools.internal.ProjectApiDescription.TypeNode;
43
import org.eclipse.pde.api.tools.internal.model.ApiModelCache;
43
import org.eclipse.pde.api.tools.internal.model.ApiModelCache;
44
import org.eclipse.pde.api.tools.internal.model.PluginProjectApiComponent;
44
import org.eclipse.pde.api.tools.internal.model.ProjectComponent;
45
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
45
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
46
import org.eclipse.pde.api.tools.internal.provisional.Factory;
46
import org.eclipse.pde.api.tools.internal.provisional.Factory;
47
import org.eclipse.pde.api.tools.internal.provisional.IApiDescription;
47
import org.eclipse.pde.api.tools.internal.provisional.IApiDescription;
Lines 118-124 Link Here
118
	 * @param project Java project
118
	 * @param project Java project
119
	 * @return API description
119
	 * @return API description
120
	 */
120
	 */
121
	public synchronized IApiDescription getApiDescription(PluginProjectApiComponent component, BundleDescription bundle) {
121
	public synchronized IApiDescription getApiDescription(ProjectComponent component, BundleDescription bundle) {
122
		IJavaProject project = component.getJavaProject();
122
		IJavaProject project = component.getJavaProject();
123
		ProjectApiDescription description = (ProjectApiDescription) fDescriptions.get(project);
123
		ProjectApiDescription description = (ProjectApiDescription) fDescriptions.get(project);
124
		if (description == null) {
124
		if (description == null) {
(-)src/org/eclipse/pde/api/tools/internal/ApiDescriptionXmlCreator.java (-1 / +1 lines)
Lines 72-78 Link Here
72
	 * @throws CoreException if unable to construct the visitor
72
	 * @throws CoreException if unable to construct the visitor
73
	 */
73
	 */
74
	public ApiDescriptionXmlCreator(IApiComponent component) throws CoreException {
74
	public ApiDescriptionXmlCreator(IApiComponent component) throws CoreException {
75
		this(component.getName(), component.getId());
75
		this(component.getName(), component.getSymbolicName());
76
	}
76
	}
77
77
78
	/**
78
	/**
(-)src/org/eclipse/pde/api/tools/internal/ProjectApiDescription.java (-6 / +6 lines)
Lines 33-40 Link Here
33
import org.eclipse.jdt.core.IPackageFragmentRoot;
33
import org.eclipse.jdt.core.IPackageFragmentRoot;
34
import org.eclipse.jdt.core.IType;
34
import org.eclipse.jdt.core.IType;
35
import org.eclipse.jdt.core.JavaModelException;
35
import org.eclipse.jdt.core.JavaModelException;
36
import org.eclipse.pde.api.tools.internal.model.BundleApiComponent;
36
import org.eclipse.pde.api.tools.internal.model.BundleComponent;
37
import org.eclipse.pde.api.tools.internal.model.PluginProjectApiComponent;
37
import org.eclipse.pde.api.tools.internal.model.ProjectComponent;
38
import org.eclipse.pde.api.tools.internal.provisional.ApiDescriptionVisitor;
38
import org.eclipse.pde.api.tools.internal.provisional.ApiDescriptionVisitor;
39
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
39
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
40
import org.eclipse.pde.api.tools.internal.provisional.Factory;
40
import org.eclipse.pde.api.tools.internal.provisional.Factory;
Lines 563-570 Link Here
563
						for (int i = 0; i < fragments.length; i++) {
563
						for (int i = 0; i < fragments.length; i++) {
564
							names.add(fragments[i].getElementName());
564
							names.add(fragments[i].getElementName());
565
						}
565
						}
566
						PluginProjectApiComponent component = getApiComponent();
566
						ProjectComponent component = getApiComponent();
567
						BundleApiComponent.initializeApiDescription(this, component.getBundleDescription(), names);
567
						BundleComponent.initializeApiDescription(this, component.getBundleDescription(), names);
568
						fPackageTimeStamp = fManifestFile.getModificationStamp();
568
						fPackageTimeStamp = fManifestFile.getModificationStamp();
569
					} catch (CoreException e) {
569
					} catch (CoreException e) {
570
						ApiPlugin.log(e.getStatus());
570
						ApiPlugin.log(e.getStatus());
Lines 712-720 Link Here
712
	 * @return API component
712
	 * @return API component
713
	 * @exception CoreException if the API component cannot be located
713
	 * @exception CoreException if the API component cannot be located
714
	 */
714
	 */
715
	private PluginProjectApiComponent getApiComponent() throws CoreException {
715
	private ProjectComponent getApiComponent() throws CoreException {
716
		IApiBaseline baseline = ApiBaselineManager.getManager().getWorkspaceBaseline();
716
		IApiBaseline baseline = ApiBaselineManager.getManager().getWorkspaceBaseline();
717
		PluginProjectApiComponent component = (PluginProjectApiComponent) baseline.getApiComponent(getJavaProject().getProject());
717
		ProjectComponent component = (ProjectComponent) baseline.getApiComponent(getJavaProject().getProject());
718
		if (component == null) {
718
		if (component == null) {
719
			throw new CoreException(new Status(IStatus.ERROR, ApiPlugin.PLUGIN_ID, "Unable to resolve project API component for API description"));  //$NON-NLS-1$
719
			throw new CoreException(new Status(IStatus.ERROR, ApiPlugin.PLUGIN_ID, "Unable to resolve project API component for API description"));  //$NON-NLS-1$
720
		}
720
		}
(-)src/org/eclipse/pde/api/tools/internal/builder/AbstractIllegalMethodReference.java (-1 / +1 lines)
Lines 72-78 Link Here
72
		IApiMember method = reference.getResolvedReference();
72
		IApiMember method = reference.getResolvedReference();
73
		String componentId = (String) fMethodComponents.get(method.getHandle());
73
		String componentId = (String) fMethodComponents.get(method.getHandle());
74
		// TODO: would it be faster to store component objects and use identity instead of equals?
74
		// TODO: would it be faster to store component objects and use identity instead of equals?
75
		return componentId != null && method.getApiComponent().getId().equals(componentId);
75
		return componentId != null && method.getApiComponent().getSymbolicName().equals(componentId);
76
	}
76
	}
77
	
77
	
78
	/* (non-Javadoc)
78
	/* (non-Javadoc)
(-)src/org/eclipse/pde/api/tools/internal/builder/AbstractIllegalTypeReference.java (-1 / +1 lines)
Lines 79-85 Link Here
79
		}
79
		}
80
		IApiMember type = reference.getResolvedReference();
80
		IApiMember type = reference.getResolvedReference();
81
		Object componentId = fIllegalTypes.get(type.getName());
81
		Object componentId = fIllegalTypes.get(type.getName());
82
		return componentId != null && type.getApiComponent().getId().equals(componentId);
82
		return componentId != null && type.getApiComponent().getSymbolicName().equals(componentId);
83
	}
83
	}
84
	/* (non-Javadoc)
84
	/* (non-Javadoc)
85
	 * @see org.eclipse.pde.api.tools.internal.search.AbstractProblemDetector#getSourceRange(org.eclipse.jdt.core.IType, org.eclipse.jface.text.IDocument, org.eclipse.pde.api.tools.internal.provisional.model.IReference)
85
	 * @see org.eclipse.pde.api.tools.internal.search.AbstractProblemDetector#getSourceRange(org.eclipse.jdt.core.IType, org.eclipse.jface.text.IDocument, org.eclipse.pde.api.tools.internal.provisional.model.IReference)
(-)src/org/eclipse/pde/api/tools/internal/builder/AbstractProblemDetector.java (-3 / +3 lines)
Lines 31-37 Link Here
31
import org.eclipse.jface.text.BadLocationException;
31
import org.eclipse.jface.text.BadLocationException;
32
import org.eclipse.jface.text.IDocument;
32
import org.eclipse.jface.text.IDocument;
33
import org.eclipse.jface.text.Position;
33
import org.eclipse.jface.text.Position;
34
import org.eclipse.pde.api.tools.internal.model.PluginProjectApiComponent;
34
import org.eclipse.pde.api.tools.internal.model.ProjectComponent;
35
import org.eclipse.pde.api.tools.internal.problems.ApiProblemFactory;
35
import org.eclipse.pde.api.tools.internal.problems.ApiProblemFactory;
36
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
36
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
37
import org.eclipse.pde.api.tools.internal.provisional.IApiMarkerConstants;
37
import org.eclipse.pde.api.tools.internal.provisional.IApiMarkerConstants;
Lines 368-375 Link Here
368
					try {
368
					try {
369
						IApiProblem problem = null;
369
						IApiProblem problem = null;
370
						IApiComponent component = reference.getMember().getApiComponent();
370
						IApiComponent component = reference.getMember().getApiComponent();
371
						if (component instanceof PluginProjectApiComponent) {
371
						if (component instanceof ProjectComponent) {
372
							PluginProjectApiComponent ppac = (PluginProjectApiComponent) component;
372
							ProjectComponent ppac = (ProjectComponent) component;
373
							IJavaProject project = ppac.getJavaProject();
373
							IJavaProject project = ppac.getJavaProject();
374
							problem = createProblem(reference, project);
374
							problem = createProblem(reference, project);
375
						} else {
375
						} else {
(-)src/org/eclipse/pde/api/tools/internal/builder/BaseApiAnalyzer.java (-18 / +18 lines)
Lines 59-65 Link Here
59
import org.eclipse.pde.api.tools.internal.ApiFilterStore;
59
import org.eclipse.pde.api.tools.internal.ApiFilterStore;
60
import org.eclipse.pde.api.tools.internal.IApiCoreConstants;
60
import org.eclipse.pde.api.tools.internal.IApiCoreConstants;
61
import org.eclipse.pde.api.tools.internal.comparator.Delta;
61
import org.eclipse.pde.api.tools.internal.comparator.Delta;
62
import org.eclipse.pde.api.tools.internal.model.PluginProjectApiComponent;
62
import org.eclipse.pde.api.tools.internal.model.ProjectComponent;
63
import org.eclipse.pde.api.tools.internal.problems.ApiProblemFactory;
63
import org.eclipse.pde.api.tools.internal.problems.ApiProblemFactory;
64
import org.eclipse.pde.api.tools.internal.problems.ApiProblemFilter;
64
import org.eclipse.pde.api.tools.internal.problems.ApiProblemFilter;
65
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
65
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
Lines 218-231 Link Here
218
			}
218
			}
219
			boolean checkfilters = false;
219
			boolean checkfilters = false;
220
			if(baseline != null) {
220
			if(baseline != null) {
221
				IApiComponent reference = baseline.getApiComponent(component.getId());
221
				IApiComponent reference = baseline.getApiComponent(component.getSymbolicName());
222
				this.fBuildState = state;
222
				this.fBuildState = state;
223
				if(fBuildState == null) {
223
				if(fBuildState == null) {
224
					fBuildState = getBuildState();
224
					fBuildState = getBuildState();
225
				}
225
				}
226
				//compatibility checks
226
				//compatibility checks
227
				if(reference != null) {
227
				if(reference != null) {
228
					localMonitor.subTask(NLS.bind(BuilderMessages.BaseApiAnalyzer_comparing_api_profiles, new String[] {reference.getId(), baseline.getName()}));
228
					localMonitor.subTask(NLS.bind(BuilderMessages.BaseApiAnalyzer_comparing_api_profiles, new String[] {reference.getSymbolicName(), baseline.getName()}));
229
					if(bcontext.hasChangedTypes()) {
229
					if(bcontext.hasChangedTypes()) {
230
						String[] changedtypes = bcontext.getStructurallyChangedTypes();
230
						String[] changedtypes = bcontext.getStructurallyChangedTypes();
231
						for(int i = 0; i < changedtypes.length; i++) {
231
						for(int i = 0; i < changedtypes.length; i++) {
Lines 242-248 Link Here
242
					}
242
					}
243
					this.fBuildState.setReexportedComponents(Util.getReexportedComponents(component));
243
					this.fBuildState.setReexportedComponents(Util.getReexportedComponents(component));
244
				} else {
244
				} else {
245
					localMonitor.subTask(NLS.bind(BuilderMessages.BaseApiAnalyzer_comparing_api_profiles, new String[] {component.getId(), baseline.getName()}));
245
					localMonitor.subTask(NLS.bind(BuilderMessages.BaseApiAnalyzer_comparing_api_profiles, new String[] {component.getSymbolicName(), baseline.getName()}));
246
					checkCompatibility(null, component, localMonitor.newChild(1));
246
					checkCompatibility(null, component, localMonitor.newChild(1));
247
					Util.updateMonitor(localMonitor);
247
					Util.updateMonitor(localMonitor);
248
				}
248
				}
Lines 823-829 Link Here
823
			}
823
			}
824
			scope = getSearchScope(component, (String[]) typenames.toArray(new String[typenames.size()]));
824
			scope = getSearchScope(component, (String[]) typenames.toArray(new String[typenames.size()]));
825
		}
825
		}
826
		SubMonitor localMonitor = SubMonitor.convert(monitor, MessageFormat.format(BuilderMessages.checking_api_usage, new String[] {component.getId()}), 2);
826
		SubMonitor localMonitor = SubMonitor.convert(monitor, MessageFormat.format(BuilderMessages.checking_api_usage, new String[] {component.getSymbolicName()}), 2);
827
		ReferenceAnalyzer analyzer = new ReferenceAnalyzer();
827
		ReferenceAnalyzer analyzer = new ReferenceAnalyzer();
828
		try {
828
		try {
829
			long start = System.currentTimeMillis();
829
			long start = System.currentTimeMillis();
Lines 858-866 Link Here
858
	 * @param monitor
858
	 * @param monitor
859
	 */
859
	 */
860
	private void checkCompatibility(final String typeName, final IApiComponent reference, final IApiComponent component, IProgressMonitor monitor) throws CoreException {
860
	private void checkCompatibility(final String typeName, final IApiComponent reference, final IApiComponent component, IProgressMonitor monitor) throws CoreException {
861
		String id = component.getId();
861
		String id = component.getSymbolicName();
862
		if (DEBUG) {
862
		if (DEBUG) {
863
			System.out.println("comparing profiles ["+reference.getId()+"] and ["+id+"] for type ["+typeName+"]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
863
			System.out.println("comparing profiles ["+reference.getSymbolicName()+"] and ["+id+"] for type ["+typeName+"]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
864
		}
864
		}
865
		IApiTypeRoot classFile = null;
865
		IApiTypeRoot classFile = null;
866
		try {
866
		try {
Lines 884-890 Link Here
884
				while (classFile == null && index < providers.length) {
884
				while (classFile == null && index < providers.length) {
885
					IApiComponent p = providers[index];
885
					IApiComponent p = providers[index];
886
					if (!p.equals(component)) {
886
					if (!p.equals(component)) {
887
						String id2 = p.getId();
887
						String id2 = p.getSymbolicName();
888
						if (Util.ORG_ECLIPSE_SWT.equals(id2)) {
888
						if (Util.ORG_ECLIPSE_SWT.equals(id2)) {
889
							classFile = p.findTypeRoot(typeName);
889
							classFile = p.findTypeRoot(typeName);
890
						} else {
890
						} else {
Lines 1011-1025 Link Here
1011
						IDelta.ADDED,
1011
						IDelta.ADDED,
1012
						IDelta.API_COMPONENT,
1012
						IDelta.API_COMPONENT,
1013
						null,
1013
						null,
1014
						component.getId(),
1014
						component.getSymbolicName(),
1015
						component.getId());
1015
						component.getSymbolicName());
1016
				Util.updateMonitor(localmonitor, 5);
1016
				Util.updateMonitor(localmonitor, 5);
1017
			} else {
1017
			} else {
1018
				try {
1018
				try {
1019
					delta = ApiComparator.compare(reference, component, VisibilityModifiers.API, localmonitor.newChild(1));
1019
					delta = ApiComparator.compare(reference, component, VisibilityModifiers.API, localmonitor.newChild(1));
1020
				} finally {
1020
				} finally {
1021
					if (DEBUG) {
1021
					if (DEBUG) {
1022
						System.out.println("Time spent for " + component.getId() + " : " + (System.currentTimeMillis() - time) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
1022
						System.out.println("Time spent for " + component.getSymbolicName() + " : " + (System.currentTimeMillis() - time) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
1023
					}
1023
					}
1024
					fPendingDeltaInfos.clear();
1024
					fPendingDeltaInfos.clear();
1025
				}
1025
				}
Lines 1350-1356 Link Here
1350
	private void createApiComponentResolutionProblem(final IApiComponent component, final String message) throws CoreException {
1350
	private void createApiComponentResolutionProblem(final IApiComponent component, final String message) throws CoreException {
1351
		IApiProblem problem = ApiProblemFactory.newApiComponentResolutionProblem(
1351
		IApiProblem problem = ApiProblemFactory.newApiComponentResolutionProblem(
1352
				Path.EMPTY.toPortableString(),
1352
				Path.EMPTY.toPortableString(),
1353
				new String[] {component.getId(), message },
1353
				new String[] {component.getSymbolicName(), message },
1354
				new String[] {IApiMarkerConstants.API_MARKER_ATTR_ID},
1354
				new String[] {IApiMarkerConstants.API_MARKER_ATTR_ID},
1355
				new Object[] {new Integer(IApiMarkerConstants.API_COMPONENT_RESOLUTION_MARKER_ID)},
1355
				new Object[] {new Integer(IApiMarkerConstants.API_COMPONENT_RESOLUTION_MARKER_ID)},
1356
				IElementDescriptor.RESOURCE,
1356
				IElementDescriptor.RESOURCE,
Lines 1377-1383 Link Here
1377
							IApiTypeRoot typeRoot = null;
1377
							IApiTypeRoot typeRoot = null;
1378
							IApiType type = null;
1378
							IApiType type = null;
1379
							try {
1379
							try {
1380
								String id = component.getId();
1380
								String id = component.getSymbolicName();
1381
								if (Util.ORG_ECLIPSE_SWT.equals(id)) {
1381
								if (Util.ORG_ECLIPSE_SWT.equals(id)) {
1382
									typeRoot = component.findTypeRoot(typeName);
1382
									typeRoot = component.findTypeRoot(typeName);
1383
								} else {
1383
								} else {
Lines 1391-1397 Link Here
1391
									while (typeRoot == null && index < providers.length) {
1391
									while (typeRoot == null && index < providers.length) {
1392
										IApiComponent p = providers[index];
1392
										IApiComponent p = providers[index];
1393
										if (!p.equals(component)) {
1393
										if (!p.equals(component)) {
1394
											String id2 = p.getId();
1394
											String id2 = p.getSymbolicName();
1395
											if (Util.ORG_ECLIPSE_SWT.equals(id2)) {
1395
											if (Util.ORG_ECLIPSE_SWT.equals(id2)) {
1396
												typeRoot = p.findTypeRoot(typeName);
1396
												typeRoot = p.findTypeRoot(typeName);
1397
											} else {
1397
											} else {
Lines 1496-1503 Link Here
1496
		Version compversion = new Version(compversionval);
1496
		Version compversion = new Version(compversionval);
1497
		Version newversion = null;
1497
		Version newversion = null;
1498
		if (DEBUG) {
1498
		if (DEBUG) {
1499
			System.out.println("reference version of " + reference.getId() + " : " + refversion); //$NON-NLS-1$ //$NON-NLS-2$
1499
			System.out.println("reference version of " + reference.getSymbolicName() + " : " + refversion); //$NON-NLS-1$ //$NON-NLS-2$
1500
			System.out.println("component version of " + component.getId() + " : " + compversion); //$NON-NLS-1$ //$NON-NLS-2$
1500
			System.out.println("component version of " + component.getSymbolicName() + " : " + compversion); //$NON-NLS-1$ //$NON-NLS-2$
1501
		}
1501
		}
1502
		IDelta[] breakingChanges = fBuildState.getBreakingChanges();
1502
		IDelta[] breakingChanges = fBuildState.getBreakingChanges();
1503
		if (breakingChanges.length != 0) {
1503
		if (breakingChanges.length != 0) {
Lines 1835-1842 Link Here
1835
	 * @return Java project or <code>null</code>
1835
	 * @return Java project or <code>null</code>
1836
	 */
1836
	 */
1837
	private IJavaProject getJavaProject(IApiComponent component) {
1837
	private IJavaProject getJavaProject(IApiComponent component) {
1838
		if (component instanceof PluginProjectApiComponent) {
1838
		if (component instanceof ProjectComponent) {
1839
			PluginProjectApiComponent pp = (PluginProjectApiComponent) component;
1839
			ProjectComponent pp = (ProjectComponent) component;
1840
			return pp.getJavaProject();
1840
			return pp.getJavaProject();
1841
		}
1841
		}
1842
		return null;
1842
		return null;
(-)src/org/eclipse/pde/api/tools/internal/builder/BuildState.java (-1 / +1 lines)
Lines 315-321 Link Here
315
			final int length = components.length;
315
			final int length = components.length;
316
			String[] result = new String[length];
316
			String[] result = new String[length];
317
			for (int i = 0; i < length; i++) {
317
			for (int i = 0; i < length; i++) {
318
				result[i] = components[i].getId();
318
				result[i] = components[i].getSymbolicName();
319
			}
319
			}
320
			this.reexportedComponents = result;
320
			this.reexportedComponents = result;
321
		}
321
		}
(-)src/org/eclipse/pde/api/tools/internal/builder/IllegalFieldReferenceDetector.java (-1 / +1 lines)
Lines 144-149 Link Here
144
			return false;
144
			return false;
145
		}
145
		}
146
		Object componentId = fFieldComponents.get(reference.getResolvedReference().getHandle());
146
		Object componentId = fFieldComponents.get(reference.getResolvedReference().getHandle());
147
		return componentId != null && reference.getResolvedReference().getApiComponent().getId().equals(componentId);
147
		return componentId != null && reference.getResolvedReference().getApiComponent().getSymbolicName().equals(componentId);
148
	}
148
	}
149
}
149
}
(-)src/org/eclipse/pde/api/tools/internal/builder/ProblemDetectorBuilder.java (-9 / +9 lines)
Lines 16-22 Link Here
16
import java.util.Set;
16
import java.util.Set;
17
17
18
import org.eclipse.core.resources.IProject;
18
import org.eclipse.core.resources.IProject;
19
import org.eclipse.pde.api.tools.internal.model.PluginProjectApiComponent;
19
import org.eclipse.pde.api.tools.internal.model.ProjectComponent;
20
import org.eclipse.pde.api.tools.internal.provisional.ApiDescriptionVisitor;
20
import org.eclipse.pde.api.tools.internal.provisional.ApiDescriptionVisitor;
21
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
21
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
22
import org.eclipse.pde.api.tools.internal.provisional.IApiAnnotations;
22
import org.eclipse.pde.api.tools.internal.provisional.IApiAnnotations;
Lines 86-107 Link Here
86
			default:
86
			default:
87
				if (!RestrictionModifiers.isUnrestricted(mask)) {
87
				if (!RestrictionModifiers.isUnrestricted(mask)) {
88
					if(RestrictionModifiers.isOverrideRestriction(mask) && fIllegalOverride != null) {
88
					if(RestrictionModifiers.isOverrideRestriction(mask) && fIllegalOverride != null) {
89
						fIllegalOverride.addIllegalMethod((IMethodDescriptor) element, fComponent.getId());
89
						fIllegalOverride.addIllegalMethod((IMethodDescriptor) element, fComponent.getSymbolicName());
90
					}
90
					}
91
					if (RestrictionModifiers.isExtendRestriction(mask) && fIllegalExtends != null) {
91
					if (RestrictionModifiers.isExtendRestriction(mask) && fIllegalExtends != null) {
92
						fIllegalExtends.addIllegalType((IReferenceTypeDescriptor) element, fComponent.getId());
92
						fIllegalExtends.addIllegalType((IReferenceTypeDescriptor) element, fComponent.getSymbolicName());
93
					}
93
					}
94
					if (RestrictionModifiers.isImplementRestriction(mask) && fIllegalImplements != null) {
94
					if (RestrictionModifiers.isImplementRestriction(mask) && fIllegalImplements != null) {
95
						fIllegalImplements.addIllegalType((IReferenceTypeDescriptor) element, fComponent.getId());
95
						fIllegalImplements.addIllegalType((IReferenceTypeDescriptor) element, fComponent.getSymbolicName());
96
					}
96
					}
97
					if (RestrictionModifiers.isInstantiateRestriction(mask) && fIllegalInstantiate != null) {
97
					if (RestrictionModifiers.isInstantiateRestriction(mask) && fIllegalInstantiate != null) {
98
						fIllegalInstantiate.addIllegalType((IReferenceTypeDescriptor) element, fComponent.getId());
98
						fIllegalInstantiate.addIllegalType((IReferenceTypeDescriptor) element, fComponent.getSymbolicName());
99
					}
99
					}
100
					if (RestrictionModifiers.isReferenceRestriction(mask)) {
100
					if (RestrictionModifiers.isReferenceRestriction(mask)) {
101
						if (element.getElementType() == IElementDescriptor.METHOD && fIllegalMethodRef != null) {
101
						if (element.getElementType() == IElementDescriptor.METHOD && fIllegalMethodRef != null) {
102
							fIllegalMethodRef.addIllegalMethod((IMethodDescriptor) element, fComponent.getId());
102
							fIllegalMethodRef.addIllegalMethod((IMethodDescriptor) element, fComponent.getSymbolicName());
103
						} else if (element.getElementType() == IElementDescriptor.FIELD && fIllegalFieldRef != null) {
103
						} else if (element.getElementType() == IElementDescriptor.FIELD && fIllegalFieldRef != null) {
104
							fIllegalFieldRef.addIllegalField((IFieldDescriptor) element, fComponent.getId());
104
							fIllegalFieldRef.addIllegalField((IFieldDescriptor) element, fComponent.getSymbolicName());
105
						}
105
						}
106
					}
106
					}
107
				}
107
				}
Lines 122-129 Link Here
122
	 * if the component is not a {@link PluginProjectApiComponent}
122
	 * if the component is not a {@link PluginProjectApiComponent}
123
	 */
123
	 */
124
	private IProject getProject(IApiComponent component) {
124
	private IProject getProject(IApiComponent component) {
125
		if(component instanceof PluginProjectApiComponent) {
125
		if(component instanceof ProjectComponent) {
126
			PluginProjectApiComponent comp = (PluginProjectApiComponent) component;
126
			ProjectComponent comp = (ProjectComponent) component;
127
			return comp.getJavaProject().getProject();
127
			return comp.getJavaProject().getProject();
128
		}
128
		}
129
		return null;
129
		return null;
(-)src/org/eclipse/pde/api/tools/internal/builder/Reference.java (-2 / +2 lines)
Lines 643-654 Link Here
643
			visibility = annot.getVisibility();
643
			visibility = annot.getVisibility();
644
			if(annot.getVisibility() == VisibilityModifiers.PRIVATE) {
644
			if(annot.getVisibility() == VisibilityModifiers.PRIVATE) {
645
				IApiComponent host = mcomponent.getHost();
645
				IApiComponent host = mcomponent.getHost();
646
				if(host != null && host.getId().equals(rcomponent.getId())) {
646
				if(host != null && host.getSymbolicName().equals(rcomponent.getSymbolicName())) {
647
					visibility = UseReportConverter.FRAGMENT_PERMISSIBLE;
647
					visibility = UseReportConverter.FRAGMENT_PERMISSIBLE;
648
				}
648
				}
649
				else {
649
				else {
650
					IApiAccess access = description.resolveAccessLevel(
650
					IApiAccess access = description.resolveAccessLevel(
651
							Factory.componentDescriptor(mcomponent.getId()),  // component descriptors in API description are not version qualified
651
							Factory.componentDescriptor(mcomponent.getSymbolicName()),  // component descriptors in API description are not version qualified
652
							getResolvedReference().getHandle().getPackage());
652
							getResolvedReference().getHandle().getPackage());
653
					if(access != null && access.getAccessLevel() == IApiAccess.FRIEND) {
653
					if(access != null && access.getAccessLevel() == IApiAccess.FRIEND) {
654
						visibility = VisibilityModifiers.PRIVATE_PERMISSIBLE;
654
						visibility = VisibilityModifiers.PRIVATE_PERMISSIBLE;
(-)src/org/eclipse/pde/api/tools/internal/builder/ReferenceResolver.java (-1 / +1 lines)
Lines 145-151 Link Here
145
	 */
145
	 */
146
	private static String createSignatureKey(IReference reference) throws CoreException {
146
	private static String createSignatureKey(IReference reference) throws CoreException {
147
		StringBuffer buffer = new StringBuffer();
147
		StringBuffer buffer = new StringBuffer();
148
		buffer.append(reference.getMember().getApiComponent().getId());
148
		buffer.append(reference.getMember().getApiComponent().getSymbolicName());
149
		buffer.append("#"); //$NON-NLS-1$
149
		buffer.append("#"); //$NON-NLS-1$
150
		buffer.append(reference.getReferencedTypeName());
150
		buffer.append(reference.getReferencedTypeName());
151
		switch (reference.getReferenceType()) {
151
		switch (reference.getReferenceType()) {
(-)src/org/eclipse/pde/api/tools/internal/builder/SystemApiDetector.java (-6 / +6 lines)
Lines 26-33 Link Here
26
import org.eclipse.jface.text.Position;
26
import org.eclipse.jface.text.Position;
27
import org.eclipse.osgi.service.resolver.BundleDescription;
27
import org.eclipse.osgi.service.resolver.BundleDescription;
28
import org.eclipse.osgi.service.resolver.ImportPackageSpecification;
28
import org.eclipse.osgi.service.resolver.ImportPackageSpecification;
29
import org.eclipse.pde.api.tools.internal.model.BundleApiComponent;
29
import org.eclipse.pde.api.tools.internal.model.BundleComponent;
30
import org.eclipse.pde.api.tools.internal.model.PluginProjectApiComponent;
30
import org.eclipse.pde.api.tools.internal.model.ProjectComponent;
31
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
31
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
32
import org.eclipse.pde.api.tools.internal.provisional.ProfileModifiers;
32
import org.eclipse.pde.api.tools.internal.provisional.ProfileModifiers;
33
import org.eclipse.pde.api.tools.internal.provisional.builder.IReference;
33
import org.eclipse.pde.api.tools.internal.provisional.builder.IReference;
Lines 353-360 Link Here
353
					 * Make sure that the resolved reference doesn't below to one of the imported package of
353
					 * Make sure that the resolved reference doesn't below to one of the imported package of
354
					 * the current component
354
					 * the current component
355
					 */
355
					 */
356
					if (apiComponent instanceof BundleApiComponent) {
356
					if (apiComponent instanceof BundleComponent) {
357
						BundleDescription bundle = ((BundleApiComponent)apiComponent).getBundleDescription();
357
						BundleDescription bundle = ((BundleComponent)apiComponent).getBundleDescription();
358
						ImportPackageSpecification[] importPackages = bundle.getImportPackages();
358
						ImportPackageSpecification[] importPackages = bundle.getImportPackages();
359
						String referencedTypeName = reference.getReferencedTypeName();
359
						String referencedTypeName = reference.getReferencedTypeName();
360
						int index = referencedTypeName.lastIndexOf('.');
360
						int index = referencedTypeName.lastIndexOf('.');
Lines 434-441 Link Here
434
				try {
434
				try {
435
					IApiProblem problem = null;
435
					IApiProblem problem = null;
436
					IApiComponent component = reference.getMember().getApiComponent();
436
					IApiComponent component = reference.getMember().getApiComponent();
437
					if (component instanceof PluginProjectApiComponent) {
437
					if (component instanceof ProjectComponent) {
438
						PluginProjectApiComponent ppac = (PluginProjectApiComponent) component;
438
						ProjectComponent ppac = (ProjectComponent) component;
439
						IJavaProject project = ppac.getJavaProject();
439
						IJavaProject project = ppac.getJavaProject();
440
						problem = createProblem(reference, project);
440
						problem = createProblem(reference, project);
441
					} else {
441
					} else {
(-)src/org/eclipse/pde/api/tools/internal/builder/TypeScope.java (-1 / +1 lines)
Lines 130-136 Link Here
130
	 * @see org.eclipse.pde.api.tools.internal.provisional.IApiTypeContainer#findClassFile(java.lang.String, java.lang.String)
130
	 * @see org.eclipse.pde.api.tools.internal.provisional.IApiTypeContainer#findClassFile(java.lang.String, java.lang.String)
131
	 */
131
	 */
132
	public IApiTypeRoot findTypeRoot(String qualifiedName, String id) throws CoreException {
132
	public IApiTypeRoot findTypeRoot(String qualifiedName, String id) throws CoreException {
133
		if (fComponent.getId().equals(id)) {
133
		if (fComponent.getSymbolicName().equals(id)) {
134
			return findTypeRoot(qualifiedName);
134
			return findTypeRoot(qualifiedName);
135
		}
135
		}
136
		return null;
136
		return null;
(-)src/org/eclipse/pde/api/tools/internal/comparator/ClassFileComparator.java (-5 / +5 lines)
Lines 92-98 Link Here
92
					if (result == null) {
92
					if (result == null) {
93
						// TODO should we report this failure ?
93
						// TODO should we report this failure ?
94
						if (Debug) {
94
						if (Debug) {
95
							System.err.println("CHECKED EXCEPTION LOOKUP: Could not find " + superName + " in profile " + profile.getName() + " from component " + apiComponent.getId()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
95
							System.err.println("CHECKED EXCEPTION LOOKUP: Could not find " + superName + " in profile " + profile.getName() + " from component " + apiComponent.getSymbolicName()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
96
						}
96
						}
97
						break;
97
						break;
98
					}
98
					}
Lines 3228-3247 Link Here
3228
		String packageName = Signatures.getPackageName(typeName);
3228
		String packageName = Signatures.getPackageName(typeName);
3229
		IApiComponent[] components = profile.resolvePackage(component, packageName);
3229
		IApiComponent[] components = profile.resolvePackage(component, packageName);
3230
		if (components == null) {
3230
		if (components == null) {
3231
			String msg = MessageFormat.format(ComparatorMessages.ClassFileComparator_1, new String[] {packageName, profile.getName(), component.getId()});
3231
			String msg = MessageFormat.format(ComparatorMessages.ClassFileComparator_1, new String[] {packageName, profile.getName(), component.getSymbolicName()});
3232
			if (Debug) {
3232
			if (Debug) {
3233
				System.err.println("TYPE LOOKUP: "+msg); //$NON-NLS-1$
3233
				System.err.println("TYPE LOOKUP: "+msg); //$NON-NLS-1$
3234
			}
3234
			}
3235
			reportStatus(new Status(IStatus.ERROR, component.getId(), msg));
3235
			reportStatus(new Status(IStatus.ERROR, component.getSymbolicName(), msg));
3236
			return null;
3236
			return null;
3237
		}
3237
		}
3238
		IApiTypeRoot result = Util.getClassFile(components, typeName); 
3238
		IApiTypeRoot result = Util.getClassFile(components, typeName); 
3239
		if (result == null) {
3239
		if (result == null) {
3240
			String msg = MessageFormat.format(ComparatorMessages.ClassFileComparator_2, new String[] {typeName, profile.getName(), component.getId()});
3240
			String msg = MessageFormat.format(ComparatorMessages.ClassFileComparator_2, new String[] {typeName, profile.getName(), component.getSymbolicName()});
3241
			if (Debug) {
3241
			if (Debug) {
3242
				System.err.println("TYPE LOOKUP: "+msg); //$NON-NLS-1$
3242
				System.err.println("TYPE LOOKUP: "+msg); //$NON-NLS-1$
3243
			}
3243
			}
3244
			reportStatus(new Status(IStatus.ERROR, component.getId(), msg));
3244
			reportStatus(new Status(IStatus.ERROR, component.getSymbolicName(), msg));
3245
			return null;
3245
			return null;
3246
		}
3246
		}
3247
		return result;
3247
		return result;
(-)src/org/eclipse/pde/api/tools/internal/model/AbstractApiComponent.java (-188 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2007, 2009 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.model;
12
13
import org.eclipse.core.runtime.CoreException;
14
import org.eclipse.pde.api.tools.internal.problems.ApiProblemFilter;
15
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
16
import org.eclipse.pde.api.tools.internal.provisional.Factory;
17
import org.eclipse.pde.api.tools.internal.provisional.IApiDescription;
18
import org.eclipse.pde.api.tools.internal.provisional.IApiFilterStore;
19
import org.eclipse.pde.api.tools.internal.provisional.descriptors.IElementDescriptor;
20
import org.eclipse.pde.api.tools.internal.provisional.model.ApiTypeContainerVisitor;
21
import org.eclipse.pde.api.tools.internal.provisional.model.IApiBaseline;
22
import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent;
23
import org.eclipse.pde.api.tools.internal.provisional.model.IApiElement;
24
import org.eclipse.pde.api.tools.internal.provisional.model.IApiTypeContainer;
25
import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblem;
26
import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblemFilter;
27
28
/**
29
 * Common implementation of an API component as a composite class file container.
30
 * 
31
 * @since 1.0.0
32
 */
33
public abstract class AbstractApiComponent extends AbstractApiTypeContainer implements IApiComponent {
34
	/**
35
	 * API description
36
	 */
37
	private IApiDescription fApiDescription = null;
38
		
39
	/**
40
	 * Api Filter store
41
	 */
42
	private IApiFilterStore fFilterStore = null;
43
	
44
	/**
45
	 * Constructs an API component in the given {@link IApiBaseline}.
46
	 * 
47
	 * @param baseline the parent {@link IApiBaseline}
48
	 */
49
	public AbstractApiComponent(IApiBaseline baseline) {
50
		super(baseline, IApiElement.COMPONENT, null);
51
	}
52
	
53
	/* (non-Javadoc)
54
	 * @see org.eclipse.pde.api.tools.model.component.IClassFileContainer#accept(org.eclipse.pde.api.tools.model.component.ClassFileContainerVisitor)
55
	 */
56
	public void accept(ApiTypeContainerVisitor visitor) throws CoreException {
57
		if (visitor.visit(this)) {
58
			super.accept(visitor);
59
		}
60
		visitor.end(this);
61
	}	
62
		
63
	/**
64
	 * @see org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent#getHost()
65
	 */
66
	public IApiComponent getHost() throws CoreException {
67
		return null;
68
	}
69
	
70
	/**
71
	 * @see org.eclipse.pde.api.tools.internal.provisional.IApiComponent#getBaseline()
72
	 */
73
	public IApiBaseline getBaseline() {
74
		return (IApiBaseline) getAncestor(IApiElement.BASELINE);
75
	}
76
77
	/* (non-Javadoc)
78
	 * @see org.eclipse.pde.api.tools.model.component.IApiComponent#dispose()
79
	 */
80
	public void dispose() {
81
		try {
82
			close();
83
		} catch (CoreException e) {
84
			ApiPlugin.log(e);
85
		}
86
		fApiDescription = null;
87
	}
88
89
	/* (non-Javadoc)
90
	 * @see org.eclipse.pde.api.tools.internal.model.ApiElement#getApiComponent()
91
	 */
92
	public IApiComponent getApiComponent() {
93
		return this;
94
	}
95
	
96
	/* (non-Javadoc)
97
	 * @see org.eclipse.pde.api.tools.model.component.IApiComponent#getApiDescription()
98
	 */
99
	public synchronized IApiDescription getApiDescription() throws CoreException {
100
		if (fApiDescription == null) {
101
			fApiDescription = createApiDescription();
102
		}
103
		return fApiDescription;
104
	}
105
	
106
	/**
107
	 * Returns whether this component has created an API description.
108
	 * 
109
	 * @return whether this component has created an API description
110
	 */
111
	protected synchronized boolean isApiDescriptionInitialized() {
112
		return fApiDescription != null;
113
	}
114
115
	/**
116
	 * Returns if this component has created an API filter store
117
	 * 
118
	 * @return true if a store has been created, false other wise
119
	 */
120
	protected synchronized boolean hasApiFilterStore() {
121
		return fFilterStore != null;
122
	}
123
	
124
	/* (non-Javadoc)
125
	 * @see org.eclipse.pde.api.tools.internal.model.AbstractApiTypeContainer#getApiTypeContainers()
126
	 */
127
	public synchronized IApiTypeContainer[] getApiTypeContainers() throws CoreException {
128
		return super.getApiTypeContainers();
129
	}
130
131
	/* (non-Javadoc)
132
	 * @see org.eclipse.pde.api.tools.internal.model.AbstractApiTypeContainer#getApiTypeContainers()
133
	 */
134
	public synchronized IApiTypeContainer[] getApiTypeContainers(String id) throws CoreException {
135
		if (this.hasFragments()) {
136
			return super.getApiTypeContainers(id);
137
		} else {
138
			return super.getApiTypeContainers();
139
		}
140
	}
141
	
142
	/**
143
	 * Creates and returns the API description for this component.
144
	 * 
145
	 * @return newly created API description for this component
146
	 */
147
	protected abstract IApiDescription createApiDescription() throws CoreException;
148
149
	/* (non-Javadoc)
150
	 * @see org.eclipse.pde.api.tools.IApiComponent#getFilterStore()
151
	 */
152
	public IApiFilterStore getFilterStore() throws CoreException {
153
		if(fFilterStore == null) {
154
			fFilterStore = createApiFilterStore();
155
		}
156
		return fFilterStore;
157
	}
158
159
	/* (non-Javadoc)
160
	 * @see org.eclipse.pde.api.tools.internal.provisional.IApiComponent#newProblemFilter(org.eclipse.pde.api.tools.internal.provisional.IApiProblem)
161
	 */
162
	public IApiProblemFilter newProblemFilter(IApiProblem problem) throws CoreException {
163
		//TODO either expose a way to make problems or change the method to accept the parts of a problem
164
		return new ApiProblemFilter(getId(), problem);
165
	}
166
	
167
	/* (non-Javadoc)
168
	 * @see org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent#getHandle()
169
	 */
170
	public IElementDescriptor getHandle() {
171
		return Factory.componentDescriptor(this.getId(), this.getVersion());
172
	}
173
	
174
	/* (non-Javadoc)
175
	 * @see org.eclipse.pde.api.tools.internal.provisional.model.IApiTypeContainer#getContainerType()
176
	 */
177
	public int getContainerType() {
178
		return IApiTypeContainer.COMPONENT;
179
	}
180
	
181
	/**
182
	 * Lazily creates a new {@link IApiFilterStore} when it is requested
183
	 * 
184
	 * @return the current {@link IApiFilterStore} for this component
185
	 * @throws CoreException
186
	 */
187
	protected abstract IApiFilterStore createApiFilterStore() throws CoreException;	
188
}
(-)src/org/eclipse/pde/api/tools/internal/model/AbstractApiTypeContainer.java (-2 / +2 lines)
Lines 116-122 Link Here
116
		for (int i = 0; i < containers.length; i++) {
116
		for (int i = 0; i < containers.length; i++) {
117
			comp = (IApiComponent) containers[i].getAncestor(IApiElement.COMPONENT);
117
			comp = (IApiComponent) containers[i].getAncestor(IApiElement.COMPONENT);
118
			if(comp != null) {
118
			if(comp != null) {
119
				origin = comp.getId();
119
				origin = comp.getSymbolicName();
120
			}
120
			}
121
			if (origin == null) {
121
			if (origin == null) {
122
				IApiTypeRoot file = containers[i].findTypeRoot(qualifiedName);
122
				IApiTypeRoot file = containers[i].findTypeRoot(qualifiedName);
Lines 180-186 Link Here
180
		IApiTypeContainer container = null;
180
		IApiTypeContainer container = null;
181
		for (Iterator iterator = this.fApiTypeContainers.iterator(); iterator.hasNext(); ) {
181
		for (Iterator iterator = this.fApiTypeContainers.iterator(); iterator.hasNext(); ) {
182
			container = (IApiTypeContainer) iterator.next();
182
			container = (IApiTypeContainer) iterator.next();
183
			origin = ((IApiComponent)container.getAncestor(IApiElement.COMPONENT)).getId();
183
			origin = ((IApiComponent)container.getAncestor(IApiElement.COMPONENT)).getSymbolicName();
184
			if (origin != null && origin.equals(id)) {
184
			if (origin != null && origin.equals(id)) {
185
				containers.add(container);
185
				containers.add(container);
186
			}
186
			}
(-)src/org/eclipse/pde/api/tools/internal/model/AbstractApiTypeRoot.java (-1 / +1 lines)
Lines 47-53 Link Here
47
		IApiType type = null;
47
		IApiType type = null;
48
		if(comp != null) {
48
		if(comp != null) {
49
			IApiBaseline baseline = comp.getBaseline();
49
			IApiBaseline baseline = comp.getBaseline();
50
			type = (IApiType) cache.getElementInfo(baseline.getName(), comp.getId(), this.getTypeName(), IApiElement.TYPE);
50
			type = (IApiType) cache.getElementInfo(baseline.getName(), comp.getSymbolicName(), this.getTypeName(), IApiElement.TYPE);
51
		}
51
		}
52
		if(type == null) {
52
		if(type == null) {
53
			type = TypeStructureBuilder.buildTypeStructure(getContents(), getApiComponent(), this);
53
			type = TypeStructureBuilder.buildTypeStructure(getContents(), getApiComponent(), this);
(-)src/org/eclipse/pde/api/tools/internal/model/ApiBaseline.java (-11 / +11 lines)
Lines 275-281 Link Here
275
		getState().setPlatformProperties(dictionary);
275
		getState().setPlatformProperties(dictionary);
276
		// clean up previous system library
276
		// clean up previous system library
277
		if (fSystemLibraryComponent != null && fComponentsById != null) {
277
		if (fSystemLibraryComponent != null && fComponentsById != null) {
278
			fComponentsById.remove(fSystemLibraryComponent.getId());
278
			fComponentsById.remove(fSystemLibraryComponent.getSymbolicName());
279
		}
279
		}
280
		if(fSystemPackageNames != null) {
280
		if(fSystemPackageNames != null) {
281
			fSystemPackageNames.clear();
281
			fSystemPackageNames.clear();
Lines 301-316 Link Here
301
	 * Adds an {@link IApiComponent} to the fComponentsById mapping
301
	 * Adds an {@link IApiComponent} to the fComponentsById mapping
302
	 * @param component
302
	 * @param component
303
	 */
303
	 */
304
	private void addComponent(IApiComponent component) throws CoreException {
304
	protected void addComponent(IApiComponent component) throws CoreException {
305
		if(component == null) {
305
		if(component == null) {
306
			return;
306
			return;
307
		}
307
		}
308
		if(fComponentsById == null) {
308
		if(fComponentsById == null) {
309
			fComponentsById = new HashMap();
309
			fComponentsById = new HashMap();
310
		}
310
		}
311
		fComponentsById.put(component.getId(), component);
311
		fComponentsById.put(component.getSymbolicName(), component);
312
		if (component instanceof PluginProjectApiComponent) {
312
		if (component instanceof ProjectComponent) {
313
			PluginProjectApiComponent projectApiComponent = (PluginProjectApiComponent) component;
313
			ProjectComponent projectApiComponent = (ProjectComponent) component;
314
			if (this.fComponentsByProjectNames == null) {
314
			if (this.fComponentsByProjectNames == null) {
315
				this.fComponentsByProjectNames = new HashMap();
315
				this.fComponentsByProjectNames = new HashMap();
316
			}
316
			}
Lines 324-330 Link Here
324
	public void addApiComponents(IApiComponent[] components) throws CoreException {
324
	public void addApiComponents(IApiComponent[] components) throws CoreException {
325
		HashSet ees = new HashSet();
325
		HashSet ees = new HashSet();
326
		for (int i = 0; i < components.length; i++) {
326
		for (int i = 0; i < components.length; i++) {
327
			BundleApiComponent component = (BundleApiComponent) components[i];
327
			BundleComponent component = (BundleComponent) components[i];
328
			if (component.isSourceComponent()) {
328
			if (component.isSourceComponent()) {
329
				continue;
329
				continue;
330
			}
330
			}
Lines 341-347 Link Here
341
	 * Resolves and initializes the system library to use based on API component requirements.
341
	 * Resolves and initializes the system library to use based on API component requirements.
342
	 * Only works when running in the framework. Has no effect if not running in the framework.
342
	 * Only works when running in the framework. Has no effect if not running in the framework.
343
	 */
343
	 */
344
	private void resolveSystemLibrary(HashSet ees) {
344
	protected void resolveSystemLibrary(HashSet ees) {
345
		if (ApiPlugin.isRunningInFramework() && fAutoResolve) {
345
		if (ApiPlugin.isRunningInFramework() && fAutoResolve) {
346
			IStatus error = null;
346
			IStatus error = null;
347
			IExecutionEnvironmentsManager manager = JavaRuntime.getExecutionEnvironmentsManager();
347
			IExecutionEnvironmentsManager manager = JavaRuntime.getExecutionEnvironmentsManager();
Lines 526-533 Link Here
526
	 * @throws CoreException
526
	 * @throws CoreException
527
	 */
527
	 */
528
	private void resolvePackage0(IApiComponent component, String packageName, List componentsList) throws CoreException {
528
	private void resolvePackage0(IApiComponent component, String packageName, List componentsList) throws CoreException {
529
		if (component instanceof BundleApiComponent) {
529
		if (component instanceof BundleComponent) {
530
			BundleDescription bundle = ((BundleApiComponent)component).getBundleDescription();
530
			BundleDescription bundle = ((BundleComponent)component).getBundleDescription();
531
			if (bundle != null) {
531
			if (bundle != null) {
532
				StateHelper helper = getState().getStateHelper();
532
				StateHelper helper = getState().getStateHelper();
533
				ExportPackageDescription[] visiblePackages = helper.getVisiblePackages(bundle);
533
				ExportPackageDescription[] visiblePackages = helper.getVisiblePackages(bundle);
Lines 793-800 Link Here
793
		ArrayList bundles = new ArrayList(components.length);
793
		ArrayList bundles = new ArrayList(components.length);
794
		for (int i = 0; i < components.length; i++) {
794
		for (int i = 0; i < components.length; i++) {
795
			IApiComponent component = components[i];
795
			IApiComponent component = components[i];
796
			if (component instanceof BundleApiComponent) {
796
			if (component instanceof BundleComponent) {
797
				bundles.add(((BundleApiComponent)component).getBundleDescription());
797
				bundles.add(((BundleComponent)component).getBundleDescription());
798
			}
798
			}
799
		}
799
		}
800
		return bundles;
800
		return bundles;
(-)src/org/eclipse/pde/api/tools/internal/model/ApiModelCache.java (-3 / +3 lines)
Lines 117-123 Link Here
117
				IApiComponent comp = element.getApiComponent();
117
				IApiComponent comp = element.getApiComponent();
118
				if(comp != null) {
118
				if(comp != null) {
119
					IApiBaseline baseline = comp.getBaseline();
119
					IApiBaseline baseline = comp.getBaseline();
120
					String id = comp.getId();
120
					String id = comp.getSymbolicName();
121
					if(id == null) {
121
					if(id == null) {
122
						return;
122
						return;
123
					}
123
					}
Lines 129-135 Link Here
129
					Cache typecache = (Cache) compcache.get(id);
129
					Cache typecache = (Cache) compcache.get(id);
130
					if(typecache == null) {
130
					if(typecache == null) {
131
						typecache = new Cache(DEFAULT_CACHE_SIZE, DEFAULT_OVERFLOW);
131
						typecache = new Cache(DEFAULT_CACHE_SIZE, DEFAULT_OVERFLOW);
132
						compcache.put(comp.getId(), typecache);
132
						compcache.put(comp.getSymbolicName(), typecache);
133
					}
133
					}
134
					ApiType type = (ApiType) element;
134
					ApiType type = (ApiType) element;
135
					if(type.isMemberType() || isMemberType(type.getName()) /*cache even a root type with a '$' in its name here as well*/) {
135
					if(type.isMemberType() || isMemberType(type.getName()) /*cache even a root type with a '$' in its name here as well*/) {
Lines 314-320 Link Here
314
					if(comp != null) {
314
					if(comp != null) {
315
						try {
315
						try {
316
							IApiBaseline baseline = comp.getBaseline();
316
							IApiBaseline baseline = comp.getBaseline();
317
							return removeElementInfo(baseline.getName(), comp.getId(), element.getName(), element.getType());
317
							return removeElementInfo(baseline.getName(), comp.getSymbolicName(), element.getName(), element.getType());
318
						}
318
						}
319
						catch(CoreException ce) {}
319
						catch(CoreException ce) {}
320
					}
320
					}
(-)src/org/eclipse/pde/api/tools/internal/model/ApiModelFactory.java (-32 / +9 lines)
Lines 22-28 Link Here
22
import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent;
22
import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent;
23
import org.eclipse.pde.api.tools.internal.util.Util;
23
import org.eclipse.pde.api.tools.internal.util.Util;
24
import org.eclipse.pde.core.plugin.IPluginModelBase;
24
import org.eclipse.pde.core.plugin.IPluginModelBase;
25
import org.eclipse.pde.core.plugin.PluginRegistry;
26
25
27
/**
26
/**
28
 * Utility class for creating new {@link org.eclipse.pde.api.tools.internal.provisional.model.IApiElement}s
27
 * Utility class for creating new {@link org.eclipse.pde.api.tools.internal.provisional.model.IApiElement}s
Lines 55-63 Link Here
55
	 * @exception CoreException if unable to create the component
54
	 * @exception CoreException if unable to create the component
56
	 */
55
	 */
57
	public static IApiComponent newApiComponent(IApiBaseline profile, String location) throws CoreException {
56
	public static IApiComponent newApiComponent(IApiBaseline profile, String location) throws CoreException {
58
		BundleApiComponent component = new BundleApiComponent(profile, location);
57
		BundleComponent component = new BundleComponent(profile, location, getBundleID());
59
		if(component.isValidBundle()) {
58
		if(component.isValidBundle()) {
60
			component.init(getBundleID());
61
			return component;
59
			return component;
62
		}
60
		}
63
		return null;
61
		return null;
Lines 66-79 Link Here
66
	/**
64
	/**
67
	 * Creates and returns a new API component for this profile based on the given
65
	 * Creates and returns a new API component for this profile based on the given
68
	 * model or <code>null</code> if the given model cannot be resolved or does not contain
66
	 * model or <code>null</code> if the given model cannot be resolved or does not contain
69
	 * a valid API component. The component is not added to the profile.
67
	 * a valid API component. The component is not added to the baseline.
70
	 *
68
	 *
69
	 * @param baseline
71
	 * @param model the given model
70
	 * @param model the given model
72
	 * @return API component or <code>null</code> if the given model cannot be resolved or does not contain
71
	 * @return API component or <code>null</code> if the given model cannot be resolved or does not contain
73
	 * a valid API component
72
	 * a valid API component
74
	 * @exception CoreException if unable to create the component
73
	 * @exception CoreException if unable to create the component
75
	 */
74
	 */
76
	public static IApiComponent newApiComponent(IApiBaseline profile, IPluginModelBase model) throws CoreException {
75
	public static IApiComponent newApiComponent(IApiBaseline baseline, IPluginModelBase model) throws CoreException {
77
		BundleDescription bundleDescription = model.getBundleDescription();
76
		BundleDescription bundleDescription = model.getBundleDescription();
78
		if (bundleDescription == null) {
77
		if (bundleDescription == null) {
79
			return null;
78
			return null;
Lines 82-122 Link Here
82
		if (location == null) {
81
		if (location == null) {
83
			return null;
82
			return null;
84
		}
83
		}
85
		BundleApiComponent component = null;
84
		BundleComponent component = null;
86
		IPluginModelBase model2 = getProjectModel(location);
85
		if (isBinaryProject(location)) {
87
		if (model2 != null && model == model2) {
86
			component = new BundleComponent(baseline, location, getBundleID());
88
			if (isBinaryProject(location)) {
89
				component = new BundleApiComponent(profile, location);
90
			} else {
91
				component = new PluginProjectApiComponent(profile, location, model);
92
			}
93
		} else {
87
		} else {
94
			component = new BundleApiComponent(profile, location);
88
			component = new ProjectComponent(baseline, location, model, getBundleID());
95
		}
89
		}
96
		if(component.isValidBundle()) {
90
		if(component.isValidBundle()) {
97
			component.init(getBundleID());
98
			return component;
91
			return component;
99
		}
92
		}
100
		return null;
93
		return null;
101
	}
94
	}
102
	
95
	
103
	/**
96
	/**
104
	 * Returns the plug-in model associated with the project at the specified location
105
	 * or <code>null</code> if none (i.e. if its an external model).
106
	 * 
107
	 * @param project location
108
	 * @return plug-in model or <code>null</code> if none
109
	 */
110
	private static IPluginModelBase getProjectModel(String location) {
111
		String projectName = (new Path(location)).lastSegment();
112
		IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
113
		if (project != null) {
114
			return PluginRegistry.findModel(project); 
115
		}
116
		return null;
117
	}
118
	
119
	/**
120
	 * Returns if the specified location is an imported binary project.
97
	 * Returns if the specified location is an imported binary project.
121
	 * <p>
98
	 * <p>
122
	 * We accept projects that are plug-ins even if not API enabled (i.e.
99
	 * We accept projects that are plug-ins even if not API enabled (i.e.
Lines 130-136 Link Here
130
	private static boolean isBinaryProject(String location) throws CoreException {
107
	private static boolean isBinaryProject(String location) throws CoreException {
131
		IPath path = new Path(location);
108
		IPath path = new Path(location);
132
		IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(path.lastSegment());
109
		IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(path.lastSegment());
133
		return project != null && Util.isBinaryProject(project);
110
		return project != null && (!project.exists() || Util.isBinaryProject(project));
134
	}
111
	}
135
112
136
	/**
113
	/**
(-)src/org/eclipse/pde/api/tools/internal/model/BundleApiComponent.java (-1206 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2007, 2009 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.model;
12
13
import java.io.BufferedReader;
14
import java.io.File;
15
import java.io.FileInputStream;
16
import java.io.FileOutputStream;
17
import java.io.IOException;
18
import java.io.InputStream;
19
import java.io.StringReader;
20
import java.net.MalformedURLException;
21
import java.net.URL;
22
import java.util.ArrayList;
23
import java.util.Dictionary;
24
import java.util.Enumeration;
25
import java.util.HashSet;
26
import java.util.Hashtable;
27
import java.util.Iterator;
28
import java.util.List;
29
import java.util.Map;
30
import java.util.Set;
31
import java.util.jar.JarFile;
32
import java.util.jar.Manifest;
33
import java.util.zip.ZipEntry;
34
import java.util.zip.ZipFile;
35
36
import javax.xml.parsers.FactoryConfigurationError;
37
import javax.xml.parsers.ParserConfigurationException;
38
import javax.xml.parsers.SAXParser;
39
import javax.xml.parsers.SAXParserFactory;
40
41
import org.eclipse.core.runtime.CoreException;
42
import org.eclipse.core.runtime.IStatus;
43
import org.eclipse.core.runtime.Path;
44
import org.eclipse.core.runtime.Status;
45
import org.eclipse.osgi.service.resolver.BundleDescription;
46
import org.eclipse.osgi.service.resolver.BundleSpecification;
47
import org.eclipse.osgi.service.resolver.ExportPackageDescription;
48
import org.eclipse.osgi.service.resolver.HostSpecification;
49
import org.eclipse.osgi.service.resolver.ResolverError;
50
import org.eclipse.osgi.service.resolver.StateObjectFactory;
51
import org.eclipse.osgi.util.ManifestElement;
52
import org.eclipse.osgi.util.NLS;
53
import org.eclipse.pde.api.tools.internal.ApiBaselineManager;
54
import org.eclipse.pde.api.tools.internal.ApiDescription;
55
import org.eclipse.pde.api.tools.internal.ApiDescriptionProcessor;
56
import org.eclipse.pde.api.tools.internal.BundleVersionRange;
57
import org.eclipse.pde.api.tools.internal.CompositeApiDescription;
58
import org.eclipse.pde.api.tools.internal.IApiCoreConstants;
59
import org.eclipse.pde.api.tools.internal.RequiredComponentDescription;
60
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
61
import org.eclipse.pde.api.tools.internal.provisional.Factory;
62
import org.eclipse.pde.api.tools.internal.provisional.IApiAccess;
63
import org.eclipse.pde.api.tools.internal.provisional.IApiDescription;
64
import org.eclipse.pde.api.tools.internal.provisional.IApiFilterStore;
65
import org.eclipse.pde.api.tools.internal.provisional.IRequiredComponentDescription;
66
import org.eclipse.pde.api.tools.internal.provisional.ProfileModifiers;
67
import org.eclipse.pde.api.tools.internal.provisional.VisibilityModifiers;
68
import org.eclipse.pde.api.tools.internal.provisional.descriptors.IPackageDescriptor;
69
import org.eclipse.pde.api.tools.internal.provisional.model.IApiBaseline;
70
import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent;
71
import org.eclipse.pde.api.tools.internal.provisional.model.IApiElement;
72
import org.eclipse.pde.api.tools.internal.provisional.model.IApiTypeContainer;
73
import org.eclipse.pde.api.tools.internal.util.FileManager;
74
import org.eclipse.pde.api.tools.internal.util.SourceDefaultHandler;
75
import org.eclipse.pde.api.tools.internal.util.Util;
76
import org.eclipse.pde.internal.core.TargetWeaver;
77
import org.osgi.framework.BundleException;
78
import org.osgi.framework.Constants;
79
import org.osgi.framework.Version;
80
import org.xml.sax.InputSource;
81
import org.xml.sax.SAXException;
82
83
/**
84
 * Implementation of an API component based on a bundle in the file system.
85
 * 
86
 * @since 1.0.0
87
 */
88
public class BundleApiComponent extends AbstractApiComponent {
89
	
90
	static final String TMP_API_FILE_PREFIX = "api"; //$NON-NLS-1$
91
	static final String TMP_API_FILE_POSTFIX = "tmp"; //$NON-NLS-1$
92
	
93
	/**
94
	 * Dictionary parsed from MANIFEST.MF
95
	 */
96
	private Dictionary fManifest;
97
	
98
	/**
99
	 * Manifest headers that are maintained after {@link BundleDescription} creation.
100
	 * Only these headers are maintained in the manifest dictionary to reduce footprint.  
101
	 */
102
	private static final String[] MANIFEST_HEADERS = new String[] {
103
		IApiCoreConstants.ECLIPSE_SOURCE_BUNDLE,
104
		Constants.BUNDLE_CLASSPATH,
105
		Constants.BUNDLE_NAME,
106
		Constants.BUNDLE_VERSION
107
	};
108
	
109
	/**
110
	 * Whether there is an underlying .api_description file
111
	 */
112
	private boolean fHasApiDescription = false;
113
	
114
	/**
115
	 * Root location of component in the file system
116
	 */
117
	private String fLocation;
118
	
119
	/**
120
	 * Underlying bundle description (OSGi model of a bundle)
121
	 */
122
	private BundleDescription fBundleDescription;
123
	
124
	/**
125
	 * Symbolic name of this bundle
126
	 */
127
	private String fSymbolicName = null;
128
	
129
	/**
130
	 * Bundle version
131
	 */
132
	private Version fVersion = null;
133
	
134
	/**
135
	 * Cached value for the lowest EEs
136
	 */
137
	private String[] lowestEEs;
138
139
	/**
140
	 * Constructs a new API component from the specified location in the file system
141
	 * in the given profile.
142
	 * 
143
	 * @param profile owning profile
144
	 * @param location directory or jar file
145
	 * @exception CoreException if unable to create a component from the specified location
146
	 */
147
	public BundleApiComponent(IApiBaseline profile, String location) throws CoreException {
148
		super(profile);
149
		fLocation = location;
150
	}
151
	
152
	/* (non-Javadoc)
153
	 * @see org.eclipse.pde.api.tools.internal.descriptors.AbstractApiComponent#dispose()
154
	 */
155
	public void dispose() {
156
		try {
157
			super.dispose();
158
		} finally {
159
			synchronized(this) {
160
				fManifest = null;
161
				fBundleDescription = null;
162
			}
163
		}
164
	}
165
	
166
	/**
167
	 * Returns this bundle's manifest as a dictionary.
168
	 * 
169
	 * @return manifest dictionary
170
	 * @exception CoreException if something goes terribly wrong
171
	 */
172
	protected synchronized Dictionary getManifest() throws CoreException {
173
		if(fManifest == null) {
174
			try {
175
				fManifest = (Dictionary) loadManifest(new File(fLocation));
176
			} catch (IOException e) {
177
				abort("Unable to load manifest due to IO error", e); //$NON-NLS-1$
178
			}
179
		}
180
		return fManifest;
181
	}
182
183
	/**
184
	 * Reduce the manifest to only contain required headers after {@link BundleDescription} creation.
185
	 */
186
	protected synchronized void doManifestCompaction() throws CoreException {
187
		Dictionary temp = fManifest;
188
		fManifest = new Hashtable(MANIFEST_HEADERS.length);
189
		for (int i = 0; i < MANIFEST_HEADERS.length; i++) {
190
			String header = MANIFEST_HEADERS[i];
191
			Object value = temp.get(header);
192
			if (value != null) {
193
				fManifest.put(header, value);
194
			}
195
		}
196
	}
197
	
198
	/**
199
	 * Returns if the bundle at the specified location is a valid bundle or not.
200
	 * Validity is determined via the existence of a readable manifest file
201
	 * @param location
202
	 * @return true if the bundle at the given location is valid false otherwise
203
	 * @throws IOException
204
	 */
205
	public boolean isValidBundle() throws CoreException {
206
		Dictionary manifest = getManifest();
207
		return manifest != null && (manifest.get(Constants.BUNDLE_NAME) != null && manifest.get(Constants.BUNDLE_VERSION) != null);
208
	}
209
	
210
	/**
211
	 * Initializes component state from the underlying bundle for the given
212
	 * state.
213
	 * 
214
	 * @param state PDE state
215
	 * @throws CoreException on failure
216
	 */
217
	protected synchronized void init(long bundleId) throws CoreException {
218
		try {
219
			Dictionary manifest = getManifest();
220
			if (isBinaryBundle() && ApiBaselineManager.WORKSPACE_API_BASELINE_ID.equals(getBaseline().getName())) {
221
				// must account for bundles in development mode - look for class files in output
222
				// folders rather than jars
223
				TargetWeaver.weaveManifest(manifest);
224
			}
225
			StateObjectFactory factory = StateObjectFactory.defaultFactory;
226
			fBundleDescription = factory.createBundleDescription(((ApiBaseline)getBaseline()).getState(), manifest, fLocation, bundleId);
227
			fSymbolicName = fBundleDescription.getSymbolicName();
228
			fVersion = fBundleDescription.getVersion();
229
			setName((String)getManifest().get(Constants.BUNDLE_NAME));
230
		} catch (BundleException e) {
231
			abort("Unable to create API component from specified location: " + fLocation, e); //$NON-NLS-1$
232
		}
233
		// compact manifest after initialization - only keep used headers
234
		doManifestCompaction();
235
	}
236
	
237
	/**
238
	 * Returns whether this API component represents a binary bundle versus a project bundle.
239
	 * 
240
	 * @return whether this API component represents a binary bundle
241
	 */
242
	protected boolean isBinaryBundle() {
243
		return true;
244
	}
245
	
246
	/* (non-Javadoc)
247
	 * @see org.eclipse.pde.api.tools.internal.AbstractApiComponent#createApiDescription()
248
	 */
249
	protected IApiDescription createApiDescription() throws CoreException {
250
		BundleDescription[] fragments = getBundleDescription().getFragments();
251
		if (fragments.length == 0) {
252
			return createLocalApiDescription();
253
		}
254
		// build a composite description
255
		IApiDescription[] descriptions = new IApiDescription[fragments.length + 1];
256
		for (int i = 0; i < fragments.length; i++) {
257
			BundleDescription fragment = fragments[i];
258
			BundleApiComponent component = (BundleApiComponent) getBaseline().getApiComponent(fragment.getSymbolicName());
259
			descriptions[i + 1] = component.getApiDescription();
260
		}
261
		descriptions[0] = createLocalApiDescription();
262
		return new CompositeApiDescription(descriptions);
263
	}
264
265
	/**
266
	 * Creates and returns this component's API description based on packages
267
	 * supplied by this component, exported packages, and associated directives.
268
	 * 
269
	 * @return API description
270
	 * @throws CoreException if unable to initialize 
271
	 */
272
	protected IApiDescription createLocalApiDescription() throws CoreException {
273
		IApiDescription apiDesc = new ApiDescription(getId());
274
		// first mark all packages as internal
275
		initializeApiDescription(apiDesc, getBundleDescription(), getLocalPackageNames());
276
		try {
277
			String xml = loadApiDescription(new File(fLocation));
278
			setHasApiDescription(xml != null);
279
			if (xml != null) {
280
				ApiDescriptionProcessor.annotateApiSettings(null, apiDesc, xml);
281
			}
282
		} catch (IOException e) {
283
			abort("Unable to load .api_description file ", e); //$NON-NLS-1$
284
		}
285
		return apiDesc;
286
	}
287
	
288
	/**
289
	 * Returns the names of all packages that originate from this bundle.
290
	 * Does not include packages that originate from fragments or a host.
291
	 * 
292
	 * @return local package names
293
	 * @throws CoreException
294
	 */
295
	protected Set getLocalPackageNames() throws CoreException {
296
		Set names = new HashSet();
297
		IApiTypeContainer[] containers = getApiTypeContainers();
298
		IApiComponent comp = null;
299
		for (int i = 0; i < containers.length; i++) {
300
			comp = (IApiComponent) containers[i].getAncestor(IApiElement.COMPONENT);
301
			if (comp != null && comp.getId().equals(getId())) {
302
				String[] packageNames = containers[i].getPackageNames();
303
				for (int j = 0; j < packageNames.length; j++) {
304
					names.add(packageNames[j]);
305
				}
306
			}
307
		}
308
		return names;
309
	}	
310
	
311
312
	/**
313
	 * Initializes the given API description based on package exports in the manifest.
314
	 * The API description for a bundle only contains packages that originate from
315
	 * this bundle (so a host will not contain API descriptions for packages that
316
	 * originate from fragments). However, a host's API description will be represented
317
	 * by a proxy that delegates to the host and all of its fragments to provide
318
	 * a complete description of the host.
319
	 * 
320
	 * @param apiDesc API description to initialize
321
	 * @param bundle the bundle to load from
322
	 * @param packages the complete set of packages names originating from the backing
323
	 * 		component
324
	 * @throws CoreException if an error occurs
325
	 */
326
	public static void initializeApiDescription(IApiDescription apiDesc, BundleDescription bundle, Set packages) throws CoreException {
327
		Iterator iterator = packages.iterator();
328
		while (iterator.hasNext()) {
329
			String name = (String) iterator.next();
330
			apiDesc.setVisibility(Factory.packageDescriptor(name), VisibilityModifiers.PRIVATE);
331
		}
332
		// then process exported packages that originate from this bundle
333
		// considering host and fragment package exports
334
		List supplied = new ArrayList();
335
		ExportPackageDescription[] exportPackages = bundle.getExportPackages();
336
		addSuppliedPackages(packages, supplied, exportPackages);
337
		HostSpecification host = bundle.getHost();
338
		if (host != null) {
339
			BundleDescription[] hosts = host.getHosts();
340
			for (int i = 0; i < hosts.length; i++) {
341
				addSuppliedPackages(packages, supplied, hosts[i].getExportPackages());
342
			}
343
		}
344
		BundleDescription[] fragments = bundle.getFragments();
345
		for (int i = 0; i < fragments.length; i++) {
346
			addSuppliedPackages(packages, supplied, fragments[i].getExportPackages());
347
		}
348
		
349
		annotateExportedPackages(apiDesc, (ExportPackageDescription[]) supplied.toArray(new ExportPackageDescription[supplied.size()]));
350
	}
351
352
	/**
353
	 * Adds package exports to the given list if the associated package originates
354
	 * from this bundle.
355
	 *   
356
	 * @param packages names of packages supplied by this bundle
357
	 * @param supplied list to append package exports to
358
	 * @param exportPackages package exports to consider
359
	 */
360
	protected static void addSuppliedPackages(Set packages, List supplied, ExportPackageDescription[] exportPackages) {
361
		for (int i = 0; i < exportPackages.length; i++) {
362
			ExportPackageDescription pkg = exportPackages[i];
363
			String name = pkg.getName();
364
			if (name.equals(".")) { //$NON-NLS-1$
365
				// translate . to default package
366
				name = Util.DEFAULT_PACKAGE_NAME;
367
			}
368
			if (packages.contains(name)) {
369
				supplied.add(pkg);
370
			}
371
		}
372
	}
373
	
374
	/**
375
	 * Annotates the API description with exported packages.
376
	 * 
377
	 * @param apiDesc description to annotate
378
	 * @param exportedPackages packages that are exported
379
	 */
380
	protected static void annotateExportedPackages(IApiDescription apiDesc, ExportPackageDescription[] exportedPackages) {
381
		for(int i = 0; i < exportedPackages.length; i++) {
382
			ExportPackageDescription pkg = exportedPackages[i];
383
			boolean internal = ((Boolean) pkg.getDirective("x-internal")).booleanValue(); //$NON-NLS-1$
384
			String[] friends = (String[]) pkg.getDirective("x-friends"); //$NON-NLS-1$
385
			String pkgName = pkg.getName();
386
			if (pkgName.equals(".")) { //$NON-NLS-1$
387
				// default package
388
				pkgName = ""; //$NON-NLS-1$
389
			}
390
			IPackageDescriptor pkgDesc = Factory.packageDescriptor(pkgName);
391
			if(internal) {
392
				apiDesc.setVisibility(pkgDesc, VisibilityModifiers.PRIVATE);
393
			}
394
			if (friends != null) {
395
				apiDesc.setVisibility(pkgDesc, VisibilityModifiers.PRIVATE);
396
				for(int j = 0; j < friends.length; j++) {
397
					//annotate the api description for x-friends access levels
398
					apiDesc.setAccessLevel(
399
							Factory.componentDescriptor(friends[j]), 
400
							Factory.packageDescriptor(pkgName), 
401
							IApiAccess.FRIEND);
402
				}
403
			}
404
			if (!internal && friends == null) {
405
				//there could have been directives that have nothing to do with
406
				//visibility, so we need to add the package as API in that case
407
				apiDesc.setVisibility(pkgDesc, VisibilityModifiers.API);
408
			}
409
		}
410
	}
411
	
412
	/* (non-Javadoc)
413
	 * @see org.eclipse.pde.api.tools.internal.AbstractApiComponent#createApiFilterStore()
414
	 */
415
	protected IApiFilterStore createApiFilterStore() throws CoreException {
416
		//always return a new empty store since we do not support filtering from bundles
417
		return null;
418
	}
419
	
420
	/**
421
	 * @see org.eclipse.pde.api.tools.internal.AbstractApiTypeContainer#createApiTypeContainers()
422
	 */
423
	protected synchronized List createApiTypeContainers() throws CoreException {
424
		if (this.fBundleDescription == null) {
425
			baselineDisposed(getBaseline());
426
		}
427
		List containers = new ArrayList(5);
428
		try {
429
			List all = new ArrayList();
430
			// build the classpath from bundle and all fragments
431
			all.add(this);
432
			boolean considerFragments = true;
433
			if (Util.ORG_ECLIPSE_SWT.equals(getId())) {
434
				// if SWT is a project to be built/analyzed don't consider its fragments
435
				considerFragments = !isApiEnabled();
436
			}
437
			if (considerFragments) { 
438
				BundleDescription[] fragments = fBundleDescription.getFragments();
439
				for (int i = 0; i < fragments.length; i++) {
440
					BundleDescription fragment = fragments[i];
441
					BundleApiComponent component = (BundleApiComponent) getBaseline().getApiComponent(fragment.getSymbolicName());
442
					if (component != null) {
443
						// force initialization of the fragment so we can retrieve its class file containers
444
						component.getApiTypeContainers();
445
						all.add(component);
446
					}
447
				}
448
			}
449
			Iterator iterator = all.iterator();
450
			Set entryNames = new HashSet(5);
451
			BundleApiComponent other = null;
452
			while (iterator.hasNext()) {
453
				BundleApiComponent component = (BundleApiComponent) iterator.next();
454
				String[] paths = getClasspathEntries(component.getManifest());
455
				for (int i = 0; i < paths.length; i++) {
456
					String path = paths[i];
457
					// don't re-process the same entry twice (except default entries ".")
458
					if (!(".".equals(path))) { //$NON-NLS-1$
459
						if (entryNames.contains(path)) {
460
							continue;
461
						}
462
					}
463
					IApiTypeContainer container = component.createApiTypeContainer(path);
464
					if (container == null) {
465
						for(Iterator iter = all.iterator(); iter.hasNext();) {
466
							other = (BundleApiComponent) iter.next();
467
							if (other != component) {
468
								container = other.createApiTypeContainer(path);
469
							}
470
						}
471
					}
472
					if (container != null) {
473
						containers.add(container);
474
						if (!(".".equals(path))) { //$NON-NLS-1$
475
							entryNames.add(path);
476
						}
477
					}
478
				}
479
			}
480
		} catch (BundleException e) {
481
			abort("Unable to parse bundle classpath", e); //$NON-NLS-1$
482
		} catch (IOException e) {
483
			abort("Unable to initialize class file containers", e); //$NON-NLS-1$
484
		}
485
		return containers;
486
	}
487
	
488
	/**
489
	 * Returns whether this API component is enabled for API analysis by the API builder.
490
	 * 
491
	 * @return whether this API component is enabled for API analysis by the API builder.
492
	 */
493
	protected boolean isApiEnabled() {
494
		return false;
495
	}
496
	
497
	/**
498
	 * Returns classpath entries defined in the given manifest.
499
	 * 
500
	 * @param manifest
501
	 * @return classpath entries as bundle relative paths
502
	 * @throws BundleException
503
	 */
504
	protected String[] getClasspathEntries(Dictionary manifest) throws BundleException {
505
		ManifestElement[] classpath = ManifestElement.parseHeader(Constants.BUNDLE_CLASSPATH, (String) manifest.get(Constants.BUNDLE_CLASSPATH));
506
		String elements[] = null;
507
		if (classpath == null) {
508
			// default classpath is '.'
509
			elements = new String[]{"."}; //$NON-NLS-1$
510
		} else {
511
			elements = new String[classpath.length];
512
			for (int i = 0; i < classpath.length; i++) {
513
				elements[i] = classpath[i].getValue();
514
			}
515
		}
516
		return elements;
517
	}
518
	
519
	/**
520
	 * Creates and returns an {@link IApiTypeContainer} at the specified path in
521
	 * this bundle, or <code>null</code> if the {@link IApiTypeContainer} does not
522
	 * exist. The path is the name (path) of entries specified by the
523
	 * <code>Bundle-ClassPath:</code> header.
524
	 * 
525
	 * @param path relative path to a class file container in this bundle
526
	 * @return {@link IApiTypeContainer} or <code>null</code>
527
	 * @exception IOException
528
	 */
529
	protected IApiTypeContainer createApiTypeContainer(String path) throws IOException, CoreException {
530
		File bundle = new File(fLocation);
531
		if (bundle.isDirectory()) {
532
			// bundle is folder
533
			File entry = new File(bundle, path);
534
			if (entry.exists()) {
535
				if (entry.isFile()) {
536
					return new ArchiveApiTypeContainer(this, entry.getCanonicalPath());
537
				} else {
538
					return new DirectoryApiTypeContainer(this, entry.getCanonicalPath());
539
				}
540
			}
541
		} else {
542
			// bundle is jar'd
543
			ZipFile zip = null;
544
			try {
545
				if (path.equals(".")) { //$NON-NLS-1$
546
					return new ArchiveApiTypeContainer(this, fLocation);
547
				} else {
548
					//classpath element can be jar or folder
549
					//https://bugs.eclipse.org/bugs/show_bug.cgi?id=279729
550
					zip = new ZipFile(fLocation);
551
					ZipEntry entry = zip.getEntry(path);
552
					if (entry != null) {
553
						File tmpfolder = new File(System.getProperty("java.io.tmpdir")); //$NON-NLS-1$
554
						if(entry.isDirectory()) {
555
							//extract the dir and all children
556
							File dir = File.createTempFile(TMP_API_FILE_PREFIX, TMP_API_FILE_POSTFIX);
557
							dir.deleteOnExit();
558
							//hack to create a temp directory
559
							// see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4735419
560
							if(dir.delete()) {
561
								dir.mkdir();
562
								FileManager.getManager().recordTempFileRoot(dir.getCanonicalPath());
563
							}
564
							extractDirectory(zip, entry.getName(), dir);
565
							if(dir.isDirectory() && dir.exists()) {
566
								return new DirectoryApiTypeContainer(this, dir.getCanonicalPath());
567
							}
568
						}
569
						else {
570
							File file = extractEntry(zip, entry, tmpfolder);
571
							if(Util.isArchive(file.getName())) {
572
								File parent = file.getParentFile();
573
								if(!parent.equals(tmpfolder)) {
574
									FileManager.getManager().recordTempFileRoot(parent.getCanonicalPath());
575
								}
576
								else {
577
									FileManager.getManager().recordTempFileRoot(file.getCanonicalPath());
578
								}
579
								return new ArchiveApiTypeContainer(this, file.getCanonicalPath());
580
							}
581
						}
582
					}
583
				}
584
			} finally {
585
				if (zip != null) {
586
					zip.close();
587
				}
588
			}
589
		}
590
		return null;
591
	}
592
		
593
	/**
594
	 * Extracts a directory from the archive given a path prefix for entries to retrieve.
595
	 * <code>null</code> can be passed in as a prefix, causing all entries to be be extracted from 
596
	 * the archive.
597
	 * 
598
	 * @param zip the {@link ZipFile} to extract from
599
	 * @param pathprefix the prefix'ing path to include for extraction
600
	 * @param parent the parent directory to extract to
601
	 * @throws IOException if the {@link ZipFile} cannot be read or extraction fails to write the file(s)
602
	 */
603
	void extractDirectory(ZipFile zip, String pathprefix, File parent) throws IOException {
604
		Enumeration entries = zip.entries();
605
		String prefix = (pathprefix == null ? Util.EMPTY_STRING : pathprefix);
606
		ZipEntry entry = null;
607
		File file = null;
608
		while (entries.hasMoreElements()) {
609
			entry = (ZipEntry) entries.nextElement();
610
			if(entry.getName().startsWith(prefix)) {
611
				file = new File(parent, entry.getName());
612
				if (entry.isDirectory()) {
613
					file.mkdir();
614
					continue;
615
				}
616
				extractEntry(zip, entry, parent);
617
			}
618
		}
619
	}
620
	
621
	/**
622
	 * Extracts a non-directory entry from a zip file and returns the File handle
623
	 * @param zip the zip to extract from
624
	 * @param entry the entry to extract
625
	 * @param parent the parent directory to add the extracted entry to
626
	 * @return the file handle to the extracted entry, <code>null</code> otherwise
627
	 * @throws IOException
628
	 */
629
	File extractEntry(ZipFile zip, ZipEntry entry, File parent) throws IOException {
630
		InputStream inputStream = null;
631
		File file;
632
		FileOutputStream outputStream = null;
633
		try {
634
			inputStream = zip.getInputStream(entry);
635
			file = new File(parent, entry.getName());
636
			File lparent = file.getParentFile();
637
			if(!lparent.exists()) {
638
				lparent.mkdirs();
639
			}
640
			outputStream = new FileOutputStream(file);
641
			byte[] bytes = new byte[8096];
642
			while (inputStream.available() > 0) {
643
				int read = inputStream.read(bytes);
644
				if (read > 0) {
645
					outputStream.write(bytes, 0, read);
646
				}
647
			}
648
		} finally {
649
			if (inputStream != null) {
650
				try {
651
					inputStream.close();
652
				} catch(IOException e) {
653
					ApiPlugin.log(e);
654
				}
655
			}
656
			if (outputStream != null) {
657
				try {
658
					outputStream.close();
659
				} catch(IOException e) {
660
					ApiPlugin.log(e);
661
				}
662
			}
663
		}
664
		return file;
665
	}
666
	
667
	/**
668
	 * Parses a bunlde's manifest into a dictionary. The bundle may be in a jar
669
	 * or in a directory at the specified location.
670
	 * 
671
	 * @param bundleLocation root location of the bundle
672
	 * @return bundle manifest dictionary or <code>null</code> if none
673
	 * @throws IOException if unable to parse
674
	 */
675
	protected Map loadManifest(File bundleLocation) throws IOException {
676
		ZipFile jarFile = null;
677
		InputStream manifestStream = null;
678
		String extension = new Path(bundleLocation.getName()).getFileExtension();
679
		try {
680
			if (extension != null && extension.equals("jar") && bundleLocation.isFile()) { //$NON-NLS-1$
681
				jarFile = new ZipFile(bundleLocation, ZipFile.OPEN_READ);
682
				ZipEntry manifestEntry = jarFile.getEntry(JarFile.MANIFEST_NAME);
683
				if (manifestEntry != null) {
684
					manifestStream = jarFile.getInputStream(manifestEntry);
685
				}
686
			} else {
687
				File file = new File(bundleLocation, JarFile.MANIFEST_NAME);
688
				if (file.exists())
689
					manifestStream = new FileInputStream(file);
690
			}
691
			if (manifestStream == null) {
692
				return null;
693
			}
694
			return ManifestElement.parseBundleManifest(manifestStream, new Hashtable(10));
695
		} catch (BundleException e) {
696
			ApiPlugin.log(e);
697
		} finally {
698
			closingZipFileAndStream(manifestStream, jarFile);
699
		}
700
		return null;
701
	}
702
	
703
	/**
704
	 * Reads and returns this bunlde's manifest in a Manifest object.
705
	 * The bundle may be in a jar or in a directory at the specified location.
706
	 * 
707
	 * @param bundleLocation root location of the bundle
708
	 * @return manifest or <code>null</code> if not present
709
	 * @throws IOException if unable to parse
710
	 */
711
	protected Manifest readManifest(File bundleLocation) throws IOException {
712
		ZipFile jarFile = null;
713
		InputStream manifestStream = null;
714
		try {
715
			String extension = new Path(bundleLocation.getName()).getFileExtension();
716
			if (extension != null && extension.equals("jar") && bundleLocation.isFile()) { //$NON-NLS-1$
717
				jarFile = new ZipFile(bundleLocation, ZipFile.OPEN_READ);
718
				ZipEntry manifestEntry = jarFile.getEntry(JarFile.MANIFEST_NAME);
719
				if (manifestEntry != null) {
720
					manifestStream = jarFile.getInputStream(manifestEntry);
721
				}
722
			} else {
723
				File file = new File(bundleLocation, JarFile.MANIFEST_NAME);
724
				if (file.exists())
725
					manifestStream = new FileInputStream(file);
726
			}
727
			if (manifestStream == null) {
728
				return null;
729
			}
730
			return new Manifest(manifestStream);
731
		} finally {
732
			closingZipFileAndStream(manifestStream, jarFile);
733
		}
734
	}
735
736
	void closingZipFileAndStream(InputStream stream, ZipFile jarFile) {
737
		try {
738
			if (stream != null) {
739
				stream.close();
740
			}
741
		} catch (IOException e) {
742
			ApiPlugin.log(e);
743
		}
744
		try {
745
			if (jarFile != null) {
746
				jarFile.close();
747
			}
748
		} catch (IOException e) {
749
			ApiPlugin.log(e);
750
		}
751
	}
752
	
753
	/**
754
	 * Reads and returns the file contents corresponding to the given file name.
755
	 * The bundle may be in a jar or in a directory at the specified location.
756
	 * 
757
	 * @param xmlFileName the given file name
758
	 * @param bundleLocation the root location of the bundle
759
	 * @return the file contents or <code>null</code> if not present
760
	 */
761
	protected String readFileContents(String xmlFileName, File bundleLocation) {
762
		ZipFile jarFile = null;
763
		InputStream stream = null;
764
		try {
765
			String extension = new Path(bundleLocation.getName()).getFileExtension();
766
			if (extension != null && extension.equals("jar") && bundleLocation.isFile()) { //$NON-NLS-1$
767
				jarFile = new ZipFile(bundleLocation, ZipFile.OPEN_READ);
768
				ZipEntry manifestEntry = jarFile.getEntry(xmlFileName);
769
				if (manifestEntry != null) {
770
					stream = jarFile.getInputStream(manifestEntry);
771
				}
772
			} else {
773
				File file = new File(bundleLocation, xmlFileName);
774
				if (file.exists()) {
775
					stream = new FileInputStream(file);
776
				}
777
			}
778
			if (stream == null) {
779
				return null;
780
			}
781
			return new String(Util.getInputStreamAsCharArray(stream, -1, IApiCoreConstants.UTF_8));
782
		} catch(IOException e) {
783
			//TODO abort
784
			ApiPlugin.log(e);
785
		} finally {
786
			closingZipFileAndStream(stream, jarFile);
787
		}
788
		return null;
789
	}
790
791
	/**
792
	 * Parses a bundle's .api_description XML into a string. The file may be in a jar
793
	 * or in a directory at the specified location.
794
	 * 
795
	 * @param bundleLocation root location of the bundle
796
	 * @return API description XML as a string or <code>null</code> if none
797
	 * @throws IOException if unable to parse
798
	 */
799
	protected String loadApiDescription(File bundleLocation) throws IOException {
800
		ZipFile jarFile = null;
801
		InputStream stream = null;
802
		String contents = null;
803
		try {
804
			String extension = new Path(bundleLocation.getName()).getFileExtension();
805
			if (extension != null && extension.equals("jar") && bundleLocation.isFile()) { //$NON-NLS-1$
806
				jarFile = new ZipFile(bundleLocation, ZipFile.OPEN_READ);
807
				ZipEntry manifestEntry = jarFile.getEntry(IApiCoreConstants.API_DESCRIPTION_XML_NAME);
808
				if (manifestEntry != null) {
809
					// new file is present
810
					stream = jarFile.getInputStream(manifestEntry);
811
				}
812
			} else {
813
				File file = new File(bundleLocation, IApiCoreConstants.API_DESCRIPTION_XML_NAME);
814
				if (file.exists()) {
815
					// use new file
816
					stream = new FileInputStream(file);
817
				}
818
			}
819
			if (stream == null) {
820
				return null;
821
			}
822
			char[] charArray = Util.getInputStreamAsCharArray(stream, -1, IApiCoreConstants.UTF_8);
823
			contents = new String(charArray);
824
		} finally {
825
			closingZipFileAndStream(stream, jarFile);
826
		}
827
		return contents;
828
	}
829
	
830
	
831
	/**
832
	 * Returns a URL describing a file inside a bundle.
833
	 * 
834
	 * @param bundleLocation root location of the bundle. May be a
835
	 *  directory or a file (jar)
836
	 * @param filePath bundle relative path to desired file
837
	 * @return URL to the file
838
	 * @throws MalformedURLException 
839
	 */
840
	protected URL getFileInBundle(File bundleLocation, String filePath) throws MalformedURLException {
841
		String extension = new Path(bundleLocation.getName()).getFileExtension();
842
		StringBuffer urlSt = new StringBuffer();
843
		if (extension != null && extension.equals("jar") && bundleLocation.isFile()) { //$NON-NLS-1$
844
			urlSt.append("jar:file:"); //$NON-NLS-1$
845
			urlSt.append(bundleLocation.getAbsolutePath());
846
			urlSt.append("!/"); //$NON-NLS-1$
847
			urlSt.append(filePath);
848
		} else {
849
			urlSt.append("file:"); //$NON-NLS-1$
850
			urlSt.append(bundleLocation.getAbsolutePath());
851
			urlSt.append(File.separatorChar);
852
			urlSt.append(filePath);
853
		}	
854
		return new URL(urlSt.toString());
855
	}
856
	
857
	/* (non-Javadoc)
858
	 * @see org.eclipse.pde.api.tools.manifest.IApiComponent#getExecutionEnvironments()
859
	 */
860
	public synchronized String[] getExecutionEnvironments() throws CoreException {
861
		if (this.fBundleDescription == null) {
862
			baselineDisposed(getBaseline());
863
		}
864
		return fBundleDescription.getExecutionEnvironments();
865
	}
866
867
	/* (non-Javadoc)
868
	 * @see org.eclipse.pde.api.tools.manifest.IApiComponent#getId()
869
	 */
870
	public final String getId() {
871
		return fSymbolicName;
872
	}
873
874
	/* (non-Javadoc)
875
	 * @see org.eclipse.pde.api.tools.manifest.IApiComponent#getRequiredComponents()
876
	 */
877
	public synchronized IRequiredComponentDescription[] getRequiredComponents() throws CoreException {
878
		if (this.fBundleDescription == null) {
879
			baselineDisposed(getBaseline());
880
		}
881
		BundleSpecification[] requiredBundles = fBundleDescription.getRequiredBundles();
882
		IRequiredComponentDescription[] req = new IRequiredComponentDescription[requiredBundles.length];
883
		for (int i = 0; i < requiredBundles.length; i++) {
884
			BundleSpecification bundle = requiredBundles[i];
885
			req[i] = new RequiredComponentDescription(bundle.getName(),
886
					new BundleVersionRange(bundle.getVersionRange()),
887
					bundle.isOptional(),
888
					bundle.isExported());
889
		}
890
		return req;
891
	}
892
893
	/* (non-Javadoc)
894
	 * @see org.eclipse.pde.api.tools.manifest.IApiComponent#getVersion()
895
	 */
896
	public synchronized String getVersion() {
897
		return fVersion.toString();
898
	}
899
	
900
	/**
901
	 * Returns this component's bundle description.
902
	 * 
903
	 * @return bundle description
904
	 */
905
	public synchronized BundleDescription getBundleDescription() throws CoreException {
906
		if (this.fBundleDescription == null) {
907
			baselineDisposed(getBaseline());
908
		}
909
		return fBundleDescription;
910
	}
911
912
	/* (non-Javadoc)
913
	 * @see java.lang.Object#toString()
914
	 */
915
	public String toString() {
916
		if (fBundleDescription != null) {
917
			try {
918
				StringBuffer buffer = new StringBuffer();
919
				buffer.append(fBundleDescription.toString());
920
				buffer.append(" - "); //$NON-NLS-1$
921
				buffer.append("[fragment: ").append(isFragment()).append("] "); //$NON-NLS-1$ //$NON-NLS-2$
922
				buffer.append("[host: ").append(fBundleDescription.getFragments().length > 0).append("] "); //$NON-NLS-1$ //$NON-NLS-2$
923
				buffer.append("[system bundle: ").append(isSystemComponent()).append("] "); //$NON-NLS-1$ //$NON-NLS-2$
924
				buffer.append("[source bundle: ").append(isSourceComponent()).append("] "); //$NON-NLS-1$ //$NON-NLS-2$
925
				return buffer.toString();
926
			}
927
			catch(CoreException ce) {} 
928
		}
929
		return super.toString();
930
	}
931
932
	/* (non-Javadoc)
933
	 * @see org.eclipse.pde.api.tools.model.component.IApiComponent#getLocation()
934
	 */
935
	public String getLocation() {
936
		return fLocation;
937
	}
938
939
	/* (non-Javadoc)
940
	 * @see org.eclipse.pde.api.tools.model.component.IApiComponent#isSystemComponent()
941
	 */
942
	public boolean isSystemComponent() {
943
		return false;
944
	}
945
	
946
	/**
947
	 * Returns a boolean option from the map or the default value if not present.
948
	 * 
949
	 * @param options option map
950
	 * @param optionName option name
951
	 * @param defaultValue default value for option if not present
952
	 * @return boolean value
953
	 */
954
	protected boolean getBooleanOption(Map options, String optionName, boolean defaultValue) {
955
		Boolean optionB = (Boolean)options.get(optionName);
956
		if (optionB != null) {
957
			return optionB.booleanValue();
958
		}
959
		return defaultValue;
960
	}
961
	
962
	/* (non-Javadoc)
963
	 * @see IApiComponent#isSourceComponent()
964
	 */
965
	public synchronized boolean isSourceComponent() throws CoreException {
966
		if (this.fManifest == null) {
967
			baselineDisposed(getBaseline());
968
		}
969
		ManifestElement[] sourceBundle = null;
970
		try {
971
			sourceBundle = ManifestElement.parseHeader(IApiCoreConstants.ECLIPSE_SOURCE_BUNDLE, (String) fManifest.get(IApiCoreConstants.ECLIPSE_SOURCE_BUNDLE));
972
		} catch (BundleException e) {
973
			// ignore
974
		}
975
		if (sourceBundle != null) {
976
			// this is a source bundle with the new format
977
			return true;
978
		}
979
		// check for the old format
980
		String pluginXMLContents = readFileContents(IApiCoreConstants.PLUGIN_XML_NAME,new File(getLocation()));
981
		if (pluginXMLContents != null) {
982
			if (containsSourceExtensionPoint(pluginXMLContents)) {
983
				return true;
984
			}
985
		}
986
		// check if it contains a fragment.xml with the appropriate extension point
987
		pluginXMLContents = readFileContents(IApiCoreConstants.FRAGMENT_XML_NAME,new File(getLocation()));
988
		if (pluginXMLContents != null) {
989
			if (containsSourceExtensionPoint(pluginXMLContents)) {
990
				return true;
991
			}
992
		}
993
		// parse XML contents to find extension points
994
		return false;
995
	}
996
997
	/**
998
	 * Check if the given source contains an source extension point.
999
	 * 
1000
	 * @param pluginXMLContents the given file contents
1001
	 * @return true if it contains a source extension point, false otherwise
1002
	 */
1003
	private boolean containsSourceExtensionPoint(String pluginXMLContents) {
1004
		SAXParserFactory factory = null;
1005
		try {
1006
			factory = SAXParserFactory.newInstance();
1007
		} catch (FactoryConfigurationError e) {
1008
			return false;
1009
		}
1010
		SAXParser saxParser = null;
1011
		try {
1012
			saxParser = factory.newSAXParser();
1013
		} catch (ParserConfigurationException e) {
1014
			// ignore
1015
		} catch (SAXException e) {
1016
			// ignore
1017
		}
1018
1019
		if (saxParser == null) {
1020
			return false;
1021
		}
1022
1023
		// Parse
1024
		InputSource inputSource = new InputSource(new BufferedReader(new StringReader(pluginXMLContents)));
1025
		try {
1026
			SourceDefaultHandler defaultHandler = new SourceDefaultHandler();
1027
			saxParser.parse(inputSource, defaultHandler);
1028
			return defaultHandler.isSource();
1029
		} catch (SAXException e) {
1030
			// ignore
1031
		} catch (IOException e) {
1032
			// ignore
1033
		}
1034
		return false;
1035
	}	
1036
1037
	/* (non-Javadoc)
1038
	 * @see org.eclipse.pde.api.tools.IApiComponent#isFragment()
1039
	 */
1040
	public synchronized boolean isFragment() throws CoreException {
1041
		if (this.fBundleDescription == null) {
1042
			baselineDisposed(getBaseline());
1043
		}
1044
		return fBundleDescription.getHost() != null;
1045
	}
1046
1047
	/**
1048
	 * @see org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent#getHost()
1049
	 */
1050
	public synchronized IApiComponent getHost() throws CoreException {
1051
		if (this.fBundleDescription == null) {
1052
			baselineDisposed(getBaseline());
1053
		}
1054
		HostSpecification host = fBundleDescription.getHost();
1055
		if(host != null) {
1056
			return getBaseline().getApiComponent(host.getName());
1057
		}
1058
		return null;
1059
	}
1060
	
1061
	/* (non-Javadoc)
1062
	 * @see org.eclipse.pde.api.tools.IApiComponent#hasFragments()
1063
	 */
1064
	public synchronized boolean hasFragments() throws CoreException {
1065
		if (this.fBundleDescription == null) {
1066
			baselineDisposed(getBaseline());
1067
		}
1068
		return fBundleDescription.getFragments().length != 0;
1069
	}
1070
	
1071
	/**
1072
	 * Sets whether this bundle has an underlying API description file.
1073
	 * 
1074
	 * @param hasApiDescription whether this bundle has an underlying API description file
1075
	 */
1076
	protected void setHasApiDescription(boolean hasApiDescription) {
1077
		fHasApiDescription = hasApiDescription;
1078
	}
1079
	
1080
	/* (non-Javadoc)
1081
	 * @see org.eclipse.pde.api.tools.internal.provisional.IApiComponent#hasApiDescription()
1082
	 */
1083
	public boolean hasApiDescription() {
1084
		// ensure initialized
1085
		try {
1086
			getApiDescription();
1087
		} catch (CoreException e) {
1088
		}
1089
		return fHasApiDescription;
1090
	}
1091
	
1092
	/* (non-Javadoc)
1093
	 * @see org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent#getLowestEEs()
1094
	 */
1095
	public String[] getLowestEEs() throws CoreException {
1096
		if (this.lowestEEs != null) return this.lowestEEs;
1097
		String[] temp = null;
1098
		String[] executionEnvironments = this.getExecutionEnvironments();
1099
		int length = executionEnvironments.length;
1100
		switch(length) {
1101
			case 0 :
1102
				return null;
1103
			case 1 :
1104
				temp = new String[] { executionEnvironments[0] };
1105
				break;
1106
			default :
1107
				int values = ProfileModifiers.NO_PROFILE_VALUE;
1108
				for (int i = 0; i < length; i++) {
1109
					values |= ProfileModifiers.getValue(executionEnvironments[i]);
1110
				}
1111
				if (ProfileModifiers.isJRE(values)) {
1112
					if (ProfileModifiers.isJRE_1_1(values)) {
1113
						temp = new String[] { ProfileModifiers.JRE_1_1_NAME };
1114
					} else if (ProfileModifiers.isJ2SE_1_2(values)) {
1115
						temp = new String[] { ProfileModifiers.J2SE_1_2_NAME };
1116
					} else if (ProfileModifiers.isJ2SE_1_3(values)) {
1117
						temp = new String[] { ProfileModifiers.J2SE_1_3_NAME };
1118
					} else if (ProfileModifiers.isJ2SE_1_4(values)) {
1119
						temp = new String[] { ProfileModifiers.J2SE_1_4_NAME };
1120
					} else if (ProfileModifiers.isJ2SE_1_5(values)) {
1121
						temp = new String[] { ProfileModifiers.J2SE_1_5_NAME };
1122
					} else {
1123
						// this is 1.6
1124
						temp = new String[] { ProfileModifiers.JAVASE_1_6_NAME };
1125
					}
1126
				}
1127
				if (ProfileModifiers.isCDC_Foundation(values)) {
1128
					if (ProfileModifiers.isCDC_1_0_FOUNDATION_1_0(values)) {
1129
						if (temp != null) {
1130
							temp = new String[] { temp[0], ProfileModifiers.CDC_1_0_FOUNDATION_1_0_NAME };
1131
						} else {
1132
							temp = new String[] { ProfileModifiers.CDC_1_0_FOUNDATION_1_0_NAME };
1133
						}
1134
					} else {
1135
						if (temp != null) {
1136
							temp = new String[] { temp[0], ProfileModifiers.CDC_1_1_FOUNDATION_1_1_NAME };
1137
						} else {
1138
							temp = new String[] { ProfileModifiers.CDC_1_1_FOUNDATION_1_1_NAME };
1139
						}
1140
					}
1141
				}
1142
				if (ProfileModifiers.isOSGi(values)) {
1143
					if (ProfileModifiers.isOSGI_MINIMUM_1_0(values)) {
1144
						if (temp != null) {
1145
							int tempLength = temp.length;
1146
							System.arraycopy(temp, 0, (temp = new String[tempLength + 1]), 0, tempLength);
1147
							temp[tempLength] = ProfileModifiers.OSGI_MINIMUM_1_0_NAME;
1148
						} else {
1149
							temp = new String[] { ProfileModifiers.OSGI_MINIMUM_1_0_NAME };
1150
						}
1151
					} else if (ProfileModifiers.isOSGI_MINIMUM_1_1(values)) {
1152
						if (temp != null) {
1153
							int tempLength = temp.length;
1154
							System.arraycopy(temp, 0, (temp = new String[tempLength + 1]), 0, tempLength);
1155
							temp[tempLength] = ProfileModifiers.OSGI_MINIMUM_1_1_NAME;
1156
						} else {
1157
							temp = new String[] { ProfileModifiers.OSGI_MINIMUM_1_1_NAME };
1158
						}
1159
					} else {
1160
						// OSGI_MINIMUM_1_2
1161
						if (temp != null) {
1162
							int tempLength = temp.length;
1163
							System.arraycopy(temp, 0, (temp = new String[tempLength + 1]), 0, tempLength);
1164
							temp[tempLength] = ProfileModifiers.OSGI_MINIMUM_1_2_NAME;
1165
						} else {
1166
							temp = new String[] { ProfileModifiers.OSGI_MINIMUM_1_2_NAME };
1167
						}
1168
					}
1169
				}
1170
		}
1171
		this.lowestEEs = temp;
1172
		return temp;
1173
	}
1174
	
1175
	/* (non-Javadoc)
1176
	 * @see org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent#getErrors()
1177
	 */
1178
	public synchronized ResolverError[] getErrors() throws CoreException {
1179
		ApiBaseline baseline = (ApiBaseline) getBaseline();
1180
		if (this.fBundleDescription == null) {
1181
			baselineDisposed(baseline);
1182
		}
1183
		if (baseline != null) {
1184
			ResolverError[] resolverErrors = baseline.getState().getResolverErrors(this.fBundleDescription);
1185
			if (resolverErrors.length == 0) {
1186
				return null;
1187
			}
1188
			return resolverErrors;
1189
		}
1190
		return null;
1191
	}
1192
	
1193
	/**
1194
	 * @param baseline the baseline that is disposed
1195
	 * @throws CoreException with the baseline disposed information
1196
	 */
1197
	protected void baselineDisposed(IApiBaseline baseline) throws CoreException {
1198
		throw new CoreException(
1199
				new Status(
1200
						IStatus.ERROR,
1201
						ApiPlugin.PLUGIN_ID,
1202
						ApiPlugin.REPORT_BASELINE_IS_DISPOSED,
1203
						NLS.bind(Messages.BundleApiComponent_baseline_disposed, baseline.getName()),
1204
						null));
1205
	}
1206
}
(-)src/org/eclipse/pde/api/tools/internal/model/BundleComponent.java (+1303 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2007, 2009 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.model;
12
13
import java.io.BufferedReader;
14
import java.io.File;
15
import java.io.FileInputStream;
16
import java.io.FileOutputStream;
17
import java.io.IOException;
18
import java.io.InputStream;
19
import java.io.StringReader;
20
import java.net.MalformedURLException;
21
import java.net.URL;
22
import java.util.ArrayList;
23
import java.util.Dictionary;
24
import java.util.Enumeration;
25
import java.util.HashSet;
26
import java.util.Hashtable;
27
import java.util.Iterator;
28
import java.util.List;
29
import java.util.Map;
30
import java.util.Set;
31
import java.util.jar.JarFile;
32
import java.util.jar.Manifest;
33
import java.util.zip.ZipEntry;
34
import java.util.zip.ZipFile;
35
36
import javax.xml.parsers.FactoryConfigurationError;
37
import javax.xml.parsers.ParserConfigurationException;
38
import javax.xml.parsers.SAXParser;
39
import javax.xml.parsers.SAXParserFactory;
40
41
import org.eclipse.core.runtime.CoreException;
42
import org.eclipse.core.runtime.IStatus;
43
import org.eclipse.core.runtime.Path;
44
import org.eclipse.core.runtime.Status;
45
import org.eclipse.osgi.service.resolver.BundleDescription;
46
import org.eclipse.osgi.service.resolver.BundleSpecification;
47
import org.eclipse.osgi.service.resolver.ExportPackageDescription;
48
import org.eclipse.osgi.service.resolver.HostSpecification;
49
import org.eclipse.osgi.service.resolver.ResolverError;
50
import org.eclipse.osgi.service.resolver.State;
51
import org.eclipse.osgi.service.resolver.StateObjectFactory;
52
import org.eclipse.osgi.util.ManifestElement;
53
import org.eclipse.osgi.util.NLS;
54
import org.eclipse.pde.api.tools.internal.ApiBaselineManager;
55
import org.eclipse.pde.api.tools.internal.ApiDescription;
56
import org.eclipse.pde.api.tools.internal.ApiDescriptionProcessor;
57
import org.eclipse.pde.api.tools.internal.BundleVersionRange;
58
import org.eclipse.pde.api.tools.internal.CompositeApiDescription;
59
import org.eclipse.pde.api.tools.internal.IApiCoreConstants;
60
import org.eclipse.pde.api.tools.internal.RequiredComponentDescription;
61
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
62
import org.eclipse.pde.api.tools.internal.provisional.Factory;
63
import org.eclipse.pde.api.tools.internal.provisional.IApiAccess;
64
import org.eclipse.pde.api.tools.internal.provisional.IApiDescription;
65
import org.eclipse.pde.api.tools.internal.provisional.IApiFilterStore;
66
import org.eclipse.pde.api.tools.internal.provisional.IRequiredComponentDescription;
67
import org.eclipse.pde.api.tools.internal.provisional.ProfileModifiers;
68
import org.eclipse.pde.api.tools.internal.provisional.VisibilityModifiers;
69
import org.eclipse.pde.api.tools.internal.provisional.descriptors.IPackageDescriptor;
70
import org.eclipse.pde.api.tools.internal.provisional.model.IApiBaseline;
71
import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent;
72
import org.eclipse.pde.api.tools.internal.provisional.model.IApiElement;
73
import org.eclipse.pde.api.tools.internal.provisional.model.IApiTypeContainer;
74
import org.eclipse.pde.api.tools.internal.util.FileManager;
75
import org.eclipse.pde.api.tools.internal.util.SourceDefaultHandler;
76
import org.eclipse.pde.api.tools.internal.util.Util;
77
import org.eclipse.pde.internal.core.TargetWeaver;
78
import org.osgi.framework.BundleException;
79
import org.osgi.framework.Constants;
80
import org.osgi.framework.Version;
81
import org.xml.sax.InputSource;
82
import org.xml.sax.SAXException;
83
84
/**
85
 * Implementation of an API component based on a bundle in the file system.
86
 * 
87
 * @since 1.0.0
88
 */
89
public class BundleComponent extends Component {
90
	
91
	static final String TMP_API_FILE_PREFIX = "api"; //$NON-NLS-1$
92
	static final String TMP_API_FILE_POSTFIX = "tmp"; //$NON-NLS-1$
93
	
94
	/**
95
	 * Dictionary parsed from MANIFEST.MF
96
	 */
97
	private Dictionary fManifest;
98
	
99
	/**
100
	 * Manifest headers that are maintained after {@link BundleDescription} creation.
101
	 * Only these headers are maintained in the manifest dictionary to reduce footprint.  
102
	 */
103
	private static final String[] MANIFEST_HEADERS = new String[] {
104
		IApiCoreConstants.ECLIPSE_SOURCE_BUNDLE,
105
		Constants.BUNDLE_CLASSPATH,
106
		Constants.BUNDLE_NAME,
107
		Constants.BUNDLE_VERSION
108
	};
109
	
110
	/**
111
	 * Whether there is an underlying .api_description file
112
	 */
113
	private boolean fHasApiDescription = false;
114
	
115
	/**
116
	 * Root location of component in the file system
117
	 */
118
	private String fLocation;
119
	
120
	/**
121
	 * Underlying bundle description (OSGi model of a bundle)
122
	 */
123
	private BundleDescription fBundleDescription;
124
	
125
	/**
126
	 * Symbolic name of this bundle
127
	 */
128
	private String fSymbolicName = null;
129
	
130
	/**
131
	 * Bundle version
132
	 */
133
	private Version fVersion = null;
134
	
135
	/**
136
	 * Cached value for the lowest EEs
137
	 */
138
	private String[] lowestEEs;
139
	
140
	/**
141
	 * Flag to know if this component is a binary bundle in the workspace
142
	 * i.e. an imported binary bundle
143
	 */
144
	private boolean fWorkspaceBinary = false;
145
	
146
	/**
147
	 * The id of this component
148
	 */
149
	private long fBundleId = 0L;
150
151
	/**
152
	 * Constructs a new API component from the specified location in the file system
153
	 * in the given profile.
154
	 * 
155
	 * @param baseline owning API baseline
156
	 * @param location directory or jar file
157
	 * @param bundleid
158
	 * @exception CoreException if unable to create a component from the specified location
159
	 */
160
	public BundleComponent(IApiBaseline baseline, String location, long bundleid) throws CoreException {
161
		super(baseline);
162
		fLocation = location;
163
		fBundleId = bundleid;
164
		fWorkspaceBinary = isBinary() && ApiBaselineManager.WORKSPACE_API_BASELINE_ID.equals(baseline.getName());
165
	}
166
	
167
	/* (non-Javadoc)
168
	 * @see org.eclipse.pde.api.tools.internal.descriptors.AbstractApiComponent#dispose()
169
	 */
170
	public void dispose() {
171
		try {
172
			super.dispose();
173
		} finally {
174
			synchronized(this) {
175
				fManifest = null;
176
				fBundleDescription = null;
177
			}
178
		}
179
	}
180
	
181
	/**
182
	 * Returns this bundle's manifest as a dictionary.
183
	 * 
184
	 * @return manifest dictionary
185
	 * @exception CoreException if something goes terribly wrong
186
	 */
187
	protected synchronized Dictionary getManifest() throws CoreException {
188
		if(fManifest == null) {
189
			try {
190
				fManifest = (Dictionary) loadManifest(new File(fLocation));
191
			} catch (IOException e) {
192
				abort("Unable to load manifest due to IO error", e); //$NON-NLS-1$
193
			}
194
		}
195
		return fManifest;
196
	}
197
198
	/**
199
	 * Reduce the manifest to only contain required headers after {@link BundleDescription} creation.
200
	 */
201
	protected synchronized void doManifestCompaction() {
202
		Dictionary temp = fManifest;
203
		fManifest = new Hashtable(MANIFEST_HEADERS.length, 1);
204
		for (int i = 0; i < MANIFEST_HEADERS.length; i++) {
205
			String header = MANIFEST_HEADERS[i];
206
			Object value = temp.get(header);
207
			if (value != null) {
208
				fManifest.put(header, value);
209
			}
210
		}
211
	}
212
	
213
	/**
214
	 * Returns if the bundle at the specified location is a valid bundle or not.
215
	 * Validity is determined via the existence of a readable manifest file
216
	 * @param location
217
	 * @return true if the bundle at the given location is valid false otherwise
218
	 * @throws IOException
219
	 */
220
	public boolean isValidBundle() throws CoreException {
221
		Dictionary manifest = getManifest();
222
		return manifest != null && (manifest.get(Constants.BUNDLE_NAME) != null && manifest.get(Constants.BUNDLE_VERSION) != null);
223
	}
224
	
225
	/* (non-Javadoc)
226
	 * @see java.lang.Object#equals(java.lang.Object)
227
	 */
228
	public boolean equals(Object obj) {
229
		if(obj instanceof BundleComponent) {
230
			BundleComponent comp = (BundleComponent) obj;
231
			return getName().equals(comp.getName()) && 
232
					getSymbolicName().equals(comp.getSymbolicName()) &&
233
					getVersion().equals(comp.getVersion());
234
		}
235
		return false;
236
	}
237
	
238
	/**
239
	 * Initializes the component
240
	 * @throws CoreException on failure
241
	 */
242
	protected synchronized void init() {
243
		if(fBundleDescription != null) {
244
			return;
245
		}
246
		try {
247
			Dictionary manifest = getManifest();
248
			if (isWorkspaceBinary()) {
249
				// must account for bundles in development mode - look for class files in output
250
				// folders rather than jars
251
				TargetWeaver.weaveManifest(manifest);
252
			}
253
			fBundleDescription = getBundleDescription(manifest, fLocation, fBundleId);
254
			if(fBundleDescription == null) {
255
				ApiPlugin.log(new Status(
256
						IStatus.ERROR, 
257
						ApiPlugin.PLUGIN_ID, 
258
						"Unable to resolve the BundleDescription for the component from: " + fLocation,  //$NON-NLS-1$
259
						null));
260
			}
261
			fSymbolicName = fBundleDescription.getSymbolicName();
262
			fVersion = fBundleDescription.getVersion();
263
			setName((String)manifest.get(Constants.BUNDLE_NAME));
264
		} catch (BundleException e) {
265
			ApiPlugin.log(new Status(
266
					IStatus.ERROR, 
267
					ApiPlugin.PLUGIN_ID, 
268
					"Unable to create API component from specified location: " + fLocation,  //$NON-NLS-1$
269
					e));
270
		}
271
		catch (CoreException ce) {
272
			ApiPlugin.log(ce);
273
		}
274
		// compact manifest after initialization - only keep used headers
275
		doManifestCompaction();
276
	}
277
	
278
	/**
279
	 * Returns if this component is a a binary bundle in the workspace
280
	 * i.e. an imported binary bundle
281
	 * @return true if the component is a binary bundle in the workspace, false otherwise
282
	 */
283
	public boolean isWorkspaceBinary() {
284
		return fWorkspaceBinary;
285
	}
286
	
287
	/**
288
	 * Returns the {@link State} from the backing baseline
289
	 * @return the state from the backing {@link ApiBaseline}
290
	 */
291
	protected State getState() {
292
		return ((ApiBaseline)getBaseline()).getState();
293
	}
294
	
295
	/**
296
	 * Returns the {@link BundleDescription} for the given manifest + state or throws an exception, never
297
	 * returns <code>null</code>
298
	 * @param manifest
299
	 * @param location
300
	 * @param id
301
	 * @return the {@link BundleDescription} or throws an exception
302
	 * @throws BundleException
303
	 */
304
	protected BundleDescription getBundleDescription(Dictionary manifest, String location, long id) throws BundleException {
305
		State state = getState();
306
		BundleDescription bundle = lookupBundle(state, manifest);
307
		if(bundle != null) {
308
			return bundle;
309
		}
310
		StateObjectFactory factory = StateObjectFactory.defaultFactory;
311
		bundle = factory.createBundleDescription(state, manifest, fLocation, id);
312
		state.addBundle(bundle);
313
		return bundle;
314
	}
315
	
316
	/**
317
	 * Tries to look up the bundle described by the given manifest in the given state
318
	 * @param manifest
319
	 * @return the bundle for the given manifest, <code>null</code> otherwise
320
	 */
321
	protected BundleDescription lookupBundle(State state, Dictionary manifest) {
322
		Version version = null;
323
		try {
324
			//just in case the version is not a number
325
			String ver = (String)manifest.get(Constants.BUNDLE_VERSION);
326
			version = ver != null ? new Version(ver) : null;
327
		}
328
		catch (NumberFormatException nfe) {
329
			version = null;
330
		}
331
		return state.getBundle((String)manifest.get(Constants.BUNDLE_SYMBOLICNAME),	version);
332
	}
333
	
334
	/**
335
	 * Returns whether this API component represents a binary bundle versus a project bundle.
336
	 * 
337
	 * @return whether this API component represents a binary bundle
338
	 */
339
	protected boolean isBinary() {
340
		return true;
341
	}
342
	
343
	/* (non-Javadoc)
344
	 * @see org.eclipse.pde.api.tools.internal.AbstractApiComponent#createApiDescription()
345
	 */
346
	protected IApiDescription createApiDescription() throws CoreException {
347
		BundleDescription[] fragments = getBundleDescription().getFragments();
348
		if (fragments.length == 0) {
349
			return createLocalApiDescription();
350
		}
351
		// build a composite description
352
		IApiDescription[] descriptions = new IApiDescription[fragments.length + 1];
353
		for (int i = 0; i < fragments.length; i++) {
354
			BundleDescription fragment = fragments[i];
355
			BundleComponent component = (BundleComponent) getBaseline().getApiComponent(fragment.getSymbolicName());
356
			descriptions[i + 1] = component.getApiDescription();
357
		}
358
		descriptions[0] = createLocalApiDescription();
359
		return new CompositeApiDescription(descriptions);
360
	}
361
362
	/**
363
	 * Creates and returns this component's API description based on packages
364
	 * supplied by this component, exported packages, and associated directives.
365
	 * 
366
	 * @return API description
367
	 * @throws CoreException if unable to initialize 
368
	 */
369
	protected IApiDescription createLocalApiDescription() throws CoreException {
370
		IApiDescription apiDesc = new ApiDescription(getSymbolicName());
371
		// first mark all packages as internal
372
		initializeApiDescription(apiDesc, getBundleDescription(), getLocalPackageNames());
373
		try {
374
			String xml = loadApiDescription(new File(fLocation));
375
			setHasApiDescription(xml != null);
376
			if (xml != null) {
377
				ApiDescriptionProcessor.annotateApiSettings(null, apiDesc, xml);
378
			}
379
		} catch (IOException e) {
380
			abort("Unable to load .api_description file ", e); //$NON-NLS-1$
381
		}
382
		return apiDesc;
383
	}
384
	
385
	/**
386
	 * Returns the names of all packages that originate from this bundle.
387
	 * Does not include packages that originate from fragments or a host.
388
	 * 
389
	 * @return local package names
390
	 * @throws CoreException
391
	 */
392
	protected Set getLocalPackageNames() throws CoreException {
393
		Set names = new HashSet();
394
		IApiTypeContainer[] containers = getApiTypeContainers();
395
		IApiComponent comp = null;
396
		for (int i = 0; i < containers.length; i++) {
397
			comp = (IApiComponent) containers[i].getAncestor(IApiElement.COMPONENT);
398
			if (comp != null && comp.getSymbolicName().equals(getSymbolicName())) {
399
				String[] packageNames = containers[i].getPackageNames();
400
				for (int j = 0; j < packageNames.length; j++) {
401
					names.add(packageNames[j]);
402
				}
403
			}
404
		}
405
		return names;
406
	}	
407
	
408
409
	/**
410
	 * Initializes the given API description based on package exports in the manifest.
411
	 * The API description for a bundle only contains packages that originate from
412
	 * this bundle (so a host will not contain API descriptions for packages that
413
	 * originate from fragments). However, a host's API description will be represented
414
	 * by a proxy that delegates to the host and all of its fragments to provide
415
	 * a complete description of the host.
416
	 * 
417
	 * @param apiDesc API description to initialize
418
	 * @param bundle the bundle to load from
419
	 * @param packages the complete set of packages names originating from the backing
420
	 * 		component
421
	 * @throws CoreException if an error occurs
422
	 */
423
	public static void initializeApiDescription(IApiDescription apiDesc, BundleDescription bundle, Set packages) throws CoreException {
424
		Iterator iterator = packages.iterator();
425
		while (iterator.hasNext()) {
426
			String name = (String) iterator.next();
427
			apiDesc.setVisibility(Factory.packageDescriptor(name), VisibilityModifiers.PRIVATE);
428
		}
429
		// then process exported packages that originate from this bundle
430
		// considering host and fragment package exports
431
		List supplied = new ArrayList();
432
		ExportPackageDescription[] exportPackages = bundle.getExportPackages();
433
		addSuppliedPackages(packages, supplied, exportPackages);
434
		HostSpecification host = bundle.getHost();
435
		if (host != null) {
436
			BundleDescription[] hosts = host.getHosts();
437
			for (int i = 0; i < hosts.length; i++) {
438
				addSuppliedPackages(packages, supplied, hosts[i].getExportPackages());
439
			}
440
		}
441
		BundleDescription[] fragments = bundle.getFragments();
442
		for (int i = 0; i < fragments.length; i++) {
443
			addSuppliedPackages(packages, supplied, fragments[i].getExportPackages());
444
		}
445
		
446
		annotateExportedPackages(apiDesc, (ExportPackageDescription[]) supplied.toArray(new ExportPackageDescription[supplied.size()]));
447
	}
448
449
	/**
450
	 * Adds package exports to the given list if the associated package originates
451
	 * from this bundle.
452
	 *   
453
	 * @param packages names of packages supplied by this bundle
454
	 * @param supplied list to append package exports to
455
	 * @param exportPackages package exports to consider
456
	 */
457
	protected static void addSuppliedPackages(Set packages, List supplied, ExportPackageDescription[] exportPackages) {
458
		for (int i = 0; i < exportPackages.length; i++) {
459
			ExportPackageDescription pkg = exportPackages[i];
460
			String name = pkg.getName();
461
			if (name.equals(".")) { //$NON-NLS-1$
462
				// translate . to default package
463
				name = Util.DEFAULT_PACKAGE_NAME;
464
			}
465
			if (packages.contains(name)) {
466
				supplied.add(pkg);
467
			}
468
		}
469
	}
470
	
471
	/**
472
	 * Annotates the API description with exported packages.
473
	 * 
474
	 * @param apiDesc description to annotate
475
	 * @param exportedPackages packages that are exported
476
	 */
477
	protected static void annotateExportedPackages(IApiDescription apiDesc, ExportPackageDescription[] exportedPackages) {
478
		for(int i = 0; i < exportedPackages.length; i++) {
479
			ExportPackageDescription pkg = exportedPackages[i];
480
			boolean internal = ((Boolean) pkg.getDirective("x-internal")).booleanValue(); //$NON-NLS-1$
481
			String[] friends = (String[]) pkg.getDirective("x-friends"); //$NON-NLS-1$
482
			String pkgName = pkg.getName();
483
			if (pkgName.equals(".")) { //$NON-NLS-1$
484
				// default package
485
				pkgName = ""; //$NON-NLS-1$
486
			}
487
			IPackageDescriptor pkgDesc = Factory.packageDescriptor(pkgName);
488
			if(internal) {
489
				apiDesc.setVisibility(pkgDesc, VisibilityModifiers.PRIVATE);
490
			}
491
			if (friends != null) {
492
				apiDesc.setVisibility(pkgDesc, VisibilityModifiers.PRIVATE);
493
				for(int j = 0; j < friends.length; j++) {
494
					//annotate the api description for x-friends access levels
495
					apiDesc.setAccessLevel(
496
							Factory.componentDescriptor(friends[j]), 
497
							Factory.packageDescriptor(pkgName), 
498
							IApiAccess.FRIEND);
499
				}
500
			}
501
			if (!internal && friends == null) {
502
				//there could have been directives that have nothing to do with
503
				//visibility, so we need to add the package as API in that case
504
				apiDesc.setVisibility(pkgDesc, VisibilityModifiers.API);
505
			}
506
		}
507
	}
508
	
509
	/* (non-Javadoc)
510
	 * @see org.eclipse.pde.api.tools.internal.AbstractApiComponent#createApiFilterStore()
511
	 */
512
	protected IApiFilterStore createApiFilterStore() throws CoreException {
513
		//always return a new empty store since we do not support filtering from bundles
514
		return null;
515
	}
516
	
517
	/**
518
	 * @see org.eclipse.pde.api.tools.internal.AbstractApiTypeContainer#createApiTypeContainers()
519
	 */
520
	protected synchronized List createApiTypeContainers() throws CoreException {
521
		if (fBundleDescription == null) {
522
			baselineDisposed(getBaseline());
523
		}
524
		List containers = new ArrayList(5);
525
		try {
526
			List all = new ArrayList();
527
			// build the classpath from bundle and all fragments
528
			all.add(this);
529
			boolean considerFragments = true;
530
			if (Util.ORG_ECLIPSE_SWT.equals(getSymbolicName())) {
531
				// if SWT is a project to be built/analyzed don't consider its fragments
532
				considerFragments = !isApiEnabled();
533
			}
534
			if (considerFragments) { 
535
				BundleDescription[] fragments = fBundleDescription.getFragments();
536
				for (int i = 0; i < fragments.length; i++) {
537
					BundleDescription fragment = fragments[i];
538
					BundleComponent component = (BundleComponent) getBaseline().getApiComponent(fragment.getSymbolicName());
539
					if (component != null) {
540
						// force initialization of the fragment so we can retrieve its class file containers
541
						component.getApiTypeContainers();
542
						all.add(component);
543
					}
544
				}
545
			}
546
			Iterator iterator = all.iterator();
547
			Set entryNames = new HashSet(5);
548
			BundleComponent other = null;
549
			while (iterator.hasNext()) {
550
				BundleComponent component = (BundleComponent) iterator.next();
551
				String[] paths = getClasspathEntries(component.getManifest());
552
				for (int i = 0; i < paths.length; i++) {
553
					String path = paths[i];
554
					// don't re-process the same entry twice (except default entries ".")
555
					if (!(".".equals(path))) { //$NON-NLS-1$
556
						if (entryNames.contains(path)) {
557
							continue;
558
						}
559
					}
560
					IApiTypeContainer container = component.createApiTypeContainer(path);
561
					if (container == null) {
562
						for(Iterator iter = all.iterator(); iter.hasNext();) {
563
							other = (BundleComponent) iter.next();
564
							if (other != component) {
565
								container = other.createApiTypeContainer(path);
566
							}
567
						}
568
					}
569
					if (container != null) {
570
						containers.add(container);
571
						if (!(".".equals(path))) { //$NON-NLS-1$
572
							entryNames.add(path);
573
						}
574
					}
575
				}
576
			}
577
		} catch (BundleException e) {
578
			abort("Unable to parse bundle classpath", e); //$NON-NLS-1$
579
		} catch (IOException e) {
580
			abort("Unable to initialize class file containers", e); //$NON-NLS-1$
581
		}
582
		return containers;
583
	}
584
	
585
	/**
586
	 * Returns whether this API component is enabled for API analysis by the API builder.
587
	 * 
588
	 * @return whether this API component is enabled for API analysis by the API builder.
589
	 */
590
	protected boolean isApiEnabled() {
591
		return false;
592
	}
593
	
594
	/**
595
	 * Returns classpath entries defined in the given manifest.
596
	 * 
597
	 * @param manifest
598
	 * @return classpath entries as bundle relative paths
599
	 * @throws BundleException
600
	 */
601
	protected String[] getClasspathEntries(Dictionary manifest) throws BundleException {
602
		ManifestElement[] classpath = ManifestElement.parseHeader(Constants.BUNDLE_CLASSPATH, (String) manifest.get(Constants.BUNDLE_CLASSPATH));
603
		String elements[] = null;
604
		if (classpath == null) {
605
			// default classpath is '.'
606
			elements = new String[]{"."}; //$NON-NLS-1$
607
		} else {
608
			elements = new String[classpath.length];
609
			for (int i = 0; i < classpath.length; i++) {
610
				elements[i] = classpath[i].getValue();
611
			}
612
		}
613
		return elements;
614
	}
615
	
616
	/**
617
	 * Creates and returns an {@link IApiTypeContainer} at the specified path in
618
	 * this bundle, or <code>null</code> if the {@link IApiTypeContainer} does not
619
	 * exist. The path is the name (path) of entries specified by the
620
	 * <code>Bundle-ClassPath:</code> header.
621
	 * 
622
	 * @param path relative path to a class file container in this bundle
623
	 * @return {@link IApiTypeContainer} or <code>null</code>
624
	 * @exception IOException
625
	 */
626
	protected IApiTypeContainer createApiTypeContainer(String path) throws IOException, CoreException {
627
		File bundle = new File(fLocation);
628
		if (bundle.isDirectory()) {
629
			// bundle is folder
630
			File entry = new File(bundle, path);
631
			if (entry.exists()) {
632
				if (entry.isFile()) {
633
					return new ArchiveApiTypeContainer(this, entry.getCanonicalPath());
634
				} else {
635
					return new DirectoryApiTypeContainer(this, entry.getCanonicalPath());
636
				}
637
			}
638
		} else {
639
			// bundle is jar'd
640
			ZipFile zip = null;
641
			try {
642
				if (path.equals(".")) { //$NON-NLS-1$
643
					return new ArchiveApiTypeContainer(this, fLocation);
644
				} else {
645
					//classpath element can be jar or folder
646
					//https://bugs.eclipse.org/bugs/show_bug.cgi?id=279729
647
					zip = new ZipFile(fLocation);
648
					ZipEntry entry = zip.getEntry(path);
649
					if (entry != null) {
650
						File tmpfolder = new File(System.getProperty("java.io.tmpdir")); //$NON-NLS-1$
651
						if(entry.isDirectory()) {
652
							//extract the dir and all children
653
							File dir = File.createTempFile(TMP_API_FILE_PREFIX, TMP_API_FILE_POSTFIX);
654
							dir.deleteOnExit();
655
							//hack to create a temp directory
656
							// see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4735419
657
							if(dir.delete()) {
658
								dir.mkdir();
659
								FileManager.getManager().recordTempFileRoot(dir.getCanonicalPath());
660
							}
661
							extractDirectory(zip, entry.getName(), dir);
662
							if(dir.isDirectory() && dir.exists()) {
663
								return new DirectoryApiTypeContainer(this, dir.getCanonicalPath());
664
							}
665
						}
666
						else {
667
							File file = extractEntry(zip, entry, tmpfolder);
668
							if(Util.isArchive(file.getName())) {
669
								File parent = file.getParentFile();
670
								if(!parent.equals(tmpfolder)) {
671
									FileManager.getManager().recordTempFileRoot(parent.getCanonicalPath());
672
								}
673
								else {
674
									FileManager.getManager().recordTempFileRoot(file.getCanonicalPath());
675
								}
676
								return new ArchiveApiTypeContainer(this, file.getCanonicalPath());
677
							}
678
						}
679
					}
680
				}
681
			} finally {
682
				if (zip != null) {
683
					zip.close();
684
				}
685
			}
686
		}
687
		return null;
688
	}
689
		
690
	/**
691
	 * Extracts a directory from the archive given a path prefix for entries to retrieve.
692
	 * <code>null</code> can be passed in as a prefix, causing all entries to be be extracted from 
693
	 * the archive.
694
	 * 
695
	 * @param zip the {@link ZipFile} to extract from
696
	 * @param pathprefix the prefix'ing path to include for extraction
697
	 * @param parent the parent directory to extract to
698
	 * @throws IOException if the {@link ZipFile} cannot be read or extraction fails to write the file(s)
699
	 */
700
	void extractDirectory(ZipFile zip, String pathprefix, File parent) throws IOException {
701
		Enumeration entries = zip.entries();
702
		String prefix = (pathprefix == null ? Util.EMPTY_STRING : pathprefix);
703
		ZipEntry entry = null;
704
		File file = null;
705
		while (entries.hasMoreElements()) {
706
			entry = (ZipEntry) entries.nextElement();
707
			if(entry.getName().startsWith(prefix)) {
708
				file = new File(parent, entry.getName());
709
				if (entry.isDirectory()) {
710
					file.mkdir();
711
					continue;
712
				}
713
				extractEntry(zip, entry, parent);
714
			}
715
		}
716
	}
717
	
718
	/**
719
	 * Extracts a non-directory entry from a zip file and returns the File handle
720
	 * @param zip the zip to extract from
721
	 * @param entry the entry to extract
722
	 * @param parent the parent directory to add the extracted entry to
723
	 * @return the file handle to the extracted entry, <code>null</code> otherwise
724
	 * @throws IOException
725
	 */
726
	File extractEntry(ZipFile zip, ZipEntry entry, File parent) throws IOException {
727
		InputStream inputStream = null;
728
		File file;
729
		FileOutputStream outputStream = null;
730
		try {
731
			inputStream = zip.getInputStream(entry);
732
			file = new File(parent, entry.getName());
733
			File lparent = file.getParentFile();
734
			if(!lparent.exists()) {
735
				lparent.mkdirs();
736
			}
737
			outputStream = new FileOutputStream(file);
738
			byte[] bytes = new byte[8096];
739
			while (inputStream.available() > 0) {
740
				int read = inputStream.read(bytes);
741
				if (read > 0) {
742
					outputStream.write(bytes, 0, read);
743
				}
744
			}
745
		} finally {
746
			if (inputStream != null) {
747
				try {
748
					inputStream.close();
749
				} catch(IOException e) {
750
					ApiPlugin.log(e);
751
				}
752
			}
753
			if (outputStream != null) {
754
				try {
755
					outputStream.close();
756
				} catch(IOException e) {
757
					ApiPlugin.log(e);
758
				}
759
			}
760
		}
761
		return file;
762
	}
763
	
764
	/**
765
	 * Parses a bunlde's manifest into a dictionary. The bundle may be in a jar
766
	 * or in a directory at the specified location.
767
	 * 
768
	 * @param bundleLocation root location of the bundle
769
	 * @return bundle manifest dictionary or <code>null</code> if none
770
	 * @throws IOException if unable to parse
771
	 */
772
	protected Map loadManifest(File bundleLocation) throws IOException {
773
		ZipFile jarFile = null;
774
		InputStream manifestStream = null;
775
		String extension = new Path(bundleLocation.getName()).getFileExtension();
776
		try {
777
			if (extension != null && extension.equals("jar") && bundleLocation.isFile()) { //$NON-NLS-1$
778
				jarFile = new ZipFile(bundleLocation, ZipFile.OPEN_READ);
779
				ZipEntry manifestEntry = jarFile.getEntry(JarFile.MANIFEST_NAME);
780
				if (manifestEntry != null) {
781
					manifestStream = jarFile.getInputStream(manifestEntry);
782
				}
783
			} else {
784
				File file = new File(bundleLocation, JarFile.MANIFEST_NAME);
785
				if (file.exists())
786
					manifestStream = new FileInputStream(file);
787
			}
788
			if (manifestStream == null) {
789
				return null;
790
			}
791
			return ManifestElement.parseBundleManifest(manifestStream, new Hashtable(10));
792
		} catch (BundleException e) {
793
			ApiPlugin.log(e);
794
		} finally {
795
			closingZipFileAndStream(manifestStream, jarFile);
796
		}
797
		return null;
798
	}
799
	
800
	/**
801
	 * Reads and returns this bunlde's manifest in a Manifest object.
802
	 * The bundle may be in a jar or in a directory at the specified location.
803
	 * 
804
	 * @param bundleLocation root location of the bundle
805
	 * @return manifest or <code>null</code> if not present
806
	 * @throws IOException if unable to parse
807
	 */
808
	protected Manifest readManifest(File bundleLocation) throws IOException {
809
		ZipFile jarFile = null;
810
		InputStream manifestStream = null;
811
		try {
812
			String extension = new Path(bundleLocation.getName()).getFileExtension();
813
			if (extension != null && extension.equals("jar") && bundleLocation.isFile()) { //$NON-NLS-1$
814
				jarFile = new ZipFile(bundleLocation, ZipFile.OPEN_READ);
815
				ZipEntry manifestEntry = jarFile.getEntry(JarFile.MANIFEST_NAME);
816
				if (manifestEntry != null) {
817
					manifestStream = jarFile.getInputStream(manifestEntry);
818
				}
819
			} else {
820
				File file = new File(bundleLocation, JarFile.MANIFEST_NAME);
821
				if (file.exists())
822
					manifestStream = new FileInputStream(file);
823
			}
824
			if (manifestStream == null) {
825
				return null;
826
			}
827
			return new Manifest(manifestStream);
828
		} finally {
829
			closingZipFileAndStream(manifestStream, jarFile);
830
		}
831
	}
832
833
	void closingZipFileAndStream(InputStream stream, ZipFile jarFile) {
834
		try {
835
			if (stream != null) {
836
				stream.close();
837
			}
838
		} catch (IOException e) {
839
			ApiPlugin.log(e);
840
		}
841
		try {
842
			if (jarFile != null) {
843
				jarFile.close();
844
			}
845
		} catch (IOException e) {
846
			ApiPlugin.log(e);
847
		}
848
	}
849
	
850
	/**
851
	 * Reads and returns the file contents corresponding to the given file name.
852
	 * The bundle may be in a jar or in a directory at the specified location.
853
	 * 
854
	 * @param xmlFileName the given file name
855
	 * @param bundleLocation the root location of the bundle
856
	 * @return the file contents or <code>null</code> if not present
857
	 */
858
	protected String readFileContents(String xmlFileName, File bundleLocation) {
859
		ZipFile jarFile = null;
860
		InputStream stream = null;
861
		try {
862
			String extension = new Path(bundleLocation.getName()).getFileExtension();
863
			if (extension != null && extension.equals("jar") && bundleLocation.isFile()) { //$NON-NLS-1$
864
				jarFile = new ZipFile(bundleLocation, ZipFile.OPEN_READ);
865
				ZipEntry manifestEntry = jarFile.getEntry(xmlFileName);
866
				if (manifestEntry != null) {
867
					stream = jarFile.getInputStream(manifestEntry);
868
				}
869
			} else {
870
				File file = new File(bundleLocation, xmlFileName);
871
				if (file.exists()) {
872
					stream = new FileInputStream(file);
873
				}
874
			}
875
			if (stream == null) {
876
				return null;
877
			}
878
			return new String(Util.getInputStreamAsCharArray(stream, -1, IApiCoreConstants.UTF_8));
879
		} catch(IOException e) {
880
			//TODO abort
881
			ApiPlugin.log(e);
882
		} finally {
883
			closingZipFileAndStream(stream, jarFile);
884
		}
885
		return null;
886
	}
887
888
	/**
889
	 * Parses a bundle's .api_description XML into a string. The file may be in a jar
890
	 * or in a directory at the specified location.
891
	 * 
892
	 * @param bundleLocation root location of the bundle
893
	 * @return API description XML as a string or <code>null</code> if none
894
	 * @throws IOException if unable to parse
895
	 */
896
	protected String loadApiDescription(File bundleLocation) throws IOException {
897
		ZipFile jarFile = null;
898
		InputStream stream = null;
899
		String contents = null;
900
		try {
901
			String extension = new Path(bundleLocation.getName()).getFileExtension();
902
			if (extension != null && extension.equals("jar") && bundleLocation.isFile()) { //$NON-NLS-1$
903
				jarFile = new ZipFile(bundleLocation, ZipFile.OPEN_READ);
904
				ZipEntry manifestEntry = jarFile.getEntry(IApiCoreConstants.API_DESCRIPTION_XML_NAME);
905
				if (manifestEntry != null) {
906
					// new file is present
907
					stream = jarFile.getInputStream(manifestEntry);
908
				}
909
			} else {
910
				File file = new File(bundleLocation, IApiCoreConstants.API_DESCRIPTION_XML_NAME);
911
				if (file.exists()) {
912
					// use new file
913
					stream = new FileInputStream(file);
914
				}
915
			}
916
			if (stream == null) {
917
				return null;
918
			}
919
			char[] charArray = Util.getInputStreamAsCharArray(stream, -1, IApiCoreConstants.UTF_8);
920
			contents = new String(charArray);
921
		} finally {
922
			closingZipFileAndStream(stream, jarFile);
923
		}
924
		return contents;
925
	}
926
	
927
	
928
	/**
929
	 * Returns a URL describing a file inside a bundle.
930
	 * 
931
	 * @param bundleLocation root location of the bundle. May be a
932
	 *  directory or a file (jar)
933
	 * @param filePath bundle relative path to desired file
934
	 * @return URL to the file
935
	 * @throws MalformedURLException 
936
	 */
937
	protected URL getFileInBundle(File bundleLocation, String filePath) throws MalformedURLException {
938
		String extension = new Path(bundleLocation.getName()).getFileExtension();
939
		StringBuffer urlSt = new StringBuffer();
940
		if (extension != null && extension.equals("jar") && bundleLocation.isFile()) { //$NON-NLS-1$
941
			urlSt.append("jar:file:"); //$NON-NLS-1$
942
			urlSt.append(bundleLocation.getAbsolutePath());
943
			urlSt.append("!/"); //$NON-NLS-1$
944
			urlSt.append(filePath);
945
		} else {
946
			urlSt.append("file:"); //$NON-NLS-1$
947
			urlSt.append(bundleLocation.getAbsolutePath());
948
			urlSt.append(File.separatorChar);
949
			urlSt.append(filePath);
950
		}	
951
		return new URL(urlSt.toString());
952
	}
953
	
954
	/* (non-Javadoc)
955
	 * @see org.eclipse.pde.api.tools.manifest.IApiComponent#getExecutionEnvironments()
956
	 */
957
	public synchronized String[] getExecutionEnvironments() throws CoreException {
958
		if (fBundleDescription == null) {
959
			baselineDisposed(getBaseline());
960
		}
961
		return fBundleDescription.getExecutionEnvironments();
962
	}
963
964
	/* (non-Javadoc)
965
	 * @see org.eclipse.pde.api.tools.manifest.IApiComponent#getSymbolicName()
966
	 */
967
	public final String getSymbolicName() {
968
		init();
969
		return fSymbolicName;
970
	}
971
972
	/* (non-Javadoc)
973
	 * @see org.eclipse.pde.api.tools.manifest.IApiComponent#getRequiredComponents()
974
	 */
975
	public synchronized IRequiredComponentDescription[] getRequiredComponents() throws CoreException {
976
		if (fBundleDescription == null) {
977
			baselineDisposed(getBaseline());
978
		}
979
		BundleSpecification[] requiredBundles = fBundleDescription.getRequiredBundles();
980
		IRequiredComponentDescription[] req = new IRequiredComponentDescription[requiredBundles.length];
981
		for (int i = 0; i < requiredBundles.length; i++) {
982
			BundleSpecification bundle = requiredBundles[i];
983
			req[i] = new RequiredComponentDescription(bundle.getName(),
984
					new BundleVersionRange(bundle.getVersionRange()),
985
					bundle.isOptional(),
986
					bundle.isExported());
987
		}
988
		return req;
989
	}
990
991
	/* (non-Javadoc)
992
	 * @see org.eclipse.pde.api.tools.manifest.IApiComponent#getVersion()
993
	 */
994
	public synchronized String getVersion() {
995
		init();
996
		return fVersion.toString();
997
	}
998
	
999
	/**
1000
	 * Returns this component's bundle description.
1001
	 * 
1002
	 * @return bundle description
1003
	 */
1004
	public synchronized BundleDescription getBundleDescription() throws CoreException {
1005
		init();
1006
		if (fBundleDescription == null) {
1007
			baselineDisposed(getBaseline());
1008
		}
1009
		return fBundleDescription;
1010
	}
1011
1012
	/* (non-Javadoc)
1013
	 * @see java.lang.Object#toString()
1014
	 */
1015
	public String toString() {
1016
		if (fBundleDescription != null) {
1017
			try {
1018
				StringBuffer buffer = new StringBuffer();
1019
				buffer.append(fBundleDescription.toString());
1020
				buffer.append(" - "); //$NON-NLS-1$
1021
				buffer.append("[fragment: ").append(isFragment()).append("] "); //$NON-NLS-1$ //$NON-NLS-2$
1022
				buffer.append("[host: ").append(fBundleDescription.getFragments().length > 0).append("] "); //$NON-NLS-1$ //$NON-NLS-2$
1023
				buffer.append("[system bundle: ").append(isSystemComponent()).append("] "); //$NON-NLS-1$ //$NON-NLS-2$
1024
				buffer.append("[source bundle: ").append(isSourceComponent()).append("] "); //$NON-NLS-1$ //$NON-NLS-2$
1025
				buffer.append("[dev bundle: ").append(fWorkspaceBinary).append("]"); //$NON-NLS-1$ //$NON-NLS-2$
1026
				return buffer.toString();
1027
			}
1028
			catch(CoreException ce) {} 
1029
		}
1030
		else {
1031
			StringBuffer buffer = new StringBuffer();
1032
			buffer.append("Un-initialized Bundle Component"); //$NON-NLS-1$
1033
			buffer.append("[location: ").append(fLocation).append("]"); //$NON-NLS-1$ //$NON-NLS-2$
1034
			buffer.append("[dev bundle: ").append(fWorkspaceBinary).append("]"); //$NON-NLS-1$ //$NON-NLS-2$
1035
			return buffer.toString();
1036
		}
1037
		return super.toString();
1038
	}
1039
1040
	/* (non-Javadoc)
1041
	 * @see org.eclipse.pde.api.tools.model.component.IApiComponent#getLocation()
1042
	 */
1043
	public String getLocation() {
1044
		return fLocation;
1045
	}
1046
1047
	/* (non-Javadoc)
1048
	 * @see org.eclipse.pde.api.tools.model.component.IApiComponent#isSystemComponent()
1049
	 */
1050
	public boolean isSystemComponent() {
1051
		return false;
1052
	}
1053
	
1054
	/* (non-Javadoc)
1055
	 * @see IApiComponent#isSourceComponent()
1056
	 */
1057
	public synchronized boolean isSourceComponent() throws CoreException {
1058
		getManifest();
1059
		if (fManifest == null) {
1060
			baselineDisposed(getBaseline());
1061
		}
1062
		ManifestElement[] sourceBundle = null;
1063
		try {
1064
			sourceBundle = ManifestElement.parseHeader(IApiCoreConstants.ECLIPSE_SOURCE_BUNDLE, (String) fManifest.get(IApiCoreConstants.ECLIPSE_SOURCE_BUNDLE));
1065
		} catch (BundleException e) {
1066
			// ignore
1067
		}
1068
		if (sourceBundle != null) {
1069
			// this is a source bundle with the new format
1070
			return true;
1071
		}
1072
		// check for the old format
1073
		String pluginXMLContents = readFileContents(IApiCoreConstants.PLUGIN_XML_NAME,new File(getLocation()));
1074
		if (pluginXMLContents != null) {
1075
			if (containsSourceExtensionPoint(pluginXMLContents)) {
1076
				return true;
1077
			}
1078
		}
1079
		// check if it contains a fragment.xml with the appropriate extension point
1080
		pluginXMLContents = readFileContents(IApiCoreConstants.FRAGMENT_XML_NAME,new File(getLocation()));
1081
		if (pluginXMLContents != null) {
1082
			if (containsSourceExtensionPoint(pluginXMLContents)) {
1083
				return true;
1084
			}
1085
		}
1086
		// parse XML contents to find extension points
1087
		return false;
1088
	}
1089
1090
	/**
1091
	 * Check if the given source contains an source extension point.
1092
	 * 
1093
	 * @param pluginXMLContents the given file contents
1094
	 * @return true if it contains a source extension point, false otherwise
1095
	 */
1096
	private boolean containsSourceExtensionPoint(String pluginXMLContents) {
1097
		SAXParserFactory factory = null;
1098
		try {
1099
			factory = SAXParserFactory.newInstance();
1100
		} catch (FactoryConfigurationError e) {
1101
			return false;
1102
		}
1103
		SAXParser saxParser = null;
1104
		try {
1105
			saxParser = factory.newSAXParser();
1106
		} catch (ParserConfigurationException e) {
1107
			// ignore
1108
		} catch (SAXException e) {
1109
			// ignore
1110
		}
1111
1112
		if (saxParser == null) {
1113
			return false;
1114
		}
1115
1116
		// Parse
1117
		InputSource inputSource = new InputSource(new BufferedReader(new StringReader(pluginXMLContents)));
1118
		try {
1119
			SourceDefaultHandler defaultHandler = new SourceDefaultHandler();
1120
			saxParser.parse(inputSource, defaultHandler);
1121
			return defaultHandler.isSource();
1122
		} catch (SAXException e) {
1123
			// ignore
1124
		} catch (IOException e) {
1125
			// ignore
1126
		}
1127
		return false;
1128
	}	
1129
1130
	/* (non-Javadoc)
1131
	 * @see org.eclipse.pde.api.tools.IApiComponent#isFragment()
1132
	 */
1133
	public synchronized boolean isFragment() throws CoreException {
1134
		init();
1135
		if (fBundleDescription == null) {
1136
			baselineDisposed(getBaseline());
1137
		}
1138
		return fBundleDescription.getHost() != null;
1139
	}
1140
1141
	/* (non-Javadoc)
1142
	 * @see org.eclipse.pde.api.tools.internal.model.Component#getHost()
1143
	 */
1144
	public synchronized IApiComponent getHost() throws CoreException {
1145
		init();
1146
		if (fBundleDescription == null) {
1147
			baselineDisposed(getBaseline());
1148
		}
1149
		HostSpecification host = fBundleDescription.getHost();
1150
		if(host != null) {
1151
			return getBaseline().getApiComponent(host.getName());
1152
		}
1153
		return null;
1154
	}
1155
	
1156
	/* (non-Javadoc)
1157
	 * @see org.eclipse.pde.api.tools.IApiComponent#hasFragments()
1158
	 */
1159
	public synchronized boolean hasFragments() throws CoreException {
1160
		init();
1161
		if (fBundleDescription == null) {
1162
			baselineDisposed(getBaseline());
1163
		}
1164
		return fBundleDescription.getFragments().length != 0;
1165
	}
1166
	
1167
	/**
1168
	 * Sets whether this bundle has an underlying API description file.
1169
	 * 
1170
	 * @param hasApiDescription whether this bundle has an underlying API description file
1171
	 */
1172
	protected void setHasApiDescription(boolean hasApiDescription) {
1173
		fHasApiDescription = hasApiDescription;
1174
	}
1175
	
1176
	/* (non-Javadoc)
1177
	 * @see org.eclipse.pde.api.tools.internal.provisional.IApiComponent#hasApiDescription()
1178
	 */
1179
	public boolean hasApiDescription() {
1180
		// ensure initialized
1181
		try {
1182
			getApiDescription();
1183
		} catch (CoreException e) {
1184
		}
1185
		return fHasApiDescription;
1186
	}
1187
	
1188
	/* (non-Javadoc)
1189
	 * @see org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent#getLowestEEs()
1190
	 */
1191
	public String[] getLowestEEs() throws CoreException {
1192
		if (lowestEEs != null) return lowestEEs;
1193
		String[] temp = null;
1194
		String[] executionEnvironments = getExecutionEnvironments();
1195
		int length = executionEnvironments.length;
1196
		switch(length) {
1197
			case 0 :
1198
				return null;
1199
			case 1 :
1200
				temp = new String[] { executionEnvironments[0] };
1201
				break;
1202
			default :
1203
				int values = ProfileModifiers.NO_PROFILE_VALUE;
1204
				for (int i = 0; i < length; i++) {
1205
					values |= ProfileModifiers.getValue(executionEnvironments[i]);
1206
				}
1207
				if (ProfileModifiers.isJRE(values)) {
1208
					if (ProfileModifiers.isJRE_1_1(values)) {
1209
						temp = new String[] { ProfileModifiers.JRE_1_1_NAME };
1210
					} else if (ProfileModifiers.isJ2SE_1_2(values)) {
1211
						temp = new String[] { ProfileModifiers.J2SE_1_2_NAME };
1212
					} else if (ProfileModifiers.isJ2SE_1_3(values)) {
1213
						temp = new String[] { ProfileModifiers.J2SE_1_3_NAME };
1214
					} else if (ProfileModifiers.isJ2SE_1_4(values)) {
1215
						temp = new String[] { ProfileModifiers.J2SE_1_4_NAME };
1216
					} else if (ProfileModifiers.isJ2SE_1_5(values)) {
1217
						temp = new String[] { ProfileModifiers.J2SE_1_5_NAME };
1218
					} else {
1219
						// this is 1.6
1220
						temp = new String[] { ProfileModifiers.JAVASE_1_6_NAME };
1221
					}
1222
				}
1223
				if (ProfileModifiers.isCDC_Foundation(values)) {
1224
					if (ProfileModifiers.isCDC_1_0_FOUNDATION_1_0(values)) {
1225
						if (temp != null) {
1226
							temp = new String[] { temp[0], ProfileModifiers.CDC_1_0_FOUNDATION_1_0_NAME };
1227
						} else {
1228
							temp = new String[] { ProfileModifiers.CDC_1_0_FOUNDATION_1_0_NAME };
1229
						}
1230
					} else {
1231
						if (temp != null) {
1232
							temp = new String[] { temp[0], ProfileModifiers.CDC_1_1_FOUNDATION_1_1_NAME };
1233
						} else {
1234
							temp = new String[] { ProfileModifiers.CDC_1_1_FOUNDATION_1_1_NAME };
1235
						}
1236
					}
1237
				}
1238
				if (ProfileModifiers.isOSGi(values)) {
1239
					if (ProfileModifiers.isOSGI_MINIMUM_1_0(values)) {
1240
						if (temp != null) {
1241
							int tempLength = temp.length;
1242
							System.arraycopy(temp, 0, (temp = new String[tempLength + 1]), 0, tempLength);
1243
							temp[tempLength] = ProfileModifiers.OSGI_MINIMUM_1_0_NAME;
1244
						} else {
1245
							temp = new String[] { ProfileModifiers.OSGI_MINIMUM_1_0_NAME };
1246
						}
1247
					} else if (ProfileModifiers.isOSGI_MINIMUM_1_1(values)) {
1248
						if (temp != null) {
1249
							int tempLength = temp.length;
1250
							System.arraycopy(temp, 0, (temp = new String[tempLength + 1]), 0, tempLength);
1251
							temp[tempLength] = ProfileModifiers.OSGI_MINIMUM_1_1_NAME;
1252
						} else {
1253
							temp = new String[] { ProfileModifiers.OSGI_MINIMUM_1_1_NAME };
1254
						}
1255
					} else {
1256
						// OSGI_MINIMUM_1_2
1257
						if (temp != null) {
1258
							int tempLength = temp.length;
1259
							System.arraycopy(temp, 0, (temp = new String[tempLength + 1]), 0, tempLength);
1260
							temp[tempLength] = ProfileModifiers.OSGI_MINIMUM_1_2_NAME;
1261
						} else {
1262
							temp = new String[] { ProfileModifiers.OSGI_MINIMUM_1_2_NAME };
1263
						}
1264
					}
1265
				}
1266
		}
1267
		lowestEEs = temp;
1268
		return temp;
1269
	}
1270
	
1271
	/* (non-Javadoc)
1272
	 * @see org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent#getErrors()
1273
	 */
1274
	public synchronized ResolverError[] getErrors() throws CoreException {
1275
		init();
1276
		ApiBaseline baseline = (ApiBaseline) getBaseline();
1277
		if (fBundleDescription == null) {
1278
			baselineDisposed(baseline);
1279
		}
1280
		if (baseline != null) {
1281
			ResolverError[] resolverErrors = baseline.getState().getResolverErrors(fBundleDescription);
1282
			if (resolverErrors.length == 0) {
1283
				return null;
1284
			}
1285
			return resolverErrors;
1286
		}
1287
		return null;
1288
	}
1289
	
1290
	/**
1291
	 * @param baseline the baseline that is disposed
1292
	 * @throws CoreException with the baseline disposed information
1293
	 */
1294
	protected void baselineDisposed(IApiBaseline baseline) throws CoreException {
1295
		throw new CoreException(
1296
				new Status(
1297
						IStatus.ERROR,
1298
						ApiPlugin.PLUGIN_ID,
1299
						ApiPlugin.REPORT_BASELINE_IS_DISPOSED,
1300
						NLS.bind(Messages.BundleApiComponent_baseline_disposed, baseline.getName()),
1301
						null));
1302
	}
1303
}
(-)src/org/eclipse/pde/api/tools/internal/model/Component.java (+192 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2007, 2009 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.model;
12
13
import org.eclipse.core.runtime.CoreException;
14
import org.eclipse.pde.api.tools.internal.problems.ApiProblemFilter;
15
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
16
import org.eclipse.pde.api.tools.internal.provisional.Factory;
17
import org.eclipse.pde.api.tools.internal.provisional.IApiDescription;
18
import org.eclipse.pde.api.tools.internal.provisional.IApiFilterStore;
19
import org.eclipse.pde.api.tools.internal.provisional.descriptors.IElementDescriptor;
20
import org.eclipse.pde.api.tools.internal.provisional.model.ApiTypeContainerVisitor;
21
import org.eclipse.pde.api.tools.internal.provisional.model.IApiBaseline;
22
import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent;
23
import org.eclipse.pde.api.tools.internal.provisional.model.IApiElement;
24
import org.eclipse.pde.api.tools.internal.provisional.model.IApiTypeContainer;
25
import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblem;
26
import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblemFilter;
27
28
/**
29
 * Common implementation of an API component as a composite class file container.
30
 * 
31
 * @since 1.0.0
32
 */
33
public abstract class Component extends AbstractApiTypeContainer implements IApiComponent {
34
	/**
35
	 * API description
36
	 */
37
	private IApiDescription fApiDescription = null;
38
		
39
	/**
40
	 * Api Filter store
41
	 */
42
	private IApiFilterStore fFilterStore = null;
43
	
44
	/**
45
	 * Constructs an API component in the given {@link IApiBaseline}.
46
	 * 
47
	 * @param baseline the parent {@link IApiBaseline}
48
	 */
49
	public Component(IApiBaseline baseline) {
50
		super(baseline, IApiElement.COMPONENT, null);
51
	}
52
	
53
	/* (non-Javadoc)
54
	 * @see org.eclipse.pde.api.tools.model.component.IClassFileContainer#accept(org.eclipse.pde.api.tools.model.component.ClassFileContainerVisitor)
55
	 */
56
	public void accept(ApiTypeContainerVisitor visitor) throws CoreException {
57
		if (visitor.visit(this)) {
58
			super.accept(visitor);
59
		}
60
		visitor.end(this);
61
	}	
62
		
63
	/* (non-Javadoc)
64
	 * @see org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent#getHost()
65
	 */
66
	public IApiComponent getHost() throws CoreException {
67
		return null;
68
	}
69
	
70
	/* (non-Javadoc)
71
	 * @see org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent#getBaseline()
72
	 */
73
	public IApiBaseline getBaseline() {
74
		return (IApiBaseline) getAncestor(IApiElement.BASELINE);
75
	}
76
77
	/* (non-Javadoc)
78
	 * @see org.eclipse.pde.api.tools.model.component.IApiComponent#dispose()
79
	 */
80
	public void dispose() {
81
		try {
82
			close();
83
		} catch (CoreException e) {
84
			ApiPlugin.log(e);
85
		}
86
		finally {
87
			synchronized(this) {
88
				fApiDescription = null;
89
			}
90
		}
91
	}
92
93
	/* (non-Javadoc)
94
	 * @see org.eclipse.pde.api.tools.internal.model.ApiElement#getApiComponent()
95
	 */
96
	public IApiComponent getApiComponent() {
97
		return this;
98
	}
99
	
100
	/* (non-Javadoc)
101
	 * @see org.eclipse.pde.api.tools.model.component.IApiComponent#getApiDescription()
102
	 */
103
	public synchronized IApiDescription getApiDescription() throws CoreException {
104
		if (fApiDescription == null) {
105
			fApiDescription = createApiDescription();
106
		}
107
		return fApiDescription;
108
	}
109
	
110
	/**
111
	 * Returns whether this component has created an API description.
112
	 * 
113
	 * @return whether this component has created an API description
114
	 */
115
	protected synchronized boolean isApiDescriptionInitialized() {
116
		return fApiDescription != null;
117
	}
118
119
	/**
120
	 * Returns if this component has created an API filter store
121
	 * 
122
	 * @return true if a store has been created, false other wise
123
	 */
124
	protected synchronized boolean hasApiFilterStore() {
125
		return fFilterStore != null;
126
	}
127
	
128
	/* (non-Javadoc)
129
	 * @see org.eclipse.pde.api.tools.internal.model.AbstractApiTypeContainer#getApiTypeContainers()
130
	 */
131
	public synchronized IApiTypeContainer[] getApiTypeContainers() throws CoreException {
132
		return super.getApiTypeContainers();
133
	}
134
135
	/* (non-Javadoc)
136
	 * @see org.eclipse.pde.api.tools.internal.model.AbstractApiTypeContainer#getApiTypeContainers()
137
	 */
138
	public synchronized IApiTypeContainer[] getApiTypeContainers(String id) throws CoreException {
139
		if (this.hasFragments()) {
140
			return super.getApiTypeContainers(id);
141
		} else {
142
			return super.getApiTypeContainers();
143
		}
144
	}
145
	
146
	/**
147
	 * Creates and returns the API description for this component.
148
	 * 
149
	 * @return newly created API description for this component
150
	 */
151
	protected abstract IApiDescription createApiDescription() throws CoreException;
152
153
	/* (non-Javadoc)
154
	 * @see org.eclipse.pde.api.tools.IApiComponent#getFilterStore()
155
	 */
156
	public IApiFilterStore getFilterStore() throws CoreException {
157
		if(fFilterStore == null) {
158
			fFilterStore = createApiFilterStore();
159
		}
160
		return fFilterStore;
161
	}
162
163
	/* (non-Javadoc)
164
	 * @see org.eclipse.pde.api.tools.internal.provisional.IApiComponent#newProblemFilter(org.eclipse.pde.api.tools.internal.provisional.IApiProblem)
165
	 */
166
	public IApiProblemFilter newProblemFilter(IApiProblem problem) throws CoreException {
167
		//TODO either expose a way to make problems or change the method to accept the parts of a problem
168
		return new ApiProblemFilter(getSymbolicName(), problem);
169
	}
170
	
171
	/* (non-Javadoc)
172
	 * @see org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent#getHandle()
173
	 */
174
	public IElementDescriptor getHandle() {
175
		return Factory.componentDescriptor(this.getSymbolicName(), this.getVersion());
176
	}
177
	
178
	/* (non-Javadoc)
179
	 * @see org.eclipse.pde.api.tools.internal.provisional.model.IApiTypeContainer#getContainerType()
180
	 */
181
	public int getContainerType() {
182
		return IApiTypeContainer.COMPONENT;
183
	}
184
	
185
	/**
186
	 * Lazily creates a new {@link IApiFilterStore} when it is requested
187
	 * 
188
	 * @return the current {@link IApiFilterStore} for this component
189
	 * @throws CoreException
190
	 */
191
	protected abstract IApiFilterStore createApiFilterStore() throws CoreException;	
192
}
(-)src/org/eclipse/pde/api/tools/internal/model/PluginProjectApiComponent.java (-392 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2007, 2009 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.model;
12
13
import java.io.IOException;
14
import java.util.ArrayList;
15
import java.util.Collections;
16
import java.util.HashMap;
17
import java.util.List;
18
import java.util.Map;
19
20
import org.eclipse.core.resources.IContainer;
21
import org.eclipse.core.resources.IFile;
22
import org.eclipse.core.resources.IProject;
23
import org.eclipse.core.resources.IResource;
24
import org.eclipse.core.resources.ResourcesPlugin;
25
import org.eclipse.core.runtime.CoreException;
26
import org.eclipse.core.runtime.IPath;
27
import org.eclipse.core.runtime.Path;
28
import org.eclipse.jdt.core.IClasspathEntry;
29
import org.eclipse.jdt.core.IJavaProject;
30
import org.eclipse.jdt.core.IPackageFragmentRoot;
31
import org.eclipse.jdt.core.JavaCore;
32
import org.eclipse.pde.api.tools.internal.ApiDescriptionManager;
33
import org.eclipse.pde.api.tools.internal.ApiFilterStore;
34
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
35
import org.eclipse.pde.api.tools.internal.provisional.IApiDescription;
36
import org.eclipse.pde.api.tools.internal.provisional.IApiFilterStore;
37
import org.eclipse.pde.api.tools.internal.provisional.model.IApiBaseline;
38
import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent;
39
import org.eclipse.pde.api.tools.internal.provisional.model.IApiTypeContainer;
40
import org.eclipse.pde.api.tools.internal.util.Util;
41
import org.eclipse.pde.core.build.IBuild;
42
import org.eclipse.pde.core.build.IBuildEntry;
43
import org.eclipse.pde.core.plugin.IPluginModelBase;
44
import org.eclipse.pde.internal.core.build.WorkspaceBuildModel;
45
46
/**
47
 * An API component for a plug-in project in the workspace.
48
 * <p>
49
 * Note: this class requires a running workspace to be instantiated.
50
 * </p>
51
 * @since 1.0.0
52
 */
53
public class PluginProjectApiComponent extends BundleApiComponent {
54
	
55
	/**
56
	 * Constant used for controlling tracing in the plug-in workspace component
57
	 */
58
	private static boolean DEBUG = Util.DEBUG;
59
	
60
	/**
61
	 * Method used for initializing tracing in the plug-in workspace component
62
	 */
63
	public static void setDebug(boolean debugValue) {
64
		DEBUG = debugValue || Util.DEBUG;
65
	}
66
		
67
	/**
68
	 * Associated Java project
69
	 */
70
	private IJavaProject fProject = null;
71
72
	/**
73
	 * Associated IPluginModelBase object
74
	 */
75
	private IPluginModelBase fModel = null;
76
	
77
	/**
78
	 * A cache of bundle class path entries to class file containers.
79
	 */
80
	private Map fPathToOutputContainers = null;
81
	
82
	/**
83
	 * A cache of output location paths to corresponding class file containers.
84
	 */
85
	private Map fOutputLocationToContainer = null;
86
87
	/**
88
	 * Constructs an API component for the given Java project in the specified profile.
89
	 * 
90
	 * @param profile the owning profile
91
	 * @param location the given location of the component
92
	 * @param model the given model
93
	 * @param project java project
94
	 * @throws CoreException if unable to create the API component
95
	 */
96
	public PluginProjectApiComponent(IApiBaseline profile, String location, IPluginModelBase model) throws CoreException {
97
		super(profile, location);
98
		IPath path = new Path(location);
99
		IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(path.lastSegment());
100
		this.fProject = JavaCore.create(project);
101
		this.fModel = model;
102
		setName(fModel.getResourceString(super.getName()));
103
	}
104
	
105
	/* (non-Javadoc)
106
	 * @see org.eclipse.pde.api.tools.internal.BundleApiComponent#isBinaryBundle()
107
	 */
108
	protected boolean isBinaryBundle() {
109
		return false;
110
	}
111
	
112
	/* (non-Javadoc)
113
	 * @see org.eclipse.pde.api.tools.internal.BundleApiComponent#isApiEnabled()
114
	 */
115
	protected boolean isApiEnabled() {
116
		return Util.isApiProject(fProject);
117
	}
118
119
	/* (non-Javadoc)
120
	 * @see org.eclipse.pde.api.tools.internal.descriptors.AbstractApiComponent#dispose()
121
	 */
122
	public void dispose() {
123
		try {
124
			if(hasApiFilterStore()) {
125
				getFilterStore().dispose();
126
			}
127
			fModel = null;
128
			if (fOutputLocationToContainer != null) {
129
				fOutputLocationToContainer.clear();
130
				fOutputLocationToContainer = null;
131
			}
132
			if (fPathToOutputContainers != null) {
133
				fPathToOutputContainers.clear();
134
				fPathToOutputContainers = null;
135
			}
136
		} 
137
		catch(CoreException ce) {
138
			ApiPlugin.log(ce);
139
		}
140
		finally {
141
			super.dispose();
142
		}
143
	}
144
	
145
	/* (non-Javadoc)
146
	 * @see org.eclipse.pde.api.tools.internal.BundleApiComponent#createLocalApiDescription()
147
	 */
148
	protected IApiDescription createLocalApiDescription() throws CoreException {
149
		long time = System.currentTimeMillis();
150
		if(Util.isApiProject(getJavaProject())) {
151
			setHasApiDescription(true);
152
		}
153
		IApiDescription apiDesc = ApiDescriptionManager.getDefault().getApiDescription(this, getBundleDescription());
154
		if (DEBUG) {
155
			System.out.println("Time to create api description for: ["+fProject.getElementName()+"] " + (System.currentTimeMillis() - time) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
156
		}
157
		return apiDesc;
158
	}
159
160
	/* (non-Javadoc)
161
	 * @see org.eclipse.pde.api.tools.internal.BundleApiComponent#createApiFilterStore()
162
	 */
163
	protected IApiFilterStore createApiFilterStore() throws CoreException {
164
		long time = System.currentTimeMillis();
165
		IApiFilterStore store = new ApiFilterStore(getJavaProject());
166
		if (DEBUG) {
167
			System.out.println("Time to create api filter store for: ["+fProject.getElementName()+"] " + (System.currentTimeMillis() - time) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
168
		}
169
		return store;
170
	}
171
	
172
	/* (non-Javadoc)
173
	 * @see org.eclipse.pde.api.tools.internal.descriptors.BundleApiComponent#createClassFileContainers()
174
	 */
175
	protected synchronized List createApiTypeContainers() throws CoreException {
176
		// first populate build.properties cache so we can create class file containers
177
		// from bundle classpath entries
178
		fPathToOutputContainers = new HashMap(4);
179
		fOutputLocationToContainer = new HashMap(4);
180
		if (fProject.exists() && fProject.getProject().isOpen()) {
181
			IFile prop = fProject.getProject().getFile("build.properties"); //$NON-NLS-1$
182
			if (prop.exists()) {
183
				WorkspaceBuildModel properties = new WorkspaceBuildModel(prop);
184
				IBuild build = properties.getBuild();
185
				IBuildEntry entry = build.getEntry("custom"); //$NON-NLS-1$
186
				if (entry != null) {
187
					String[] tokens = entry.getTokens();
188
					if (tokens.length == 1 && tokens[0].equals("true")) { //$NON-NLS-1$
189
						// hack : add the current output location for each classpath entries
190
						IClasspathEntry[] classpathEntries = fProject.getRawClasspath();
191
						List containers = new ArrayList();
192
						for (int i = 0; i < classpathEntries.length; i++) {
193
							IClasspathEntry classpathEntry = classpathEntries[i];
194
							switch(classpathEntry.getEntryKind()) {
195
								case IClasspathEntry.CPE_SOURCE :
196
									String containerPath = classpathEntry.getPath().removeFirstSegments(1).toString();
197
									IApiTypeContainer container = getApiTypeContainer(containerPath, this);
198
									if (container != null && !containers.contains(container)) {
199
										containers.add(container);
200
									}
201
									break;
202
								case IClasspathEntry.CPE_VARIABLE :
203
									classpathEntry = JavaCore.getResolvedClasspathEntry(classpathEntry);
204
									//$FALL-THROUGH$
205
								case IClasspathEntry.CPE_LIBRARY :
206
									IPath path = classpathEntry.getPath();
207
									if (Util.isArchive(path.lastSegment())) {
208
										IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(path);
209
										if (resource != null) {
210
											// jar inside the workspace
211
											containers.add(new ArchiveApiTypeContainer(this, resource.getLocation().toOSString()));
212
										} else {
213
											// external jar
214
											containers.add(new ArchiveApiTypeContainer(this, path.toOSString()));
215
										}
216
									}
217
									break;
218
							}
219
						}
220
						if (!containers.isEmpty()) {
221
							IApiTypeContainer cfc = null;
222
							if (containers.size() == 1) {
223
								cfc = (IApiTypeContainer) containers.get(0);
224
							} else {
225
								cfc = new CompositeApiTypeContainer(this, containers);
226
							}
227
							fPathToOutputContainers.put(".", cfc); //$NON-NLS-1$
228
						}
229
					}
230
				} else {
231
					IBuildEntry[] entries = build.getBuildEntries();
232
					int length = entries.length;
233
					for (int i = 0; i < length; i++) {
234
						IBuildEntry buildEntry = entries[i];
235
						if (buildEntry.getName().startsWith(IBuildEntry.JAR_PREFIX)) {
236
							String jar = buildEntry.getName().substring(IBuildEntry.JAR_PREFIX.length());
237
							String[] tokens = buildEntry.getTokens();
238
							if (tokens.length == 1) {
239
								IApiTypeContainer container = getApiTypeContainer(tokens[0], this);
240
								if (container != null) {
241
									fPathToOutputContainers.put(jar, container);
242
								}
243
							} else {
244
								List containers = new ArrayList();
245
								for (int j = 0; j < tokens.length; j++) {
246
									String currentToken = tokens[j];
247
									IApiTypeContainer container = getApiTypeContainer(currentToken, this);
248
									if (container != null && !containers.contains(container)) {
249
										containers.add(container);
250
									}
251
								}
252
								if (!containers.isEmpty()) {
253
									IApiTypeContainer cfc = null;
254
									if (containers.size() == 1) {
255
										cfc = (IApiTypeContainer) containers.get(0);
256
									} else {
257
										cfc = new CompositeApiTypeContainer(this, containers);
258
									}
259
									fPathToOutputContainers.put(jar, cfc);
260
								}
261
							}
262
						}
263
					}
264
				}
265
			}
266
			return super.createApiTypeContainers();
267
		}
268
		return Collections.EMPTY_LIST;
269
	}
270
	
271
	/* (non-Javadoc)
272
	 * @see org.eclipse.pde.api.tools.internal.BundleApiComponent#createClassFileContainer(java.lang.String)
273
	 */
274
	protected IApiTypeContainer createApiTypeContainer(String path) throws IOException, CoreException {
275
		if (this.fPathToOutputContainers == null) {
276
			baselineDisposed(getBaseline());
277
		}
278
		IApiTypeContainer container = (IApiTypeContainer) fPathToOutputContainers.get(path);
279
		if (container == null) {
280
			// could be a binary jar included in the plug-in, just look for it
281
			container = findApiTypeContainer(path);
282
		}
283
		return container;
284
	}
285
	
286
	/** 
287
	 * Finds and returns an existing {@link IApiTypeContainer} at the specified location
288
	 * in this project, or <code>null</code> if none.
289
	 * 
290
	 * @param location project relative path to the class file container
291
	 * @return {@link IApiTypeContainer} or <code>null</code>
292
	 */
293
	private IApiTypeContainer findApiTypeContainer(String location) {
294
		IResource res = fProject.getProject().findMember(new Path(location));
295
		if (res != null) {
296
			if (res.getType() == IResource.FILE) {
297
				return new ArchiveApiTypeContainer(this, res.getLocation().toOSString());
298
			} else {
299
				return new DirectoryApiTypeContainer(this, res.getLocation().toOSString());
300
			}
301
		}
302
		return null;
303
	}
304
	
305
	/** 
306
	 * Finds and returns an {@link IApiTypeContainer} for the specified
307
	 * source folder, or <code>null</code> if it does not exist. If the
308
	 * source folder shares an output location with a previous source
309
	 * folder, the output location is shared (a new one is not created).
310
	 * 
311
	 * @param location project relative path to the source folder
312
	 * @return {@link IApiTypeContainer} or <code>null</code>
313
	 */
314
	private IApiTypeContainer getApiTypeContainer(String location, IApiComponent component) throws CoreException {
315
		if (this.fOutputLocationToContainer == null) {
316
			baselineDisposed(getBaseline());
317
		}
318
		IResource res = fProject.getProject().findMember(new Path(location));
319
		if (res != null) {
320
			IPackageFragmentRoot root = fProject.getPackageFragmentRoot(res);
321
			if (root.exists()) {
322
				if (root.getKind() == IPackageFragmentRoot.K_BINARY) {
323
					if (res.getType() == IResource.FOLDER) {
324
						// class file folder
325
						IPath location2 = res.getLocation();
326
						IApiTypeContainer cfc = (IApiTypeContainer) fOutputLocationToContainer.get(location2);
327
						if (cfc == null) {
328
							cfc = new FolderApiTypeContainer(component, (IContainer) res);
329
							fOutputLocationToContainer.put(location2, cfc);
330
						}
331
						return cfc;
332
					}
333
				} else {
334
					IClasspathEntry entry = root.getRawClasspathEntry();
335
					IPath outputLocation = entry.getOutputLocation();
336
					if (outputLocation == null) {
337
						outputLocation = fProject.getOutputLocation();
338
					}
339
					IApiTypeContainer cfc = (IApiTypeContainer) fOutputLocationToContainer.get(outputLocation);
340
					if (cfc == null) {
341
						IPath projectFullPath = fProject.getProject().getFullPath();
342
						IContainer container = null;
343
						if (projectFullPath.equals(outputLocation)) {
344
							// The project is its own output location
345
							container = fProject.getProject();
346
						} else {
347
							container = fProject.getProject().getWorkspace().getRoot().getFolder(outputLocation);
348
						}
349
						if (container.exists()) {
350
							cfc = new FolderApiTypeContainer(component, container);
351
							fOutputLocationToContainer.put(outputLocation, cfc);
352
						}
353
					}
354
					return cfc;
355
				}
356
			}
357
		}
358
		return null;
359
	}	
360
	
361
	/**
362
	 * Returns the Java project associated with this component.
363
	 * 
364
	 * @return associated Java project
365
	 */
366
	public IJavaProject getJavaProject() {
367
		return fProject;
368
	}
369
	
370
	/**
371
	 * Returns the cached API type container for the given package fragment root, or <code>null</code>
372
	 * if none. The given package fragment has to be a SOURCE package fragment - this method is only
373
	 * used by the project API description to obtain a class file corresponding to a compilation unit
374
	 * when tag scanning (to resolve signatures).
375
	 *  
376
	 * @param root source package fragment root
377
	 * @return API type container associated with the package fragment root, or <code>null</code> 
378
	 * 	if none
379
	 */
380
	public IApiTypeContainer getTypeContainer(IPackageFragmentRoot root) throws CoreException {
381
		if (root.getKind() == IPackageFragmentRoot.K_SOURCE) {
382
			getApiTypeContainers(); // ensure initialized
383
			IResource resource = root.getResource();
384
			if (resource != null) {
385
				String location = resource.getProjectRelativePath().toString();
386
				return getApiTypeContainer(location, this);
387
			}
388
		}
389
		return null;
390
	}
391
	
392
}
(-)src/org/eclipse/pde/api/tools/internal/model/ProjectComponent.java (+402 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2007, 2009 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.model;
12
13
import java.io.IOException;
14
import java.util.ArrayList;
15
import java.util.Collections;
16
import java.util.Dictionary;
17
import java.util.HashMap;
18
import java.util.List;
19
import java.util.Map;
20
21
import org.eclipse.core.resources.IContainer;
22
import org.eclipse.core.resources.IFile;
23
import org.eclipse.core.resources.IProject;
24
import org.eclipse.core.resources.IResource;
25
import org.eclipse.core.resources.ResourcesPlugin;
26
import org.eclipse.core.runtime.CoreException;
27
import org.eclipse.core.runtime.IPath;
28
import org.eclipse.core.runtime.Path;
29
import org.eclipse.jdt.core.IClasspathEntry;
30
import org.eclipse.jdt.core.IJavaProject;
31
import org.eclipse.jdt.core.IPackageFragmentRoot;
32
import org.eclipse.jdt.core.JavaCore;
33
import org.eclipse.osgi.service.resolver.BundleDescription;
34
import org.eclipse.pde.api.tools.internal.ApiDescriptionManager;
35
import org.eclipse.pde.api.tools.internal.ApiFilterStore;
36
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
37
import org.eclipse.pde.api.tools.internal.provisional.IApiDescription;
38
import org.eclipse.pde.api.tools.internal.provisional.IApiFilterStore;
39
import org.eclipse.pde.api.tools.internal.provisional.model.IApiBaseline;
40
import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent;
41
import org.eclipse.pde.api.tools.internal.provisional.model.IApiTypeContainer;
42
import org.eclipse.pde.api.tools.internal.util.Util;
43
import org.eclipse.pde.core.build.IBuild;
44
import org.eclipse.pde.core.build.IBuildEntry;
45
import org.eclipse.pde.core.plugin.IPluginModelBase;
46
import org.eclipse.pde.internal.core.build.WorkspaceBuildModel;
47
import org.osgi.framework.BundleException;
48
49
/**
50
 * An API component for a plug-in project in the workspace.
51
 * <p>
52
 * Note: this class requires a running workspace to be instantiated.
53
 * </p>
54
 * @since 1.0.0
55
 */
56
public class ProjectComponent extends BundleComponent {
57
	
58
	/**
59
	 * Constant used for controlling tracing in the plug-in workspace component
60
	 */
61
	private static boolean DEBUG = Util.DEBUG;
62
	
63
	/**
64
	 * Method used for initializing tracing in the plug-in workspace component
65
	 */
66
	public static void setDebug(boolean debugValue) {
67
		DEBUG = debugValue || Util.DEBUG;
68
	}
69
		
70
	/**
71
	 * Associated Java project
72
	 */
73
	private IJavaProject fProject = null;
74
75
	/**
76
	 * Associated IPluginModelBase object
77
	 */
78
	private IPluginModelBase fModel = null;
79
	
80
	/**
81
	 * A cache of bundle class path entries to class file containers.
82
	 */
83
	private Map fPathToOutputContainers = null;
84
	
85
	/**
86
	 * A cache of output location paths to corresponding class file containers.
87
	 */
88
	private Map fOutputLocationToContainer = null;
89
90
	/**
91
	 * Constructs an API component for the given Java project in the specified profile.
92
	 * 
93
	 * @param baseline the owning API baseline
94
	 * @param location the given location of the component
95
	 * @param model the given model
96
	 * @param bundleid
97
	 * @throws CoreException if unable to create the API component
98
	 */
99
	public ProjectComponent(IApiBaseline baseline, String location, IPluginModelBase model, long bundleid) throws CoreException {
100
		super(baseline, location, bundleid);
101
		IPath path = new Path(location);
102
		IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(path.lastSegment());
103
		this.fProject = JavaCore.create(project);
104
		this.fModel = model;
105
		setName(fModel.getResourceString(super.getName()));
106
	}
107
	
108
	/* (non-Javadoc)
109
	 * @see org.eclipse.pde.api.tools.internal.BundleApiComponent#isBinaryBundle()
110
	 */
111
	protected boolean isBinary() {
112
		return false;
113
	}
114
	
115
	/* (non-Javadoc)
116
	 * @see org.eclipse.pde.api.tools.internal.model.BundleApiComponent#getBundleDescription(java.util.Dictionary, java.lang.String, long)
117
	 */
118
	protected BundleDescription getBundleDescription(Dictionary manifest, String location, long id) throws BundleException {
119
		return fModel.getBundleDescription();
120
	}
121
	
122
	/* (non-Javadoc)
123
	 * @see org.eclipse.pde.api.tools.internal.BundleApiComponent#isApiEnabled()
124
	 */
125
	protected boolean isApiEnabled() {
126
		return Util.isApiProject(fProject);
127
	}
128
129
	/* (non-Javadoc)
130
	 * @see org.eclipse.pde.api.tools.internal.descriptors.AbstractApiComponent#dispose()
131
	 */
132
	public void dispose() {
133
		try {
134
			if(hasApiFilterStore()) {
135
				getFilterStore().dispose();
136
			}
137
			fModel = null;
138
			if (fOutputLocationToContainer != null) {
139
				fOutputLocationToContainer.clear();
140
				fOutputLocationToContainer = null;
141
			}
142
			if (fPathToOutputContainers != null) {
143
				fPathToOutputContainers.clear();
144
				fPathToOutputContainers = null;
145
			}
146
		} 
147
		catch(CoreException ce) {
148
			ApiPlugin.log(ce);
149
		}
150
		finally {
151
			super.dispose();
152
		}
153
	}
154
	
155
	/* (non-Javadoc)
156
	 * @see org.eclipse.pde.api.tools.internal.BundleApiComponent#createLocalApiDescription()
157
	 */
158
	protected IApiDescription createLocalApiDescription() throws CoreException {
159
		long time = System.currentTimeMillis();
160
		if(Util.isApiProject(getJavaProject())) {
161
			setHasApiDescription(true);
162
		}
163
		IApiDescription apiDesc = ApiDescriptionManager.getDefault().getApiDescription(this, getBundleDescription());
164
		if (DEBUG) {
165
			System.out.println("Time to create api description for: ["+fProject.getElementName()+"] " + (System.currentTimeMillis() - time) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
166
		}
167
		return apiDesc;
168
	}
169
170
	/* (non-Javadoc)
171
	 * @see org.eclipse.pde.api.tools.internal.BundleApiComponent#createApiFilterStore()
172
	 */
173
	protected IApiFilterStore createApiFilterStore() throws CoreException {
174
		long time = System.currentTimeMillis();
175
		IApiFilterStore store = new ApiFilterStore(getJavaProject());
176
		if (DEBUG) {
177
			System.out.println("Time to create api filter store for: ["+fProject.getElementName()+"] " + (System.currentTimeMillis() - time) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
178
		}
179
		return store;
180
	}
181
	
182
	/* (non-Javadoc)
183
	 * @see org.eclipse.pde.api.tools.internal.descriptors.BundleApiComponent#createClassFileContainers()
184
	 */
185
	protected synchronized List createApiTypeContainers() throws CoreException {
186
		// first populate build.properties cache so we can create class file containers
187
		// from bundle classpath entries
188
		fPathToOutputContainers = new HashMap(4);
189
		fOutputLocationToContainer = new HashMap(4);
190
		if (fProject.exists() && fProject.getProject().isOpen()) {
191
			IFile prop = fProject.getProject().getFile("build.properties"); //$NON-NLS-1$
192
			if (prop.exists()) {
193
				WorkspaceBuildModel properties = new WorkspaceBuildModel(prop);
194
				IBuild build = properties.getBuild();
195
				IBuildEntry entry = build.getEntry("custom"); //$NON-NLS-1$
196
				if (entry != null) {
197
					String[] tokens = entry.getTokens();
198
					if (tokens.length == 1 && tokens[0].equals("true")) { //$NON-NLS-1$
199
						// hack : add the current output location for each classpath entries
200
						IClasspathEntry[] classpathEntries = fProject.getRawClasspath();
201
						List containers = new ArrayList();
202
						for (int i = 0; i < classpathEntries.length; i++) {
203
							IClasspathEntry classpathEntry = classpathEntries[i];
204
							switch(classpathEntry.getEntryKind()) {
205
								case IClasspathEntry.CPE_SOURCE :
206
									String containerPath = classpathEntry.getPath().removeFirstSegments(1).toString();
207
									IApiTypeContainer container = getApiTypeContainer(containerPath, this);
208
									if (container != null && !containers.contains(container)) {
209
										containers.add(container);
210
									}
211
									break;
212
								case IClasspathEntry.CPE_VARIABLE :
213
									classpathEntry = JavaCore.getResolvedClasspathEntry(classpathEntry);
214
									//$FALL-THROUGH$
215
								case IClasspathEntry.CPE_LIBRARY :
216
									IPath path = classpathEntry.getPath();
217
									if (Util.isArchive(path.lastSegment())) {
218
										IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(path);
219
										if (resource != null) {
220
											// jar inside the workspace
221
											containers.add(new ArchiveApiTypeContainer(this, resource.getLocation().toOSString()));
222
										} else {
223
											// external jar
224
											containers.add(new ArchiveApiTypeContainer(this, path.toOSString()));
225
										}
226
									}
227
									break;
228
							}
229
						}
230
						if (!containers.isEmpty()) {
231
							IApiTypeContainer cfc = null;
232
							if (containers.size() == 1) {
233
								cfc = (IApiTypeContainer) containers.get(0);
234
							} else {
235
								cfc = new CompositeApiTypeContainer(this, containers);
236
							}
237
							fPathToOutputContainers.put(".", cfc); //$NON-NLS-1$
238
						}
239
					}
240
				} else {
241
					IBuildEntry[] entries = build.getBuildEntries();
242
					int length = entries.length;
243
					for (int i = 0; i < length; i++) {
244
						IBuildEntry buildEntry = entries[i];
245
						if (buildEntry.getName().startsWith(IBuildEntry.JAR_PREFIX)) {
246
							String jar = buildEntry.getName().substring(IBuildEntry.JAR_PREFIX.length());
247
							String[] tokens = buildEntry.getTokens();
248
							if (tokens.length == 1) {
249
								IApiTypeContainer container = getApiTypeContainer(tokens[0], this);
250
								if (container != null) {
251
									fPathToOutputContainers.put(jar, container);
252
								}
253
							} else {
254
								List containers = new ArrayList();
255
								for (int j = 0; j < tokens.length; j++) {
256
									String currentToken = tokens[j];
257
									IApiTypeContainer container = getApiTypeContainer(currentToken, this);
258
									if (container != null && !containers.contains(container)) {
259
										containers.add(container);
260
									}
261
								}
262
								if (!containers.isEmpty()) {
263
									IApiTypeContainer cfc = null;
264
									if (containers.size() == 1) {
265
										cfc = (IApiTypeContainer) containers.get(0);
266
									} else {
267
										cfc = new CompositeApiTypeContainer(this, containers);
268
									}
269
									fPathToOutputContainers.put(jar, cfc);
270
								}
271
							}
272
						}
273
					}
274
				}
275
			}
276
			return super.createApiTypeContainers();
277
		}
278
		return Collections.EMPTY_LIST;
279
	}
280
	
281
	/* (non-Javadoc)
282
	 * @see org.eclipse.pde.api.tools.internal.BundleApiComponent#createClassFileContainer(java.lang.String)
283
	 */
284
	protected IApiTypeContainer createApiTypeContainer(String path) throws IOException, CoreException {
285
		if (this.fPathToOutputContainers == null) {
286
			baselineDisposed(getBaseline());
287
		}
288
		IApiTypeContainer container = (IApiTypeContainer) fPathToOutputContainers.get(path);
289
		if (container == null) {
290
			// could be a binary jar included in the plug-in, just look for it
291
			container = findApiTypeContainer(path);
292
		}
293
		return container;
294
	}
295
	
296
	/** 
297
	 * Finds and returns an existing {@link IApiTypeContainer} at the specified location
298
	 * in this project, or <code>null</code> if none.
299
	 * 
300
	 * @param location project relative path to the class file container
301
	 * @return {@link IApiTypeContainer} or <code>null</code>
302
	 */
303
	private IApiTypeContainer findApiTypeContainer(String location) {
304
		IResource res = fProject.getProject().findMember(new Path(location));
305
		if (res != null) {
306
			if (res.getType() == IResource.FILE) {
307
				return new ArchiveApiTypeContainer(this, res.getLocation().toOSString());
308
			} else {
309
				return new DirectoryApiTypeContainer(this, res.getLocation().toOSString());
310
			}
311
		}
312
		return null;
313
	}
314
	
315
	/** 
316
	 * Finds and returns an {@link IApiTypeContainer} for the specified
317
	 * source folder, or <code>null</code> if it does not exist. If the
318
	 * source folder shares an output location with a previous source
319
	 * folder, the output location is shared (a new one is not created).
320
	 * 
321
	 * @param location project relative path to the source folder
322
	 * @return {@link IApiTypeContainer} or <code>null</code>
323
	 */
324
	private IApiTypeContainer getApiTypeContainer(String location, IApiComponent component) throws CoreException {
325
		if (this.fOutputLocationToContainer == null) {
326
			baselineDisposed(getBaseline());
327
		}
328
		IResource res = fProject.getProject().findMember(new Path(location));
329
		if (res != null) {
330
			IPackageFragmentRoot root = fProject.getPackageFragmentRoot(res);
331
			if (root.exists()) {
332
				if (root.getKind() == IPackageFragmentRoot.K_BINARY) {
333
					if (res.getType() == IResource.FOLDER) {
334
						// class file folder
335
						IPath location2 = res.getLocation();
336
						IApiTypeContainer cfc = (IApiTypeContainer) fOutputLocationToContainer.get(location2);
337
						if (cfc == null) {
338
							cfc = new FolderApiTypeContainer(component, (IContainer) res);
339
							fOutputLocationToContainer.put(location2, cfc);
340
						}
341
						return cfc;
342
					}
343
				} else {
344
					IClasspathEntry entry = root.getRawClasspathEntry();
345
					IPath outputLocation = entry.getOutputLocation();
346
					if (outputLocation == null) {
347
						outputLocation = fProject.getOutputLocation();
348
					}
349
					IApiTypeContainer cfc = (IApiTypeContainer) fOutputLocationToContainer.get(outputLocation);
350
					if (cfc == null) {
351
						IPath projectFullPath = fProject.getProject().getFullPath();
352
						IContainer container = null;
353
						if (projectFullPath.equals(outputLocation)) {
354
							// The project is its own output location
355
							container = fProject.getProject();
356
						} else {
357
							container = fProject.getProject().getWorkspace().getRoot().getFolder(outputLocation);
358
						}
359
						if (container.exists()) {
360
							cfc = new FolderApiTypeContainer(component, container);
361
							fOutputLocationToContainer.put(outputLocation, cfc);
362
						}
363
					}
364
					return cfc;
365
				}
366
			}
367
		}
368
		return null;
369
	}	
370
	
371
	/**
372
	 * Returns the Java project associated with this component.
373
	 * 
374
	 * @return associated Java project
375
	 */
376
	public IJavaProject getJavaProject() {
377
		return fProject;
378
	}
379
	
380
	/**
381
	 * Returns the cached API type container for the given package fragment root, or <code>null</code>
382
	 * if none. The given package fragment has to be a SOURCE package fragment - this method is only
383
	 * used by the project API description to obtain a class file corresponding to a compilation unit
384
	 * when tag scanning (to resolve signatures).
385
	 *  
386
	 * @param root source package fragment root
387
	 * @return API type container associated with the package fragment root, or <code>null</code> 
388
	 * 	if none
389
	 */
390
	public IApiTypeContainer getTypeContainer(IPackageFragmentRoot root) throws CoreException {
391
		if (root.getKind() == IPackageFragmentRoot.K_SOURCE) {
392
			getApiTypeContainers(); // ensure initialized
393
			IResource resource = root.getResource();
394
			if (resource != null) {
395
				String location = resource.getProjectRelativePath().toString();
396
				return getApiTypeContainer(location, this);
397
			}
398
		}
399
		return null;
400
	}
401
	
402
}
(-)src/org/eclipse/pde/api/tools/internal/model/SystemLibraryApiComponent.java (-3 / +3 lines)
Lines 31-37 Link Here
31
 * 
31
 * 
32
 * @since 1.0.0
32
 * @since 1.0.0
33
 */
33
 */
34
public class SystemLibraryApiComponent extends AbstractApiComponent {
34
public class SystemLibraryApiComponent extends Component {
35
	
35
	
36
	/**
36
	/**
37
	 * Execution environment profile symbolic name.
37
	 * Execution environment profile symbolic name.
Lines 84-90 Link Here
84
	 * @see org.eclipse.pde.api.tools.internal.descriptors.AbstractApiComponent#createApiDescription()
84
	 * @see org.eclipse.pde.api.tools.internal.descriptors.AbstractApiComponent#createApiDescription()
85
	 */
85
	 */
86
	protected IApiDescription createApiDescription() throws CoreException {
86
	protected IApiDescription createApiDescription() throws CoreException {
87
		IApiDescription api = new ApiDescription(getId());
87
		IApiDescription api = new ApiDescription(getSymbolicName());
88
		for (int i = 0; i < fSystemPackages.length; i++) {
88
		for (int i = 0; i < fSystemPackages.length; i++) {
89
			IPackageDescriptor pkg  = Factory.packageDescriptor(fSystemPackages[i]);
89
			IPackageDescriptor pkg  = Factory.packageDescriptor(fSystemPackages[i]);
90
			api.setVisibility(pkg, VisibilityModifiers.API);
90
			api.setVisibility(pkg, VisibilityModifiers.API);
Lines 130-136 Link Here
130
	/* (non-Javadoc)
130
	/* (non-Javadoc)
131
	 * @see org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent#getId()
131
	 * @see org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent#getId()
132
	 */
132
	 */
133
	public String getId() {
133
	public String getSymbolicName() {
134
		return fExecEnv[0];
134
		return fExecEnv[0];
135
	}
135
	}
136
	
136
	
(-)src/org/eclipse/pde/api/tools/internal/model/WorkspaceBaseline.java (+59 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2009 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.model;
12
13
import java.util.Arrays;
14
import java.util.HashSet;
15
16
import org.eclipse.core.runtime.CoreException;
17
import org.eclipse.osgi.service.resolver.State;
18
import org.eclipse.pde.api.tools.internal.ApiBaselineManager;
19
import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent;
20
import org.eclipse.pde.internal.core.PDECore;
21
22
23
/**
24
 * Describes the workspace baseline. Tracks the PDE model for the workspace
25
 * 
26
 * @since 1.1
27
 */
28
public class WorkspaceBaseline extends ApiBaseline {
29
	
30
	/**
31
	 * Constructor
32
	 */
33
	public WorkspaceBaseline() {
34
		super(ApiBaselineManager.WORKSPACE_API_BASELINE_ID);
35
	}
36
	
37
	/* (non-Javadoc)
38
	 * @see org.eclipse.pde.api.tools.internal.model.ApiBaseline#getState()
39
	 */
40
	public State getState() {
41
		return PDECore.getDefault().getModelManager().getState().getState();
42
	}
43
	
44
	/* (non-Javadoc)
45
	 * @see IApiBaseline#addApiComponents(org.eclipse.pde.api.tools.model.component.IApiComponent[], boolean)
46
	 */
47
	public void addApiComponents(IApiComponent[] components) throws CoreException {
48
		HashSet ees = new HashSet();
49
		for (int i = 0; i < components.length; i++) {
50
			BundleComponent component = (BundleComponent) components[i];
51
			if (component.isSourceComponent()) {
52
				continue;
53
			}
54
			addComponent(component);
55
			ees.addAll(Arrays.asList(component.getExecutionEnvironments()));
56
		}
57
		resolveSystemLibrary(ees);
58
	}
59
}
(-)src/org/eclipse/pde/api/tools/internal/provisional/ApiPlugin.java (-2 / +2 lines)
Lines 43-49 Link Here
43
import org.eclipse.pde.api.tools.internal.builder.ReferenceResolver;
43
import org.eclipse.pde.api.tools.internal.builder.ReferenceResolver;
44
import org.eclipse.pde.api.tools.internal.comparator.ClassFileComparator;
44
import org.eclipse.pde.api.tools.internal.comparator.ClassFileComparator;
45
import org.eclipse.pde.api.tools.internal.descriptors.ElementDescriptorImpl;
45
import org.eclipse.pde.api.tools.internal.descriptors.ElementDescriptorImpl;
46
import org.eclipse.pde.api.tools.internal.model.PluginProjectApiComponent;
46
import org.eclipse.pde.api.tools.internal.model.ProjectComponent;
47
import org.eclipse.pde.api.tools.internal.provisional.comparator.ApiComparator;
47
import org.eclipse.pde.api.tools.internal.provisional.comparator.ApiComparator;
48
import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblemTypes;
48
import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblemTypes;
49
import org.eclipse.pde.api.tools.internal.provisional.scanner.TagScanner;
49
import org.eclipse.pde.api.tools.internal.provisional.scanner.TagScanner;
Lines 587-593 Link Here
587
			}
587
			}
588
			option = Platform.getDebugOption(PLUGIN_WORKSPACE_COMPONENT_DEBUG);
588
			option = Platform.getDebugOption(PLUGIN_WORKSPACE_COMPONENT_DEBUG);
589
			if(option != null) {
589
			if(option != null) {
590
				PluginProjectApiComponent.setDebug(option.equalsIgnoreCase(TRUE));
590
				ProjectComponent.setDebug(option.equalsIgnoreCase(TRUE));
591
			}
591
			}
592
			option = Platform.getDebugOption(API_PROFILE_MANAGER_DEBUG);
592
			option = Platform.getDebugOption(API_PROFILE_MANAGER_DEBUG);
593
			if(option != null) {
593
			if(option != null) {
(-)src/org/eclipse/pde/api/tools/internal/provisional/comparator/ApiComparator.java (-10 / +10 lines)
Lines 145-151 Link Here
145
				Util.updateMonitor(localmonitor);
145
				Util.updateMonitor(localmonitor);
146
				IApiComponent apiComponent = apiComponents[i];
146
				IApiComponent apiComponent = apiComponents[i];
147
				if (!apiComponent.isSystemComponent()) {
147
				if (!apiComponent.isSystemComponent()) {
148
					String id = apiComponent.getId();
148
					String id = apiComponent.getSymbolicName();
149
					IApiComponent apiComponent2 = baseline.getApiComponent(id);
149
					IApiComponent apiComponent2 = baseline.getApiComponent(id);
150
					IDelta delta = null;
150
					IDelta delta = null;
151
					if (apiComponent2 == null) {
151
					if (apiComponent2 == null) {
Lines 186-192 Link Here
186
				Util.updateMonitor(localmonitor);
186
				Util.updateMonitor(localmonitor);
187
				IApiComponent apiComponent = apiComponents2[i];
187
				IApiComponent apiComponent = apiComponents2[i];
188
				if (!apiComponent.isSystemComponent()) {
188
				if (!apiComponent.isSystemComponent()) {
189
					String id = apiComponent.getId();
189
					String id = apiComponent.getSymbolicName();
190
					if (!apiComponentsIds.contains(id)) {
190
					if (!apiComponentsIds.contains(id)) {
191
						// addition of an API component
191
						// addition of an API component
192
						globalDelta.add(
192
						globalDelta.add(
Lines 240-246 Link Here
240
			Util.updateMonitor(localmonitor, 1);
240
			Util.updateMonitor(localmonitor, 1);
241
			IDelta delta = null;
241
			IDelta delta = null;
242
			if (!component.isSystemComponent()) {
242
			if (!component.isSystemComponent()) {
243
				String id = component.getId();
243
				String id = component.getSymbolicName();
244
				IApiComponent apiComponent2 = referenceBaseline.getApiComponent(id);
244
				IApiComponent apiComponent2 = referenceBaseline.getApiComponent(id);
245
				if (apiComponent2 == null) {
245
				if (apiComponent2 == null) {
246
					// report addition of an API component
246
					// report addition of an API component
Lines 313-322 Link Here
313
						IDelta.ADDED,
313
						IDelta.ADDED,
314
						IDelta.API_COMPONENT,
314
						IDelta.API_COMPONENT,
315
						null,
315
						null,
316
						component2.getId(),
316
						component2.getSymbolicName(),
317
						Util.getComponentVersionsId(component2));
317
						Util.getComponentVersionsId(component2));
318
			} else if (component2 == null) {
318
			} else if (component2 == null) {
319
				String referenceComponentId = referenceComponent.getId();
319
				String referenceComponentId = referenceComponent.getSymbolicName();
320
				return new Delta(
320
				return new Delta(
321
						null,
321
						null,
322
						IDelta.API_PROFILE_ELEMENT_TYPE,
322
						IDelta.API_PROFILE_ELEMENT_TYPE,
Lines 330-336 Link Here
330
			if (referenceBaseline == null || baseline == null) {
330
			if (referenceBaseline == null || baseline == null) {
331
				throw new IllegalArgumentException("The baselines cannot be null"); //$NON-NLS-1$
331
				throw new IllegalArgumentException("The baselines cannot be null"); //$NON-NLS-1$
332
			}
332
			}
333
			String referenceComponentId = referenceComponent.getId();
333
			String referenceComponentId = referenceComponent.getSymbolicName();
334
			final Delta globalDelta = new Delta();
334
			final Delta globalDelta = new Delta();
335
	
335
	
336
			// check the EE first
336
			// check the EE first
Lines 451-457 Link Here
451
			}
451
			}
452
			String typeName = typeRoot2.getTypeName();
452
			String typeName = typeRoot2.getTypeName();
453
			IApiTypeRoot typeRoot = null;
453
			IApiTypeRoot typeRoot = null;
454
			String id = component.getId();
454
			String id = component.getSymbolicName();
455
			if (Util.ORG_ECLIPSE_SWT.equals(id)) {
455
			if (Util.ORG_ECLIPSE_SWT.equals(id)) {
456
				typeRoot = component.findTypeRoot(typeName);
456
				typeRoot = component.findTypeRoot(typeName);
457
			} else {
457
			} else {
Lines 737-743 Link Here
737
			final Delta globalDelta, 
737
			final Delta globalDelta, 
738
			final IProgressMonitor monitor) throws CoreException {
738
			final IProgressMonitor monitor) throws CoreException {
739
		final Set typeRootBaseLineNames = new HashSet();
739
		final Set typeRootBaseLineNames = new HashSet();
740
		final String id = component.getId();
740
		final String id = component.getSymbolicName();
741
		IApiTypeContainer[] typeRootContainers = null;
741
		IApiTypeContainer[] typeRootContainers = null;
742
		IApiTypeContainer[] typeRootContainers2 = null;
742
		IApiTypeContainer[] typeRootContainers2 = null;
743
		final SubMonitor localmonitor = SubMonitor.convert(monitor, 4);
743
		final SubMonitor localmonitor = SubMonitor.convert(monitor, 4);
Lines 790-796 Link Here
790
										Util.updateMonitor(localmonitor);
790
										Util.updateMonitor(localmonitor);
791
										IApiComponent p = providers[index];
791
										IApiComponent p = providers[index];
792
										if (!p.equals(component2)) {
792
										if (!p.equals(component2)) {
793
											String id2 = p.getId();
793
											String id2 = p.getSymbolicName();
794
											if (Util.ORG_ECLIPSE_SWT.equals(id2)) {
794
											if (Util.ORG_ECLIPSE_SWT.equals(id2)) {
795
												typeRoot2 = p.findTypeRoot(typeName);
795
												typeRoot2 = p.findTypeRoot(typeName);
796
											} else {
796
											} else {
Lines 965-971 Link Here
965
												while (typeRoot2 == null && index < providers.length) {
965
												while (typeRoot2 == null && index < providers.length) {
966
													IApiComponent p = providers[index];
966
													IApiComponent p = providers[index];
967
													if (!p.equals(component2)) {
967
													if (!p.equals(component2)) {
968
														String id2 = p.getId();
968
														String id2 = p.getSymbolicName();
969
														if (Util.ORG_ECLIPSE_SWT.equals(id2)) {
969
														if (Util.ORG_ECLIPSE_SWT.equals(id2)) {
970
															typeRoot2 = p.findTypeRoot(typeName);
970
															typeRoot2 = p.findTypeRoot(typeName);
971
														} else {
971
														} else {
(-)src/org/eclipse/pde/api/tools/internal/provisional/comparator/CompareApiScopeVisitor.java (-2 / +2 lines)
Lines 95-101 Link Here
95
				this.containsErrors = true;
95
				this.containsErrors = true;
96
				return false;
96
				return false;
97
			}
97
			}
98
			IApiComponent referenceComponent = this.referenceBaseline.getApiComponent(component.getId());
98
			IApiComponent referenceComponent = this.referenceBaseline.getApiComponent(component.getSymbolicName());
99
			if (referenceComponent != null && referenceComponent.getErrors() != null) {
99
			if (referenceComponent != null && referenceComponent.getErrors() != null) {
100
				this.containsErrors = true;
100
				this.containsErrors = true;
101
				return false;
101
				return false;
Lines 140-146 Link Here
140
			this.containsErrors = true;
140
			this.containsErrors = true;
141
			return;
141
			return;
142
		}
142
		}
143
		IApiComponent referenceComponent = this.referenceBaseline.getApiComponent(apiComponent.getId());
143
		IApiComponent referenceComponent = this.referenceBaseline.getApiComponent(apiComponent.getSymbolicName());
144
		if (referenceComponent == null) return;
144
		if (referenceComponent == null) return;
145
		if (referenceComponent.getErrors() != null) {
145
		if (referenceComponent.getErrors() != null) {
146
			this.containsErrors = true;
146
			this.containsErrors = true;
(-)src/org/eclipse/pde/api/tools/internal/provisional/model/IApiComponent.java (-2 / +2 lines)
Lines 30-40 Link Here
30
	
30
	
31
	/**
31
	/**
32
	 * Returns this component's symbolic name. This is a handle-only 
32
	 * Returns this component's symbolic name. This is a handle-only 
33
	 * method - the component may not exist or ay be disposed.
33
	 * method - the component may not exist or may be disposed.
34
	 * 
34
	 * 
35
	 * @return component's symbolic name
35
	 * @return component's symbolic name
36
	 */
36
	 */
37
	public String getId();
37
	public String getSymbolicName();
38
	
38
	
39
	/**
39
	/**
40
	 * Returns this component's API description.
40
	 * Returns this component's API description.
(-)src/org/eclipse/pde/api/tools/internal/provisional/search/ApiSearchEngine.java (-2 / +2 lines)
Lines 304-314 Link Here
304
			MultiStatus mstatus = null;
304
			MultiStatus mstatus = null;
305
			for (int i = 0; i < scopeelements.length; i++) {
305
			for (int i = 0; i < scopeelements.length; i++) {
306
				try {
306
				try {
307
					taskname = MessageFormat.format(SearchMessages.ApiSearchEngine_searching_project, new String[] {scopeelements[i].getApiComponent().getId(), fRequestorContext});
307
					taskname = MessageFormat.format(SearchMessages.ApiSearchEngine_searching_project, new String[] {scopeelements[i].getApiComponent().getSymbolicName(), fRequestorContext});
308
					localmonitor.setTaskName(taskname);
308
					localmonitor.setTaskName(taskname);
309
					if(DEBUG) {
309
					if(DEBUG) {
310
						loopstart = System.currentTimeMillis();
310
						loopstart = System.currentTimeMillis();
311
						System.out.println("Searching "+scopeelements[i].getApiComponent().getId()+"..."); //$NON-NLS-1$ //$NON-NLS-2$
311
						System.out.println("Searching "+scopeelements[i].getApiComponent().getSymbolicName()+"..."); //$NON-NLS-1$ //$NON-NLS-2$
312
					}
312
					}
313
					searchReferences(requestor, scopeelements[i], reporter, localmonitor.newChild(1));
313
					searchReferences(requestor, scopeelements[i], reporter, localmonitor.newChild(1));
314
					localmonitor.setTaskName(taskname);
314
					localmonitor.setTaskName(taskname);
(-)src/org/eclipse/pde/api/tools/internal/search/UseSearchRequestor.java (-2 / +2 lines)
Lines 114-120 Link Here
114
					if(pparts.length != 2) {
114
					if(pparts.length != 2) {
115
						continue;
115
						continue;
116
					}
116
					}
117
					if(container.getApiComponent().getId().equals(pparts[0])) {
117
					if(container.getApiComponent().getSymbolicName().equals(pparts[0])) {
118
						if(container.getName().endsWith(pparts[1])) {
118
						if(container.getName().endsWith(pparts[1])) {
119
							return false;
119
							return false;
120
						}
120
						}
Lines 133-139 Link Here
133
			IApiMember member = reference.getResolvedReference();
133
			IApiMember member = reference.getResolvedReference();
134
			if(member != null) {
134
			if(member != null) {
135
				IApiComponent component = member.getApiComponent();
135
				IApiComponent component = member.getApiComponent();
136
				if(!fComponentIds.contains(component.getId())) {
136
				if(!fComponentIds.contains(component.getSymbolicName())) {
137
					return false;
137
					return false;
138
				}
138
				}
139
				if(component.equals(reference.getMember().getApiComponent())) {
139
				if(component.equals(reference.getMember().getApiComponent())) {
(-)src/org/eclipse/pde/api/tools/internal/search/XmlSearchReporter.java (-1 / +1 lines)
Lines 96-102 Link Here
96
	 */
96
	 */
97
	String getId(IApiComponent component) throws CoreException {
97
	String getId(IApiComponent component) throws CoreException {
98
		StringBuffer buffer = new StringBuffer();
98
		StringBuffer buffer = new StringBuffer();
99
		buffer.append(component.getId()).append(" ").append('(').append(component.getVersion()).append(')'); //$NON-NLS-1$
99
		buffer.append(component.getSymbolicName()).append(" ").append('(').append(component.getVersion()).append(')'); //$NON-NLS-1$
100
		return buffer.toString();
100
		return buffer.toString();
101
	}
101
	}
102
102
(-)src/org/eclipse/pde/api/tools/internal/util/Util.java (-4 / +4 lines)
Lines 1965-1971 Link Here
1965
	 * @return API component + version identifier
1965
	 * @return API component + version identifier
1966
	 */
1966
	 */
1967
	public static String getDeltaComponentVersionsId(IApiComponent component) {
1967
	public static String getDeltaComponentVersionsId(IApiComponent component) {
1968
		StringBuffer buffer = new StringBuffer(component.getId());
1968
		StringBuffer buffer = new StringBuffer(component.getSymbolicName());
1969
		String version = component.getVersion();
1969
		String version = component.getVersion();
1970
		// remove the qualifier part
1970
		// remove the qualifier part
1971
		if (version != null) {
1971
		if (version != null) {
Lines 1995-2001 Link Here
1995
	 * @return API component + version identifier
1995
	 * @return API component + version identifier
1996
	 */
1996
	 */
1997
	public static String getComponentVersionsId(IApiComponent component) {
1997
	public static String getComponentVersionsId(IApiComponent component) {
1998
		StringBuffer buffer = new StringBuffer(component.getId());
1998
		StringBuffer buffer = new StringBuffer(component.getSymbolicName());
1999
		String version = component.getVersion();
1999
		String version = component.getVersion();
2000
		// remove the qualifier part
2000
		// remove the qualifier part
2001
		if (version != null) {
2001
		if (version != null) {
Lines 2202-2208 Link Here
2202
	public static final Comparator componentsorter = new Comparator(){
2202
	public static final Comparator componentsorter = new Comparator(){
2203
		public int compare(Object o1, Object o2) {
2203
		public int compare(Object o1, Object o2) {
2204
			if(o1 instanceof IApiComponent && o2 instanceof IApiComponent) {
2204
			if(o1 instanceof IApiComponent && o2 instanceof IApiComponent) {
2205
				return ((IApiComponent)o1).getId().compareTo(((IApiComponent)o2).getId());
2205
				return ((IApiComponent)o1).getSymbolicName().compareTo(((IApiComponent)o2).getSymbolicName());
2206
			}
2206
			}
2207
			if(o1 instanceof SkippedComponent && o2 instanceof SkippedComponent) {
2207
			if(o1 instanceof SkippedComponent && o2 instanceof SkippedComponent) {
2208
				return ((SkippedComponent)o1).getComponentId().compareTo(((SkippedComponent)o2).getComponentId());
2208
				return ((SkippedComponent)o1).getComponentId().compareTo(((SkippedComponent)o2).getComponentId());
Lines 2289-2295 Link Here
2289
				pattern = Pattern.compile(componentname);
2289
				pattern = Pattern.compile(componentname);
2290
				String componentid = null;
2290
				String componentid = null;
2291
				for (int j = 0, max2 = components.length; j < max2; j++) {
2291
				for (int j = 0, max2 = components.length; j < max2; j++) {
2292
					componentid = components[j].getId();
2292
					componentid = components[j].getSymbolicName();
2293
					if (pattern.matcher(componentid).matches()) {
2293
					if (pattern.matcher(componentid).matches()) {
2294
						list.add(componentid);
2294
						list.add(componentid);
2295
					}
2295
					}
(-)src_ant/org/eclipse/pde/api/tools/internal/tasks/APIToolsAnalysisTask.java (-2 / +2 lines)
Lines 598-604 Link Here
598
			Set visitedApiComponentNames = new HashSet();
598
			Set visitedApiComponentNames = new HashSet();
599
			for (int i = 0; i < length; i++) {
599
			for (int i = 0; i < length; i++) {
600
				IApiComponent apiComponent = apiComponents[i];
600
				IApiComponent apiComponent = apiComponents[i];
601
				String name = apiComponent.getId();
601
				String name = apiComponent.getSymbolicName();
602
				visitedApiComponentNames.add(name);
602
				visitedApiComponentNames.add(name);
603
				if (apiComponent.isSystemComponent()) {
603
				if (apiComponent.isSystemComponent()) {
604
					continue;
604
					continue;
Lines 644-650 Link Here
644
			IApiComponent[] baselineApiComponents = referenceBaseline.getApiComponents();
644
			IApiComponent[] baselineApiComponents = referenceBaseline.getApiComponents();
645
			for (int i = 0, max = baselineApiComponents.length; i < max; i++) {
645
			for (int i = 0, max = baselineApiComponents.length; i < max; i++) {
646
				IApiComponent apiComponent = baselineApiComponents[i];
646
				IApiComponent apiComponent = baselineApiComponents[i];
647
				String id = apiComponent.getId();
647
				String id = apiComponent.getSymbolicName();
648
				if (!visitedApiComponentNames.remove(id)) {
648
				if (!visitedApiComponentNames.remove(id)) {
649
					//remove component in the current baseline
649
					//remove component in the current baseline
650
					IApiProblem problem = ApiProblemFactory.newApiProblem(id,
650
					IApiProblem problem = ApiProblemFactory.newApiProblem(id,
(-)src_ant/org/eclipse/pde/api/tools/internal/tasks/ApiMigrationTask.java (-2 / +2 lines)
Lines 259-265 Link Here
259
		if(!allowresolve) {
259
		if(!allowresolve) {
260
			ResolverError[] errors = component.getErrors();
260
			ResolverError[] errors = component.getErrors();
261
			if(errors != null) {
261
			if(errors != null) {
262
				this.notsearched.add(new SkippedComponent(component.getId(), component.getVersion(), errors)); 
262
				this.notsearched.add(new SkippedComponent(component.getSymbolicName(), component.getVersion(), errors)); 
263
				return false;
263
				return false;
264
			}
264
			}
265
		}
265
		}
Lines 267-273 Link Here
267
			return false;
267
			return false;
268
		}
268
		}
269
		if(pattern != null) {
269
		if(pattern != null) {
270
			return pattern.matcher(component.getId()).matches();
270
			return pattern.matcher(component.getSymbolicName()).matches();
271
		}
271
		}
272
		return true;
272
		return true;
273
	}
273
	}
(-)src_ant/org/eclipse/pde/api/tools/internal/tasks/ApiUseTask.java (-4 / +4 lines)
Lines 311-317 Link Here
311
		if(!allowresolve) {
311
		if(!allowresolve) {
312
			ResolverError[] errors = component.getErrors();
312
			ResolverError[] errors = component.getErrors();
313
			if(errors != null) {
313
			if(errors != null) {
314
				this.notsearched.add(new SkippedComponent(component.getId(), component.getVersion(), errors)); 
314
				this.notsearched.add(new SkippedComponent(component.getSymbolicName(), component.getVersion(), errors)); 
315
				return false;
315
				return false;
316
			}
316
			}
317
		}
317
		}
Lines 319-325 Link Here
319
			return false;
319
			return false;
320
		}
320
		}
321
		if(pattern != null) {
321
		if(pattern != null) {
322
			return pattern.matcher(component.getId()).matches();
322
			return pattern.matcher(component.getSymbolicName()).matches();
323
		}
323
		}
324
		return true;
324
		return true;
325
	}
325
	}
Lines 343-355 Link Here
343
		}
343
		}
344
		for (int i = 0; i < components.length; i++) {
344
		for (int i = 0; i < components.length; i++) {
345
			if(acceptComponent(components[i], pattern, true)) {
345
			if(acceptComponent(components[i], pattern, true)) {
346
				ids.add(components[i].getId());
346
				ids.add(components[i].getSymbolicName());
347
			}
347
			}
348
			if(acceptComponent(components[i], pattern2, false)) {
348
			if(acceptComponent(components[i], pattern2, false)) {
349
				scope.add(components[i]);
349
				scope.add(components[i]);
350
			}
350
			}
351
			else {
351
			else {
352
				this.notsearched.add(new SkippedComponent(components[i].getId(), components[i].getVersion(), components[i].getErrors()));
352
				this.notsearched.add(new SkippedComponent(components[i].getSymbolicName(), components[i].getVersion(), components[i].getErrors()));
353
			}
353
			}
354
		}
354
		}
355
	}
355
	}
(-)src_ant/org/eclipse/pde/api/tools/internal/tasks/CompareTask.java (-1 / +1 lines)
Lines 107-113 Link Here
107
							pattern = Pattern.compile(componentName);
107
							pattern = Pattern.compile(componentName);
108
							for (int j = 0, max2 = apiComponents.length; j < max2; j++) {
108
							for (int j = 0, max2 = apiComponents.length; j < max2; j++) {
109
								IApiComponent apiComponent = apiComponents[j];
109
								IApiComponent apiComponent = apiComponents[j];
110
								String componentId = apiComponent.getId();
110
								String componentId = apiComponent.getSymbolicName();
111
								Matcher matcher = pattern.matcher(componentId);
111
								Matcher matcher = pattern.matcher(componentId);
112
								if (matcher.matches()) {
112
								if (matcher.matches()) {
113
									scope.addElement(apiComponent);
113
									scope.addElement(apiComponent);
(-)src/org/eclipse/pde/api/tools/model/tests/ApiBaselineTests.java (-3 / +3 lines)
Lines 148-154 Link Here
148
	private void validateComponent(IApiBaseline baseline, String id, String name, String version, String environment, List<IRequiredComponentDescription> requiredComponents) throws CoreException {
148
	private void validateComponent(IApiBaseline baseline, String id, String name, String version, String environment, List<IRequiredComponentDescription> requiredComponents) throws CoreException {
149
		IApiComponent component = baseline.getApiComponent(id);
149
		IApiComponent component = baseline.getApiComponent(id);
150
		
150
		
151
		assertEquals("Id: ", id , component.getId());
151
		assertEquals("Id: ", id , component.getSymbolicName());
152
		assertEquals("Name: ", name , component.getName());
152
		assertEquals("Name: ", name , component.getName());
153
		assertEquals("Version: ", version , component.getVersion());
153
		assertEquals("Version: ", version , component.getVersion());
154
		String[] envs = component.getExecutionEnvironments();
154
		String[] envs = component.getExecutionEnvironments();
Lines 273-279 Link Here
273
		IApiComponent[] prerequisiteComponents = baseline.getPrerequisiteComponents(new IApiComponent[]{component});
273
		IApiComponent[] prerequisiteComponents = baseline.getPrerequisiteComponents(new IApiComponent[]{component});
274
		for (int i = 0; i < prerequisiteComponents.length; i++) {
274
		for (int i = 0; i < prerequisiteComponents.length; i++) {
275
			IApiComponent apiComponent = prerequisiteComponents[i];
275
			IApiComponent apiComponent = prerequisiteComponents[i];
276
			if (apiComponent.getId().equals("org.eclipse.osgi")) {
276
			if (apiComponent.getSymbolicName().equals("org.eclipse.osgi")) {
277
				// done
277
				// done
278
				return;
278
				return;
279
			}
279
			}
Lines 293-299 Link Here
293
		assertEquals("Wrong number of dependents", 2, dependents.length);
293
		assertEquals("Wrong number of dependents", 2, dependents.length);
294
		for (int i = 0; i < dependents.length; i++) {
294
		for (int i = 0; i < dependents.length; i++) {
295
			IApiComponent apiComponent = dependents[i];
295
			IApiComponent apiComponent = dependents[i];
296
			if (apiComponent.getId().equals("component.b")) {
296
			if (apiComponent.getSymbolicName().equals("component.b")) {
297
				// done
297
				// done
298
				return;
298
				return;
299
			}
299
			}
(-)src/org/eclipse/pde/api/tools/model/tests/BadClassfileTests.java (-3 / +3 lines)
Lines 21-27 Link Here
21
import org.eclipse.pde.api.tools.internal.ApiDescription;
21
import org.eclipse.pde.api.tools.internal.ApiDescription;
22
import org.eclipse.pde.api.tools.internal.CompilationUnit;
22
import org.eclipse.pde.api.tools.internal.CompilationUnit;
23
import org.eclipse.pde.api.tools.internal.builder.Reference;
23
import org.eclipse.pde.api.tools.internal.builder.Reference;
24
import org.eclipse.pde.api.tools.internal.model.AbstractApiComponent;
24
import org.eclipse.pde.api.tools.internal.model.Component;
25
import org.eclipse.pde.api.tools.internal.model.ApiBaseline;
25
import org.eclipse.pde.api.tools.internal.model.ApiBaseline;
26
import org.eclipse.pde.api.tools.internal.model.DirectoryApiTypeContainer;
26
import org.eclipse.pde.api.tools.internal.model.DirectoryApiTypeContainer;
27
import org.eclipse.pde.api.tools.internal.provisional.IApiDescription;
27
import org.eclipse.pde.api.tools.internal.provisional.IApiDescription;
Lines 92-98 Link Here
92
	 */
92
	 */
93
	public void testSearchEngine() throws Exception {
93
	public void testSearchEngine() throws Exception {
94
		writePreamble("testSearchEngine()");
94
		writePreamble("testSearchEngine()");
95
		final AbstractApiComponent component = new AbstractApiComponent(null) {
95
		final Component component = new Component(null) {
96
			public boolean isSystemComponent() {return false;}
96
			public boolean isSystemComponent() {return false;}
97
			public boolean isSourceComponent() throws CoreException {return false;}
97
			public boolean isSourceComponent() throws CoreException {return false;}
98
			public boolean isFragment() throws CoreException {return false;}
98
			public boolean isFragment() throws CoreException {return false;}
Lines 102-108 Link Here
102
			public IRequiredComponentDescription[] getRequiredComponents() throws CoreException {return null;}
102
			public IRequiredComponentDescription[] getRequiredComponents() throws CoreException {return null;}
103
			public String[] getLowestEEs() throws CoreException {return null;}
103
			public String[] getLowestEEs() throws CoreException {return null;}
104
			public String getLocation() {return null;}
104
			public String getLocation() {return null;}
105
			public String getId() {return "test";}
105
			public String getSymbolicName() {return "test";}
106
			public String[] getExecutionEnvironments() throws CoreException {return null;}
106
			public String[] getExecutionEnvironments() throws CoreException {return null;}
107
			public ResolverError[] getErrors() throws CoreException {return null;}
107
			public ResolverError[] getErrors() throws CoreException {return null;}
108
			protected List createApiTypeContainers() throws CoreException {
108
			protected List createApiTypeContainers() throws CoreException {
(-)src/org/eclipse/pde/api/tools/model/tests/ComponentManifestTests.java (-1 / +1 lines)
Lines 53-59 Link Here
53
		IApiBaseline baseline = TestSuiteHelper.newApiBaseline("test", TestSuiteHelper.getEEDescriptionFile());
53
		IApiBaseline baseline = TestSuiteHelper.newApiBaseline("test", TestSuiteHelper.getEEDescriptionFile());
54
		IApiComponent component = ApiModelFactory.newApiComponent(baseline, file.getAbsolutePath());
54
		IApiComponent component = ApiModelFactory.newApiComponent(baseline, file.getAbsolutePath());
55
		baseline.addApiComponents(new IApiComponent[] { component });
55
		baseline.addApiComponents(new IApiComponent[] { component });
56
		assertEquals("Id: ", "org.eclipse.debug.ui" , component.getId());
56
		assertEquals("Id: ", "org.eclipse.debug.ui" , component.getSymbolicName());
57
		assertEquals("Name: ", "Debug Platform UI" , component.getName());
57
		assertEquals("Name: ", "Debug Platform UI" , component.getName());
58
		assertEquals("Version: ", "3.3.100.qualifier" , component.getVersion());
58
		assertEquals("Version: ", "3.3.100.qualifier" , component.getVersion());
59
		String[] envs = component.getExecutionEnvironments();
59
		String[] envs = component.getExecutionEnvironments();
(-)src/org/eclipse/pde/api/tools/model/tests/TestSuiteHelper.java (-4 / +4 lines)
Lines 90-96 Link Here
90
			IApiComponent component = ApiModelFactory.newApiComponent(baseline, bundle.getAbsolutePath());
90
			IApiComponent component = ApiModelFactory.newApiComponent(baseline, bundle.getAbsolutePath());
91
			if(component != null) {
91
			if(component != null) {
92
				components.add(component);
92
				components.add(component);
93
				requiredComponents.add(component.getId());
93
				requiredComponents.add(component.getSymbolicName());
94
			}
94
			}
95
		}
95
		}
96
		// collect required components
96
		// collect required components
Lines 148-154 Link Here
148
			public String getLocation() {
148
			public String getLocation() {
149
				return null;
149
				return null;
150
			}
150
			}
151
			public String getId() {
151
			public String getSymbolicName() {
152
				return id;
152
				return id;
153
			}
153
			}
154
			public String[] getExecutionEnvironments() {
154
			public String[] getExecutionEnvironments() {
Lines 263-269 Link Here
263
					IApiComponent component = ApiModelFactory.newApiComponent(baseline, bundle.getAbsolutePath());
263
					IApiComponent component = ApiModelFactory.newApiComponent(baseline, bundle.getAbsolutePath());
264
					if(component != null) {
264
					if(component != null) {
265
						components.add(component);
265
						components.add(component);
266
						requiredComponents.add(component.getId());
266
						requiredComponents.add(component.getSymbolicName());
267
					}
267
					}
268
				}
268
				}
269
			}
269
			}
Lines 406-412 Link Here
406
				} else {
406
				} else {
407
					IApiComponent apiComponent = ApiModelFactory.newApiComponent(baseline, bundle.getAbsolutePath());
407
					IApiComponent apiComponent = ApiModelFactory.newApiComponent(baseline, bundle.getAbsolutePath());
408
					collection.add(apiComponent);
408
					collection.add(apiComponent);
409
					done.add(apiComponent.getId());
409
					done.add(apiComponent.getSymbolicName());
410
					addAllRequired(baseline, done, apiComponent, collection);
410
					addAllRequired(baseline, done, apiComponent, collection);
411
				}
411
				}
412
			}
412
			}
(-)src/org/eclipse/pde/api/tools/search/tests/SkippedComponentTests.java (-22 / +22 lines)
Lines 46-53 Link Here
46
		try {
46
		try {
47
			IApiComponent tcomp = getTestingComponent();
47
			IApiComponent tcomp = getTestingComponent();
48
			assertNotNull("The testing component should not be null", tcomp);
48
			assertNotNull("The testing component should not be null", tcomp);
49
			SkippedComponent scomp1 = new SkippedComponent(tcomp.getId(), tcomp.getVersion(), tcomp.getErrors());
49
			SkippedComponent scomp1 = new SkippedComponent(tcomp.getSymbolicName(), tcomp.getVersion(), tcomp.getErrors());
50
			SkippedComponent scomp2 = new SkippedComponent(tcomp.getId(), tcomp.getVersion(), tcomp.getErrors());
50
			SkippedComponent scomp2 = new SkippedComponent(tcomp.getSymbolicName(), tcomp.getVersion(), tcomp.getErrors());
51
			assertEquals("The components should be equal", scomp1, scomp2);
51
			assertEquals("The components should be equal", scomp1, scomp2);
52
			assertTrue("The components should not be equal", !scomp1.equals(tcomp));
52
			assertTrue("The components should not be equal", !scomp1.equals(tcomp));
53
			assertTrue("The components should not be equal", !scomp2.equals(tcomp));
53
			assertTrue("The components should not be equal", !scomp2.equals(tcomp));
Lines 64-71 Link Here
64
		try {
64
		try {
65
			IApiComponent tcomp = getTestingComponent();
65
			IApiComponent tcomp = getTestingComponent();
66
			assertNotNull("The testing component should not be null", tcomp);
66
			assertNotNull("The testing component should not be null", tcomp);
67
			SkippedComponent scomp1 = new SkippedComponent(tcomp.getId(), tcomp.getVersion(), tcomp.getErrors());
67
			SkippedComponent scomp1 = new SkippedComponent(tcomp.getSymbolicName(), tcomp.getVersion(), tcomp.getErrors());
68
			SkippedComponent scomp2 = new SkippedComponent(tcomp.getId(), tcomp.getVersion(), tcomp.getErrors());
68
			SkippedComponent scomp2 = new SkippedComponent(tcomp.getSymbolicName(), tcomp.getVersion(), tcomp.getErrors());
69
			assertEquals("The component hashcodes should be equal", scomp1.hashCode(), scomp2.hashCode());
69
			assertEquals("The component hashcodes should be equal", scomp1.hashCode(), scomp2.hashCode());
70
		}
70
		}
71
		catch(Exception e) {
71
		catch(Exception e) {
Lines 80-90 Link Here
80
		try {
80
		try {
81
			IApiComponent tcomp = getTestingComponent();
81
			IApiComponent tcomp = getTestingComponent();
82
			assertNotNull("The testing component should not be null", tcomp);
82
			assertNotNull("The testing component should not be null", tcomp);
83
			SkippedComponent scomp1 = new SkippedComponent(tcomp.getId(), tcomp.getVersion(), tcomp.getErrors());
83
			SkippedComponent scomp1 = new SkippedComponent(tcomp.getSymbolicName(), tcomp.getVersion(), tcomp.getErrors());
84
			SkippedComponent scomp2 = new SkippedComponent(tcomp.getId(), tcomp.getVersion(), tcomp.getErrors());
84
			SkippedComponent scomp2 = new SkippedComponent(tcomp.getSymbolicName(), tcomp.getVersion(), tcomp.getErrors());
85
			assertEquals("The component ids should be equal", scomp1.getComponentId(), scomp2.getComponentId());
85
			assertEquals("The component ids should be equal", scomp1.getComponentId(), scomp2.getComponentId());
86
			assertEquals("The component ids should be equal", scomp1.getComponentId(), tcomp.getId());
86
			assertEquals("The component ids should be equal", scomp1.getComponentId(), tcomp.getSymbolicName());
87
			assertEquals("The component ids should be equal", scomp2.getComponentId(), tcomp.getId());
87
			assertEquals("The component ids should be equal", scomp2.getComponentId(), tcomp.getSymbolicName());
88
		}
88
		}
89
		catch(Exception e) {
89
		catch(Exception e) {
90
			fail(e.getMessage());
90
			fail(e.getMessage());
Lines 98-106 Link Here
98
		try {
98
		try {
99
			IApiComponent tcomp = getTestingComponent();
99
			IApiComponent tcomp = getTestingComponent();
100
			assertNotNull("The testing component should not be null", tcomp);
100
			assertNotNull("The testing component should not be null", tcomp);
101
			SkippedComponent scomp1 = new SkippedComponent(tcomp.getId(), tcomp.getVersion(), tcomp.getErrors());
101
			SkippedComponent scomp1 = new SkippedComponent(tcomp.getSymbolicName(), tcomp.getVersion(), tcomp.getErrors());
102
			assertFalse("The testing component was not excluded", scomp1.wasExcluded());
102
			assertFalse("The testing component was not excluded", scomp1.wasExcluded());
103
			scomp1 = new SkippedComponent(tcomp.getId(), tcomp.getVersion(), null);
103
			scomp1 = new SkippedComponent(tcomp.getSymbolicName(), tcomp.getVersion(), null);
104
			assertTrue("The testing component was excluded", scomp1.wasExcluded());
104
			assertTrue("The testing component was excluded", scomp1.wasExcluded());
105
		}
105
		}
106
		catch(Exception e) {
106
		catch(Exception e) {
Lines 115-123 Link Here
115
		try {
115
		try {
116
			IApiComponent tcomp = getTestingComponent();
116
			IApiComponent tcomp = getTestingComponent();
117
			assertNotNull("The testing component should not be null", tcomp);
117
			assertNotNull("The testing component should not be null", tcomp);
118
			SkippedComponent scomp1 = new SkippedComponent(tcomp.getId(), tcomp.getVersion(), null);
118
			SkippedComponent scomp1 = new SkippedComponent(tcomp.getSymbolicName(), tcomp.getVersion(), null);
119
			assertFalse("The testing component did have resolution errors", scomp1.hasResolutionErrors());
119
			assertFalse("The testing component did have resolution errors", scomp1.hasResolutionErrors());
120
			scomp1 = new SkippedComponent(tcomp.getId(), tcomp.getVersion(), tcomp.getErrors());
120
			scomp1 = new SkippedComponent(tcomp.getSymbolicName(), tcomp.getVersion(), tcomp.getErrors());
121
			assertTrue("The testing component did not have resolution errors", scomp1.hasResolutionErrors());
121
			assertTrue("The testing component did not have resolution errors", scomp1.hasResolutionErrors());
122
		}
122
		}
123
		catch(Exception e) {
123
		catch(Exception e) {
Lines 132-138 Link Here
132
		try {
132
		try {
133
			IApiComponent tcomp = getTestingComponent();
133
			IApiComponent tcomp = getTestingComponent();
134
			assertNotNull("The testing component should not be null", tcomp);
134
			assertNotNull("The testing component should not be null", tcomp);
135
			SkippedComponent scomp1 = new SkippedComponent(tcomp.getId(), tcomp.getVersion(), tcomp.getErrors());
135
			SkippedComponent scomp1 = new SkippedComponent(tcomp.getSymbolicName(), tcomp.getVersion(), tcomp.getErrors());
136
			assertNull("there should be no ancestors for SkippedComponents", scomp1.getAncestor(IApiElement.COMPONENT));
136
			assertNull("there should be no ancestors for SkippedComponents", scomp1.getAncestor(IApiElement.COMPONENT));
137
		}
137
		}
138
		catch(Exception e) {
138
		catch(Exception e) {
Lines 147-153 Link Here
147
		try {
147
		try {
148
			IApiComponent tcomp = getTestingComponent();
148
			IApiComponent tcomp = getTestingComponent();
149
			assertNotNull("The testing component should not be null", tcomp);
149
			assertNotNull("The testing component should not be null", tcomp);
150
			SkippedComponent scomp1 = new SkippedComponent(tcomp.getId(), tcomp.getVersion(), tcomp.getErrors());
150
			SkippedComponent scomp1 = new SkippedComponent(tcomp.getSymbolicName(), tcomp.getVersion(), tcomp.getErrors());
151
			assertNull("there should be no IApiComponent object for SkippedComponents", scomp1.getApiComponent());
151
			assertNull("there should be no IApiComponent object for SkippedComponents", scomp1.getApiComponent());
152
		}
152
		}
153
		catch(Exception e) {
153
		catch(Exception e) {
Lines 162-169 Link Here
162
		try {
162
		try {
163
			IApiComponent tcomp = getTestingComponent();
163
			IApiComponent tcomp = getTestingComponent();
164
			assertNotNull("The testing component should not be null", tcomp);
164
			assertNotNull("The testing component should not be null", tcomp);
165
			SkippedComponent scomp1 = new SkippedComponent(tcomp.getId(), tcomp.getVersion(), tcomp.getErrors());
165
			SkippedComponent scomp1 = new SkippedComponent(tcomp.getSymbolicName(), tcomp.getVersion(), tcomp.getErrors());
166
			assertEquals("The names should be equal", tcomp.getId(), scomp1.getName());
166
			assertEquals("The names should be equal", tcomp.getSymbolicName(), scomp1.getName());
167
		}
167
		}
168
		catch(Exception e) {
168
		catch(Exception e) {
169
			fail(e.getMessage());
169
			fail(e.getMessage());
Lines 177-183 Link Here
177
		try {
177
		try {
178
			IApiComponent tcomp = getTestingComponent();
178
			IApiComponent tcomp = getTestingComponent();
179
			assertNotNull("The testing component should not be null", tcomp);
179
			assertNotNull("The testing component should not be null", tcomp);
180
			SkippedComponent scomp1 = new SkippedComponent(tcomp.getId(), tcomp.getVersion(), tcomp.getErrors());
180
			SkippedComponent scomp1 = new SkippedComponent(tcomp.getSymbolicName(), tcomp.getVersion(), tcomp.getErrors());
181
			assertNull("there should be no parentt object for SkippedComponents", scomp1.getParent());
181
			assertNull("there should be no parentt object for SkippedComponents", scomp1.getParent());
182
		}
182
		}
183
		catch(Exception e) {
183
		catch(Exception e) {
Lines 192-198 Link Here
192
		try {
192
		try {
193
			IApiComponent tcomp = getTestingComponent();
193
			IApiComponent tcomp = getTestingComponent();
194
			assertNotNull("The testing component should not be null", tcomp);
194
			assertNotNull("The testing component should not be null", tcomp);
195
			SkippedComponent scomp1 = new SkippedComponent(tcomp.getId(), tcomp.getVersion(), tcomp.getErrors());
195
			SkippedComponent scomp1 = new SkippedComponent(tcomp.getSymbolicName(), tcomp.getVersion(), tcomp.getErrors());
196
			assertEquals("The type should be IApiElement.COMPONENT", IApiElement.COMPONENT, scomp1.getType());
196
			assertEquals("The type should be IApiElement.COMPONENT", IApiElement.COMPONENT, scomp1.getType());
197
		}
197
		}
198
		catch(Exception e) {
198
		catch(Exception e) {
Lines 207-213 Link Here
207
		try {
207
		try {
208
			IApiComponent tcomp = getTestingComponent();
208
			IApiComponent tcomp = getTestingComponent();
209
			assertNotNull("The testing component should not be null", tcomp);
209
			assertNotNull("The testing component should not be null", tcomp);
210
			SkippedComponent scomp1 = new SkippedComponent(tcomp.getId(), tcomp.getVersion(), tcomp.getErrors());
210
			SkippedComponent scomp1 = new SkippedComponent(tcomp.getSymbolicName(), tcomp.getVersion(), tcomp.getErrors());
211
			assertEquals("The version should be 1.0.0", scomp1.getVersion(), DEFAULT_VERSION);
211
			assertEquals("The version should be 1.0.0", scomp1.getVersion(), DEFAULT_VERSION);
212
		}
212
		}
213
		catch(Exception e) {
213
		catch(Exception e) {
Lines 222-228 Link Here
222
		try {
222
		try {
223
			IApiComponent tcomp = getTestingComponent();
223
			IApiComponent tcomp = getTestingComponent();
224
			assertNotNull("The testing component should not be null", tcomp);
224
			assertNotNull("The testing component should not be null", tcomp);
225
			SkippedComponent scomp1 = new SkippedComponent(tcomp.getId(), tcomp.getVersion(), tcomp.getErrors());
225
			SkippedComponent scomp1 = new SkippedComponent(tcomp.getSymbolicName(), tcomp.getVersion(), tcomp.getErrors());
226
			assertNotNull("There should be resolution errors for the testing component", scomp1.getErrors());
226
			assertNotNull("There should be resolution errors for the testing component", scomp1.getErrors());
227
		}
227
		}
228
		catch(Exception e) {
228
		catch(Exception e) {
Lines 237-247 Link Here
237
		try {
237
		try {
238
			IApiComponent tcomp = getTestingComponent();
238
			IApiComponent tcomp = getTestingComponent();
239
			assertNotNull("The testing component should not be null", tcomp);
239
			assertNotNull("The testing component should not be null", tcomp);
240
			SkippedComponent scomp1 = new SkippedComponent(tcomp.getId(), tcomp.getVersion(), tcomp.getErrors());
240
			SkippedComponent scomp1 = new SkippedComponent(tcomp.getSymbolicName(), tcomp.getVersion(), tcomp.getErrors());
241
			assertNotNull("There should be resolution errors for the testing component", scomp1.getErrors());
241
			assertNotNull("There should be resolution errors for the testing component", scomp1.getErrors());
242
			String reason = scomp1.getErrorDetails();
242
			String reason = scomp1.getErrorDetails();
243
			assertTrue("The reason should be because of a unresolved constraint", reason.startsWith("Require-Bundle:"));
243
			assertTrue("The reason should be because of a unresolved constraint", reason.startsWith("Require-Bundle:"));
244
			scomp1 = new SkippedComponent(tcomp.getId(), tcomp.getVersion(), null);
244
			scomp1 = new SkippedComponent(tcomp.getSymbolicName(), tcomp.getVersion(), null);
245
			assertNull("There should be no errors for the testing component", scomp1.getErrors());
245
			assertNull("There should be no errors for the testing component", scomp1.getErrors());
246
			reason = scomp1.getErrorDetails();
246
			reason = scomp1.getErrorDetails();
247
			assertTrue("The reason should be because it was exclude", reason.startsWith("This component was excluded from the search by the search parameters."));
247
			assertTrue("The reason should be because it was exclude", reason.startsWith("This component was excluded from the search by the search parameters."));
(-)src/org/eclipse/pde/api/tools/search/tests/TestReporter.java (-1 / +1 lines)
Lines 86-92 Link Here
86
	 * @see org.eclipse.pde.api.tools.internal.provisional.search.IApiSearchReporter#reportResults(org.eclipse.pde.api.tools.internal.provisional.model.IApiElement, org.eclipse.pde.api.tools.internal.provisional.builder.IReference[])
86
	 * @see org.eclipse.pde.api.tools.internal.provisional.search.IApiSearchReporter#reportResults(org.eclipse.pde.api.tools.internal.provisional.model.IApiElement, org.eclipse.pde.api.tools.internal.provisional.builder.IReference[])
87
	 */
87
	 */
88
	public void reportResults(IApiElement element, IReference[] references) {
88
	public void reportResults(IApiElement element, IReference[] references) {
89
		String name = (element.getType() == IApiElement.COMPONENT ? ((IApiComponent)element).getId() : element.getName());
89
		String name = (element.getType() == IApiElement.COMPONENT ? ((IApiComponent)element).getSymbolicName() : element.getName());
90
		if(this.references == null) {
90
		if(this.references == null) {
91
			//expecting no references
91
			//expecting no references
92
			if(references.length > 0) {
92
			if(references.length > 0) {
(-)src/org/eclipse/pde/api/tools/search/tests/TestRequestor.java (-4 / +4 lines)
Lines 13-19 Link Here
13
import java.util.HashSet;
13
import java.util.HashSet;
14
14
15
import org.eclipse.core.runtime.CoreException;
15
import org.eclipse.core.runtime.CoreException;
16
import org.eclipse.pde.api.tools.internal.model.PluginProjectApiComponent;
16
import org.eclipse.pde.api.tools.internal.model.ProjectComponent;
17
import org.eclipse.pde.api.tools.internal.provisional.IApiAnnotations;
17
import org.eclipse.pde.api.tools.internal.provisional.IApiAnnotations;
18
import org.eclipse.pde.api.tools.internal.provisional.VisibilityModifiers;
18
import org.eclipse.pde.api.tools.internal.provisional.VisibilityModifiers;
19
import org.eclipse.pde.api.tools.internal.provisional.builder.IReference;
19
import org.eclipse.pde.api.tools.internal.provisional.builder.IReference;
Lines 161-167 Link Here
161
	 */
161
	 */
162
	private boolean acceptComponent0(IApiComponent component) throws CoreException {
162
	private boolean acceptComponent0(IApiComponent component) throws CoreException {
163
		return component != null &&  
163
		return component != null &&  
164
				!this.excluded.contains(component.getId()) && 
164
				!this.excluded.contains(component.getSymbolicName()) && 
165
				isApiComponent(component);
165
				isApiComponent(component);
166
	}
166
	}
167
	
167
	
Lines 172-179 Link Here
172
	 * @return true if the project represented by the given component is API tools enabled false otherwise
172
	 * @return true if the project represented by the given component is API tools enabled false otherwise
173
	 */
173
	 */
174
	private boolean isApiComponent(IApiComponent component) {
174
	private boolean isApiComponent(IApiComponent component) {
175
		if(component instanceof PluginProjectApiComponent) {
175
		if(component instanceof ProjectComponent) {
176
			PluginProjectApiComponent comp = (PluginProjectApiComponent) component;
176
			ProjectComponent comp = (ProjectComponent) component;
177
			return comp.hasApiDescription();
177
			return comp.hasApiDescription();
178
		}
178
		}
179
		else {
179
		else {
(-)test-xml/META-INF/MANIFEST.MF (-1 / +1 lines)
Lines 1-7 Link Here
1
Manifest-Version: 1.0
1
Manifest-Version: 1.0
2
Bundle-Name: test
2
Bundle-Name: test
3
Bundle-SymbolicName: test
3
Bundle-SymbolicName: test
4
Bundle-Version: test
4
Bundle-Version: 1.0
5
Export-Package: .,
5
Export-Package: .,
6
 a.b.c,
6
 a.b.c,
7
 a.b.c.spi,
7
 a.b.c.spi,
(-)src/org/eclipse/pde/api/tools/ui/internal/ApiToolsLabelProvider.java (-1 / +1 lines)
Lines 181-187 Link Here
181
	public String getText(Object element) {
181
	public String getText(Object element) {
182
		if (element instanceof IApiComponent) {
182
		if (element instanceof IApiComponent) {
183
			IApiComponent comp = (IApiComponent) element;
183
			IApiComponent comp = (IApiComponent) element;
184
			return MessageFormat.format(Messages.ApiToolsLabelProvider_0, new String[]{comp.getId(), comp.getVersion()});
184
			return MessageFormat.format(Messages.ApiToolsLabelProvider_0, new String[]{comp.getSymbolicName(), comp.getVersion()});
185
		}
185
		}
186
		if (element instanceof File) {
186
		if (element instanceof File) {
187
			try {
187
			try {
(-)src/org/eclipse/pde/api/tools/ui/internal/actions/DeltaSession.java (-4 / +4 lines)
Lines 436-442 Link Here
436
					if (apiComponent != null && (kind == IDelta.REMOVED)) {
436
					if (apiComponent != null && (kind == IDelta.REMOVED)) {
437
						// need to handle reexported types
437
						// need to handle reexported types
438
						IApiTypeRoot typeRoot = null;
438
						IApiTypeRoot typeRoot = null;
439
						String id = apiComponent.getId();
439
						String id = apiComponent.getSymbolicName();
440
						switch(delta.getFlags()) {
440
						switch(delta.getFlags()) {
441
							case IDelta.REEXPORTED_TYPE :
441
							case IDelta.REEXPORTED_TYPE :
442
							case IDelta.REEXPORTED_API_TYPE :
442
							case IDelta.REEXPORTED_API_TYPE :
Lines 452-458 Link Here
452
								while (typeRoot == null && index < providers.length) {
452
								while (typeRoot == null && index < providers.length) {
453
									IApiComponent p = providers[index];
453
									IApiComponent p = providers[index];
454
									if (!p.equals(apiComponent)) {
454
									if (!p.equals(apiComponent)) {
455
										String id2 = p.getId();
455
										String id2 = p.getSymbolicName();
456
										if (Util.ORG_ECLIPSE_SWT.equals(id2)) {
456
										if (Util.ORG_ECLIPSE_SWT.equals(id2)) {
457
											typeRoot = p.findTypeRoot(typeName);
457
											typeRoot = p.findTypeRoot(typeName);
458
										} else {
458
										} else {
Lines 484-490 Link Here
484
						IApiComponent apiComponent = baseline.getApiComponent(componentID);
484
						IApiComponent apiComponent = baseline.getApiComponent(componentID);
485
						if (apiComponent != null) {
485
						if (apiComponent != null) {
486
							IApiTypeRoot typeRoot = null;
486
							IApiTypeRoot typeRoot = null;
487
							String id = apiComponent.getId();
487
							String id = apiComponent.getSymbolicName();
488
							switch(delta.getFlags()) {
488
							switch(delta.getFlags()) {
489
								case IDelta.REEXPORTED_TYPE :
489
								case IDelta.REEXPORTED_TYPE :
490
								case IDelta.REEXPORTED_API_TYPE :
490
								case IDelta.REEXPORTED_API_TYPE :
Lines 500-506 Link Here
500
									while (typeRoot == null && index < providers.length) {
500
									while (typeRoot == null && index < providers.length) {
501
										IApiComponent p = providers[index];
501
										IApiComponent p = providers[index];
502
										if (!p.equals(apiComponent)) {
502
										if (!p.equals(apiComponent)) {
503
											String id2 = p.getId();
503
											String id2 = p.getSymbolicName();
504
											if (Util.ORG_ECLIPSE_SWT.equals(id2)) {
504
											if (Util.ORG_ECLIPSE_SWT.equals(id2)) {
505
												typeRoot = p.findTypeRoot(typeName);
505
												typeRoot = p.findTypeRoot(typeName);
506
											} else {
506
											} else {
(-)src/org/eclipse/pde/api/tools/ui/internal/markers/RemoveFilterProblemResolution.java (-2 / +2 lines)
Lines 25-31 Link Here
25
import org.eclipse.core.runtime.SubMonitor;
25
import org.eclipse.core.runtime.SubMonitor;
26
import org.eclipse.osgi.util.NLS;
26
import org.eclipse.osgi.util.NLS;
27
import org.eclipse.pde.api.tools.internal.ApiBaselineManager;
27
import org.eclipse.pde.api.tools.internal.ApiBaselineManager;
28
import org.eclipse.pde.api.tools.internal.model.PluginProjectApiComponent;
28
import org.eclipse.pde.api.tools.internal.model.ProjectComponent;
29
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
29
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
30
import org.eclipse.pde.api.tools.internal.provisional.IApiFilterStore;
30
import org.eclipse.pde.api.tools.internal.provisional.IApiFilterStore;
31
import org.eclipse.pde.api.tools.internal.provisional.IApiMarkerConstants;
31
import org.eclipse.pde.api.tools.internal.provisional.IApiMarkerConstants;
Lines 108-114 Link Here
108
				}
108
				}
109
				resource = markers[i].getResource();
109
				resource = markers[i].getResource();
110
				component = ApiBaselineManager.getManager().getWorkspaceBaseline().getApiComponent(resource.getProject());
110
				component = ApiBaselineManager.getManager().getWorkspaceBaseline().getApiComponent(resource.getProject());
111
				if(component instanceof PluginProjectApiComponent) {
111
				if(component instanceof ProjectComponent) {
112
					filters = (HashSet) map.get(component);
112
					filters = (HashSet) map.get(component);
113
					if(filters == null) {
113
					if(filters == null) {
114
						filters = new HashSet();
114
						filters = new HashSet();
(-)src/org/eclipse/pde/api/tools/ui/internal/use/ApiUseScanJob.java (-6 / +6 lines)
Lines 283-299 Link Here
283
		localmonitor.setWorkRemaining(components.length);
283
		localmonitor.setWorkRemaining(components.length);
284
		for (int i = 0; i < components.length; i++) {
284
		for (int i = 0; i < components.length; i++) {
285
			IApiComponent component = components[i];
285
			IApiComponent component = components[i];
286
			localmonitor.subTask(NLS.bind(Messages.ApiUseScanJob_checking_component, component.getId()));
286
			localmonitor.subTask(NLS.bind(Messages.ApiUseScanJob_checking_component, component.getSymbolicName()));
287
			Util.updateMonitor(localmonitor, 1);
287
			Util.updateMonitor(localmonitor, 1);
288
			if (acceptComponent(component, pattern, true)) {
288
			if (acceptComponent(component, pattern, true)) {
289
				ids.add(component.getId());
289
				ids.add(component.getSymbolicName());
290
			}
290
			}
291
			if (acceptComponent(component, pattern2, false)) {
291
			if (acceptComponent(component, pattern2, false)) {
292
				scope.add(component);
292
				scope.add(component);
293
			}
293
			}
294
			else {
294
			else {
295
				localmonitor.subTask(NLS.bind(Messages.ApiUseScanJob_skipping_component, component.getId()));
295
				localmonitor.subTask(NLS.bind(Messages.ApiUseScanJob_skipping_component, component.getSymbolicName()));
296
				this.notsearched.add(new SkippedComponent(component.getId(), component.getVersion(), null));
296
				this.notsearched.add(new SkippedComponent(component.getSymbolicName(), component.getVersion(), null));
297
			}
297
			}
298
		}
298
		}
299
	}
299
	}
Lines 326-332 Link Here
326
		if(!allowresolve) {
326
		if(!allowresolve) {
327
			ResolverError[] errors = component.getErrors();
327
			ResolverError[] errors = component.getErrors();
328
			if(errors != null) {
328
			if(errors != null) {
329
				this.notsearched.add(new SkippedComponent(component.getId(), component.getVersion(), errors)); 
329
				this.notsearched.add(new SkippedComponent(component.getSymbolicName(), component.getVersion(), errors)); 
330
				return false;
330
				return false;
331
			}
331
			}
332
		}
332
		}
Lines 334-340 Link Here
334
			return false;
334
			return false;
335
		}
335
		}
336
		if(pattern != null) {
336
		if(pattern != null) {
337
			return pattern.matcher(component.getId()).matches();
337
			return pattern.matcher(component.getSymbolicName()).matches();
338
		}
338
		}
339
		return true;
339
		return true;
340
	}
340
	}

Return to bug 233643