Coverage Report - com.jcabi.xml.DomParser
 
Classes in this File Line Coverage Branch Coverage Complexity
DomParser
50%
11/22
18%
3/16
7
 
 1  
 /**
 2  
  * Copyright (c) 2012-2017, jcabi.com
 3  
  * All rights reserved.
 4  
  *
 5  
  * Redistribution and use in source and binary forms, with or without
 6  
  * modification, are permitted provided that the following conditions
 7  
  * are met: 1) Redistributions of source code must retain the above
 8  
  * copyright notice, this list of conditions and the following
 9  
  * disclaimer. 2) Redistributions in binary form must reproduce the above
 10  
  * copyright notice, this list of conditions and the following
 11  
  * disclaimer in the documentation and/or other materials provided
 12  
  * with the distribution. 3) Neither the name of the jcabi.com nor
 13  
  * the names of its contributors may be used to endorse or promote
 14  
  * products derived from this software without specific prior written
 15  
  * permission.
 16  
  *
 17  
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 18  
  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
 19  
  * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 20  
  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 21  
  * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 22  
  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 23  
  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 24  
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 25  
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 26  
  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 27  
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 28  
  * OF THE POSSIBILITY OF SUCH DAMAGE.
 29  
  */
 30  
 package com.jcabi.xml;
 31  
 
 32  
 import com.jcabi.log.Logger;
 33  
 import java.io.ByteArrayInputStream;
 34  
 import java.io.IOException;
 35  
 import java.io.UnsupportedEncodingException;
 36  
 import java.util.regex.Pattern;
 37  
 import javax.xml.parsers.DocumentBuilderFactory;
 38  
 import javax.xml.parsers.ParserConfigurationException;
 39  
 import lombok.EqualsAndHashCode;
 40  
 import lombok.ToString;
 41  
 import org.w3c.dom.Document;
 42  
 import org.xml.sax.SAXException;
 43  
 
 44  
 /**
 45  
  * Convenient parser of XML to DOM.
 46  
  *
 47  
  * <p>Objects of this class are immutable and thread-safe.
 48  
  *
 49  
  * @author Yegor Bugayenko (yegor@teamed.io)
 50  
  * @version $Id: 8c877ef25e09a2e271adfc7a5224d5dc84b10904 $
 51  
  * @since 0.1
 52  
  */
 53  0
 @ToString
 54  0
 @EqualsAndHashCode(of = "xml")
 55  
 final class DomParser {
 56  
 
 57  
     /**
 58  
      * Pattern to detect if passed txt looks like xml. Patterns constants are
 59  
      * auto-generated by Maven at compile time using the script in
 60  
      * "src/main/groovy/GeneratePatterns.groovy".
 61  
      */
 62  1
     private static final Pattern PATTERN = Pattern.compile(Patterns.XML);
 63  
 
 64  
     /**
 65  
      * The XML as a text.
 66  
      */
 67  
     private final transient String xml;
 68  
 
 69  
     /**
 70  
      * Document builder factory to use for parsing.
 71  
      */
 72  
     private final transient DocumentBuilderFactory factory;
 73  
 
 74  
     /**
 75  
      * Public ctor.
 76  
      *
 77  
      * <p>An {@link IllegalArgumentException} may be thrown if the parameter
 78  
      * passed is not in XML format. It doesn't perform a strict validation
 79  
      * and is not guaranteed that an exception will be thrown whenever
 80  
      * the parameter is not XML.
 81  
      *
 82  
      * @param fct Document builder factory to use
 83  
      * @param txt The XML in text
 84  
      */
 85  419
     DomParser(final DocumentBuilderFactory fct, final String txt) {
 86  419
         if (txt.isEmpty()) {
 87  0
             throw new IllegalArgumentException("Empty document, not an XML");
 88  
         }
 89  419
         if (!DomParser.PATTERN.matcher(txt.replaceAll("\\s", "")).matches()) {
 90  3
             throw new IllegalArgumentException(
 91  
                 String.format("Doesn't look like XML: '%s'", txt)
 92  
             );
 93  
         }
 94  416
         this.xml = txt;
 95  416
         this.factory = fct;
 96  416
     }
 97  
 
 98  
     /**
 99  
      * Get document of body.
 100  
      * @return The document
 101  
      */
 102  
     public Document document() {
 103  
         final Document doc;
 104  
         try {
 105  410
             doc = this.factory.newDocumentBuilder().parse(
 106  
                 new ByteArrayInputStream(this.xml.getBytes("UTF-8"))
 107  
             );
 108  0
         } catch (final UnsupportedEncodingException ex) {
 109  0
             throw new IllegalStateException(ex);
 110  0
         } catch (final IOException ex) {
 111  0
             throw new IllegalStateException(ex);
 112  0
         } catch (final ParserConfigurationException ex) {
 113  0
             throw new IllegalStateException(ex);
 114  0
         } catch (final SAXException ex) {
 115  0
             throw new IllegalArgumentException(
 116  
                 Logger.format("Invalid XML: \"%s\"", this.xml), ex
 117  
             );
 118  410
         }
 119  410
         return doc;
 120  
     }
 121  
 
 122  
 }