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

COVERAGE SUMMARY FOR SOURCE FILE [SystemApiDetector.java]

nameclass, %method, %block, %line, %
SystemApiDetector.java100% (1/1)38%  (5/13)15%  (119/778)17%  (34.6/203)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class SystemApiDetector100% (1/1)38%  (5/13)15%  (119/778)17%  (34.6/203)
getDisplay (IApiMember, boolean): String 0%   (0/1)0%   (0/55)0%   (0/16)
getElementType (IReference): int 0%   (0/1)0%   (0/14)0%   (0/6)
getMessageArgs (IReference): String [] 0%   (0/1)0%   (0/129)0%   (0/27)
getProblemFlags (IReference): int 0%   (0/1)0%   (0/17)0%   (0/7)
getProblemKind (): int 0%   (0/1)0%   (0/2)0%   (0/1)
getQualifiedMessageArgs (IReference): String [] 0%   (0/1)0%   (0/128)0%   (0/27)
getSeverityKey (): String 0%   (0/1)0%   (0/2)0%   (0/1)
getSourceRange (IType, IDocument, IReference): Position 0%   (0/1)0%   (0/196)0%   (0/50)
isProblem (IReference): boolean 100% (1/1)35%  (38/109)34%  (10/29)
createProblems (): List 100% (1/1)40%  (24/60)39%  (7/18)
considerReference (IReference): boolean 100% (1/1)85%  (52/61)82%  (15.6/19)
SystemApiDetector (): void 100% (1/1)100% (3/3)100% (1/1)
getReferenceKinds (): int 100% (1/1)100% (2/2)100% (1/1)

