Source Code Cross Referenced for SortedBugCollection.java in  » Code-Analyzer » findbugs » edu » umd » cs » findbugs » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Code Analyzer » findbugs » edu.umd.cs.findbugs 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * FindBugs - Find bugs in Java programs
0003:         * Copyright (C) 2003-2005 University of Maryland
0004:         * 
0005:         * This library is free software; you can redistribute it and/or
0006:         * modify it under the terms of the GNU Lesser General Public
0007:         * License as published by the Free Software Foundation; either
0008:         * version 2.1 of the License, or (at your option) any later version.
0009:         * 
0010:         * This library is distributed in the hope that it will be useful,
0011:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0013:         * Lesser General Public License for more details.
0014:         * 
0015:         * You should have received a copy of the GNU Lesser General Public
0016:         * License along with this library; if not, write to the Free Software
0017:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
0018:         */
0019:
0020:        package edu.umd.cs.findbugs;
0021:
0022:        import java.io.BufferedInputStream;
0023:        import java.io.BufferedOutputStream;
0024:        import java.io.BufferedReader;
0025:        import java.io.ByteArrayInputStream;
0026:        import java.io.File;
0027:        import java.io.FileInputStream;
0028:        import java.io.FileOutputStream;
0029:        import java.io.IOException;
0030:        import java.io.InputStream;
0031:        import java.io.OutputStream;
0032:        import java.io.Reader;
0033:        import java.io.StringWriter;
0034:        import java.math.BigInteger;
0035:        import java.security.MessageDigest;
0036:        import java.util.Collection;
0037:        import java.util.Comparator;
0038:        import java.util.HashMap;
0039:        import java.util.HashSet;
0040:        import java.util.Iterator;
0041:        import java.util.LinkedHashSet;
0042:        import java.util.LinkedList;
0043:        import java.util.List;
0044:        import java.util.Map;
0045:        import java.util.Set;
0046:        import java.util.SortedSet;
0047:        import java.util.TreeMap;
0048:        import java.util.TreeSet;
0049:        import java.util.zip.GZIPInputStream;
0050:
0051:        import javax.xml.transform.TransformerException;
0052:
0053:        import org.dom4j.Document;
0054:        import org.dom4j.DocumentException;
0055:        import org.dom4j.DocumentFactory;
0056:        import org.xml.sax.InputSource;
0057:        import org.xml.sax.SAXException;
0058:        import org.xml.sax.SAXParseException;
0059:        import org.xml.sax.XMLReader;
0060:        import org.xml.sax.helpers.XMLReaderFactory;
0061:
0062:        import edu.umd.cs.findbugs.annotations.CheckForNull;
0063:        import edu.umd.cs.findbugs.annotations.NonNull;
0064:        import edu.umd.cs.findbugs.ba.AnalysisContext;
0065:        import edu.umd.cs.findbugs.ba.MissingClassException;
0066:        import edu.umd.cs.findbugs.model.ClassFeatureSet;
0067:        import edu.umd.cs.findbugs.util.Util;
0068:        import edu.umd.cs.findbugs.xml.Dom4JXMLOutput;
0069:        import edu.umd.cs.findbugs.xml.OutputStreamXMLOutput;
0070:        import edu.umd.cs.findbugs.xml.XMLAttributeList;
0071:        import edu.umd.cs.findbugs.xml.XMLOutput;
0072:        import edu.umd.cs.findbugs.xml.XMLOutputUtil;
0073:
0074:        /**
0075:         * An implementation of {@link BugCollection} that keeps the BugInstances
0076:         * sorted by class (using the native comparison ordering of BugInstance's
0077:         * compareTo() method as a tie-breaker).
0078:         *
0079:         * @see BugInstance
0080:         * @author David Hovemeyer
0081:         */
0082:        public class SortedBugCollection implements  BugCollection {
0083:            long analysisTimestamp = System.currentTimeMillis();
0084:            String analysisVersion = Version.RELEASE;
0085:            private boolean withMessages = false;
0086:
0087:            private static final boolean REPORT_SUMMARY_HTML = SystemProperties
0088:                    .getBoolean("findbugs.report.SummaryHTML");
0089:
0090:            public long getAnalysisTimestamp() {
0091:                return analysisTimestamp;
0092:            }
0093:
0094:            public void setAnalysisTimestamp(long timestamp) {
0095:                analysisTimestamp = timestamp;
0096:            }
0097:
0098:            /**
0099:             * Add a Collection of BugInstances to this BugCollection object.
0100:             * This just calls add(BugInstance) for each instance in the input collection.
0101:             *
0102:             * @param collection the Collection of BugInstances to add
0103:             */
0104:            public void addAll(Collection<BugInstance> collection) {
0105:                for (BugInstance aCollection : collection) {
0106:                    add(aCollection);
0107:                }
0108:            }
0109:
0110:            /**
0111:             * Add a Collection of BugInstances to this BugCollection object.
0112:             *
0113:             * @param collection       the Collection of BugInstances to add
0114:             * @param updateActiveTime true if active time of added BugInstances should
0115:             *                         be updated to match collection: false if not
0116:             */
0117:            public void addAll(Collection<BugInstance> collection,
0118:                    boolean updateActiveTime) {
0119:                for (BugInstance warning : collection) {
0120:                    add(warning, updateActiveTime);
0121:                }
0122:            }
0123:
0124:            /**
0125:             * Add a BugInstance to this BugCollection.
0126:             * This just calls add(bugInstance, true).
0127:             *
0128:             * @param bugInstance the BugInstance
0129:             * @return true if the BugInstance was added, or false if a matching
0130:             *         BugInstance was already in the BugCollection
0131:             */
0132:            public boolean add(BugInstance bugInstance) {
0133:                return add(bugInstance, true);
0134:            }
0135:
0136:            /**
0137:             * Add an analysis error.
0138:             *
0139:             * @param message the error message
0140:             */
0141:            public void addError(String message) {
0142:                addError(message, null);
0143:            }
0144:
0145:            /**
0146:             * Get the current AppVersion.
0147:             */
0148:            public AppVersion getCurrentAppVersion() {
0149:                return new AppVersion(getSequenceNumber()).setReleaseName(
0150:                        getReleaseName()).setTimestamp(getTimestamp())
0151:                        .setNumClasses(getProjectStats().getNumClasses())
0152:                        .setCodeSize(getProjectStats().getCodeSize());
0153:            }
0154:
0155:            /**
0156:             * Read XML data from given file into this object,
0157:             * populating given Project as a side effect.
0158:             *
0159:             * @param fileName name of the file to read
0160:             * @param project  the Project
0161:             */
0162:            public void readXML(String fileName, Project project)
0163:                    throws IOException, DocumentException {
0164:                readXML(new File(fileName), project);
0165:            }
0166:
0167:            /**
0168:             * Read XML data from given file into this object,
0169:             * populating given Project as a side effect.
0170:             *
0171:             * @param file    the file
0172:             * @param project the Project
0173:             */
0174:            public void readXML(File file, Project project) throws IOException,
0175:                    DocumentException {
0176:                project.setCurrentWorkingDirectory(file.getParentFile());
0177:                InputStream in = new BufferedInputStream(new FileInputStream(
0178:                        file));
0179:                if (file.getName().endsWith(".gz"))
0180:                    in = new GZIPInputStream(in);
0181:                readXML(in, project, file);
0182:            }
0183:
0184:            /**
0185:             * Read XML data from given input stream into this
0186:             * object, populating the Project as a side effect.
0187:             * An attempt will be made to close the input stream
0188:             * (even if an exception is thrown).
0189:             *
0190:             * @param in      the InputStream
0191:             * @param project the Project
0192:             */
0193:            public void readXML(InputStream in, Project project, File base)
0194:                    throws IOException, DocumentException {
0195:                if (in == null)
0196:                    throw new IllegalArgumentException();
0197:
0198:                try {
0199:                    if (project == null)
0200:                        throw new IllegalArgumentException();
0201:                    doReadXML(in, project, base);
0202:                } finally {
0203:                    in.close();
0204:                }
0205:            }
0206:
0207:            public void readXML(InputStream in, Project project)
0208:                    throws IOException, DocumentException {
0209:                doReadXML(in, project, null);
0210:
0211:            }
0212:
0213:            private void doReadXML(InputStream in, Project project, File base)
0214:                    throws IOException, DocumentException {
0215:
0216:                checkInputStream(in);
0217:
0218:                try {
0219:                    SAXBugCollectionHandler handler = new SAXBugCollectionHandler(
0220:                            this , project, base);
0221:
0222:                    XMLReader xr = null;
0223:                    if (true)
0224:                        try {
0225:                            xr = XMLReaderFactory.createXMLReader();
0226:                        } catch (SAXException e) {
0227:                            AnalysisContext.logError(
0228:                                    "Couldn't create XMLReaderFactory", e);
0229:                        }
0230:
0231:                    if (xr == null) {
0232:                        xr = new org.dom4j.io.aelfred.SAXDriver();
0233:                    }
0234:                    xr.setContentHandler(handler);
0235:                    xr.setErrorHandler(handler);
0236:
0237:                    Reader reader = Util.getReader(in);
0238:
0239:                    xr.parse(new InputSource(reader));
0240:                } catch (SAXParseException e) {
0241:                    throw new DocumentException("Parse error at line "
0242:                            + e.getLineNumber() + " : " + e.getColumnNumber(),
0243:                            e);
0244:                } catch (SAXException e) {
0245:                    // FIXME: throw SAXException from method?
0246:                    throw new DocumentException("Sax error ", e);
0247:                } finally {
0248:                    in.close();
0249:                }
0250:
0251:                // Presumably, project is now up-to-date
0252:                project.setModified(false);
0253:            }
0254:
0255:            /**
0256:             * Write this BugCollection to a file as XML.
0257:             *
0258:             * @param fileName the file to write to
0259:             * @param project  the Project from which the BugCollection was generated
0260:             */
0261:            public void writeXML(String fileName, Project project)
0262:                    throws IOException {
0263:                BufferedOutputStream out = new BufferedOutputStream(
0264:                        new FileOutputStream(fileName));
0265:                writeXML(out, project);
0266:            }
0267:
0268:            /**
0269:             * Write this BugCollection to a file as XML.
0270:             *
0271:             * @param file    the file to write to
0272:             * @param project the Project from which the BugCollection was generated
0273:             */
0274:            public void writeXML(File file, Project project) throws IOException {
0275:                BufferedOutputStream out = new BufferedOutputStream(
0276:                        new FileOutputStream(file));
0277:                writeXML(out, project);
0278:            }
0279:
0280:            /**
0281:             * Convert the BugCollection into a dom4j Document object.
0282:             *
0283:             * @param project the Project from which the BugCollection was generated
0284:             * @return the Document representing the BugCollection as a dom4j tree
0285:             */
0286:            public Document toDocument(Project project) {
0287:                if (project == null)
0288:                    throw new NullPointerException("No project");
0289:                DocumentFactory docFactory = new DocumentFactory();
0290:                Document document = docFactory.createDocument();
0291:                Dom4JXMLOutput treeBuilder = new Dom4JXMLOutput(document);
0292:
0293:                try {
0294:                    writeXML(treeBuilder, project);
0295:                } catch (IOException e) {
0296:                    // Can't happen
0297:                }
0298:
0299:                return document;
0300:            }
0301:
0302:            /**
0303:             * Write the BugCollection to given output stream as XML.
0304:             * The output stream will be closed, even if an exception is thrown.
0305:             *
0306:             * @param out     the OutputStream to write to
0307:             * @param project the Project from which the BugCollection was generated
0308:             */
0309:            public void writeXML(OutputStream out, Project project)
0310:                    throws IOException {
0311:                XMLOutput xmlOutput;
0312:                if (project == null)
0313:                    throw new NullPointerException("No project");
0314:                if (withMessages)
0315:                    xmlOutput = new OutputStreamXMLOutput(out,
0316:                            "http://findbugs.sourceforge.net/xsl/default.xsl");
0317:                else
0318:                    xmlOutput = new OutputStreamXMLOutput(out);
0319:
0320:                writeXML(xmlOutput, project);
0321:            }
0322:
0323:            public void writePrologue(XMLOutput xmlOutput, Project project)
0324:                    throws IOException {
0325:                xmlOutput.beginDocument();
0326:                xmlOutput.openTag(ROOT_ELEMENT_NAME, new XMLAttributeList()
0327:                        .addAttribute("version", analysisVersion)
0328:                        .addAttribute("sequence",
0329:                                String.valueOf(getSequenceNumber()))
0330:                        .addAttribute("timestamp",
0331:                                String.valueOf(getTimestamp())).addAttribute(
0332:                                "analysisTimestamp",
0333:                                String.valueOf(getAnalysisTimestamp()))
0334:
0335:                        .addAttribute("release", getReleaseName()));
0336:                project.writeXML(xmlOutput);
0337:            }
0338:
0339:            private String getQuickInstanceHash(BugInstance bugInstance) {
0340:                String hash = bugInstance.getInstanceHash();
0341:                if (hash != null)
0342:                    return hash;
0343:                MessageDigest digest = null;
0344:                try {
0345:                    digest = MessageDigest.getInstance("MD5");
0346:                } catch (Exception e2) {
0347:                    // OK, we won't digest
0348:                    assert true;
0349:                }
0350:                hash = bugInstance.getInstanceKey();
0351:                if (digest != null) {
0352:                    byte[] data = digest.digest(hash.getBytes());
0353:                    String tmp = new BigInteger(1, data).toString(16);
0354:                    if (false)
0355:                        System.out.println(hash + " -> " + tmp);
0356:                    hash = tmp;
0357:                }
0358:                bugInstance.setInstanceHash(hash);
0359:                return hash;
0360:            }
0361:
0362:            public void computeBugHashes() {
0363:                if (preciseHashOccurrenceNumbersAvailable)
0364:                    return;
0365:                invalidateHashes();
0366:                MessageDigest digest = null;
0367:                try {
0368:                    digest = MessageDigest.getInstance("MD5");
0369:                } catch (Exception e2) {
0370:                    // OK, we won't digest
0371:                }
0372:
0373:                HashMap<String, Integer> seen = new HashMap<String, Integer>();
0374:
0375:                for (BugInstance bugInstance : getCollection()) {
0376:                    String hash = bugInstance.getInstanceHash();
0377:                    if (hash == null) {
0378:                        hash = bugInstance.getInstanceKey();
0379:
0380:                        if (digest != null) {
0381:                            byte[] data = digest.digest(hash.getBytes());
0382:                            String tmp = new BigInteger(1, data).toString(16);
0383:                            if (false)
0384:                                System.out.println(hash + " -> " + tmp);
0385:                            hash = tmp;
0386:                        }
0387:                        bugInstance.setInstanceHash(hash);
0388:                    }
0389:                    Integer count = seen.get(hash);
0390:                    if (count == null) {
0391:                        bugInstance.setInstanceOccurrenceNum(0);
0392:                        seen.put(hash, 0);
0393:                    } else {
0394:                        bugInstance.setInstanceOccurrenceNum(count + 1);
0395:                        seen.put(hash, count + 1);
0396:                    }
0397:                }
0398:                for (BugInstance bugInstance : getCollection())
0399:                    bugInstance.setInstanceOccurrenceMax(seen.get(bugInstance
0400:                            .getInstanceHash()));
0401:                preciseHashOccurrenceNumbersAvailable = true;
0402:            }
0403:
0404:            /**
0405:             * Write the BugCollection to an XMLOutput object.
0406:             * The finish() method of the XMLOutput object is guaranteed
0407:             * to be called.
0408:             *
0409:             * <p>
0410:             * To write the SummaryHTML element, set property
0411:             * findbugs.report.SummaryHTML to "true".
0412:             * </p>
0413:             *
0414:             * @param xmlOutput the XMLOutput object
0415:             * @param project   the Project from which the BugCollection was generated
0416:             */
0417:            public void writeXML(XMLOutput xmlOutput, @NonNull
0418:            Project project) throws IOException {
0419:                if (project == null)
0420:                    throw new NullPointerException("No project");
0421:                try {
0422:                    writePrologue(xmlOutput, project);
0423:                    if (withMessages)
0424:                        computeBugHashes();
0425:
0426:                    // Write BugInstances
0427:                    for (BugInstance bugInstance : getCollection())
0428:                        bugInstance.writeXML(xmlOutput, withMessages);
0429:
0430:                    writeEpilogue(xmlOutput);
0431:                } finally {
0432:                    xmlOutput.finish();
0433:                }
0434:            }
0435:
0436:            public void writeEpilogue(XMLOutput xmlOutput) throws IOException {
0437:                if (withMessages) {
0438:                    writeBugCategories(xmlOutput);
0439:                    writeBugPatterns(xmlOutput);
0440:                    writeBugCodes(xmlOutput);
0441:                }
0442:                // Errors, missing classes
0443:                emitErrors(xmlOutput);
0444:
0445:                // Statistics
0446:                getProjectStats().writeXML(xmlOutput);
0447:
0448:                //		// Class and method hashes
0449:                //		xmlOutput.openTag(CLASS_HASHES_ELEMENT_NAME);
0450:                //		for (Iterator<ClassHash> i = classHashIterator(); i.hasNext();) {
0451:                //			ClassHash classHash = i.next();
0452:                //			classHash.writeXML(xmlOutput);
0453:                //		}
0454:                //		xmlOutput.closeTag(CLASS_HASHES_ELEMENT_NAME);
0455:
0456:                // Class features
0457:                xmlOutput.openTag("ClassFeatures");
0458:                for (Iterator<ClassFeatureSet> i = classFeatureSetIterator(); i
0459:                        .hasNext();) {
0460:                    ClassFeatureSet classFeatureSet = i.next();
0461:                    classFeatureSet.writeXML(xmlOutput);
0462:                }
0463:                xmlOutput.closeTag("ClassFeatures");
0464:
0465:                // AppVersions
0466:                xmlOutput.openTag(HISTORY_ELEMENT_NAME);
0467:                for (Iterator<AppVersion> i = appVersionIterator(); i.hasNext();) {
0468:                    AppVersion appVersion = i.next();
0469:                    appVersion.writeXML(xmlOutput);
0470:                }
0471:                xmlOutput.closeTag(HISTORY_ELEMENT_NAME);
0472:
0473:                // Summary HTML
0474:                if (REPORT_SUMMARY_HTML) {
0475:                    String html = getSummaryHTML();
0476:                    if (html != null && !html.equals("")) {
0477:                        xmlOutput.openTag(SUMMARY_HTML_ELEMENT_NAME);
0478:                        xmlOutput.writeCDATA(html);
0479:                        xmlOutput.closeTag(SUMMARY_HTML_ELEMENT_NAME);
0480:                    }
0481:                }
0482:
0483:                xmlOutput.closeTag(ROOT_ELEMENT_NAME);
0484:            }
0485:
0486:            private void writeBugPatterns(XMLOutput xmlOutput)
0487:                    throws IOException {
0488:                // Find bug types reported
0489:                Set<String> bugTypeSet = new HashSet<String>();
0490:                for (Iterator<BugInstance> i = iterator(); i.hasNext();) {
0491:                    BugInstance bugInstance = i.next();
0492:                    BugPattern bugPattern = bugInstance.getBugPattern();
0493:                    if (bugPattern != null) {
0494:                        bugTypeSet.add(bugPattern.getType());
0495:                    }
0496:                }
0497:                // Emit element describing each reported bug pattern
0498:                for (String bugType : bugTypeSet) {
0499:                    BugPattern bugPattern = I18N.instance().lookupBugPattern(
0500:                            bugType);
0501:                    if (bugPattern == null)
0502:                        continue;
0503:
0504:                    XMLAttributeList attributeList = new XMLAttributeList();
0505:                    attributeList.addAttribute("type", bugType);
0506:                    attributeList
0507:                            .addAttribute("abbrev", bugPattern.getAbbrev());
0508:                    attributeList.addAttribute("category", bugPattern
0509:                            .getCategory());
0510:                    if (bugPattern.getCWEid() != 0) {
0511:                        attributeList.addAttribute("cweid", Integer
0512:                                .toString(bugPattern.getCWEid()));
0513:                    }
0514:                    xmlOutput.openTag("BugPattern", attributeList);
0515:
0516:                    xmlOutput.openTag("ShortDescription");
0517:                    xmlOutput.writeText(bugPattern.getShortDescription());
0518:                    xmlOutput.closeTag("ShortDescription");
0519:
0520:                    xmlOutput.openTag("Details");
0521:                    xmlOutput.writeCDATA(bugPattern.getDetailText());
0522:                    xmlOutput.closeTag("Details");
0523:
0524:                    xmlOutput.closeTag("BugPattern");
0525:                }
0526:            }
0527:
0528:            private void writeBugCodes(XMLOutput xmlOutput) throws IOException {
0529:                // Find bug codes reported
0530:                Set<String> bugCodeSet = new HashSet<String>();
0531:                for (Iterator<BugInstance> i = iterator(); i.hasNext();) {
0532:                    BugInstance bugInstance = i.next();
0533:                    String bugCode = bugInstance.getAbbrev();
0534:                    if (bugCode != null) {
0535:                        bugCodeSet.add(bugCode);
0536:                    }
0537:                }
0538:                // Emit element describing each reported bug code
0539:                for (String bugCodeAbbrev : bugCodeSet) {
0540:                    BugCode bugCode = I18N.instance().getBugCode(bugCodeAbbrev);
0541:                    String bugCodeDescription = bugCode.getDescription();
0542:                    if (bugCodeDescription == null)
0543:                        continue;
0544:
0545:                    XMLAttributeList attributeList = new XMLAttributeList();
0546:                    attributeList.addAttribute("abbrev", bugCodeAbbrev);
0547:                    if (bugCode.getCWEid() != 0) {
0548:                        attributeList.addAttribute("cweid", Integer
0549:                                .toString(bugCode.getCWEid()));
0550:                    }
0551:                    xmlOutput.openTag("BugCode", attributeList);
0552:
0553:                    xmlOutput.openTag("Description");
0554:                    xmlOutput.writeText(bugCodeDescription);
0555:                    xmlOutput.closeTag("Description");
0556:
0557:                    xmlOutput.closeTag("BugCode");
0558:                }
0559:            }
0560:
0561:            private void writeBugCategories(XMLOutput xmlOutput)
0562:                    throws IOException {
0563:                // Find bug categories reported
0564:                Set<String> bugCatSet = new HashSet<String>();
0565:                for (Iterator<BugInstance> i = iterator(); i.hasNext();) {
0566:                    BugInstance bugInstance = i.next();
0567:                    BugPattern bugPattern = bugInstance.getBugPattern();
0568:                    if (bugPattern != null) {
0569:                        bugCatSet.add(bugPattern.getCategory());
0570:                    }
0571:                }
0572:                // Emit element describing each reported bug code
0573:                for (String bugCat : bugCatSet) {
0574:                    String bugCatDescription = I18N.instance()
0575:                            .getBugCategoryDescription(bugCat);
0576:                    if (bugCatDescription == null)
0577:                        continue;
0578:
0579:                    XMLAttributeList attributeList = new XMLAttributeList();
0580:                    attributeList.addAttribute("category", bugCat);
0581:
0582:                    xmlOutput.openTag("BugCategory", attributeList);
0583:
0584:                    xmlOutput.openTag("Description");
0585:                    xmlOutput.writeText(bugCatDescription);
0586:                    xmlOutput.closeTag("Description");
0587:
0588:                    xmlOutput.closeTag("BugCategory");
0589:                }
0590:            }
0591:
0592:            private void emitErrors(XMLOutput xmlOutput) throws IOException {
0593:                //System.err.println("Writing errors to XML output");
0594:
0595:                xmlOutput.openTag(ERRORS_ELEMENT_NAME);
0596:
0597:                // Emit Error elements describing analysis errors
0598:                for (Iterator<AnalysisError> i = errorIterator(); i.hasNext();) {
0599:                    AnalysisError error = i.next();
0600:                    xmlOutput.openTag(ERROR_ELEMENT_NAME);
0601:
0602:                    xmlOutput.openTag(ERROR_MESSAGE_ELEMENT_NAME);
0603:                    xmlOutput.writeText(error.getMessage());
0604:                    xmlOutput.closeTag(ERROR_MESSAGE_ELEMENT_NAME);
0605:
0606:                    if (error.getExceptionMessage() != null) {
0607:                        xmlOutput.openTag(ERROR_EXCEPTION_ELEMENT_NAME);
0608:                        xmlOutput.writeText(error.getExceptionMessage());
0609:                        xmlOutput.closeTag(ERROR_EXCEPTION_ELEMENT_NAME);
0610:
0611:                        String stackTrace[] = error.getStackTrace();
0612:                        if (stackTrace != null) {
0613:                            for (String aStackTrace : stackTrace) {
0614:                                xmlOutput
0615:                                        .openTag(ERROR_STACK_TRACE_ELEMENT_NAME);
0616:                                xmlOutput.writeText(aStackTrace);
0617:                                xmlOutput
0618:                                        .closeTag(ERROR_STACK_TRACE_ELEMENT_NAME);
0619:                            }
0620:                        }
0621:
0622:                        if (false && error.getNestedExceptionMessage() != null) {
0623:                            xmlOutput.openTag(ERROR_EXCEPTION_ELEMENT_NAME);
0624:                            xmlOutput.writeText(error
0625:                                    .getNestedExceptionMessage());
0626:                            xmlOutput.closeTag(ERROR_EXCEPTION_ELEMENT_NAME);
0627:
0628:                            stackTrace = error.getNestedStackTrace();
0629:                            if (stackTrace != null) {
0630:                                for (String aStackTrace : stackTrace) {
0631:                                    xmlOutput
0632:                                            .openTag(ERROR_STACK_TRACE_ELEMENT_NAME);
0633:                                    xmlOutput.writeText(aStackTrace);
0634:                                    xmlOutput
0635:                                            .closeTag(ERROR_STACK_TRACE_ELEMENT_NAME);
0636:                                }
0637:                            }
0638:                        }
0639:                    }
0640:                    xmlOutput.closeTag(ERROR_ELEMENT_NAME);
0641:                }
0642:
0643:                // Emit missing classes
0644:                XMLOutputUtil.writeElementList(xmlOutput,
0645:                        MISSING_CLASS_ELEMENT_NAME, missingClassIterator());
0646:
0647:                xmlOutput.closeTag(ERRORS_ELEMENT_NAME);
0648:            }
0649:
0650:            private void checkInputStream(InputStream in) throws IOException {
0651:                if (in.markSupported()) {
0652:                    byte[] buf = new byte[200];
0653:                    in.mark(buf.length);
0654:
0655:                    int numRead = 0;
0656:                    while (numRead < buf.length) {
0657:                        int n = in.read(buf, numRead, buf.length - numRead);
0658:                        if (n < 0)
0659:                            throw new IOException(
0660:                                    "XML does not contain saved bug data");
0661:                        numRead += n;
0662:                    }
0663:
0664:                    in.reset();
0665:
0666:                    BufferedReader reader = new BufferedReader(Util
0667:                            .getReader(new ByteArrayInputStream(buf)));
0668:                    try {
0669:                        String line;
0670:                        while ((line = reader.readLine()) != null) {
0671:                            if (line.startsWith("<BugCollection"))
0672:                                return;
0673:                        }
0674:                    } finally {
0675:                        reader.close();
0676:                    }
0677:
0678:                    throw new IOException("XML does not contain saved bug data");
0679:                }
0680:            }
0681:
0682:            /**
0683:             * Clone all of the BugInstance objects in the source Collection
0684:             * and add them to the destination Collection.
0685:             *
0686:             * @param dest   the destination Collection
0687:             * @param source the source Collection
0688:             */
0689:            public static void cloneAll(Collection<BugInstance> dest,
0690:                    Collection<BugInstance> source) {
0691:                for (BugInstance obj : source) {
0692:                    dest.add((BugInstance) obj.clone());
0693:                }
0694:            }
0695:
0696:            public static class BugInstanceComparator implements 
0697:                    Comparator<BugInstance> {
0698:                private BugInstanceComparator() {
0699:                }
0700:
0701:                public int compare(BugInstance lhs, BugInstance rhs) {
0702:                    ClassAnnotation lca = lhs.getPrimaryClass();
0703:                    ClassAnnotation rca = rhs.getPrimaryClass();
0704:                    if (lca == null || rca == null)
0705:                        throw new IllegalStateException(
0706:                                "null class annotation: " + lca + "," + rca);
0707:                    int cmp = lca.getClassName().compareTo(rca.getClassName());
0708:                    if (cmp != 0)
0709:                        return cmp;
0710:                    return lhs.compareTo(rhs);
0711:                }
0712:
0713:                public static final BugInstanceComparator instance = new BugInstanceComparator();
0714:            }
0715:
0716:            public static class MultiversionBugInstanceComparator extends
0717:                    BugInstanceComparator {
0718:                @Override
0719:                public int compare(BugInstance lhs, BugInstance rhs) {
0720:                    int result = super .compare(lhs, rhs);
0721:                    if (result != 0)
0722:                        return result;
0723:                    long diff = lhs.getFirstVersion() - rhs.getFirstVersion();
0724:                    if (diff == 0)
0725:                        diff = lhs.getLastVersion() - rhs.getLastVersion();
0726:                    if (diff < 0)
0727:                        return -1;
0728:                    if (diff > 0)
0729:                        return 1;
0730:                    return 0;
0731:                }
0732:
0733:                public static final MultiversionBugInstanceComparator instance = new MultiversionBugInstanceComparator();
0734:            }
0735:
0736:            private Comparator<BugInstance> comparator;
0737:            private TreeSet<BugInstance> bugSet;
0738:            private LinkedHashSet<AnalysisError> errorList;
0739:            private TreeSet<String> missingClassSet;
0740:            @CheckForNull
0741:            private String summaryHTML;
0742:            private ProjectStats projectStats;
0743:            //	private Map<String, ClassHash> classHashMap;
0744:            private Map<String, ClassFeatureSet> classFeatureSetMap;
0745:            private List<AppVersion> appVersionList;
0746:
0747:            private boolean preciseHashOccurrenceNumbersAvailable = false;
0748:            /**
0749:             * Sequence number of the most-recently analyzed version
0750:             * of the code.
0751:             */
0752:            private long sequence;
0753:            /**
0754:             * Release name of the analyzed application.
0755:             */
0756:            private String releaseName;
0757:            /**
0758:             * Current analysis timestamp.
0759:             */
0760:            private long timestamp;
0761:
0762:            /**
0763:             * Constructor.
0764:             * Creates an empty object.
0765:             */
0766:            public SortedBugCollection() {
0767:                this (new ProjectStats());
0768:            }
0769:
0770:            /**
0771:             * Constructor.
0772:             * Creates an empty object.
0773:             */
0774:            public SortedBugCollection(Comparator<BugInstance> comparator) {
0775:                this (new ProjectStats(), comparator);
0776:            }
0777:
0778:            /**
0779:             * Constructor.
0780:             * Creates an empty object given an existing ProjectStats.
0781:             * 
0782:             * @param projectStats the ProjectStats
0783:             */
0784:            public SortedBugCollection(ProjectStats projectStats) {
0785:                this (projectStats, MultiversionBugInstanceComparator.instance);
0786:            }
0787:
0788:            /**
0789:             * Constructor.
0790:             * Creates an empty object given an existing ProjectStats.
0791:             * 
0792:             * @param projectStats the ProjectStats
0793:             * @param comparator to use for sorting bug instances
0794:             */
0795:            public SortedBugCollection(ProjectStats projectStats,
0796:                    Comparator<BugInstance> comparator) {
0797:                this .projectStats = projectStats;
0798:                this .comparator = comparator;
0799:                bugSet = new TreeSet<BugInstance>(comparator);
0800:                errorList = new LinkedHashSet<AnalysisError>() {
0801:                    @Override
0802:                    public boolean add(AnalysisError a) {
0803:                        if (this .size() > 1000)
0804:                            return false;
0805:                        return super .add(a);
0806:                    }
0807:                };
0808:                missingClassSet = new TreeSet<String>();
0809:                summaryHTML = null;
0810:                classFeatureSetMap = new TreeMap<String, ClassFeatureSet>();
0811:                sequence = 0L;
0812:                appVersionList = new LinkedList<AppVersion>();
0813:                releaseName = "";
0814:                timestamp = -1L;
0815:            }
0816:
0817:            public boolean add(BugInstance bugInstance, boolean updateActiveTime) {
0818:                preciseHashOccurrenceNumbersAvailable = false;
0819:                if (updateActiveTime) {
0820:                    bugInstance.setFirstVersion(sequence);
0821:                }
0822:
0823:                return bugSet.add(bugInstance);
0824:            }
0825:
0826:            private void invalidateHashes() {
0827:                preciseHashOccurrenceNumbersAvailable = false;
0828:            }
0829:
0830:            public boolean remove(BugInstance bugInstance) {
0831:                invalidateHashes();
0832:                return bugSet.remove(bugInstance);
0833:            }
0834:
0835:            public Iterator<BugInstance> iterator() {
0836:                return bugSet.iterator();
0837:            }
0838:
0839:            public Collection<BugInstance> getCollection() {
0840:                return bugSet;
0841:            }
0842:
0843:            public void addError(String message, Throwable exception) {
0844:                if (exception instanceof  MissingClassException) {
0845:                    MissingClassException e = (MissingClassException) exception;
0846:                    addMissingClass(AbstractBugReporter.getMissingClassName(e
0847:                            .getClassNotFoundException()));
0848:                    return;
0849:                }
0850:                if (exception instanceof  ClassNotFoundException) {
0851:                    ClassNotFoundException e = (ClassNotFoundException) exception;
0852:                    addMissingClass(AbstractBugReporter.getMissingClassName(e));
0853:                    return;
0854:                }
0855:                if (exception instanceof  edu.umd.cs.findbugs.classfile.MissingClassException) {
0856:                    edu.umd.cs.findbugs.classfile.MissingClassException e = (edu.umd.cs.findbugs.classfile.MissingClassException) exception;
0857:                    addMissingClass(AbstractBugReporter.getMissingClassName(e
0858:                            .toClassNotFoundException()));
0859:                    return;
0860:                }
0861:                errorList.add(new AnalysisError(message, exception));
0862:            }
0863:
0864:            public void addError(AnalysisError error) {
0865:                errorList.add(error);
0866:            }
0867:
0868:            public void addMissingClass(String className) {
0869:                if (className.startsWith("[")) {
0870:                    assert false : "Bad class name " + className;
0871:                    return;
0872:                }
0873:                missingClassSet.add(className);
0874:            }
0875:
0876:            public Iterator<AnalysisError> errorIterator() {
0877:                return errorList.iterator();
0878:            }
0879:
0880:            public Iterator<String> missingClassIterator() {
0881:                return missingClassSet.iterator();
0882:            }
0883:
0884:            public boolean contains(BugInstance bugInstance) {
0885:                return bugSet.contains(bugInstance);
0886:            }
0887:
0888:            public BugInstance getMatching(BugInstance bugInstance) {
0889:                SortedSet<BugInstance> tailSet = bugSet.tailSet(bugInstance);
0890:                if (tailSet.isEmpty())
0891:                    return null;
0892:                BugInstance first = tailSet.first();
0893:                return bugInstance.equals(first) ? first : null;
0894:            }
0895:
0896:            public String getSummaryHTML() throws IOException {
0897:                if (summaryHTML == null) {
0898:                    try {
0899:                        StringWriter writer = new StringWriter();
0900:                        ProjectStats stats = getProjectStats();
0901:                        stats.transformSummaryToHTML(writer);
0902:                        summaryHTML = writer.toString();
0903:                    } catch (final TransformerException e) {
0904:                        IOException ioe = new IOException(
0905:                                "Couldn't generate summary HTML");
0906:                        ioe.initCause(e);
0907:                        throw ioe;
0908:                    }
0909:                }
0910:
0911:                return summaryHTML;
0912:            }
0913:
0914:            public ProjectStats getProjectStats() {
0915:                return projectStats;
0916:            }
0917:
0918:            /* (non-Javadoc)
0919:             * @see edu.umd.cs.findbugs.BugCollection#lookupFromUniqueId(java.lang.String)
0920:             */
0921:            @Deprecated
0922:            public BugInstance lookupFromUniqueId(String uniqueId) {
0923:                for (BugInstance bug : bugSet)
0924:                    if (bug.getInstanceHash().equals(uniqueId))
0925:                        return bug;
0926:                return null;
0927:            }
0928:
0929:            public long getSequenceNumber() {
0930:                return sequence;
0931:            }
0932:
0933:            public void setSequenceNumber(long sequence) {
0934:                this .sequence = sequence;
0935:            }
0936:
0937:            public SortedBugCollection duplicate() {
0938:                SortedBugCollection dup = new SortedBugCollection(
0939:                        (ProjectStats) projectStats.clone(), comparator);
0940:
0941:                SortedBugCollection.cloneAll(dup.bugSet, this .bugSet);
0942:                dup.errorList.addAll(this .errorList);
0943:                dup.missingClassSet.addAll(this .missingClassSet);
0944:                dup.summaryHTML = this .summaryHTML;
0945:                //		dup.classHashMap.putAll(this.classHashMap);
0946:                dup.classFeatureSetMap.putAll(this .classFeatureSetMap);
0947:                dup.sequence = this .sequence;
0948:                dup.timestamp = this .timestamp;
0949:                dup.releaseName = this .releaseName;
0950:                for (AppVersion appVersion : appVersionList) {
0951:                    dup.appVersionList.add((AppVersion) appVersion.clone());
0952:                }
0953:
0954:                return dup;
0955:            }
0956:
0957:            /* (non-Javadoc)
0958:             * @see edu.umd.cs.findbugs.BugCollection#clearBugInstances()
0959:             */
0960:
0961:            public void clearBugInstances() {
0962:                bugSet.clear();
0963:                invalidateHashes();
0964:
0965:            }
0966:
0967:            /* (non-Javadoc)
0968:             * @see edu.umd.cs.findbugs.BugCollection#getReleaseName()
0969:             */
0970:
0971:            public String getReleaseName() {
0972:                if (releaseName == null)
0973:                    return "";
0974:                return releaseName;
0975:            }
0976:
0977:            /* (non-Javadoc)
0978:             * @see edu.umd.cs.findbugs.BugCollection#setReleaseName(java.lang.String)
0979:             */
0980:
0981:            public void setReleaseName(String releaseName) {
0982:                this .releaseName = releaseName;
0983:            }
0984:
0985:            /* (non-Javadoc)
0986:             * @see edu.umd.cs.findbugs.BugCollection#appVersionIterator()
0987:             */
0988:
0989:            public Iterator<AppVersion> appVersionIterator() {
0990:                return appVersionList.iterator();
0991:            }
0992:
0993:            /* (non-Javadoc)
0994:             * @see edu.umd.cs.findbugs.BugCollection#addAppVersion(edu.umd.cs.findbugs.AppVersion)
0995:             */
0996:
0997:            public void addAppVersion(AppVersion appVersion) {
0998:                appVersionList.add(appVersion);
0999:            }
1000:
1001:            /* (non-Javadoc)
1002:             * @see edu.umd.cs.findbugs.BugCollection#clearAppVersions()
1003:             */
1004:
1005:            public void clearAppVersions() {
1006:                appVersionList.clear();
1007:            }
1008:
1009:            /* (non-Javadoc)
1010:             * @see edu.umd.cs.findbugs.BugCollection#createEmptyCollectionWithMetadata()
1011:             */
1012:
1013:            public SortedBugCollection createEmptyCollectionWithMetadata() {
1014:                SortedBugCollection dup = new SortedBugCollection(
1015:                        (ProjectStats) projectStats.clone(), comparator);
1016:                dup.errorList.addAll(this .errorList);
1017:                dup.missingClassSet.addAll(this .missingClassSet);
1018:                dup.summaryHTML = this .summaryHTML;
1019:                dup.classFeatureSetMap.putAll(this .classFeatureSetMap);
1020:                dup.sequence = this .sequence;
1021:                dup.timestamp = this .timestamp;
1022:                dup.releaseName = this .releaseName;
1023:                for (AppVersion appVersion : appVersionList) {
1024:                    dup.appVersionList.add((AppVersion) appVersion.clone());
1025:                }
1026:
1027:                return dup;
1028:            }
1029:
1030:            /* (non-Javadoc)
1031:             * @see edu.umd.cs.findbugs.BugCollection#setTimestamp(long)
1032:             */
1033:
1034:            public void setTimestamp(long timestamp) {
1035:                this .timestamp = timestamp;
1036:            }
1037:
1038:            /* (non-Javadoc)
1039:             * @see edu.umd.cs.findbugs.BugCollection#getTimestamp()
1040:             */
1041:
1042:            public long getTimestamp() {
1043:                return timestamp;
1044:            }
1045:
1046:            /* (non-Javadoc)
1047:             * @see edu.umd.cs.findbugs.BugCollection#getClassFeatureSet(java.lang.String)
1048:             */
1049:
1050:            public ClassFeatureSet getClassFeatureSet(String className) {
1051:                return classFeatureSetMap.get(className);
1052:            }
1053:
1054:            /* (non-Javadoc)
1055:             * @see edu.umd.cs.findbugs.BugCollection#setClassFeatureSet(edu.umd.cs.findbugs.model.ClassFeatureSet)
1056:             */
1057:
1058:            public void setClassFeatureSet(ClassFeatureSet classFeatureSet) {
1059:                classFeatureSetMap.put(classFeatureSet.getClassName(),
1060:                        classFeatureSet);
1061:            }
1062:
1063:            /* (non-Javadoc)
1064:             * @see edu.umd.cs.findbugs.BugCollection#classFeatureSetIterator()
1065:             */
1066:
1067:            public Iterator<ClassFeatureSet> classFeatureSetIterator() {
1068:                return classFeatureSetMap.values().iterator();
1069:            }
1070:
1071:            /* (non-Javadoc)
1072:             * @see edu.umd.cs.findbugs.BugCollection#clearClassFeatures()
1073:             */
1074:            public void clearClassFeatures() {
1075:                classFeatureSetMap.clear();
1076:            }
1077:
1078:            /**
1079:             * @param withMessages The withMessages to set.
1080:             */
1081:            public void setWithMessages(boolean withMessages) {
1082:                this .withMessages = withMessages;
1083:            }
1084:
1085:            /**
1086:             * @return Returns the withMessages.
1087:             */
1088:            public boolean getWithMessages() {
1089:                return withMessages;
1090:            }
1091:
1092:            /* (non-Javadoc)
1093:             * @see edu.umd.cs.findbugs.BugCollection#getAppVersionFromSequenceNumber(int)
1094:             */
1095:            public AppVersion getAppVersionFromSequenceNumber(long target) {
1096:                for (AppVersion av : appVersionList)
1097:                    if (av.getSequenceNumber() == target)
1098:                        return av;
1099:                if (target == this .getSequenceNumber())
1100:                    return this .getCurrentAppVersion();
1101:                return null;
1102:            }
1103:
1104:            /* (non-Javadoc)
1105:             * @see edu.umd.cs.findbugs.BugCollection#findBug(java.lang.String, java.lang.String, int)
1106:             */
1107:            public BugInstance findBug(String instanceHash, String bugType,
1108:                    int lineNumber) {
1109:                for (BugInstance bug : bugSet)
1110:                    if (bug.getInstanceHash().equals(instanceHash)
1111:                            && bug.getBugPattern().getType().equals(bugType)
1112:                            && bug.getPrimarySourceLineAnnotation()
1113:                                    .getStartLine() == lineNumber)
1114:                        return bug;
1115:                return null;
1116:            }
1117:
1118:            /**
1119:             * @param version
1120:             */
1121:            public void setAnalysisVersion(String version) {
1122:                this .analysisVersion = version;
1123:
1124:            }
1125:        }
1126:
1127:        // vim:ts=4
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.