1 package org.andromda.maven.plugin.site;
2
3 import java.io.ByteArrayInputStream;
4 import java.io.ByteArrayOutputStream;
5 import java.io.File;
6 import java.io.FileWriter;
7 import java.io.IOException;
8 import java.io.InputStream;
9 import java.net.URL;
10 import java.util.List;
11 import javax.xml.parsers.DocumentBuilder;
12 import javax.xml.parsers.DocumentBuilderFactory;
13 import javax.xml.parsers.ParserConfigurationException;
14 import javax.xml.transform.Result;
15 import javax.xml.transform.Source;
16 import javax.xml.transform.TransformerFactory;
17 import javax.xml.transform.dom.DOMSource;
18 import javax.xml.transform.stream.StreamResult;
19 import javax.xml.transform.stream.StreamSource;
20 import org.apache.commons.lang.StringUtils;
21 import org.dom4j.Element;
22 import org.dom4j.io.SAXReader;
23 import org.dom4j.io.XMLWriter;
24 import org.w3c.dom.Document;
25 import org.xml.sax.EntityResolver;
26 import org.xml.sax.InputSource;
27 import org.xml.sax.SAXException;
28
29
30
31
32
33
34
35
36 public class XslTransformer
37 {
38 private String projectName;
39
40
41
42
43
44 public XslTransformer()
45 {
46
47 }
48
49
50
51
52
53
54
55 public XslTransformer(String projectNameIn)
56 {
57 this.projectName = projectNameIn;
58 }
59
60
61
62
63
64
65
66
67 public void transform(
68 final String xmlDocument,
69 final String transformation,
70 final String outputLocation)
71 {
72 try
73 {
74 this.transform(xmlDocument, new File(transformation).toURI().toURL(), outputLocation);
75 }
76 catch (final Exception exception)
77 {
78 throw new RuntimeException(exception);
79 }
80 }
81
82
83
84
85
86
87
88
89 public void transform(
90 final String xmlDocument,
91 final URL xslt,
92 final String outputLocation)
93 {
94 try
95 {
96 if (StringUtils.isNotBlank(xmlDocument))
97 {
98 final Source xmlSource = new DOMSource(this.urlToDocument(xmlDocument));
99 final TransformerFactory factory = TransformerFactory.newInstance();
100 if (xslt != null)
101 {
102 final Source xsltSource = new StreamSource(xslt.openStream());
103 final javax.xml.transform.Transformer transformer = factory.newTransformer(xsltSource);
104 final ByteArrayOutputStream output = new ByteArrayOutputStream();
105 final Result result = new StreamResult(output);
106 transformer.transform(
107 xmlSource,
108 result);
109
110 final byte[] outputResult = output.toByteArray();
111 final org.dom4j.Document document = replaceVariableProperties(outputResult);
112
113 if (StringUtils.isNotBlank(outputLocation))
114 {
115 final File fileOutput = new File(outputLocation);
116 final File parent = fileOutput.getParentFile();
117 if (parent != null)
118 {
119 parent.mkdirs();
120 }
121
122 FileWriter fwriter = new FileWriter(fileOutput);
123 XMLWriter writer = new XMLWriter(fwriter);
124 writer.write(document);
125 writer.flush();
126 writer.close();
127 fwriter.close();
128 }
129 }
130 }
131 }
132 catch (final Exception exception)
133 {
134 throw new RuntimeException(exception);
135 }
136 }
137
138
139
140
141
142
143
144
145
146 @SuppressWarnings("static-method")
147 private Document urlToDocument(String url)
148 throws Exception
149 {
150 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
151 DocumentBuilder builder = factory.newDocumentBuilder();
152 builder.setEntityResolver(new XslTransformerEntityResolver(url));
153 return builder.parse(new InputSource(url));
154 }
155
156
157
158
159
160 private static final String SYSTEM_ID_FILE = "file:";
161
162
163
164
165 private static final class XslTransformerEntityResolver
166 implements EntityResolver
167 {
168 private String xmlDocument;
169
170 XslTransformerEntityResolver(final String xmlDocument)
171 {
172 this.xmlDocument = xmlDocument;
173 }
174
175
176
177
178 @SuppressWarnings("resource")
179 public InputSource resolveEntity(
180 final String publicId,
181 final String systemId)
182 throws SAXException, IOException
183 {
184 InputSource source = null;
185 String path = systemId;
186 if (path != null && path.startsWith(SYSTEM_ID_FILE))
187 {
188 final String xmlResource = this.xmlDocument;
189 path = path.replaceFirst(
190 SYSTEM_ID_FILE,
191 "");
192
193
194 path = path.replaceAll(
195 "\\+",
196 "/").replaceAll(
197 "/+",
198 "/");
199
200
201 if (path.startsWith("/"))
202 {
203 path = path.substring(
204 1,
205 path.length());
206 }
207 final String xmlResourceName = xmlResource.replaceAll(
208 ".*(\\+|/)",
209 "");
210
211 InputStream inputStream = null;
212 URL uri = new File(StringUtils.replace(
213 xmlResource,
214 xmlResourceName,
215 path)).toURI().toURL();
216 if (uri != null)
217 {
218 inputStream = uri.openStream();
219 }
220 if (inputStream != null)
221 {
222 source = new InputSource(inputStream);
223 source.setPublicId(publicId);
224 if (uri != null)
225 {
226 source.setSystemId(uri.toString());
227 }
228 }
229 }
230 return source;
231 }
232 }
233
234
235
236
237
238
239
240
241
242 private org.dom4j.Document replaceVariableProperties(byte[] documentBuffer)
243 throws Exception
244 {
245 SAXReader reader = new SAXReader();
246 org.dom4j.Document document = reader.read(new ByteArrayInputStream(documentBuffer));
247
248
249 List<Element> elements = document.selectNodes("//*");
250 for (final Element element : elements)
251 {
252 if (StringUtils.contains(element.getText(), "%module%"))
253 {
254 element.setText(
255 StringUtils.replace(
256 element.getText(),
257 "%module%",
258 this.getProjectName()));
259 }
260 }
261 elements.clear();
262
263 elements = document.selectNodes("//*[contains(@*,'%module%')]");
264 for (final Element element : elements)
265 {
266 element.addAttribute(
267 "name",
268 StringUtils.replace(
269 element.attributeValue("name"),
270 "%module%",
271 this.getProjectName()));
272 }
273 return document;
274 }
275
276
277
278
279 public String getProjectName()
280 {
281 return projectName;
282 }
283
284
285
286
287 public void setProjectName(String projectName)
288 {
289 this.projectName = projectName;
290 }
291 }