1 package org.andromda.core.transformation;
2
3 import java.io.ByteArrayInputStream;
4 import java.io.ByteArrayOutputStream;
5 import java.io.File;
6 import java.io.FileOutputStream;
7 import java.io.InputStream;
8 import java.net.URL;
9 import java.util.Arrays;
10 import java.util.Collection;
11 import java.util.Iterator;
12 import javax.xml.transform.Result;
13 import javax.xml.transform.Source;
14 import javax.xml.transform.TransformerException;
15 import javax.xml.transform.TransformerFactory;
16 import javax.xml.transform.URIResolver;
17 import javax.xml.transform.stream.StreamResult;
18 import javax.xml.transform.stream.StreamSource;
19 import org.andromda.core.common.AndroMDALogger;
20 import org.andromda.core.common.ResourceUtils;
21 import org.andromda.core.configuration.Transformation;
22 import org.apache.commons.lang.StringUtils;
23
24
25
26
27
28
29
30
31
32 public class XslTransformer
33 implements Transformer
34 {
35
36
37
38
39
40 public InputStream transform(
41 final String modelUri,
42 final Transformation[] xsltTransformations)
43 {
44 try
45 {
46 InputStream stream = null;
47 if (StringUtils.isNotBlank(modelUri))
48 {
49 final URL modelUrl = new URL(modelUri);
50 if (xsltTransformations != null && xsltTransformations.length > 0)
51 {
52 Source modelSource = new StreamSource(modelUrl.openStream());
53 final Collection<Transformation> xslts = Arrays.asList(xsltTransformations);
54 final TransformerFactory factory = TransformerFactory.newInstance();
55 final TransformerURIResolver resolver = new TransformerURIResolver();
56 factory.setURIResolver(resolver);
57 for (final Iterator<Transformation> xsltIterator = xslts.iterator(); xsltIterator.hasNext();)
58 {
59 final Transformation transformation = xsltIterator.next();
60 final URL xslt = new URL(transformation.getUri());
61 resolver.setLocation(xslt);
62 AndroMDALogger.info("Applying transformation --> '" + xslt + '\'');
63 final Source xsltSource = new StreamSource(xslt.openStream());
64 final javax.xml.transform.Transformer transformer = factory.newTransformer(xsltSource);
65 final ByteArrayOutputStream output = new ByteArrayOutputStream();
66 final Result result = new StreamResult(output);
67 transformer.transform(modelSource, result);
68 final byte[] outputResult = output.toByteArray();
69 stream = new ByteArrayInputStream(outputResult);
70
71
72 final String outputLocation = transformation.getOutputLocation();
73 if (StringUtils.isNotBlank(outputLocation))
74 {
75 final File fileOutput = new File(outputLocation);
76 final File parent = fileOutput.getParentFile();
77 if (parent != null)
78 {
79 parent.mkdirs();
80 }
81 FileOutputStream outputStream = new FileOutputStream(fileOutput);
82 AndroMDALogger.info("Transformation output: '" + outputLocation + '\'');
83 outputStream.write(outputResult);
84 outputStream.flush();
85 outputStream.close();
86 }
87 if (xsltIterator.hasNext())
88 {
89 modelSource = new StreamSource(stream);
90 }
91 }
92 }
93 else
94 {
95 stream = modelUrl.openStream();
96 }
97 }
98 return stream;
99 }
100 catch (final Exception exception)
101 {
102 throw new XslTransformerException(exception);
103 }
104 }
105
106
107
108
109
110 static final class TransformerURIResolver
111 implements URIResolver
112 {
113
114
115
116 public Source resolve(
117 final String href,
118 final String base)
119 throws TransformerException
120 {
121 Source source = null;
122 if (this.location != null)
123 {
124 String locationUri = ResourceUtils.normalizePath(this.location.toString());
125 locationUri = locationUri.substring(0, locationUri.lastIndexOf('/') + 1);
126 source = new StreamSource(locationUri + href);
127 }
128 return source;
129 }
130
131
132
133
134 private URL location;
135
136
137
138
139
140
141 public void setLocation(URL location)
142 {
143 this.location = location;
144 }
145 }
146 }