1/*******************************************************************************
2 * Copyright (c) 2008, 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.builder;
12 
13import java.util.HashMap;
14import java.util.Iterator;
15import java.util.LinkedList;
16import java.util.List;
17import java.util.Map;
18 
19import org.eclipse.core.runtime.CoreException;
20import org.eclipse.jdt.core.IJavaProject;
21import org.eclipse.jdt.core.ISourceRange;
22import org.eclipse.jdt.core.IType;
23import org.eclipse.jdt.core.Signature;
24import org.eclipse.jface.text.BadLocationException;
25import org.eclipse.jface.text.IDocument;
26import org.eclipse.jface.text.Position;
27import org.eclipse.osgi.service.resolver.BundleDescription;
28import org.eclipse.osgi.service.resolver.ImportPackageSpecification;
29import org.eclipse.pde.api.tools.internal.model.BundleApiComponent;
30import org.eclipse.pde.api.tools.internal.model.PluginProjectApiComponent;
31import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
32import org.eclipse.pde.api.tools.internal.provisional.ProfileModifiers;
33import org.eclipse.pde.api.tools.internal.provisional.builder.IReference;
34import org.eclipse.pde.api.tools.internal.provisional.descriptors.IElementDescriptor;
35import org.eclipse.pde.api.tools.internal.provisional.model.IApiBaseline;
36import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent;
37import org.eclipse.pde.api.tools.internal.provisional.model.IApiElement;
38import org.eclipse.pde.api.tools.internal.provisional.model.IApiField;
39import org.eclipse.pde.api.tools.internal.provisional.model.IApiMember;
40import org.eclipse.pde.api.tools.internal.provisional.model.IApiMethod;
41import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblem;
42import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblemTypes;
43import org.eclipse.pde.api.tools.internal.util.Signatures;
44import org.eclipse.pde.api.tools.internal.util.Util;
45 
46/**
47 * Detects references to fields, methods and types that are not available for a specific EE.
48 * 
49 * @since 1.1
50 */
51public class SystemApiDetector extends AbstractProblemDetector {
52        
53        private Map referenceEEs;
54        
55        /**
56         * Constructor
57         */
58        public SystemApiDetector() {}
59        
60        /* (non-Javadoc)
61         * @see org.eclipse.pde.api.tools.internal.builder.AbstractProblemDetector#getElementType(org.eclipse.pde.api.tools.internal.provisional.builder.IReference)
62         */
63        protected int getElementType(IReference reference) {
64                IApiMember member = reference.getMember();
65                switch(member.getType()) {
66                        case IApiElement.TYPE :
67                                return IElementDescriptor.TYPE;
68                        case IApiElement.METHOD :
69                                return IElementDescriptor.METHOD;
70                        case IApiElement.FIELD :
71                                return IElementDescriptor.FIELD;
72                        default :
73                                return 0;
74                }
75        }
76 
77        /* (non-Javadoc)
78         * @see org.eclipse.pde.api.tools.internal.builder.AbstractProblemDetector#getMessageArgs(org.eclipse.pde.api.tools.internal.provisional.builder.IReference)
79         */
80        protected String[] getMessageArgs(IReference reference)
81                        throws CoreException {
82                IApiMember member = reference.getMember();
83                String eeValue = ProfileModifiers.getName(((Integer) this.referenceEEs.get(reference)).intValue());
84                String simpleTypeName = Signatures.getSimpleTypeName(reference.getReferencedTypeName());
85                if (simpleTypeName.indexOf('$') != -1) {
86                        simpleTypeName = simpleTypeName.replace('$', '.');
87                }
88                switch (reference.getReferenceType()) {
89                        case IReference.T_TYPE_REFERENCE: {
90                                return new String[] {
91                                                getDisplay(member, false),
92                                                simpleTypeName,
93                                                eeValue,
94                                };
95                        }
96                        case IReference.T_FIELD_REFERENCE:{
97                                return new String[] {
98                                                getDisplay(member, false),
99                                                simpleTypeName,
100                                                reference.getReferencedMemberName(),
101                                                eeValue,
102                                };
103                        }
104                        case IReference.T_METHOD_REFERENCE:{
105                                String referenceMemberName = reference.getReferencedMemberName();
106                                if (Util.isConstructor(referenceMemberName)) {
107                                        return new String[] {
108                                                        getDisplay(member, false),
109                                                        Signature.toString(reference.getReferencedSignature(), simpleTypeName, null, false, false),
110                                                        eeValue,
111                                        };
112                                } else {
113                                        return new String[] {
114                                                        getDisplay(member, false),
115                                                        simpleTypeName,
116                                                        Signature.toString(reference.getReferencedSignature(), referenceMemberName, null, false, false),
117                                                        eeValue,
118                                        };
119                                }
120                        }
121                }
122                return null;
123        }
124 
125        /**
126         * Returns the signature to display for found problems
127         * @param member the member to get the signature from
128         * @param qualified if the returned signature should be type-qualified or not
129         * @return
130         * @throws CoreException
131         */
132        private String getDisplay(IApiMember member, boolean qualified) throws CoreException {
133                String typeName = qualified ? getTypeName(member) : getSimpleTypeName(member);
134                if (typeName.indexOf('$') != -1) {
135                        typeName = typeName.replace('$', '.');
136                }
137                switch(member.getType()) {
138                        case IApiElement.FIELD : {
139                                StringBuffer buffer = new StringBuffer();
140                                IApiField field = (IApiField) member;
141                                buffer
142                                        .append(typeName)
143                                        .append('.')
144                                        .append(field.getName());
145                                return String.valueOf(buffer);
146                        }
147                        case IApiElement.METHOD : {
148                                // reference in a method declaration
149                                IApiMethod method = (IApiMethod) member;
150                                if(qualified) {
151                                        return Signatures.getMethodSignature(method);
152                                }
153                                return Signatures.getQualifiedMethodSignature(method);
154                        }
155                }
156                return typeName;
157        }
158        
159        /* (non-Javadoc)
160         * @see org.eclipse.pde.api.tools.internal.builder.AbstractProblemDetector#getProblemFlags(org.eclipse.pde.api.tools.internal.provisional.builder.IReference)
161         */
162        protected int getProblemFlags(IReference reference) {
163                switch(reference.getReferenceType()) {
164                        case IReference.T_TYPE_REFERENCE : {
165                                return IApiProblem.NO_FLAGS;
166                        }
167                        case IReference.T_METHOD_REFERENCE : {
168                                if (Util.isConstructor(reference.getReferencedMemberName())) {
169                                        return IApiProblem.CONSTRUCTOR_METHOD;
170                                }
171                                return IApiProblem.METHOD;
172                        }
173                        case IReference.T_FIELD_REFERENCE : {
174                                return IApiProblem.FIELD;
175                        }
176                        default : {
177                                return IApiProblem.NO_FLAGS;
178                        }
179                }
180        }
181 
182        /* (non-Javadoc)
183         * @see org.eclipse.pde.api.tools.internal.builder.AbstractProblemDetector#getProblemKind()
184         */
185        protected int getProblemKind() {
186                return IApiProblem.INVALID_REFERENCE_IN_SYSTEM_LIBRARIES;
187        }
188 
189        /* (non-Javadoc)
190         * @see org.eclipse.pde.api.tools.internal.builder.AbstractProblemDetector#getQualifiedMessageArgs(org.eclipse.pde.api.tools.internal.provisional.builder.IReference)
191         */
192        protected String[] getQualifiedMessageArgs(IReference reference) throws CoreException {
193                IApiMember member = reference.getMember();
194                String eeValue = ProfileModifiers.getName(((Integer) this.referenceEEs.get(reference)).intValue());
195                String simpleTypeName = reference.getReferencedTypeName();
196                if (simpleTypeName.indexOf('$') != -1) {
197                        simpleTypeName = simpleTypeName.replace('$', '.');
198                }
199                switch (reference.getReferenceType()) {
200                        case IReference.T_TYPE_REFERENCE: {
201                                return new String[] {
202                                                getDisplay(member, false),
203                                                simpleTypeName,
204                                                eeValue,
205                                };
206                        }
207                        case IReference.T_FIELD_REFERENCE:{
208                                return new String[] {
209                                                getDisplay(member, false),
210                                                simpleTypeName,
211                                                reference.getReferencedMemberName(),
212                                                eeValue,
213                                };
214                        }
215                        case IReference.T_METHOD_REFERENCE:{
216                                String referenceMemberName = reference.getReferencedMemberName();
217                                if (Util.isConstructor(referenceMemberName)) {
218                                        return new String[] {
219                                                        getDisplay(member, false),
220                                                        Signature.toString(reference.getReferencedSignature(), simpleTypeName, null, false, false),
221                                                        eeValue,
222                                        };
223                                } else {
224                                        return new String[] {
225                                                        getDisplay(member, false),
226                                                        simpleTypeName,
227                                                        Signature.toString(reference.getReferencedSignature(), referenceMemberName, null, false, false),
228                                                        eeValue,
229                                        };
230                                }
231                        }
232                }
233                return null;
234        }
235 
236        /* (non-Javadoc)
237         * @see org.eclipse.pde.api.tools.internal.builder.AbstractProblemDetector#getSeverityKey()
238         */
239        protected String getSeverityKey() {
240                return IApiProblemTypes.INVALID_REFERENCE_IN_SYSTEM_LIBRARIES;
241        }
242 
243        /* (non-Javadoc)
244         * @see org.eclipse.pde.api.tools.internal.builder.AbstractProblemDetector#getSourceRange(org.eclipse.jdt.core.IType, org.eclipse.jface.text.IDocument, org.eclipse.pde.api.tools.internal.provisional.builder.IReference)
245         */
246        protected Position getSourceRange(IType type, IDocument document, IReference reference) throws CoreException, BadLocationException {
247                switch(reference.getReferenceType()) {
248                        case IReference.T_TYPE_REFERENCE : {
249                                int linenumber = reference.getLineNumber();
250                                if (linenumber > 0) {
251                                        linenumber--;
252                                }
253                                if (linenumber > 0) {
254                                        int offset = document.getLineOffset(linenumber);
255                                        String line = document.get(offset, document.getLineLength(linenumber));
256                                        String qname = reference.getReferencedTypeName().replace('$', '.');
257                                        int first = line.indexOf(qname);
258                                        if(first < 0) {
259                                                qname = Signatures.getSimpleTypeName(reference.getReferencedTypeName());
260                                                qname = qname.replace('$', '.');
261                                                first = line.indexOf(qname);
262                                        }
263                                        Position pos = null;
264                                        if(first > -1) {
265                                                pos = new Position(offset + first, qname.length());
266                                        }
267                                        else {
268                                                //optimistically select the whole line since we can't find the correct variable name and we can't just select
269                                                //the first occurrence
270                                                pos = new Position(offset, line.length());
271                                        }
272                                        return pos;
273                                } else {
274                                        IApiMember apiMember = reference.getMember();
275                                        switch(apiMember.getType()) {
276                                                case IApiElement.FIELD : {
277                                                        IApiField field = (IApiField) reference.getMember();
278                                                        return getSourceRangeForField(type, reference, field);
279                                                }
280                                                case IApiElement.METHOD : {
281                                                        // reference in a method declaration
282                                                        IApiMethod method = (IApiMethod) reference.getMember();
283                                                        return getSourceRangeForMethod(type, reference, method);
284                                                }
285                                        }
286                                        // reference in a type declaration
287                                        ISourceRange range = type.getNameRange();
288                                        Position pos = null;
289                                        if(range != null) {
290                                                pos = new Position(range.getOffset(), range.getLength());
291                                        }
292                                        if(pos == null) {
293                                                return defaultSourcePosition(type, reference);
294                                        }
295                                        return pos;
296                                }
297                        }
298                        case IReference.T_FIELD_REFERENCE : {
299                                int linenumber = reference.getLineNumber();
300                                if (linenumber > 0) {
301                                        return getFieldNameRange(reference.getReferencedTypeName(), reference.getReferencedMemberName(), document, reference);
302                                }
303                                // reference in a field declaration
304                                IApiField field = (IApiField) reference.getMember();
305                                return getSourceRangeForField(type, reference, field);
306                        }
307                        case IReference.T_METHOD_REFERENCE : {
308                                if (reference.getLineNumber() >= 0) {
309                                        String referenceMemberName = reference.getReferencedMemberName();
310                                        String methodName = null;
311                                        boolean isConstructor = Util.isConstructor(referenceMemberName);
312                                        if (isConstructor) {
313                                                methodName = Signatures.getSimpleTypeName(reference.getReferencedTypeName().replace('$', '.'));
314                                        } else {
315                                                methodName = referenceMemberName;
316                                        }
317                                        Position pos = getMethodNameRange(isConstructor, methodName, document, reference);
318                                        if(pos == null) {
319                                                return defaultSourcePosition(type, reference);
320                                        }
321                                        return pos;
322                                }
323                                // reference in a method declaration
324                                IApiMethod method = (IApiMethod) reference.getMember();
325                                return getSourceRangeForMethod(type, reference, method);
326                        }
327                        default :
328                                return null;
329                }
330        }
331 
332        /* (non-Javadoc)
333         * @see org.eclipse.pde.api.tools.internal.search.AbstractProblemDetector#isProblem(org.eclipse.pde.api.tools.internal.provisional.model.IReference)
334         */
335        protected boolean isProblem(IReference reference) {
336                // the reference must be in the system library
337                try {
338                        IApiMember member = reference.getMember();
339                        IApiComponent apiComponent = member.getApiComponent();
340                        String[] lowestEEs = apiComponent.getLowestEEs();
341                        if (lowestEEs == null) {
342                                // this should not be true for Eclipse bundle as they should always have a EE set
343                                return false;
344                        }
345                        loop: for (int i = 0, max = lowestEEs.length; i < max; i++) {
346                                String lowestEE = lowestEEs[i];
347                                int eeValue = ProfileModifiers.getValue(lowestEE); 
348                                if (eeValue == ProfileModifiers.NO_PROFILE_VALUE) {
349                                        return false;
350                                }
351                                if (!((Reference) reference).resolve(eeValue)) {
352                                        /*
353                                         * Make sure that the resolved reference doesn't below to one of the imported package of
354                                         * the current component
355                                         */
356                                        if (apiComponent instanceof BundleApiComponent) {
357                                                BundleDescription bundle = ((BundleApiComponent)apiComponent).getBundleDescription();
358                                                ImportPackageSpecification[] importPackages = bundle.getImportPackages();
359                                                String referencedTypeName = reference.getReferencedTypeName();
360                                                int index = referencedTypeName.lastIndexOf('.');
361                                                String packageName = referencedTypeName.substring(0, index);
362                                                for (int j = 0, max2 = importPackages.length; j < max2; j++) {
363                                                        ImportPackageSpecification importPackageSpecification = importPackages[j];
364                                                        // get the IPackageDescriptor for the element descriptor
365                                                        String importPackageName = importPackageSpecification.getName();
366                                                        if (importPackageName.equals(packageName)) {
367                                                                continue loop;
368                                                        }
369                                                }
370                                        }
371                                        if (this.referenceEEs == null) {
372                                                this.referenceEEs = new HashMap(3);
373                                        }
374                                        this.referenceEEs.put(reference, new Integer(eeValue));
375                                        return true;
376                                }
377                        }
378                } catch (CoreException e) {
379                        ApiPlugin.log(e);
380                }
381                return false;
382        }
383        
384        /* (non-Javadoc)
385         * @see org.eclipse.pde.api.tools.internal.provisional.builder.IApiProblemDetector#considerReference(org.eclipse.pde.api.tools.internal.provisional.builder.IReference)
386         */
387        public boolean considerReference(IReference reference) {
388                try {
389                        IApiComponent apiComponent = reference.getMember().getApiComponent();
390                        IApiBaseline baseline = apiComponent.getBaseline();
391                        if (baseline == null) return false;
392                        String referencedTypeName = reference.getReferencedTypeName();
393                        // extract the package name
394                        int index = referencedTypeName.lastIndexOf('.');
395                        if (index == -1) return false;
396                        String substring = referencedTypeName.substring(0, index);
397                        IApiComponent[] resolvePackages = baseline.resolvePackage(apiComponent, substring);
398                        switch(resolvePackages.length) {
399                                case 1 : {
400                                        if (resolvePackages[0].isSystemComponent()) {
401                                                switch(reference.getReferenceKind()) {
402                                                        case IReference.REF_OVERRIDE :
403                                                        case IReference.REF_CONSTANTPOOL :
404                                                                return false;
405                                                }
406                                                ((Reference) reference).setResolveStatus(false);
407                                                retainReference(reference);
408                                                return true;
409                                        }
410                                }
411                        }
412                } catch (CoreException e) {
413                        ApiPlugin.log(e);
414                }
415                return false;
416        }
417 
418        /* (non-Javadoc)
419         * @see org.eclipse.pde.api.tools.internal.provisional.builder.IApiProblemDetector#getReferenceKinds()
420         */
421        public int getReferenceKinds() {
422                return IReference.MASK_REF_ALL & ~IReference.REF_OVERRIDE;
423        }
424        /* (non-Javadoc)
425         * @see org.eclipse.pde.api.tools.internal.provisional.search.IApiProblemDetector#createProblems()
426         */
427        public List createProblems() {
428                List references = getRetainedReferences();
429                List problems = new LinkedList();
430                Iterator iterator = references.iterator();
431                while (iterator.hasNext()) {
432                        IReference reference = (IReference) iterator.next();
433                        if (isProblem(reference)) {
434                                try {
435                                        IApiProblem problem = null;
436                                        IApiComponent component = reference.getMember().getApiComponent();
437                                        if (component instanceof PluginProjectApiComponent) {
438                                                PluginProjectApiComponent ppac = (PluginProjectApiComponent) component;
439                                                IJavaProject project = ppac.getJavaProject();
440                                                problem = createProblem(reference, project);
441                                        } else {
442                                                problem = createProblem(reference);
443                                        }
444                                        if (problem != null) {
445                                                problems.add(problem);
446                                        }
447                                } catch (CoreException e) {
448                                        ApiPlugin.log(e.getStatus());
449                                }
450                        }
451                }
452                return problems;
453        }
454}

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