📄 saxbugcollectionhandler.java
字号:
/* * FindBugs - Find bugs in Java programs * Copyright (C) 2004-2005 University of Maryland * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */package edu.umd.cs.findbugs;import java.io.File;import java.util.ArrayList;import java.util.Stack;import java.util.regex.Pattern;import org.xml.sax.Attributes;import org.xml.sax.SAXException;import org.xml.sax.helpers.DefaultHandler;import edu.umd.cs.findbugs.ba.ClassHash;import edu.umd.cs.findbugs.filter.AndMatcher;import edu.umd.cs.findbugs.filter.BugMatcher;import edu.umd.cs.findbugs.filter.ClassMatcher;import edu.umd.cs.findbugs.filter.CompoundMatcher;import edu.umd.cs.findbugs.filter.DesignationMatcher;import edu.umd.cs.findbugs.filter.FieldMatcher;import edu.umd.cs.findbugs.filter.Filter;import edu.umd.cs.findbugs.filter.FirstVersionMatcher;import edu.umd.cs.findbugs.filter.LastVersionMatcher;import edu.umd.cs.findbugs.filter.LocalMatcher;import edu.umd.cs.findbugs.filter.Matcher;import edu.umd.cs.findbugs.filter.MethodMatcher;import edu.umd.cs.findbugs.filter.OrMatcher;import edu.umd.cs.findbugs.filter.PriorityMatcher;import edu.umd.cs.findbugs.model.ClassFeatureSet;import edu.umd.cs.findbugs.util.Strings;/** * Build a BugCollection based on SAX events. * This is intended to replace the old DOM-based parsing * of XML bug result files, which was very slow. * * @author David Hovemeyer */public class SAXBugCollectionHandler extends DefaultHandler { /** * */ private static final String FIND_BUGS_FILTER = "FindBugsFilter"; /** * */ private static final String PROJECT = "Project"; /** * */ private static final String BUG_COLLECTION = "BugCollection"; private BugCollection bugCollection; private Project project; private Stack<CompoundMatcher> matcherStack = new Stack<CompoundMatcher>(); private Filter filter; private ArrayList<String> elementStack; private StringBuffer textBuffer; private BugInstance bugInstance; private PackageMemberAnnotation packageMemberAnnotation; private AnalysisError analysisError;// private ClassHash classHash; private ClassFeatureSet classFeatureSet; private ArrayList<String> stackTrace; private int nestingOfIgnoredElements = 0; private final File base; private final String topLevelName; public SAXBugCollectionHandler(String topLevelName, BugCollection bugCollection, Project project, File base) { this.topLevelName = topLevelName; this.bugCollection = bugCollection; this.project = project; this.elementStack = new ArrayList<String>(); this.textBuffer = new StringBuffer(); this.stackTrace = new ArrayList<String>(); this.base = base; } public SAXBugCollectionHandler(BugCollection bugCollection, Project project, File base) { this(BUG_COLLECTION, bugCollection, project, base); } public SAXBugCollectionHandler(Project project, File base) { this(PROJECT, null, project, base); } public SAXBugCollectionHandler(Filter filter, File base) { this(FIND_BUGS_FILTER, null, null, base); this.filter = filter; pushCompoundMatcher(filter); } Pattern ignoredElement = Pattern.compile("Message|ShortMessage|LongMessage"); public boolean discardedElement(String qName) { return ignoredElement.matcher(qName).matches(); } private static boolean DEBUG = false; @Override public void startElement(String uri, String name, String qName, Attributes attributes) throws SAXException { // URI should always be empty. // So, qName is the name of the element. if (discardedElement(qName)) { nestingOfIgnoredElements++; } else if (nestingOfIgnoredElements > 0) { // ignore it } else { // We should be parsing the outer BugCollection element. if (elementStack.isEmpty() && !qName.equals(topLevelName)) throw new SAXException( "Invalid top-level element (expected " + topLevelName + ", saw " + qName + ")"); if (qName.equals(BUG_COLLECTION)) { // Read and set the sequence number. String version = attributes.getValue("version"); if (bugCollection instanceof SortedBugCollection) ((SortedBugCollection)bugCollection).setAnalysisVersion(version); // Read and set the sequence number. String sequence = attributes.getValue("sequence"); long seqval = parseLong(sequence, 0L); bugCollection.setSequenceNumber(seqval); // Read and set timestamp. String timestamp = attributes.getValue("timestamp"); long tsval = parseLong(timestamp, -1L); bugCollection.setTimestamp(tsval); // Read and set timestamp. String analysisTimestamp = attributes.getValue("analysisTimestamp"); if (analysisTimestamp != null) { bugCollection.setAnalysisTimestamp(parseLong(analysisTimestamp, -1L)); } // Set release name, if present. String releaseName = attributes.getValue("release"); bugCollection.setReleaseName((releaseName != null) ? releaseName : ""); } else if (isTopLevelFilter(qName)) { if (project != null) { filter = new Filter(); project.setSuppressionFilter(filter); } matcherStack.clear(); pushCompoundMatcher(filter); } else if (qName.equals(PROJECT)) { // Project element String filename = attributes.getValue(Project.FILENAME_ATTRIBUTE_NAME); if (filename != null) project.setProjectFileName(filename); String projectName = attributes.getValue(Project.PROJECTNAME_ATTRIBUTE_NAME); if (projectName != null) project.setProjectName(projectName); } else { String outerElement = elementStack.get(elementStack.size() - 1); if (outerElement.equals(BUG_COLLECTION)) { // Parsing a top-level element of the BugCollection if (qName.equals("BugInstance")) { // BugInstance element - get required type and priority attributes String type = getRequiredAttribute(attributes, "type", qName); String priority = getRequiredAttribute(attributes, "priority", qName); try { int prio = Integer.parseInt(priority); bugInstance = new BugInstance(type, prio); } catch (NumberFormatException e) { throw new SAXException("BugInstance with invalid priority value \"" + priority + "\"", e); } String uniqueId = attributes.getValue("uid"); if (uniqueId != null) { bugInstance.setUniqueId(uniqueId); } String firstVersion = attributes.getValue("first"); if (firstVersion != null) { bugInstance.setFirstVersion(Long.parseLong(firstVersion)); } String lastVersion = attributes.getValue("last"); if (lastVersion != null) { bugInstance.setLastVersion(Long.parseLong(lastVersion)); } if (bugInstance.getLastVersion() >= 0 && bugInstance.getFirstVersion() > bugInstance.getLastVersion()) throw new IllegalStateException("huh"); String introducedByChange = attributes.getValue("introducedByChange"); if (introducedByChange != null) { bugInstance.setIntroducedByChangeOfExistingClass(TigerSubstitutes.parseBoolean(introducedByChange)); } String removedByChange = attributes.getValue("removedByChange"); if (removedByChange != null) { bugInstance.setRemovedByChangeOfPersistingClass(TigerSubstitutes.parseBoolean(removedByChange)); } String oldInstanceHash = attributes.getValue("instanceHash"); if (oldInstanceHash != null) { bugInstance.setOldInstanceHash(oldInstanceHash); } } else if (qName.equals("FindBugsSummary")) { String timestamp = getRequiredAttribute(attributes, "timestamp", qName); try { bugCollection.getProjectStats().setTimestamp(timestamp); } catch (java.text.ParseException e) { throw new SAXException("Unparseable sequence number: '" + timestamp + "'", e); } } } else if (outerElement.equals("BugInstance")) { parseBugInstanceContents(qName, attributes); } else if (outerElement.equals("Method") || outerElement.equals("Field") || outerElement.equals("Class")) { if (qName.equals("SourceLine")) { // package member elements can contain nested SourceLine elements. packageMemberAnnotation.setSourceLines(createSourceLineAnnotation(qName, attributes)); } } else if (outerElement.equals(BugCollection.ERRORS_ELEMENT_NAME)) { if (qName.equals(BugCollection.ANALYSIS_ERROR_ELEMENT_NAME) || qName.equals(BugCollection.ERROR_ELEMENT_NAME)) { analysisError = new AnalysisError("Unknown error"); stackTrace.clear(); } } else if (outerElement.equals("PackageStats")) { if (qName.equals("ClassStats")) { String className = getRequiredAttribute(attributes, "class", qName); Boolean isInterface = Boolean.valueOf( getRequiredAttribute(attributes, "interface", qName)); int size = Integer.valueOf( getRequiredAttribute(attributes, "size", qName)); String sourceFile = attributes.getValue("sourceFile"); bugCollection.getProjectStats().addClass(className, sourceFile, isInterface, size); } } else if (isTopLevelFilter(outerElement) || outerElement.equals("Match") || outerElement.equals("And") || outerElement.equals("Or")) { parseMatcher(qName, attributes); } else if (outerElement.equals("ClassFeatures")) { if (qName.equals(ClassFeatureSet.ELEMENT_NAME)) { String className = getRequiredAttribute(attributes, "class", qName); classFeatureSet = new ClassFeatureSet(); classFeatureSet.setClassName(className); } } else if (outerElement.equals(ClassFeatureSet.ELEMENT_NAME)) { if (qName.equals(ClassFeatureSet.FEATURE_ELEMENT_NAME)) { String value = getRequiredAttribute(attributes, "value", qName); classFeatureSet.addFeature(value); } } else if (outerElement.equals(BugCollection.HISTORY_ELEMENT_NAME)) { if (qName.equals(AppVersion.ELEMENT_NAME)) { try { String sequence = getRequiredAttribute(attributes, "sequence", qName); String timestamp = attributes.getValue("timestamp"); String releaseName = attributes.getValue("release"); String codeSize = attributes.getValue("codeSize"); String numClasses = attributes.getValue("numClasses"); AppVersion appVersion = new AppVersion(Long.valueOf(sequence)); if (timestamp != null) appVersion.setTimestamp(Long.valueOf(timestamp)); if (releaseName != null) appVersion.setReleaseName(releaseName); if (codeSize != null) appVersion.setCodeSize(Integer.parseInt(codeSize)); if (numClasses != null) appVersion.setNumClasses(Integer.parseInt(numClasses)); bugCollection.addAppVersion(appVersion); } catch (NumberFormatException e) { throw new SAXException("Invalid AppVersion element", e); } } } } } textBuffer.delete(0, textBuffer.length()); elementStack.add(qName); } private boolean isTopLevelFilter(String qName) { return qName.equals(FIND_BUGS_FILTER) || qName.equals("SuppressionFilter"); } private void addMatcher(Matcher m) { if (m == null) throw new IllegalArgumentException("matcher must not be null");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -