1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.archetype.common.util;
20
21 import javax.xml.XMLConstants;
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.TransformerException;
28 import javax.xml.transform.TransformerFactory;
29 import javax.xml.transform.dom.DOMSource;
30 import javax.xml.transform.stream.StreamResult;
31 import javax.xml.transform.stream.StreamSource;
32
33 import java.io.IOException;
34 import java.io.InputStream;
35 import java.io.Reader;
36 import java.io.Writer;
37
38 import org.apache.maven.archetype.exception.InvalidPackaging;
39 import org.apache.maven.archetype.old.ArchetypeTemplateProcessingException;
40 import org.w3c.dom.Document;
41 import org.w3c.dom.Element;
42 import org.w3c.dom.Node;
43 import org.w3c.dom.NodeList;
44 import org.xml.sax.InputSource;
45 import org.xml.sax.SAXException;
46
47
48
49
50 public final class PomUtils {
51
52 private PomUtils() {
53 throw new IllegalStateException("no instantiable constructor");
54 }
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 public static boolean addNewModule(String artifactId, Reader fileReader, Writer fileWriter)
72 throws ArchetypeTemplateProcessingException, InvalidPackaging, IOException, ParserConfigurationException,
73 SAXException, TransformerException {
74 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
75 dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
76 dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
77 dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
78 dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
79 dbf.setXIncludeAware(false);
80 dbf.setExpandEntityReferences(false);
81
82 DocumentBuilder db = dbf.newDocumentBuilder();
83 InputSource inputSource = new InputSource();
84 inputSource.setCharacterStream(fileReader);
85 Document document = db.parse(inputSource);
86
87 Element project = document.getDocumentElement();
88 if (!"project".equals(project.getNodeName())) {
89 throw new ArchetypeTemplateProcessingException("Unable to find root element 'project'.");
90 }
91
92 String packaging = null;
93 Node packagingNode = getChildNode(project, "packaging");
94 if (packagingNode != null) {
95 packaging = packagingNode.getTextContent();
96 }
97 if (!"pom".equals(packaging)) {
98 throw new InvalidPackaging(
99 "Unable to add module to the current project as it is not of packaging type 'pom'");
100 }
101
102 Node modules = getChildNode(project, "modules");
103
104 if (!hasArtifactIdInModules(artifactId, modules)) {
105 Element module = document.createElement("module");
106 module.setTextContent(artifactId);
107 if (modules == null) {
108 modules = document.createElement("modules");
109 project.appendChild(modules);
110 }
111
112
113 modules.appendChild(document.createTextNode(" "));
114
115 modules.appendChild(module);
116
117
118 modules.appendChild(document.createTextNode("\n "));
119
120 TransformerFactory tf = TransformerFactory.newInstance();
121 tf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
122 tf.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
123
124 tf.setAttribute("indent-number", 2);
125 try (InputStream xsl = PomUtils.class.getResourceAsStream("/prettyprint.xsl")) {
126 final Transformer tr = tf.newTransformer(new StreamSource(xsl));
127 tr.setOutputProperty(OutputKeys.INDENT, "yes");
128 tr.setOutputProperty(OutputKeys.METHOD, "xml");
129 tr.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
130 tr.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
131 document.getDomConfig().setParameter("infoset", Boolean.TRUE);
132 document.getDocumentElement().normalize();
133 tr.transform(new DOMSource(document), new StreamResult(fileWriter));
134 }
135 return true;
136 } else {
137 return false;
138 }
139 }
140
141 private static Node getChildNode(Element parent, String name) {
142 Node namedNode = null;
143 NodeList nodes = parent.getChildNodes();
144 for (int len = nodes.getLength(), i = 0; i < len; i++) {
145 Node node = nodes.item(i);
146 if (node.getNodeType() == Node.ELEMENT_NODE && name.equals(node.getNodeName())) {
147 namedNode = node;
148 break;
149 }
150 }
151 return namedNode;
152 }
153
154 private static boolean hasArtifactIdInModules(String artifactId, Node modules) {
155 if (modules != null) {
156 Node module = modules.getFirstChild();
157 while (module != null) {
158 if (module.getNodeType() == Node.ELEMENT_NODE && artifactId.equals(module.getTextContent())) {
159 return true;
160 }
161 module = module.getNextSibling();
162 }
163 }
164 return false;
165 }
166 }