/* * Copyright 2000-2011 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jetbrains.buildServer.xmlReportPlugin; import org.jetbrains.annotations.NotNull; import org.xml.sax.*; import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.helpers.XMLReaderFactory; import java.io.File; import java.util.Map; public abstract class XmlReportParser extends DefaultHandler { private final XMLReader myXmlReader; protected StringBuilder myCData; public static String formatText(@NotNull StringBuilder s) { return s.toString().replace("\r", "").replace("\n", " ").replaceAll("\\s+", " ").replaceAll("<[a-z]>|", "").trim(); } // public static String formatTextWithouNewLine(@NotNull StringBuffer s) { // return s.toString().replace("\r", "").replaceAll("\\s+", " ").trim(); // } protected static int getNumber(String number) { if (number != null) { try { return Integer.parseInt(number); } catch (NumberFormatException e) { return 0; } } return 0; } public static XMLReader createXmlReader(ContentHandler contentHandler, ErrorHandler errHandler, boolean validate) throws SAXException { final XMLReader xmlReader = createXmlReader(); xmlReader.setContentHandler(contentHandler); xmlReader.setErrorHandler(errHandler); setValidationFeature(validate, xmlReader); return xmlReader; } private static XMLReader createXmlReader() throws SAXException { try { return XMLReaderFactory.createXMLReader("com.sun.org.apache.xerces.internal.parsers.SAXParser"); } catch (Exception e) { XmlReportPlugin.LOG.warn("Failed to load default SAXParser", e); return XMLReaderFactory.createXMLReader(); } } private static void setValidationFeature(boolean validate, XMLReader xmlReader) throws SAXNotRecognizedException, SAXNotSupportedException { try { xmlReader.setFeature("http://xml.org/sax/features/validation", validate); } catch (Exception e) { XmlReportPlugin.LOG.warn("Failed to set validation: " + validate, e); } } protected XmlReportParser() { try { myXmlReader = createXmlReader(this, this, false); } catch (Exception e) { throw new RuntimeException(e); } } public void logReportTotals(@NotNull ReportFileContext context, boolean verbose) { } void logParsingTotals(@NotNull final SessionContext sessionContext, @NotNull Map parameters, boolean verbose) { } protected final void doSAXParse(@NotNull ReportFileContext context) throws Exception { clearCData(); myXmlReader.parse(new InputSource(context.getFile().toURI().toString())); } protected void clearCData() { if (myCData != null) { myCData.delete(0, myCData.length()); } } @Override public void characters(char ch[], int start, int length) throws SAXException { if (myCData != null) { myCData.append(ch, start, length); } } public abstract void parse(@NotNull ReportFileContext data) throws Exception; /** * This method is used to dispose the parser (ex. close streams, dispose loggers). * Will be called after parser done all it's work */ public void dispose() {} public boolean supportOnTheFlyParsing() { return false; } public boolean isReportComplete(@NotNull final File report) { // here we preparse the report to check it's complete final CompleteReportHandler handler = new CompleteReportHandler(); try { final XMLReader reader = createXmlReader(handler, null, false); reader.parse(new InputSource(report.toURI().toString())); return handler.isReportComplete(); } catch (SAXParseException e) { return false; } catch (Exception e) { return true; } } private final class CompleteReportHandler extends DefaultHandler { private boolean myReportComplete = false; public boolean isReportComplete() { return myReportComplete; } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if (getRootTag().equals(localName)) myReportComplete = true; } } @NotNull protected abstract String getRootTag(); }