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

COVERAGE SUMMARY FOR SOURCE FILE [UseScanParser.java]

nameclass, %method, %block, %line, %
UseScanParser.java0%   (0/4)0%   (0/22)0%   (0/716)0%   (0/174)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class UseScanParser0%   (0/1)0%   (0/15)0%   (0/425)0%   (0/110)
UseScanParser (): void 0%   (0/1)0%   (0/12)0%   (0/4)
endMember (): void 0%   (0/1)0%   (0/12)0%   (0/4)
endReferencingComponent (): void 0%   (0/1)0%   (0/12)0%   (0/4)
endTargetComponent (): void 0%   (0/1)0%   (0/12)0%   (0/4)
enterReferenceKind (int): void 0%   (0/1)0%   (0/4)0%   (0/2)
enterReferencingComponent (IComponentDescriptor): void 0%   (0/1)0%   (0/35)0%   (0/12)
enterTargetComponent (IComponentDescriptor): void 0%   (0/1)0%   (0/34)0%   (0/12)
enterTargetMember (IMemberDescriptor): void 0%   (0/1)0%   (0/27)0%   (0/6)
enterVisibility (int): void 0%   (0/1)0%   (0/4)0%   (0/2)
getDirectories (File): File [] 0%   (0/1)0%   (0/9)0%   (0/2)
getParser (): SAXParser 0%   (0/1)0%   (0/19)0%   (0/6)
getTypeFromFileName (File): int 0%   (0/1)0%   (0/18)0%   (0/5)
parse (String, IProgressMonitor, UseScanVisitor): void 0%   (0/1)0%   (0/176)0%   (0/39)
setReference (IMemberDescriptor, int): void 0%   (0/1)0%   (0/19)0%   (0/3)
sort (File []): File [] 0%   (0/1)0%   (0/32)0%   (0/5)
     
class UseScanParser$10%   (0/1)0%   (0/2)0%   (0/18)0%   (0/3)
UseScanParser$1 (UseScanParser): void 0%   (0/1)0%   (0/6)0%   (0/2)
accept (File): boolean 0%   (0/1)0%   (0/12)0%   (0/1)
     
class UseScanParser$20%   (0/1)0%   (0/2)0%   (0/16)0%   (0/3)
UseScanParser$2 (UseScanParser): void 0%   (0/1)0%   (0/6)0%   (0/2)
accept (File): boolean 0%   (0/1)0%   (0/10)0%   (0/1)
     
class UseScanParser$ReferenceHandler0%   (0/1)0%   (0/3)0%   (0/257)0%   (0/61)
UseScanParser$ReferenceHandler (UseScanParser, int): void 0%   (0/1)0%   (0/12)0%   (0/4)
getIdVersion (String): String [] 0%   (0/1)0%   (0/55)0%   (0/10)
startElement (String, String, String, Attributes): void 0%   (0/1)0%   (0/190)0%   (0/47)

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.search;
12 
13import java.io.File;
14import java.io.FileFilter;
15import java.io.IOException;
16import java.util.ArrayList;
17import java.util.Collections;
18import java.util.List;
19 
20import javax.xml.parsers.ParserConfigurationException;
21import javax.xml.parsers.SAXParser;
22import javax.xml.parsers.SAXParserFactory;
23 
24import org.eclipse.core.runtime.IProgressMonitor;
25import org.eclipse.core.runtime.SubMonitor;
26import org.eclipse.osgi.util.NLS;
27import org.eclipse.pde.api.tools.internal.IApiXmlConstants;
28import org.eclipse.pde.api.tools.internal.provisional.Factory;
29import org.eclipse.pde.api.tools.internal.provisional.builder.IReference;
30import org.eclipse.pde.api.tools.internal.provisional.descriptors.IComponentDescriptor;
31import org.eclipse.pde.api.tools.internal.provisional.descriptors.IMemberDescriptor;
32import org.eclipse.pde.api.tools.internal.util.Util;
33import org.xml.sax.Attributes;
34import org.xml.sax.SAXException;
35import org.xml.sax.helpers.DefaultHandler;
36 
37/**
38 * Parses a use scan (XML) to visit a {@link UseScanVisitor}
39 */
40public class UseScanParser {
41        
42        private UseScanVisitor visitor;
43        
44        private IComponentDescriptor targetComponent;
45        private IComponentDescriptor referencingComponent;
46        private IMemberDescriptor targetMember;
47        private int referenceKind;
48        private int visibility;
49        
50        private boolean visitReferencingComponent = true;
51        private boolean visitMembers = true;
52        private boolean visitReferences = true;
53 
54        /**
55         * Handler to resolve a reference
56         */
57        class ReferenceHandler extends DefaultHandler {
58 
59                // type of file being analyzed - type reference, method reference, field reference
60                private int type = 0;
61 
62                /**
63                 * Constructor
64                 * 
65                 * @param type one of IReference.T_TYPE_REFERENCE, IReference.T_METHOD_REFERENCE,
66                 *                         IReference.T_FIELD_REFERENCE
67                 */
68                public ReferenceHandler(int type) {
69                        this.type = type;
70                }
71                
72                private String[] getIdVersion(String value) {
73                        int index = value.indexOf(' ');
74                        if (index > 0) {
75                                String id = value.substring(0, index);
76                                String version = value.substring(index + 1);
77                                if (version.startsWith("(")) { //$NON-NLS-1$
78                                        version = version.substring(1);
79                                        if (version.endsWith(")")) { //$NON-NLS-1$
80                                                version = version.substring(0,version.length() - 2);
81                                        }
82                                }
83                                return new String[]{id, version};
84                        }
85                        return new String[]{value, null};
86                }
87                
88                
89                /* (non-Javadoc)
90                 * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
91                 */
92                public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
93                        if (IApiXmlConstants.REFERENCES.equals(name)) {
94                                String target = attributes.getValue(IApiXmlConstants.ATTR_REFEREE);
95                                String source = attributes.getValue(IApiXmlConstants.ATTR_ORIGIN);
96                                String[] idv = getIdVersion(target);
97                                enterTargetComponent(Factory.componentDescriptor(idv[0], idv[1]));
98                                idv = getIdVersion(source);
99                                enterReferencingComponent(Factory.componentDescriptor(idv[0], idv[1]));
100                                String visString = attributes.getValue(IApiXmlConstants.ATTR_REFERENCE_VISIBILITY);
101                                try {
102                                        int vis = Integer.parseInt(visString);
103                                        enterVisibility(vis);
104                                } catch (NumberFormatException e) {
105                                        // TODO:
106                                        enterVisibility(-1);
107                                        System.out.println("Internal error: invalid visibility: " + visString); //$NON-NLS-1$
108                                }
109                        } else if(IApiXmlConstants.ELEMENT_TARGET.equals(name)) {
110                                String qName = attributes.getValue(IApiXmlConstants.ATTR_TYPE);
111                                String memberName = attributes.getValue(IApiXmlConstants.ATTR_MEMBER_NAME);
112                                String signature = attributes.getValue(IApiXmlConstants.ATTR_SIGNATURE);
113                                IMemberDescriptor member = null;
114                                switch (type) {
115                                        case IReference.T_TYPE_REFERENCE:
116                                                member = Factory.typeDescriptor(qName);
117                                                break;
118                                        case IReference.T_METHOD_REFERENCE:
119                                                member = Factory.methodDescriptor(qName, memberName, signature);
120                                                break;
121                                        case IReference.T_FIELD_REFERENCE:
122                                                member = Factory.fieldDescriptor(qName, memberName);
123                                                break;
124                                }
125                                enterTargetMember(member);
126                        } else if (IApiXmlConstants.REFERENCE_KIND.equals(name)) {
127                                String value = attributes.getValue(IApiXmlConstants.ATTR_KIND);
128                                if (value != null) {
129                                        try {
130                                                enterReferenceKind(Integer.parseInt(value));
131                                        } catch (NumberFormatException e) {
132                                                // ERROR
133                                                System.out.println(NLS.bind("Internal error: invalid reference kind: {0}", value)); //$NON-NLS-1$
134                                        }
135                                }
136                        } else if (IApiXmlConstants.ATTR_REFERENCE.equals(name)) {
137                                String qName = attributes.getValue(IApiXmlConstants.ATTR_TYPE);
138                                String memberName = attributes.getValue(IApiXmlConstants.ATTR_MEMBER_NAME);
139                                String signature = attributes.getValue(IApiXmlConstants.ATTR_SIGNATURE);
140                                IMemberDescriptor origin = null;
141                                if (signature != null) {
142                                        origin = Factory.methodDescriptor(qName, memberName, signature);
143                                } else if (memberName != null) {
144                                        origin = Factory.fieldDescriptor(qName, memberName);
145                                } else {
146                                        origin = Factory.typeDescriptor(qName);
147                                }
148                                String line = attributes.getValue(IApiXmlConstants.ATTR_LINE_NUMBER);
149                                try {
150                                        int num = Integer.parseInt(line);
151                                        setReference(origin, num);
152                                } catch (NumberFormatException e) {
153                                        // TODO:
154                                        System.out.println("Internal error: invalid line number: " + line); //$NON-NLS-1$
155                                }
156                        }
157                }
158        }
159        
160        /**
161         * Resolves references from an API use scan rooted at the specified location in the file
162         * system in the given baseline.
163         * 
164         * @param xmlLocation root of API use scan (XML directory).
165         * @param monitor progress monitor
166         * @param baseline API baseline to resolve references in
167         */
168        public void parse(String xmlLocation, IProgressMonitor monitor, UseScanVisitor usv) throws Exception {
169                if (xmlLocation == null) {
170                        throw new Exception(SearchMessages.missing_xml_files_location);
171                }
172                visitor = usv;
173                File reportsRoot = new File(xmlLocation);
174                if (!reportsRoot.exists() || !reportsRoot.isDirectory()) {
175                        throw new Exception(NLS.bind(SearchMessages.invalid_directory_name, xmlLocation));
176                }
177                SubMonitor localmonitor = SubMonitor.convert(monitor, SearchMessages.UseScanParser_parsing, 8);
178                localmonitor.setTaskName(SearchMessages.UseReportConverter_collecting_dir_info);
179                File[] referees = getDirectories(reportsRoot);
180                Util.updateMonitor(localmonitor, 1);
181                File[] origins = null;
182                File[] xmlfiles = null;
183                SubMonitor smonitor = localmonitor.newChild(7);
184                smonitor.setWorkRemaining(referees.length);
185                visitor.visitScan();
186                try {
187                        SAXParser parser = getParser();
188                        for (int i = 0; i < referees.length; i++) {
189                                smonitor.setTaskName(NLS.bind(SearchMessages.UseScanParser_analyzing_references, new String[] {referees[i].getName()}));
190                                origins = getDirectories(referees[i]);
191                                origins = sort(origins); // sort to visit in determined order
192                                for (int j = 0; j < origins.length; j++) {
193                                        xmlfiles = Util.getAllFiles(origins[j], new FileFilter() {
194                                                public boolean accept(File pathname) {
195                                                        return pathname.isDirectory() || pathname.getName().endsWith(".xml"); //$NON-NLS-1$
196                                                }
197                                        });
198                                        if (xmlfiles != null) {
199                                                xmlfiles = sort(xmlfiles); // sort to visit in determined order
200                                                for (int k = 0; k < xmlfiles.length; k++) {
201                                                        try {
202                                                                ReferenceHandler handler = new ReferenceHandler(getTypeFromFileName(xmlfiles[k]));
203                                                                parser.parse(xmlfiles[k], handler);
204                                                        } 
205                                                        catch (SAXException e) {}
206                                                        catch (IOException e) {}
207                                                }
208                                        }
209                                }
210                                Util.updateMonitor(smonitor, 1);
211                        }
212                        endMember();
213                        endReferencingComponent();
214                        endTargetComponent();
215                }
216                finally {
217                        visitor.endVisitScan();
218                        if(!smonitor.isCanceled()) {
219                                smonitor.done();
220                        }
221                }                
222        }
223        
224        /**
225         * Returns a parser
226         * @return default parser
227         * @throws Exception forwarded general exception that can be trapped in Ant builds
228         */
229        SAXParser getParser() throws Exception {
230                SAXParserFactory factory = SAXParserFactory.newInstance();
231                try {
232                        return factory.newSAXParser();
233                } catch (ParserConfigurationException pce) {
234                        throw new Exception(SearchMessages.UseReportConverter_pce_error_getting_parser, pce);
235                } catch (SAXException se) {
236                        throw new Exception(SearchMessages.UseReportConverter_se_error_parser_handle, se);
237                }
238        }        
239        
240        /**
241         * Returns all the child directories form the given directory
242         * @param file
243         * @return
244         */
245        private File[] getDirectories(File file) {
246                File[] directories = file.listFiles(new FileFilter() {
247                        public boolean accept(File pathname) {
248                                return pathname.isDirectory() && !pathname.isHidden();
249                        }
250                });
251                return directories;
252        }        
253        
254        /**
255         * Returns the {@link IReference} type from the file name
256         * @param xmlfile
257         * @return the type from the file name
258         */
259        private int getTypeFromFileName(File xmlfile) {
260                if(xmlfile.getName().indexOf(XmlReferenceDescriptorWriter.TYPE_REFERENCES) > -1) {
261                        return IReference.T_TYPE_REFERENCE;
262                }
263                if(xmlfile.getName().indexOf(XmlReferenceDescriptorWriter.METHOD_REFERENCES) > -1) {
264                        return IReference.T_METHOD_REFERENCE;
265                }
266                return IReference.T_FIELD_REFERENCE;
267        }
268        
269        public void enterTargetComponent(IComponentDescriptor component) {
270                boolean different = false;
271                if (targetComponent == null) {
272                        different = true;
273                } else {
274                        if (!targetComponent.equals(component)) {
275                                different = true;
276                        }
277                }
278                if (different) {
279                        // end visit
280                        endMember();
281                        endReferencingComponent();
282                        endTargetComponent();
283                        
284                        // start next
285                        targetComponent = component;
286                        visitReferencingComponent = visitor.visitComponent(targetComponent);
287                }
288        }
289        
290        public void enterReferencingComponent(IComponentDescriptor component) {
291                boolean different = false;
292                if (referencingComponent == null) {
293                        different = true;
294                } else {
295                        if (!referencingComponent.equals(component)) {
296                                different = true;
297                        }
298                }
299                if (different) {
300                        // end visit
301                        endMember();
302                        endReferencingComponent();
303                        
304                        // start next
305                        referencingComponent = component;
306                        if (visitReferencingComponent) {
307                                visitMembers = visitor.visitReferencingComponent(referencingComponent);
308                        }
309                }                
310        }
311        
312        public void enterVisibility(int vis) {
313                visibility = vis;
314        }
315        
316        public void enterTargetMember(IMemberDescriptor member) {
317                if (targetMember == null || !targetMember.equals(member)) {
318                        endMember();
319                        targetMember = member;
320                        if (visitReferencingComponent && visitMembers) {
321                                visitReferences  =visitor.visitMember(targetMember);
322                        }
323                }
324        }
325        
326        public void enterReferenceKind(int refKind) {
327                referenceKind = refKind;
328        }
329        
330        public void setReference(IMemberDescriptor from, int lineNumber) {
331                if (visitReferencingComponent&& visitMembers && visitReferences) {
332                        visitor.visitReference(referenceKind, from, lineNumber, visibility);
333                }
334        }
335        
336        private void endMember() {
337                if (targetMember != null) {
338                        visitor.endVisitMember(targetMember);
339                        targetMember = null;
340                }
341        }
342        
343        private void endReferencingComponent() {
344                if (referencingComponent != null) {
345                        visitor.endVisitReferencingComponent(referencingComponent);
346                        referencingComponent = null;
347                }
348        }
349        
350        private void endTargetComponent() {
351                if (targetComponent != null) {
352                        visitor.endVisit(targetComponent);
353                        targetComponent = null;
354                }
355        }
356        
357        /**
358         * Sorts the given files by name (not path).
359         * 
360         * @param files
361         * @return sorted files
362         */
363        private File[] sort(File[] files) {
364                List sorted = new ArrayList(files.length + 2);
365                for (int i = 0; i < files.length; i++) {
366                        sorted.add(files[i]);
367                }
368                
369                Collections.sort(sorted, Util.filesorter);
370                return (File[]) sorted.toArray(new File[sorted.size()]);
371        }
372}

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