View Javadoc

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