Coverage Report - org.apache.camel.maven.GenerateDocBookMojo
 
Classes in this File Line Coverage Branch Coverage Complexity
GenerateDocBookMojo
0% 
0% 
0
 
 1  
 /**
 2  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  
  * contributor license agreements.  See the NOTICE file distributed with
 4  
  * this work for additional information regarding copyright ownership.
 5  
  * The ASF licenses this file to You under the Apache License, Version 2.0
 6  
  * (the "License"); you may not use this file except in compliance with
 7  
  * the License.  You may obtain a copy of the License at
 8  
  *
 9  
  *      http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 package org.apache.camel.maven;
 18  
 
 19  
 import org.apache.maven.plugin.AbstractMojo;
 20  
 import org.apache.maven.plugin.MojoExecutionException;
 21  
 
 22  
 import java.io.File;
 23  
 import java.io.FileOutputStream;
 24  
 import java.io.IOException;
 25  
 import java.io.BufferedInputStream;
 26  
 import java.io.BufferedOutputStream;
 27  
 import java.io.FileWriter;
 28  
 import java.io.ByteArrayOutputStream;
 29  
 import java.io.InputStream;
 30  
 import java.io.PrintWriter;
 31  
 import java.util.ArrayList;
 32  
 import java.util.Iterator;
 33  
 import java.util.List;
 34  
 import java.util.StringTokenizer;
 35  
 import java.net.URL;
 36  
 import java.net.URLConnection;
 37  
 
 38  
 import javax.xml.transform.Transformer;
 39  
 import javax.xml.transform.TransformerFactory;
 40  
 import javax.xml.transform.dom.DOMSource;
 41  
 import javax.xml.transform.stream.StreamResult;
 42  
 import javax.xml.transform.stream.StreamSource;
 43  
 
 44  
 import org.w3c.dom.Element;
 45  
 import org.w3c.dom.NodeList;
 46  
 import org.w3c.dom.Document;
 47  
 import org.w3c.dom.Node;
 48  
 import org.w3c.dom.NamedNodeMap;
 49  
 
 50  
 import org.w3c.tidy.DOMElementImpl;
 51  
 import org.w3c.tidy.Tidy;
 52  
 
 53  
 import org.apache.commons.logging.Log;
 54  
 import org.apache.commons.logging.LogFactory;
 55  
 
 56  
 /**
 57  
  * Goal which extracts the content of a wiki page and converts it to docbook
 58  
  * format
 59  
  * 
 60  
  * @goal htmlToDocbook
 61  
  * @phase process-sources
 62  
  */
 63  0
 public class GenerateDocBookMojo extends AbstractMojo {
 64  
 
 65  
         /**
 66  
          * Base URL.
 67  
          * 
 68  
          * @parameter expression="${baseURL}"
 69  
          *            default-value="http://activemq.apache.org/camel/"
 70  
          * @required
 71  
          */
 72  
         private String baseURL;
 73  
 
 74  
         /**
 75  
          * List of resources
 76  
          * 
 77  
          * @parameter
 78  
          */
 79  
         private String[] resources;
 80  
 
 81  
         /**
 82  
          * List of author's fullname
 83  
          * 
 84  
          * @parameter
 85  
          */
 86  
         private String[] authors;
 87  
 
 88  
         /**
 89  
          * Location of the xsl file.
 90  
          * 
 91  
          * @parameter expression="${configDirectory}"
 92  
          *           
 93  
          */
 94  
         private String xslFile;
 95  
 
 96  
         /**
 97  
          * Location of the output directory.
 98  
          * 
 99  
          * @parameter expression="${project.build.directory}/docbkx/docbkx-source"
 100  
          */
 101  
         private String outputPath;
 102  
 
 103  
         /**
 104  
          * Location of the output directory for wiki source.
 105  
          * 
 106  
          * @parameter expression="${project.build.directory}/docbkx/wiki-source"
 107  
          */
 108  
         private String wikiOutputPath;
 109  
 
 110  
         /**
 111  
          * @parameter expression="${title}"
 112  
          * @required
 113  
          */
 114  
         private String title;
 115  
 
 116  
         /**
 117  
          * @parameter expression="${subtitle}"
 118  
          */
 119  
         private String subtitle;
 120  
 
 121  
         /**
 122  
          * @parameter expression="${mainFilename}" default-value="manual"
 123  
          * @required
 124  
          */
 125  
         private String mainFilename;
 126  
 
 127  
         /**
 128  
          * @parameter expression="${version}" default-value="${project.version}"
 129  
          */
 130  
         private String version;
 131  
 
 132  
         /**
 133  
          * @parameter expression="${legalNotice}"
 134  
          */
 135  
         private String legalNotice;
 136  
 
 137  
         /**
 138  
          * Location of image files.
 139  
          * 
 140  
          * @parameter expression="${project.build.directory}/site/book/images"
 141  
          *            
 142  
          */
 143  
         private String imageLocation;
 144  
 
 145  
         private String chapterId;
 146  
 
 147  0
         private static final transient Log log = LogFactory
 148  
                         .getLog(GenerateDocBookMojo.class);
 149  
 
 150  
         public void execute() throws MojoExecutionException {
 151  0
                 File outputDir = new File(outputPath);
 152  0
                 File wikiOutputDir = new File(wikiOutputPath);
 153  0
                 File imageDir = new File(imageLocation);
 154  0
                 if (!outputDir.exists()) {
 155  0
                         outputDir.mkdirs();
 156  0
                         imageDir.mkdirs();
 157  0
                         wikiOutputDir.mkdirs();
 158  
                 }
 159  0
                 this.createMainXML();
 160  
 
 161  0
                 for (int i = 0; i < resources.length; ++i) {
 162  0
                         this.setChapterId(removeExtension(resources[i]));
 163  
 
 164  0
                         process(resources[i]);
 165  
                 }
 166  
 
 167  0
         }
 168  
 
 169  
         /**
 170  
          * Extract the wiki content and tranform it into docbook format
 171  
          * 
 172  
          * @param resource
 173  
          */
 174  
         public void process(String resource) {
 175  
 
 176  0
                 Tidy tidy = new Tidy();
 177  0
                 ByteArrayOutputStream out = null;
 178  0
                 BufferedOutputStream output = null;
 179  0
                 BufferedOutputStream wikiOutput = null;
 180  0
                 StreamSource streamSource = null;
 181  
 
 182  0
                 tidy.setXmlOut(true);
 183  
                 try {
 184  0
                         out = new ByteArrayOutputStream();
 185  0
                         URL u = new URL(baseURL + resource);
 186  0
                         Document doc = tidy.parseDOM(
 187  
                                         new BufferedInputStream(u.openStream()), out);
 188  0
                         out.close();
 189  
                         // let's extract the div element with class="wiki-content
 190  
                         // maincontent"
 191  0
                         NodeList nodeList = doc.getElementsByTagName("div");
 192  0
                         for (int i = 0; i < nodeList.getLength(); ++i) {
 193  0
                                 Node node = nodeList.item(i);
 194  
 
 195  0
                                 NamedNodeMap nm = node.getAttributes();
 196  0
                                 Node attr = nm.getNamedItem("class");
 197  
 
 198  0
                                 if (attr != null
 199  
                                                 && attr.getNodeValue().equalsIgnoreCase(
 200  
                                                                 "wiki-content maincontent")) {
 201  0
                                         downloadImages(node);
 202  
                                         // These attributes will be used by xsl to
 203  0
                                         Element element = (Element) node;
 204  0
                                         element.setAttribute("chapterId", chapterId);
 205  0
                                         element.setAttribute("baseURL", baseURL);
 206  0
                                         element.setAttribute("imageLocation", "../images/");
 207  
 
 208  0
                                         DOMSource source = new DOMSource(
 209  
                                                         processH2Section(doc, node));
 210  
 
 211  0
                                         output = new BufferedOutputStream(new FileOutputStream(
 212  
                                                         outputPath + File.separator
 213  
                                                                         + removeExtension(resource) + ".xml"));
 214  0
                                         StreamResult result = new StreamResult(output);
 215  0
                                         TransformerFactory tFactory = TransformerFactory
 216  
                                                         .newInstance();
 217  0
                                         if (xslFile != null && !xslFile.trim().equals("")) {
 218  0
                                                 streamSource = new StreamSource(xslFile);
 219  0
                                         } else {
 220  0
                                                 InputStream xslStream = getClass().getResourceAsStream(
 221  
                                                                 "/docbook.xsl");
 222  0
                                                 streamSource = new StreamSource(xslStream);
 223  
                                         }
 224  
 
 225  0
                                         Transformer transformer = tFactory
 226  
                                                         .newTransformer(streamSource);
 227  0
                                         transformer.transform(source, result);
 228  
 
 229  
                                         // generate the wiki source for debugging
 230  0
                                         wikiOutput = new BufferedOutputStream(new FileOutputStream(
 231  
                                                         wikiOutputPath + File.separator
 232  
                                                                         + removeExtension(resource) + ".html"));
 233  0
                                         result = new StreamResult(wikiOutput);
 234  0
                                         transformer = tFactory.newTransformer();
 235  0
                                         transformer.transform(source, result);
 236  
 
 237  0
                                         break;
 238  
                                 }
 239  
 
 240  
                         }
 241  
 
 242  0
                 } catch (Exception e) {
 243  0
                         log.debug("Exception processing wiki content", e);
 244  
                 } finally {
 245  0
                         try {
 246  0
                                 if (output != null)
 247  0
                                         output.close();
 248  0
                         } catch (IOException e) {
 249  
                                 // TODO Auto-generated catch block
 250  0
                                 log.debug("Exception closing output stream", e);
 251  0
                         }
 252  0
                 }
 253  0
         }
 254  
 
 255  
         /*
 256  
          *  create the main docbook xml file 
 257  
          */
 258  
         public void createMainXML() {
 259  
                 try {
 260  
 
 261  0
                         PrintWriter out = new PrintWriter(new FileWriter(outputPath
 262  
                                         + File.separator + mainFilename + ".xml"));
 263  
 
 264  0
                         out
 265  
                                         .println("<!DOCTYPE book PUBLIC \"-//OASIS//DTD DocBook XML V4.4//EN\" \"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd\" ");
 266  0
                         out.println("[");
 267  
 
 268  0
                         for (int i = 0; i < resources.length; ++i) {
 269  0
                                 out.println("<!ENTITY " + removeExtension(resources[i])
 270  
                                                 + " SYSTEM \"" + removeExtension(resources[i])
 271  
                                                 + ".xml\">");
 272  
                         }
 273  
 
 274  0
                         out.println("]>");
 275  0
                         out.println("<book>");
 276  0
                         out.println("<bookinfo>");
 277  0
                         out.println("<title>" + title + "</title>");
 278  0
                         out.println("<subtitle>" + subtitle + "</subtitle>");
 279  0
                         out.println("<releaseinfo>" + version + "</releaseinfo>");
 280  0
                         out.println(" <authorgroup>");
 281  0
                         if (authors != null) {
 282  0
                                 for (int i = 0; i < authors.length; ++i) {
 283  0
                                         StringTokenizer name = new StringTokenizer(authors[i]);
 284  0
                                         String fname = name.nextToken();
 285  0
                                         String lname = "";
 286  0
                                         if (name.hasMoreTokens()) {
 287  0
                                                 lname = name.nextToken();
 288  
                                         }
 289  0
                                         out.println("<author>");
 290  0
                                         out.println("<firstname>" + fname + "</firstname>");
 291  0
                                         out.println("<surname>" + lname + "</surname>");
 292  0
                                         out.println("</author>");
 293  
 
 294  
                                 }
 295  
                         }
 296  
 
 297  0
                         out.println("</authorgroup>");
 298  0
                         out.println("<legalnotice>");
 299  0
                         if (legalNotice != null && legalNotice.length() > 0) {
 300  0
                                 out.println("<para>");
 301  0
                                 out.println(legalNotice);
 302  0
                                 out.println("</para>");
 303  0
                         } else {
 304  0
                                 out
 305  
                                                 .println("<para>Licensed to the Apache Software Foundation (ASF) under one or more");
 306  0
                                 out
 307  
                                                 .println("contributor license agreements. See the NOTICE file distributed with");
 308  0
                                 out
 309  
                                                 .println("this work for additional information regarding copyright ownership. The");
 310  0
                                 out
 311  
                                                 .println("ASF licenses this file to You under the Apache License, Version 2.0 (the");
 312  0
                                 out
 313  
                                                 .println("\"License\"); you may not use this file except in compliance with the");
 314  0
                                 out
 315  
                                                 .println("License. You may obtain a copy of the License at</para>");
 316  0
                                 out
 317  
                                                 .println("<para>http://www.apache.org/licenses/LICENSE-2.0</para>");
 318  0
                                 out
 319  
                                                 .println("<para>Unless required by applicable law or agreed to in writing,");
 320  0
                                 out
 321  
                                                 .println(" software distributed under the License is distributed on an \"AS IS\"");
 322  0
                                 out
 323  
                                                 .println("BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or");
 324  0
                                 out
 325  
                                                 .println("implied. See the License for the specific language governing permissions");
 326  0
                                 out.println("and limitations under the License.</para>");
 327  
                         }
 328  
 
 329  0
                         out.println("</legalnotice>");
 330  0
                         out.println("</bookinfo>");
 331  0
                         out.println("<toc></toc>");
 332  
 
 333  0
                         for (int i = 0; i < resources.length; ++i) {
 334  0
                                 out.println("&" + removeExtension(resources[i]) + ";");
 335  
                         }
 336  
 
 337  0
                         out.println("</book>");
 338  0
                         out.flush();
 339  0
                         out.close();
 340  
 
 341  0
                 } catch (IOException e) {
 342  
                         // TODO Auto-generated catch block
 343  0
                         log.debug("Exception in creating manual.xml file", e);
 344  0
                 }
 345  0
         }
 346  
 
 347  
         public void downloadImages(Node node) {
 348  0
                 List<String> imageList = getImageUrls(node);
 349  0
                 Iterator<String> iter = imageList.iterator();
 350  0
                 while (iter.hasNext()) {
 351  0
                         String imageUrl = (String) iter.next();
 352  0
                         String imageFile = "imageFile";
 353  
 
 354  
                         //check if url path is relative
 355  0
                         if (imageUrl.indexOf("http://") < 0) {
 356  0
                                 imageUrl = baseURL + imageUrl;
 357  
                         }
 358  
                         try {
 359  
 
 360  0
                                 URL url = new URL(imageUrl);
 361  0
                                 StringTokenizer st = new StringTokenizer(url.getFile(), "/");
 362  0
                                 while (st.hasMoreTokens()) {
 363  0
                                         imageFile = st.nextToken();
 364  0
                                 }
 365  
 
 366  0
                                 URLConnection connection = url.openConnection();
 367  0
                                 InputStream stream = connection.getInputStream();
 368  0
                                 BufferedInputStream in = new BufferedInputStream(stream);
 369  0
                                 FileOutputStream file = new FileOutputStream(imageLocation
 370  
                                                 + File.separator + imageFile);
 371  0
                                 BufferedOutputStream out = new BufferedOutputStream(file);
 372  
                                 int i;
 373  0
                                 while ((i = in.read()) != -1) {
 374  0
                                         out.write(i);
 375  0
                                 }
 376  0
                                 out.flush();
 377  0
                         } catch (Exception e) {
 378  0
                                 log.debug("Exception in downloading image " + imageFile, e);
 379  0
                         }
 380  
 
 381  0
                 }
 382  0
         }
 383  
 
 384  
         public List<String> getImageUrls(Node node) {
 385  0
                 List<String> list = new ArrayList<String>();
 386  0
                 DOMElementImpl doc = (DOMElementImpl) node;
 387  0
                 NodeList imageList = doc.getElementsByTagName("img");
 388  
 
 389  0
                 if (imageList != null) {
 390  0
                         for (int i = 0; i < imageList.getLength(); ++i) {
 391  0
                                 Node imageNode = imageList.item(i);
 392  
 
 393  0
                                 NamedNodeMap nm = imageNode.getAttributes();
 394  0
                                 Node attr = nm.getNamedItem("src");
 395  0
                                 if (attr != null) {
 396  0
                                         list.add(attr.getNodeValue());
 397  
                                 }
 398  
 
 399  
                         }
 400  
                 }
 401  0
                 return list;
 402  
         }
 403  
 
 404  
         public String getChapterId() {
 405  0
                 return chapterId;
 406  
         }
 407  
 
 408  
         public void setChapterId(String chapterId) {
 409  0
                 this.chapterId = chapterId;
 410  0
         }
 411  
 
 412  
         public String removeExtension(String resource) {
 413  0
                 int index = resource.indexOf('.');
 414  0
                 return resource.substring(0, index);
 415  
         }
 416  
 
 417  
         /*
 418  
          * creates a <h2_section> node  and place all nodes  after a <h2> node until another <h2> node is found. 
 419  
          * This is so that we can divide chapter contents into section delimited by a <h2> node
 420  
          */
 421  
 
 422  
         public Node processH2Section(Document doc, Node node) {
 423  0
                 NodeList nodeList = node.getChildNodes();
 424  0
                 Node h2Node = null;
 425  0
                 Node pNode = null;
 426  0
                 boolean firstInstanceOfH2 = false;
 427  
 
 428  0
                 for (int x = 0; x < nodeList.getLength(); ++x) {
 429  0
                         Node node2 = nodeList.item(x);
 430  
 
 431  0
                         if (node2 != null) {
 432  0
                                 String nodes = node2.getNodeName();
 433  
 
 434  0
                                 if (nodes.equalsIgnoreCase("h2")) {
 435  0
                                         h2Node = node2.appendChild(doc.createElement("h2_section"));
 436  0
                                 } else {
 437  
                                         //if first node is not a <p> or a h2 node, create a <p> node and place all succeeding nodes 
 438  
                                         //inside this node until a <p> or <h2> node is found
 439  0
                                         if (x == 0 && !nodes.equalsIgnoreCase("p")
 440  
                                                         && !nodes.equalsIgnoreCase("h2")) {
 441  0
                                                 pNode = node
 442  
                                                                 .insertBefore(doc.createElement("p"), node2);
 443  0
                                                 x++;
 444  0
                                                 firstInstanceOfH2 = true;
 445  
                                         }
 446  0
                                         if (firstInstanceOfH2) {
 447  0
                                                 if (node2 == node.getLastChild()) {
 448  0
                                                         pNode.appendChild(node2.cloneNode(true));
 449  0
                                                 } else {
 450  0
                                                         Node nextNode = node2.getNextSibling();
 451  0
                                                         pNode.appendChild(node2.cloneNode(true));
 452  0
                                                         if (nextNode.getNodeName().equalsIgnoreCase("h2")
 453  
                                                                         || nextNode.getNodeName().equalsIgnoreCase(
 454  
                                                                                         "p")) {
 455  0
                                                                 firstInstanceOfH2 = false;
 456  
                                                         }
 457  
                                                 }
 458  
 
 459  
                                         }
 460  
 
 461  0
                                         if (h2Node != null) {
 462  0
                                                 h2Node.appendChild(node2.cloneNode(true));
 463  
                                         }
 464  
                                 }
 465  
 
 466  
                         }
 467  
                 }
 468  
 
 469  
                 //let's remove all  nodes that are not <h2> or <p> - they should already have been copied inside an <h2> or <p> node
 470  0
                 NodeList nodeList3 = node.getChildNodes();
 471  0
                 boolean afterH2 = false;
 472  0
                 for (int x = 0; x < nodeList3.getLength(); ++x) {
 473  0
                         Node node2 = nodeList3.item(x);
 474  0
                         if (node2.getNodeName().equalsIgnoreCase("h2") && !afterH2) {
 475  0
                                 afterH2 = true;
 476  
                         }
 477  
 
 478  0
                         if (node2 != null && !node2.getNodeName().equalsIgnoreCase("p")
 479  
                                         && !node2.getNodeName().equalsIgnoreCase("h2")) {
 480  0
                                 node.removeChild(node2);
 481  0
                                 x--;
 482  
                         }
 483  
                 }
 484  0
                 return node;
 485  
         }
 486  
 }