1 package net.sf.tomp.xtcl.command;
2
3 import java.io.PrintStream;
4 import java.util.ArrayList;
5 import java.util.Iterator;
6 import java.util.List;
7
8 import javax.xml.parsers.SAXParserFactory;
9 import javax.xml.transform.Result;
10 import javax.xml.transform.Source;
11 import javax.xml.transform.Templates;
12 import javax.xml.transform.Transformer;
13 import javax.xml.transform.TransformerException;
14 import javax.xml.transform.TransformerFactory;
15 import javax.xml.transform.sax.SAXSource;
16 import javax.xml.transform.sax.SAXTransformerFactory;
17 import javax.xml.transform.sax.TransformerHandler;
18 import javax.xml.transform.stream.StreamResult;
19 import javax.xml.transform.stream.StreamSource;
20
21 import net.sf.tomp.xtcl.Context;
22 import net.sf.tomp.xtcl.filter.HasOutputProperties;
23 import net.sf.tomp.xtcl.filter.HasOutputPropertiesWrapper;
24
25 import org.xml.sax.XMLFilter;
26 import org.xml.sax.XMLReader;
27 import org.xml.sax.helpers.LocatorImpl;
28
29 /***
30 * Command to assemble and store a transformation chain
31 *
32 * @author tomp
33 */
34 public class Chain extends VarCommand {
35
36 /*** reference to the source */
37 protected String sourceRef;
38
39 /*** reference to the filters or styles in the chain */
40 protected List filterStyleRefs = new ArrayList();
41
42 /*** reference to the result of the chain */
43 protected String resultRef;
44
45 /***
46 * sets source ref name
47 *
48 * @param s source ref name
49 */
50 public void setSourceRef(String s) {
51 sourceRef = s;
52 }
53
54 /***
55 * adds filter or style reference
56 *
57 * @param s filter or style reference
58 */
59 public void addFilterStyleRef(String s) {
60 filterStyleRefs.add(s);
61 }
62
63 /***
64 * DOCUMENT ME!
65 *
66 * @param s DOCUMENT ME!
67 */
68 public void setResultRef(String s) {
69 resultRef = s;
70 }
71
72 /***
73 * Creates and executes a chain transformation by
74 * chaining SAX filters and XSLT-based SAX filters.
75 *
76 * @param context
77 * @return
78 * @throws Exception
79 */
80 public int execute(Context context) throws Exception {
81 try {
82 TransformerFactory tf = context.getTransformerFactory();
83
84 if (!tf.getFeature(SAXSource.FEATURE)) {
85 throw new TransformerException("Not a SAXTransformerFactory");
86 }
87
88 SAXTransformerFactory stf = (SAXTransformerFactory) tf;
89
90 SAXParserFactory spf = context.getSAXParserFactory();
91
92 spf.setNamespaceAware(true);
93
94 XMLReader xr = spf.newSAXParser().getXMLReader();
95
96 Source source = sourceRef.startsWith("$") ? context
97 .refToSource(sourceRef) : new StreamSource(context
98 .getFile(sourceRef));
99
100 Result result = resultRef.startsWith("$") ? context
101 .refToResult(resultRef) : new StreamResult(context
102 .getFile(resultRef));
103
104
105 if (source instanceof SAXSource) {
106 xr = ((SAXSource) source).getXMLReader();
107 }
108 XMLReader f = xr;
109 XMLReader prev = xr;
110
111 Iterator i = filterStyleRefs.iterator();
112
113 if (i.hasNext()) {
114
115 while (i.hasNext()) {
116 Templates t = null;
117 TransformerHandler th = null;
118
119 String ref = (String) i.next();
120 Object value = null;
121
122 if (ref.startsWith("$")) {
123 value = context.get(ref);
124
125
126
127 if (!(value instanceof XMLFilter)) {
128 t = context.refToStyle(ref);
129 }
130 } else {
131
132 t = stf.newTemplates(new StreamSource(context
133 .getFile(ref)));
134 }
135
136
137 if (i.hasNext()) {
138 f = (t == null) ? context.refToXMLFilter(ref) : stf
139 .newXMLFilter(t);
140
141
142 ((XMLFilter) f).setParent(prev);
143
144
145
146
147
148
149
150 } else {
151
152 if (value instanceof XMLFilter) {
153 f = context.refToXMLFilter(ref);
154
155
156
157 ((XMLFilter) f).setParent(prev);
158
159
160
161
162
163
164
165
166 th = stf.newTransformerHandler();
167
168
169 if (f instanceof HasOutputProperties) {
170 ((HasOutputProperties) f)
171 .setOutputPropertiesListener(new HasOutputPropertiesWrapper(
172 th));
173 }
174 } else {
175
176 th = stf.newTransformerHandler(t);
177
178
179
180
181
182
183
184 }
185
186 f.setContentHandler(th);
187 f
188 .setProperty(
189 "http://xml.org/sax/properties/lexical-handler",
190 th);
191 th.setResult(result);
192
193
194
195
196
197 f.parse(SAXSource.sourceToInputSource(source));
198
199
200
201 }
202
203 prev = f;
204 }
205 } else {
206
207 Transformer transf = tf.newTransformer();
208
209 transf.transform(source, result);
210 }
211
212 return done(context, 0);
213 } catch (TransformerException te) {
214 PrintStream out = context.getOut();
215
216 te.printStackTrace(out);
217
218 return done(context, 1);
219 }
220 }
221
222 /***
223 * @return "CHAIN " + sourceRef + " -> " + resultRef + " STYLES/FILTERS ("
224 + listList(filterStyleRefs) + ")";
225 */
226 public String toString() {
227 return "CHAIN " + sourceRef + " -> " + resultRef + " STYLES/FILTERS ("
228 + listList(filterStyleRefs) + ")";
229 }
230
231 static class SimpleLocator extends LocatorImpl {
232 public SimpleLocator(String systemId) {
233 setSystemId(systemId);
234 setPublicId(systemId);
235 setColumnNumber(-1);
236 setLineNumber(-1);
237 }
238
239 public String toString() {
240 return "SimpleLocator.systemId=" + getSystemId();
241 }
242 }
243 }
244
245
246
247
248
249
250
251
252
253
254