View Javadoc

1   /*
2    * Copyright 2008-2013 smartics, Kronseder & Reiner GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package de.smartics.maven.issues.notes;
17  
18  import java.io.IOException;
19  import java.io.InputStream;
20  import java.io.StringWriter;
21  
22  import javax.xml.parsers.DocumentBuilder;
23  import javax.xml.parsers.DocumentBuilderFactory;
24  import javax.xml.parsers.ParserConfigurationException;
25  import javax.xml.transform.OutputKeys;
26  import javax.xml.transform.Transformer;
27  import javax.xml.transform.TransformerConfigurationException;
28  import javax.xml.transform.TransformerException;
29  import javax.xml.transform.TransformerFactory;
30  import javax.xml.transform.dom.DOMSource;
31  import javax.xml.transform.stream.StreamResult;
32  
33  import org.w3c.dom.Document;
34  import org.w3c.dom.Node;
35  import org.w3c.dom.NodeList;
36  import org.xml.sax.SAXException;
37  
38  /**
39   * The reader to read manual release notes to include in the report.
40   *
41   * @author <a href="mailto:robert.reiner@smartics.de">Robert Reiner</a>
42   * @version $Revision:591 $
43   */
44  public class NotesReader
45  {
46    // ********************************* Fields *********************************
47  
48    // --- constants ------------------------------------------------------------
49  
50    // --- members --------------------------------------------------------------
51  
52    // ****************************** Initializer *******************************
53  
54    // ****************************** Constructors ******************************
55  
56    /**
57     * Default constructor.
58     */
59    public NotesReader()
60    {
61    }
62  
63    // ****************************** Inner Classes *****************************
64  
65    // ********************************* Methods ********************************
66  
67    // --- init -----------------------------------------------------------------
68  
69    // --- get&set --------------------------------------------------------------
70  
71    // --- business -------------------------------------------------------------
72  
73    /**
74     * Reads the document from the input stream and returns the content of the
75     * body element.
76     *
77     * @param inputStream the stream to read from.
78     * @return the content of the body element.
79     * @throws IOException if the body content cannot be extracted.
80     */
81    public String read(final InputStream inputStream) throws IOException
82    {
83      final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
84      DocumentBuilder builder = null;
85      try
86      {
87        builder = factory.newDocumentBuilder();
88        final Document document = builder.parse(inputStream);
89        return extractBodyContent(document);
90      }
91      catch (final ParserConfigurationException e)
92      {
93        final IOException ex =
94            new IOException(
95                "Cannot create parser to read description file from stream.");
96        ex.initCause(e);
97        throw ex; // NOPMD Original stack trace is preserved.
98      }
99      catch (final SAXException e)
100     {
101       final IOException ex =
102           new IOException("Cannot read description file from stream.");
103       ex.initCause(e);
104       throw ex; // NOPMD Original stack trace is preserved.
105     }
106   }
107 
108   /**
109    * Extracts the body content from the document.
110    *
111    * @param document the complete document to extract the content of the body
112    *          element.
113    * @return the content of the body element as a string.
114    * @throws IOException if there is more or less than one body element or there
115    *           are problems processing the document.
116    */
117   private String extractBodyContent(final Document document) throws IOException
118   {
119     final NodeList bodyList = document.getElementsByTagName("body");
120     final int bodyCount = bodyList.getLength();
121     if (bodyCount != 1)
122     {
123       throw new IOException("Expected one body element, found " + bodyCount
124                             + '.');
125     }
126 
127     final Node body = bodyList.item(0);
128 
129     return extractContent(body);
130   }
131 
132   /**
133    * Extracts the content of the body element, removing the body tags.
134    *
135    * @param body the node whose content is requested.
136    * @return the content of the body element.
137    * @throws IOException if there is a problem processing the node.
138    */
139   private String extractContent(final Node body) throws IOException
140   {
141     try
142     {
143       final DOMSource source = new DOMSource(body);
144       final StringWriter writer = new StringWriter(2048);
145       final StreamResult result = new StreamResult(writer);
146       final TransformerFactory transformerFactory =
147           TransformerFactory.newInstance();
148       final Transformer transformer = transformerFactory.newTransformer();
149       // transformer.setOutputProperty(OutputKeys.INDENT, "yes");
150       transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
151       transformer.transform(source, result);
152 
153       final String content = writer.toString();
154       final int start = content.indexOf("<body>") + "<body>".length();
155       final int end = content.lastIndexOf("</body>");
156 
157       return content.substring(start, end).trim();
158     }
159     catch (final TransformerConfigurationException e)
160     {
161       final IOException ex =
162           new IOException("Cannot write description file to memory.");
163       ex.initCause(e);
164       throw ex; // NOPMD Original stack trace is preserved.
165     }
166     catch (final TransformerException e)
167     {
168       final IOException ex =
169           new IOException("Cannot write description file to memory.");
170       ex.initCause(e);
171       throw ex; // NOPMD Original stack trace is preserved.
172     }
173   }
174 
175   // --- object basics --------------------------------------------------------
176 
177 }