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 [XmlReferenceDescriptorWriter.java]

nameclass, %method, %block, %line, %
XmlReferenceDescriptorWriter.java100% (1/1)93%  (13/14)79%  (710/895)77%  (184.2/239)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class XmlReferenceDescriptorWriter100% (1/1)93%  (13/14)79%  (710/895)77%  (184.2/239)
setAlternate (IComponentDescriptor): void 0%   (0/1)0%   (0/4)0%   (0/2)
getFormattedTypeName (String): String 100% (1/1)30%  (6/20)29%  (2/7)
getRefTypeName (int): String 100% (1/1)40%  (4/10)40%  (2/5)
findKindElement (Element, Integer): Element 100% (1/1)50%  (15/30)56%  (3.9/7)
findTypeElement (Element, String): Element 100% (1/1)52%  (17/33)55%  (4.9/9)
writeReferences (IReferenceDescriptor []): void 100% (1/1)56%  (32/57)56%  (7.8/14)
addMemberDetails (Element, IMemberDescriptor): void 100% (1/1)57%  (25/44)67%  (8/12)
getText (IMemberDescriptor): String 100% (1/1)65%  (11/17)60%  (3/5)
writeGroup (String, String, File, String, HashMap, int): void 100% (1/1)69%  (162/235)66%  (42.5/64)
XmlReferenceDescriptorWriter (String): void 100% (1/1)79%  (26/33)67%  (8/12)
collateResults (IReferenceDescriptor []): void 100% (1/1)100% (168/168)100% (43/43)
getId (IComponentDescriptor): String 100% (1/1)100% (21/21)100% (3/3)
writeReference (Document, Element, IReferenceDescriptor): void 100% (1/1)100% (67/67)100% (17/17)
writeXML (File): void 100% (1/1)100% (156/156)100% (39/39)

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.BufferedWriter;
14import java.io.File;
15import java.io.FileInputStream;
16import java.io.FileNotFoundException;
17import java.io.FileWriter;
18import java.io.IOException;
19import java.util.HashMap;
20import java.util.HashSet;
21import java.util.Iterator;
22import java.util.Map;
23 
24import javax.xml.parsers.DocumentBuilder;
25import javax.xml.parsers.DocumentBuilderFactory;
26import javax.xml.parsers.FactoryConfigurationError;
27import javax.xml.parsers.ParserConfigurationException;
28 
29import org.eclipse.core.runtime.CoreException;
30import org.eclipse.pde.api.tools.internal.IApiXmlConstants;
31import org.eclipse.pde.api.tools.internal.builder.Reference;
32import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
33import org.eclipse.pde.api.tools.internal.provisional.VisibilityModifiers;
34import org.eclipse.pde.api.tools.internal.provisional.builder.IReference;
35import org.eclipse.pde.api.tools.internal.provisional.descriptors.IComponentDescriptor;
36import org.eclipse.pde.api.tools.internal.provisional.descriptors.IElementDescriptor;
37import org.eclipse.pde.api.tools.internal.provisional.descriptors.IFieldDescriptor;
38import org.eclipse.pde.api.tools.internal.provisional.descriptors.IMemberDescriptor;
39import org.eclipse.pde.api.tools.internal.provisional.descriptors.IMethodDescriptor;
40import org.eclipse.pde.api.tools.internal.provisional.descriptors.IReferenceTypeDescriptor;
41import org.eclipse.pde.api.tools.internal.util.Signatures;
42import org.eclipse.pde.api.tools.internal.util.Util;
43import org.w3c.dom.Document;
44import org.w3c.dom.Element;
45import org.w3c.dom.NodeList;
46import org.xml.sax.SAXException;
47import org.xml.sax.helpers.DefaultHandler;
48 
49/**
50 * Writes reference descriptions to XML files.
51 * 
52 * @since 1.0.1
53 */
54public class XmlReferenceDescriptorWriter {
55 
56        /**
57         * file names for the output reference files
58         */
59        public static final String TYPE_REFERENCES = "type_references"; //$NON-NLS-1$
60        public static final String METHOD_REFERENCES = "method_references"; //$NON-NLS-1$
61        public static final String FIELD_REFERENCES = "field_references"; //$NON-NLS-1$
62        
63        private String fLocation = null;
64        private HashMap fReferenceMap = null;
65        private DocumentBuilder parser = null;
66        
67        /**
68         * Alternate API component where references were unresolved, or <code>null</code>
69         * if not to be reported.
70         */
71        private IComponentDescriptor alternate;
72        
73        /**
74         * Constructor
75         * 
76         * @param location the absolute path in the local file system to the folder to write the reports to 
77         * @param debug if debugging infos should be written out to the console
78         */
79        public XmlReferenceDescriptorWriter(String location) {
80                fLocation = location;
81                try {
82                        parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
83                        parser.setErrorHandler(new DefaultHandler());
84                }
85                catch(FactoryConfigurationError fce) {
86                        ApiPlugin.log(fce);
87                } 
88                catch (ParserConfigurationException pce) {
89                        ApiPlugin.log(pce);
90                }
91        }
92 
93        /**
94         * Writes the given references to XML files.
95         * 
96         * @param references
97         */
98        public void writeReferences(IReferenceDescriptor[] references) {
99                if(fLocation != null) {
100                        try {
101                                File parent = new File(fLocation);
102                                if(!parent.exists()) {
103                                        parent.mkdirs();
104                                }
105                                collateResults(references);
106                                writeXML(parent);
107                        } 
108                        catch (Exception e) {
109                                ApiPlugin.log(e);
110                        }
111                        finally {
112                                if(fReferenceMap != null) {
113                                        fReferenceMap.clear();
114                                        fReferenceMap = null;
115                                }
116                        }
117                }
118        }
119        
120        /**
121         * Collates the results into like reference kinds
122         * @param references
123         */
124        private void collateResults(IReferenceDescriptor[] references) throws CoreException {
125                if(fReferenceMap == null) {
126                        fReferenceMap = new HashMap();
127                }
128                Integer type = null;
129                Integer visibility = null;
130                String id = null;
131                String tname = null;
132                HashMap rmap = null;
133                HashMap mmap = null;
134                HashMap vmap = null;
135                HashMap tmap = null;
136                HashSet reflist = null;
137                IComponentDescriptor rcomponent = null;
138                IComponentDescriptor mcomponent = null;
139                for (int i = 0; i < references.length; i++) {
140                        rcomponent = references[i].getReferencedComponent(); 
141                        id = getId(rcomponent);
142                        rmap = (HashMap) fReferenceMap.get(id);
143                        if(rmap == null) {
144                                rmap = new HashMap();
145                                fReferenceMap.put(id, rmap);
146                        }
147                        mcomponent = references[i].getComponent(); 
148                        id = getId(mcomponent);
149                        mmap = (HashMap) rmap.get(id);
150                        if(mmap == null) {
151                                mmap = new HashMap();
152                                rmap.put(id, mmap);
153                        }
154                        visibility = new Integer(references[i].getVisibility());
155//                        fDescription = rcomponent.getApiDescription();
156//                        annot = fDescription.resolveAnnotations(references[i].getResolvedReference().getHandle());
157//                        if(annot != null) {
158//                                visibility = new Integer(annot.getVisibility());
159//                                if(annot.getVisibility() == VisibilityModifiers.PRIVATE) {
160//                                        IApiComponent host = mcomponent.getHost();
161//                                        if(host != null && host.getId().equals(rcomponent.getId())) {
162//                                                visibility = new Integer(UseReportConverter.FRAGMENT_PERMISSIBLE);
163//                                        }
164//                                        else {
165//                                                IApiAccess access = fDescription.resolveAccessLevel(
166//                                                                mcomponent.getHandle(), 
167//                                                                getPackageDescriptor(references[i].getResolvedReference()));
168//                                                if(access != null && access.getAccessLevel() == IApiAccess.FRIEND) {
169//                                                        visibility = new Integer(VisibilityModifiers.PRIVATE_PERMISSIBLE);
170//                                                }
171//                                        }
172//                                }
173//                        }
174//                        else {
175//                                //overflow for those references that cannot be resolved
176//                                visibility = new Integer(VisibilityModifiers.ALL_VISIBILITIES);
177//                        }
178                        vmap = (HashMap) mmap.get(visibility);
179                        if(vmap == null) {
180                                vmap = new HashMap();
181                                mmap.put(visibility, vmap);
182                        }
183                        type = new Integer(references[i].getReferenceType());
184                        tmap = (HashMap) vmap.get(type);
185                        if(tmap == null) {
186                                tmap = new HashMap();
187                                vmap.put(type, tmap);
188                        }
189                        tname = getText(references[i].getReferencedMember());
190                        reflist = (HashSet) tmap.get(tname);
191                        if(reflist == null) {
192                                reflist = new HashSet();
193                                tmap.put(tname, reflist);
194                        }
195                        reflist.add(references[i]);
196                }
197        }
198        
199        /**
200         * Resolves the id to use for the component in the mapping
201         * @param component
202         * @return the id to use for the component in the mapping, includes the version information as well
203         * @throws CoreException
204         */
205        String getId(IComponentDescriptor component) throws CoreException {
206                StringBuffer buffer = new StringBuffer();
207                buffer.append(component.getId()).append(" ").append('(').append(component.getVersion()).append(')'); //$NON-NLS-1$
208                return buffer.toString();
209        }
210        
211        /**
212         * Returns a formatted version of the references xml file name for use during conversion via the default
213         * XSLT file
214         * @param groupname
215         * @return a formatted version of the references file name
216         */
217        private String getFormattedTypeName(String groupname) {
218                if(TYPE_REFERENCES.equals(groupname)) {
219                        return "Types"; //$NON-NLS-1$
220                }
221                if(METHOD_REFERENCES.equals(groupname)) {
222                        return "Methods"; //$NON-NLS-1$
223                }
224                if(FIELD_REFERENCES.equals(groupname)) {
225                        return "Fields"; //$NON-NLS-1$
226                }
227                return "unknown references"; //$NON-NLS-1$
228        }
229        
230        /**
231         * Returns the name for the file of references base on the given type
232         * @param type
233         * @return
234         */
235        private String getRefTypeName(int type) {
236                switch(type) {
237                        case IReference.T_TYPE_REFERENCE: return TYPE_REFERENCES;
238                        case IReference.T_METHOD_REFERENCE: return METHOD_REFERENCES;
239                        case IReference.T_FIELD_REFERENCE: return FIELD_REFERENCES;
240                }
241                return "unknown_reference_kinds"; //$NON-NLS-1$
242        }
243        
244        /**
245         * Writes out the XML for the given api element using the collated {@link IReference}s
246         * @param parent
247         * @throws CoreException
248         * @throws FileNotFoundException
249         * @throws IOException
250         */
251        private void writeXML(File parent) throws CoreException, FileNotFoundException, IOException {
252                HashMap vismap = null;
253                HashMap typemap = null;
254                HashMap rmap = null;
255                HashMap mmap = null;
256                Integer type = null;
257                Integer vis = null;
258                String id = null;
259                String referee = null;
260                File root = null;
261                File location = null;
262                File base = null;
263                for(Iterator iter = fReferenceMap.entrySet().iterator(); iter.hasNext();) {
264                        Map.Entry entry = (Map.Entry) iter.next();
265                        id = (String) entry.getKey();
266                        referee = id;
267                        base = new File(parent, id);
268                        if(!base.exists()) {
269                                base.mkdir();
270                        }
271                        rmap = (HashMap) entry.getValue();
272                        for(Iterator iter2 = rmap.entrySet().iterator(); iter2.hasNext();) {
273                                Map.Entry entry2 = (Map.Entry) iter2.next();
274                                id = (String) entry2.getKey();
275                                root = new File(base, id);
276                                if(!root.exists()) {
277                                        root.mkdir();
278                                }
279                                mmap = (HashMap) entry2.getValue();
280                                for(Iterator iter4 = mmap.entrySet().iterator(); iter4.hasNext();) {
281                                        Map.Entry entry3 = (Map.Entry) iter4.next();
282                                        vis = (Integer) entry3.getKey();
283                                        location = new File(root, VisibilityModifiers.getVisibilityName(vis.intValue()));
284                                        if(!location.exists()) {
285                                                location.mkdir();
286                                        }
287                                        vismap = (HashMap) entry3.getValue();
288                                        for(Iterator iter3 = vismap.entrySet().iterator(); iter3.hasNext();) {
289                                                Map.Entry entry4 = (Map.Entry) iter3.next();
290                                                type = (Integer) entry4.getKey();
291                                                typemap = (HashMap) entry4.getValue();
292                                                writeGroup(id, referee, location, getRefTypeName(type.intValue()), typemap, vis.intValue());
293                                        }
294                                }
295                        }
296                }
297        }
298        
299        /**
300         * Writes out a group of references under the newly created element with the given name
301         * @param origin the name of the bundle that has the references in it
302         * @param referee the name of the bundle that is referenced
303         * @param parent
304         * @param name
305         * @param map
306         * @param visibility
307         */
308        private void writeGroup(String origin, String referee, File parent, String name, HashMap map, int visibility) throws CoreException, FileNotFoundException, IOException {
309                if(parent.exists()) {
310                        BufferedWriter writer = null;
311                        try {
312                                Document doc = null;
313                                Element root = null;
314                                int count = 0;
315                                File out = new File(parent, name+".xml"); //$NON-NLS-1$
316                                if(out.exists()) {
317                                        try {
318                                                FileInputStream inputStream = null;
319                                                try {
320                                                        inputStream = new FileInputStream(out);
321                                                        doc = this.parser.parse(inputStream);
322                                                } catch (IOException e) {
323                                                        e.printStackTrace();
324                                                } finally {
325                                                        if (inputStream != null) {
326                                                                inputStream.close();
327                                                        }
328                                                }
329                                                if (doc == null) {
330                                                        return;
331                                                }
332                                                root = doc.getDocumentElement();
333                                                String value = root.getAttribute(IApiXmlConstants.ATTR_REFERENCE_COUNT);
334                                                count = Integer.parseInt(value);
335                                        }
336                                        catch(SAXException se) {
337                                                se.printStackTrace();
338                                        }
339                                }
340                                else {
341                                        doc = Util.newDocument();
342                                        root = doc.createElement(IApiXmlConstants.REFERENCES);
343                                        doc.appendChild(root);
344                                        root.setAttribute(IApiXmlConstants.ATTR_REFERENCE_VISIBILITY, Integer.toString(visibility));
345                                        root.setAttribute(IApiXmlConstants.ATTR_ORIGIN, origin);
346                                        root.setAttribute(IApiXmlConstants.ATTR_REFEREE, referee);
347                                        root.setAttribute(IApiXmlConstants.ATTR_NAME, getFormattedTypeName(name));
348                                        if (alternate != null) {
349                                                root.setAttribute(IApiXmlConstants.ATTR_ALTERNATE, getId(alternate));
350                                        }
351                                }
352                                if(doc == null) {
353                                        return;
354                                }
355                                String tname = null;
356                                HashSet refs = null;
357                                Element telement = null;
358                                for(Iterator iter = map.entrySet().iterator(); iter.hasNext();) {
359                                        Map.Entry entry = (Map.Entry) iter.next();
360                                        tname = (String) entry.getKey();
361                                        telement = findTypeElement(root, tname);
362                                        if(telement == null) {
363                                                telement = doc.createElement(IApiXmlConstants.ELEMENT_TARGET);
364                                                telement.setAttribute(IApiXmlConstants.ATTR_NAME, tname);
365                                                root.appendChild(telement);
366                                        }
367                                        refs = (HashSet) entry.getValue();
368                                        if(refs != null) {
369                                                for(Iterator iter2 = refs.iterator(); iter2.hasNext();) {
370                                                        count++;
371                                                        IReferenceDescriptor ref = (IReferenceDescriptor) iter2.next();
372                                                        writeReference(doc, telement, ref);
373                                                        if (!iter2.hasNext()) {
374                                                                // set qualified referenced attributes
375                                                                IMemberDescriptor resolved  = ref.getReferencedMember();
376                                                                if (resolved != null) {
377                                                                        addMemberDetails(telement, resolved);
378                                                                }
379                                                        }
380                                                }
381                                        }
382                                }
383                                root.setAttribute(IApiXmlConstants.ATTR_REFERENCE_COUNT, Integer.toString(count));
384                                writer = new BufferedWriter(new FileWriter(out));
385                                writer.write(Util.serializeDocument(doc));
386                                writer.flush();
387                        }
388                        finally {
389                                if (writer != null) {
390                                        writer.close();
391                                }
392                        }
393                }
394        }
395        
396        /**
397         * Add member descriptor details to the given element.
398         * 
399         * @param element XML element
400         * @param member member to add details for
401         */
402        private void addMemberDetails(Element element, IMemberDescriptor member) {
403                switch (member.getElementType()) {
404                case IElementDescriptor.TYPE:
405                        element.setAttribute(IApiXmlConstants.ATTR_TYPE, ((IReferenceTypeDescriptor)member).getQualifiedName());
406                        break;
407                case IElementDescriptor.FIELD:
408                        IReferenceTypeDescriptor encl = member.getEnclosingType();
409                        element.setAttribute(IApiXmlConstants.ATTR_TYPE, encl.getQualifiedName());
410                        element.setAttribute(IApiXmlConstants.ATTR_MEMBER_NAME, member.getName());
411                        break;
412                case IElementDescriptor.METHOD:
413                        encl = member.getEnclosingType();
414                        element.setAttribute(IApiXmlConstants.ATTR_TYPE, encl.getQualifiedName());
415                        element.setAttribute(IApiXmlConstants.ATTR_MEMBER_NAME, member.getName());
416                        element.setAttribute(IApiXmlConstants.ATTR_SIGNATURE, ((IMethodDescriptor)member).getSignature());
417                        break;
418                }
419        }
420        
421        /**
422         * gets the root kind element
423         * @param root
424         * @param kind
425         * @return
426         */
427        private Element findTypeElement(Element root, String tname) {
428                if(tname == null) {
429                        return null;
430                }
431                Element kelement = null;
432                NodeList nodes = root.getElementsByTagName(IApiXmlConstants.ELEMENT_TARGET);
433                for (int i = 0; i < nodes.getLength(); i++) {
434                        kelement = (Element) nodes.item(i);
435                        if(tname.equals(kelement.getAttribute(IApiXmlConstants.ATTR_NAME))) {
436                                return kelement;
437                        }
438                }
439                return null;
440        }
441        
442        /**
443         * gets the root kind element
444         * @param root
445         * @param kind
446         * @return
447         */
448        private Element findKindElement(Element root, Integer kind) {
449                Element kelement = null;
450                NodeList nodes = root.getElementsByTagName(IApiXmlConstants.REFERENCE_KIND);
451                for (int i = 0; i < nodes.getLength(); i++) {
452                        kelement = (Element) nodes.item(i);
453                        if(kind.toString().equals(kelement.getAttribute(IApiXmlConstants.ATTR_KIND))) {
454                                return kelement;
455                        }
456                }
457                return null;
458        }
459        
460        /**
461         * Writes the attributes from the given {@link IReference} into a new {@link Element} that is added to 
462         * the given parent.
463         * 
464         * @param document
465         * @param parent
466         * @param reference
467         */
468        private void writeReference(Document document, Element parent, IReferenceDescriptor reference) throws CoreException {
469                Element kelement = null;
470                Integer kind = new Integer(reference.getReferenceKind());
471                kelement = findKindElement(parent, kind);
472                if(kelement == null) {
473                        kelement = document.createElement(IApiXmlConstants.REFERENCE_KIND);
474                        kelement.setAttribute(IApiXmlConstants.ATTR_REFERENCE_KIND_NAME, Reference.getReferenceText(kind.intValue()));
475                        kelement.setAttribute(IApiXmlConstants.ATTR_KIND, kind.toString());
476                        parent.appendChild(kelement);
477                }
478                Element relement = document.createElement(IApiXmlConstants.ATTR_REFERENCE);
479                IMemberDescriptor member = reference.getMember();
480                relement.setAttribute(IApiXmlConstants.ATTR_ORIGIN, getText(member));
481                // add detailed information about origin
482                addMemberDetails(relement, member);
483                member = reference.getReferencedMember();
484                if(member != null) {
485                        relement.setAttribute(IApiXmlConstants.ATTR_LINE_NUMBER, Integer.toString(reference.getLineNumber()));
486                        kelement.appendChild(relement);
487                }
488        }
489        
490        /**
491         * Returns the text to set in the attribute for the given {@link IApiMember}
492         * @param member
493         * @return
494         * @throws CoreException
495         */
496        private String getText(IMemberDescriptor member) throws CoreException {
497                switch(member.getElementType()) {
498                        case IElementDescriptor.TYPE: return Signatures.getQualifiedTypeSignature((IReferenceTypeDescriptor) member);
499                        case IElementDescriptor.METHOD: return Signatures.getQualifiedMethodSignature((IMethodDescriptor) member);
500                        case IElementDescriptor.FIELD: return Signatures.getQualifiedFieldSignature((IFieldDescriptor) member);
501                }
502                return null;
503        }
504 
505        /**
506         * Sets the alternate component where references were unresolved, or <code>null</code>
507         * if none.
508         * 
509         * @param other component descriptor or <code>null</code>
510         */
511        public void setAlternate(IComponentDescriptor other) {
512                alternate = other;
513        }
514}

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