EMMA Coverage Report (generated Thu Nov 26 15:54:18 CST 2009)
[all classes][org.eclipse.pde.api.tools.internal.provisional.search]

COVERAGE SUMMARY FOR SOURCE FILE [ApiSearchEngine.java]

nameclass, %method, %block, %line, %
ApiSearchEngine.java100% (2/2)100% (14/14)74%  (454/610)68%  (100.1/147)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ApiSearchEngine100% (1/1)100% (7/7)69%  (339/488)63%  (71.1/113)
searchReferences (IApiSearchRequestor, IApiElement, IApiSearchReporter, IProg... 100% (1/1)33%  (42/127)34%  (12.4/36)
setDebug (boolean): void 100% (1/1)56%  (5/9)78%  (1.6/2)
search (IApiBaseline, IApiSearchRequestor, IApiSearchReporter, IProgressMonit... 100% (1/1)81%  (180/221)75%  (32.2/43)
getResolvedReferences (IApiSearchRequestor, IApiType, IProgressMonitor): List 100% (1/1)84%  (36/43)75%  (6.8/9)
acceptReferences (IApiSearchRequestor, IApiType, List, IProgressMonitor): List 100% (1/1)84%  (64/76)75%  (14.3/19)
<static initializer> 100% (1/1)100% (6/6)100% (3/3)
ApiSearchEngine (): void 100% (1/1)100% (6/6)100% (2/2)
     
class ApiSearchEngine$ReferenceExtractor100% (1/1)100% (7/7)94%  (115/122)85%  (29/34)
end (String, IApiTypeRoot): void 100% (1/1)75%  (6/8)67%  (2/3)
visit (String, IApiTypeRoot): void 100% (1/1)89%  (40/45)67%  (8/12)
ApiSearchEngine$ReferenceExtractor (ApiSearchEngine, IApiSearchRequestor, IAp... 100% (1/1)100% (39/39)100% (12/12)
endVisitPackage (String): void 100% (1/1)100% (3/3)100% (2/2)
reportResults (): void 100% (1/1)100% (17/17)100% (3/3)
visit (IApiComponent): boolean 100% (1/1)100% (5/5)100% (1/1)
visit (IApiTypeContainer): boolean 100% (1/1)100% (5/5)100% (1/1)

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 *******************************************************************************/
11package org.eclipse.pde.api.tools.internal.provisional.search;
12 
13import java.util.ArrayList;
14import java.util.Collections;
15import java.util.Iterator;
16import java.util.List;
17 
18import org.eclipse.core.runtime.CoreException;
19import org.eclipse.core.runtime.IProgressMonitor;
20import org.eclipse.core.runtime.IStatus;
21import org.eclipse.core.runtime.MultiStatus;
22import org.eclipse.core.runtime.Status;
23import org.eclipse.core.runtime.SubMonitor;
24import org.eclipse.pde.api.tools.internal.builder.Reference;
25import org.eclipse.pde.api.tools.internal.builder.ReferenceResolver;
26import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
27import org.eclipse.pde.api.tools.internal.provisional.builder.IReference;
28import org.eclipse.pde.api.tools.internal.provisional.model.ApiTypeContainerVisitor;
29import org.eclipse.pde.api.tools.internal.provisional.model.IApiBaseline;
30import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent;
31import org.eclipse.pde.api.tools.internal.provisional.model.IApiElement;
32import org.eclipse.pde.api.tools.internal.provisional.model.IApiMember;
33import org.eclipse.pde.api.tools.internal.provisional.model.IApiScope;
34import org.eclipse.pde.api.tools.internal.provisional.model.IApiType;
35import org.eclipse.pde.api.tools.internal.provisional.model.IApiTypeContainer;
36import org.eclipse.pde.api.tools.internal.provisional.model.IApiTypeRoot;
37import org.eclipse.pde.api.tools.internal.search.SearchMessages;
38import org.eclipse.pde.api.tools.internal.util.Util;
39 
40import com.ibm.icu.text.MessageFormat;
41 
42/**
43 * Engine used to search for API use 
44 * 
45 * @since 1.0.0
46 */
47public final class ApiSearchEngine {
48        
49        /**
50         * Default empty array for no search matches
51         */
52        public static final IReference[] NO_REFERENCES = new IReference[0];
53        
54        /**
55         * Constant used for controlling tracing in the search engine
56         */
57        private static boolean DEBUG = Util.DEBUG;
58        
59        /**
60         * Visitor used to extract references from the component is is passed to
61         */
62        class ReferenceExtractor extends ApiTypeContainerVisitor {
63                static final int COLLECTOR_MAX = 2500;
64                private List collector = null;
65                private IApiSearchRequestor requestor = null;
66                private IApiSearchReporter reporter = null;
67                IApiElement element = null;
68                private SubMonitor monitor = null;
69                
70                /**
71                 * Constructor
72                 */
73                public ReferenceExtractor(IApiSearchRequestor requestor, IApiSearchReporter reporter, IApiElement element, IProgressMonitor monitor) {
74                        collector = new ArrayList();
75                        this.requestor = requestor;
76                        this.reporter = reporter;
77                        this.element = element;
78                        this.monitor = (SubMonitor) monitor;
79                }
80                
81                /* (non-Javadoc)
82                 * @see org.eclipse.pde.api.tools.internal.provisional.model.ApiTypeContainerVisitor#visit(org.eclipse.pde.api.tools.internal.provisional.model.IApiTypeContainer)
83                 */
84                public boolean visit(IApiTypeContainer container) {
85                        return requestor.acceptContainer(container);
86                }
87                
88                /* (non-Javadoc)
89                 * @see org.eclipse.pde.api.tools.internal.provisional.model.ApiTypeContainerVisitor#visit(java.lang.String, org.eclipse.pde.api.tools.internal.provisional.model.IApiTypeRoot)
90                 */
91                public void visit(String packageName, IApiTypeRoot typeroot) {
92                        if(monitor.isCanceled()) {
93                                return;
94                        }
95                        try {
96                                IApiType type = typeroot.getStructure();
97                                if(type == null || !requestor.acceptMember(type)) {
98                                        return;
99                                }                                
100                                collector.addAll(acceptReferences(requestor, 
101                                                type, 
102                                                getResolvedReferences(requestor, type, monitor.newChild(1)), 
103                                                monitor.newChild(1)));
104                        }
105                        catch(CoreException ce) {
106                                ApiPlugin.log(ce);
107                        }
108                }
109                
110                /* (non-Javadoc)
111                 * @see org.eclipse.pde.api.tools.internal.provisional.model.ApiTypeContainerVisitor#end(java.lang.String, org.eclipse.pde.api.tools.internal.provisional.model.IApiTypeRoot)
112                 */
113                public void end(String packageName, IApiTypeRoot typeroot) {
114                        if(this.collector.size() >= COLLECTOR_MAX) {
115                                reportResults();
116                        }
117                }
118                
119                /**
120                 * @see org.eclipse.pde.api.tools.internal.provisional.model.ApiTypeContainerVisitor#visit(org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent)
121                 */
122                public boolean visit(IApiComponent component) {
123                        return requestor.acceptComponent(component);
124                }
125                
126                /* (non-Javadoc)
127                 * @see org.eclipse.pde.api.tools.internal.provisional.model.ApiTypeContainerVisitor#endVisitPackage(java.lang.String)
128                 */
129                public void endVisitPackage(String packageName) {
130                        reportResults();
131                }
132                
133                private void reportResults() {
134                        reporter.reportResults(this.element, (IReference[]) collector.toArray(new IReference[collector.size()]));
135                        collector.clear();
136                }
137        }
138        
139        /**
140         * Method used for initializing tracing
141         */
142        public static void setDebug(boolean debugValue) {
143                DEBUG = debugValue || Util.DEBUG;
144        }
145        
146        /**
147         * Simple string used for reporting what is being searched
148         */
149        private String fRequestorContext = null;
150        
151        /**
152         * Returns the set of resolved references for the given {@link IApiType}
153         * @param requestor
154         * @param type
155         * @param monitor
156         * @return The listing of resolved references from the given {@link IApiType}
157         * @throws CoreException
158         */
159        List getResolvedReferences(IApiSearchRequestor requestor, IApiType type, IProgressMonitor monitor) throws CoreException {
160                String name = type.getSimpleName();
161                SubMonitor localmonitor = SubMonitor.convert(monitor, 
162                                MessageFormat.format(SearchMessages.ApiSearchEngine_extracting_refs_from, new String[] {(name == null ? SearchMessages.ApiSearchEngine_anonymous_type : name)}), 2);
163                try {
164                        List refs = type.extractReferences(requestor.getReferenceKinds(), localmonitor.newChild(1));
165                        ReferenceResolver.resolveReferences(refs, localmonitor.newChild(1));
166                        return refs;
167                }
168                finally {
169                        localmonitor.done();
170                }
171        }
172        
173        /**
174         * Runs the given list of references through the search requestor to determine if they should be kept or not
175         * @param requestor
176         * @param type
177         * @param references
178         * @param monitor
179         * @return
180         * @throws CoreException
181         */
182        List acceptReferences(IApiSearchRequestor requestor, IApiType type, List references, IProgressMonitor monitor) throws CoreException {
183                ArrayList refs = new ArrayList();
184                Reference ref = null;
185                SubMonitor localmonitor = SubMonitor.convert(monitor, references.size());
186                IApiMember member = null;
187                try {
188                        for (Iterator iter = references.iterator(); iter.hasNext();) {
189                                if(localmonitor.isCanceled()) {
190                                        return Collections.EMPTY_LIST;
191                                }
192                                ref = (Reference) iter.next();
193                                member = ref.getResolvedReference();
194                                if(member == null) {
195                                        continue;
196                                }
197                                localmonitor.setTaskName(MessageFormat.format(SearchMessages.ApiSearchEngine_searching_for_use_from, new String[] {fRequestorContext, type.getName()}));
198                                if(requestor.acceptReference(ref)) {
199                                        refs.add(ref);
200                                }
201                                localmonitor.worked(1);
202                        }
203                }
204                finally {
205                        localmonitor.done();
206                }
207                return refs;
208        }
209        
210        /**
211         * Searches for all accepted {@link IReference}s from the given {@link IApiElement}
212         * @param requestor
213         * @param element
214         * @param monitor
215         * @return the collection of accepted {@link IReference}s or an empty list, never <code>null</code>
216         * @throws CoreException
217         */
218        private void searchReferences(IApiSearchRequestor requestor, IApiElement element, IApiSearchReporter reporter, IProgressMonitor monitor) throws CoreException {
219                List refs = null;
220                SubMonitor localmonitor = SubMonitor.convert(monitor, 3);
221                try {
222                        switch(element.getType()) {
223                                case IApiElement.TYPE: {
224                                        if(localmonitor.isCanceled()) {
225                                                reporter.reportResults(element, NO_REFERENCES);
226                                        }
227                                        IApiType type = (IApiType) element;
228                                        refs = acceptReferences(requestor, 
229                                                        type, 
230                                                        getResolvedReferences(requestor, type, localmonitor.newChild(1)),
231                                                        localmonitor.newChild(1));
232                                        reporter.reportResults(element, (IReference[]) refs.toArray(new IReference[refs.size()]));
233                                        break;
234                                }
235                                case IApiElement.COMPONENT: {
236                                        if(localmonitor.isCanceled()) {
237                                                reporter.reportResults(element, NO_REFERENCES);
238                                        }
239                                        ReferenceExtractor visitor = new ReferenceExtractor(requestor, reporter, element, localmonitor.newChild(1));
240                                        IApiComponent comp = (IApiComponent) element;
241                                        comp.accept(visitor);
242                                        comp.close();
243                                        Util.updateMonitor(localmonitor, 1);
244                                        break;
245                                }
246                                case IApiElement.FIELD:
247                                case IApiElement.METHOD: {
248                                        if(localmonitor.isCanceled()) {
249                                                reporter.reportResults(element, NO_REFERENCES);
250                                        }
251                                        IApiMember member = (IApiMember) element;
252                                        IApiType type = member.getEnclosingType();
253                                        if(type != null) {
254                                                refs = acceptReferences(requestor, 
255                                                                type, 
256                                                                getResolvedReferences(requestor, type, localmonitor.newChild(1)), 
257                                                                localmonitor.newChild(1));
258                                        }
259                                        if (refs != null) {
260                                                reporter.reportResults(element, (IReference[]) refs.toArray(new IReference[refs.size()]));
261                                        }
262                                        break;
263                                }
264                        }
265                        Util.updateMonitor(localmonitor, 1);
266                }
267                finally {
268                        localmonitor.done();
269                }
270        }
271        
272        /**
273         * Searches for all of the use of API or internal code from the given 
274         * {@link IApiComponent} within the given {@link IApiBaseline}
275         * 
276         * @param baseline the baseline to search within
277         * @param requestor the requestor to use for the search
278         * @param reporter the reporter to use when reporting any search results to the user
279         * @param monitor the monitor to report progress to
280         * @throws CoreException if the search fails
281         */
282        public void search(IApiBaseline baseline, IApiSearchRequestor requestor, IApiSearchReporter reporter, IProgressMonitor monitor) throws CoreException {
283                if(baseline == null || reporter == null || requestor == null) {
284                        return;
285                }
286                IApiScope scope = requestor.getScope();
287                if(scope == null) {
288                        return;
289                }
290                fRequestorContext = SearchMessages.ApiSearchEngine_api_internal;
291                if(requestor.includesAPI() && !requestor.includesInternal()) {
292                        fRequestorContext = SearchMessages.ApiSearchEngine_api;
293                }
294                if(requestor.includesInternal() && !requestor.includesAPI()) {
295                        fRequestorContext = SearchMessages.ApiSearchEngine_internal;
296                }
297                IApiElement[] scopeelements = scope.getApiElements();
298                SubMonitor localmonitor = SubMonitor.convert(monitor, 
299                                MessageFormat.format(SearchMessages.ApiSearchEngine_searching_projects, new String[] {fRequestorContext}), scopeelements.length*2+1);
300                try {
301                        long start = System.currentTimeMillis();
302                        long loopstart = 0;
303                        String taskname = null;
304                        MultiStatus mstatus = null;
305                        for (int i = 0; i < scopeelements.length; i++) {
306                                try {
307                                        taskname = MessageFormat.format(SearchMessages.ApiSearchEngine_searching_project, new String[] {scopeelements[i].getApiComponent().getId(), fRequestorContext});
308                                        localmonitor.setTaskName(taskname);
309                                        if(DEBUG) {
310                                                loopstart = System.currentTimeMillis();
311                                                System.out.println("Searching "+scopeelements[i].getApiComponent().getId()+"..."); //$NON-NLS-1$ //$NON-NLS-2$
312                                        }
313                                        searchReferences(requestor, scopeelements[i], reporter, localmonitor.newChild(1));
314                                        localmonitor.setTaskName(taskname);
315                                        if(localmonitor.isCanceled()) {
316                                                reporter.reportResults(scopeelements[i], NO_REFERENCES);
317                                                return;
318                                        }
319                                        localmonitor.worked(1);
320                                        if(DEBUG) {
321                                                System.out.println(Math.round((((float)(i+1))/scopeelements.length)*100)+"% done in "+(System.currentTimeMillis()-loopstart)+" ms"); //$NON-NLS-1$ //$NON-NLS-2$
322                                        }
323                                }
324                                catch(CoreException ce) {
325                                        if(mstatus == null) {
326                                                mstatus = new MultiStatus(ApiPlugin.PLUGIN_ID, IStatus.ERROR, null, null);
327                                        }
328                                        mstatus.add(new Status(IStatus.ERROR, ApiPlugin.PLUGIN_ID, ce.getMessage(), ce));
329                                }
330                        }
331                        if(DEBUG) {
332                                System.out.println("Total Search Time: "+((System.currentTimeMillis()-start)/1000)+" seconds");  //$NON-NLS-1$//$NON-NLS-2$
333                        }
334                        if(mstatus != null) {
335                                throw new CoreException(mstatus);
336                        }
337                }
338                finally {
339                        localmonitor.done();
340                }
341        }
342}

[all classes][org.eclipse.pde.api.tools.internal.provisional.search]
EMMA 2.0.5312 EclEmma Fix 1 (C) Vladimir Roubtsov