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.search; |
12 | |
13 | import java.util.Comparator; |
14 | import java.util.TreeSet; |
15 | |
16 | import org.eclipse.osgi.service.resolver.BundleDescription; |
17 | import org.eclipse.osgi.service.resolver.ResolverError; |
18 | import org.eclipse.osgi.service.resolver.VersionConstraint; |
19 | import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent; |
20 | import org.eclipse.pde.api.tools.internal.provisional.model.IApiElement; |
21 | |
22 | |
23 | public class SkippedComponent implements IApiElement{ |
24 | /** |
25 | * the id of of the skipped component |
26 | */ |
27 | private String componentid; |
28 | /** |
29 | * The version of the component |
30 | */ |
31 | private String version; |
32 | /** |
33 | * the set of resolution errors barring the component from being scanned |
34 | */ |
35 | private ResolverError[] errors = null; |
36 | |
37 | /** |
38 | * Constructor |
39 | * @param componentid |
40 | * @param version |
41 | * @param errors the {@link ResolverError}s, if any, that prevented this component from being scanned |
42 | */ |
43 | public SkippedComponent(String componentid, String version, ResolverError[] errors) { |
44 | this.componentid = componentid; |
45 | this.version = version; |
46 | this.errors = errors; |
47 | } |
48 | |
49 | /* (non-Javadoc) |
50 | * @see java.lang.Object#equals(java.lang.Object) |
51 | */ |
52 | public boolean equals(Object obj) { |
53 | if(obj instanceof SkippedComponent) { |
54 | return this.componentid.equals(((SkippedComponent)obj).componentid); |
55 | } |
56 | return false; |
57 | } |
58 | |
59 | /* (non-Javadoc) |
60 | * @see java.lang.Object#hashCode() |
61 | */ |
62 | public int hashCode() { |
63 | return this.componentid.hashCode(); |
64 | } |
65 | |
66 | /** |
67 | * @return the component id of the skipped component |
68 | */ |
69 | public String getComponentId() { |
70 | return this.componentid; |
71 | } |
72 | |
73 | /** |
74 | * @return true if the component was skipped because it appeared in an exclude list |
75 | */ |
76 | public boolean wasExcluded() { |
77 | return this.errors == null; |
78 | } |
79 | |
80 | /** |
81 | * @return true if the the component had resolution errors |
82 | */ |
83 | public boolean hasResolutionErrors() { |
84 | return this.errors != null; |
85 | } |
86 | |
87 | /** |
88 | * @see org.eclipse.pde.api.tools.internal.provisional.model.IApiElement#getAncestor(int) |
89 | */ |
90 | public IApiElement getAncestor(int ancestorType) { |
91 | return null; |
92 | } |
93 | |
94 | /** |
95 | * @return the version |
96 | */ |
97 | public String getVersion() { |
98 | return this.version; |
99 | } |
100 | |
101 | /** |
102 | * @see org.eclipse.pde.api.tools.internal.provisional.model.IApiElement#getApiComponent() |
103 | */ |
104 | public IApiComponent getApiComponent() { |
105 | return null; |
106 | } |
107 | |
108 | /** |
109 | * @see org.eclipse.pde.api.tools.internal.provisional.model.IApiElement#getName() |
110 | */ |
111 | public String getName() { |
112 | return this.componentid; |
113 | } |
114 | |
115 | /** |
116 | * @see org.eclipse.pde.api.tools.internal.provisional.model.IApiElement#getParent() |
117 | */ |
118 | public IApiElement getParent() { |
119 | return null; |
120 | } |
121 | |
122 | /** |
123 | * @see org.eclipse.pde.api.tools.internal.provisional.model.IApiElement#getType() |
124 | */ |
125 | public int getType() { |
126 | return IApiElement.COMPONENT; |
127 | } |
128 | |
129 | /** |
130 | * @return the errors |
131 | */ |
132 | public ResolverError[] getErrors() { |
133 | return this.errors; |
134 | } |
135 | |
136 | /** |
137 | * Resolves the root errors for the given set of errors |
138 | * @param errors |
139 | * @param collector |
140 | * @return the resolved leaf set of problem messages |
141 | */ |
142 | private String[] resolveRootErrors(ResolverError[] errors) { |
143 | TreeSet collector = new TreeSet(new Comparator() { |
144 | public int compare(Object o1, Object o2) { |
145 | return ((String)o1).compareTo(o2); |
146 | } |
147 | }); |
148 | ResolverError error = null; |
149 | VersionConstraint[] constraints = null; |
150 | BundleDescription[] bundle = new BundleDescription[1]; |
151 | for (int i = 0; i < errors.length; i++) { |
152 | error = errors[i]; |
153 | if(error.getType() != ResolverError.MISSING_REQUIRE_BUNDLE) { |
154 | collector.add(error.toString()); |
155 | } |
156 | bundle[0] = error.getBundle(); |
157 | constraints = bundle[0].getContainingState().getStateHelper().getUnsatisfiedLeaves(bundle); |
158 | if(constraints.length == 0) { |
159 | collector.add(error.toString()); |
160 | } |
161 | for (int j = 0; j < constraints.length; j++) { |
162 | collector.add(constraints[j].toString()); |
163 | } |
164 | } |
165 | return (String[]) collector.toArray(new String[collector.size()]); |
166 | } |
167 | |
168 | /** |
169 | * @return the formatted details of why the component was skipped |
170 | */ |
171 | public String getErrorDetails() { |
172 | if(this.errors != null) { |
173 | StringBuffer buffer = new StringBuffer(); |
174 | String[] problems = resolveRootErrors(this.errors); |
175 | for (int i = 0; i < problems.length; i++) { |
176 | buffer.append(problems[i]).append("<br/>"); //$NON-NLS-1$ |
177 | } |
178 | return buffer.toString(); |
179 | } |
180 | return SearchMessages.SkippedComponent_component_was_excluded; |
181 | } |
182 | } |