1:
37:
38: package ;
39:
40: import ;
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63: import ;
64: import ;
65: import ;
66: import ;
67: import ;
68: import ;
69: import ;
70: import ;
71: import ;
72: import ;
73:
74:
79: public class TransformerFactoryImpl
80: extends SAXTransformerFactory
81: {
82:
83: final XPathFactory xpathFactory;
84: final XSLURIResolver resolver;
85: ErrorListener userListener;
86: URIResolver userResolver;
87:
88: public TransformerFactoryImpl()
89: {
90: xpathFactory = new gnu.xml.xpath.XPathFactoryImpl();
91: resolver = new XSLURIResolver();
92: }
93:
94: public Transformer newTransformer(Source source)
95: throws TransformerConfigurationException
96: {
97: Stylesheet stylesheet = newStylesheet(source, 0, null);
98: Properties outputProperties =
99: new TransformerOutputProperties(stylesheet);
100: TransformerImpl transformer =
101: new TransformerImpl(this, stylesheet, outputProperties);
102: stylesheet.transformer = transformer;
103: return transformer;
104: }
105:
106: public Transformer newTransformer()
107: throws TransformerConfigurationException
108: {
109: return new TransformerImpl(this, null, new Properties());
110: }
111:
112: public Templates newTemplates(Source source)
113: throws TransformerConfigurationException
114: {
115: Stylesheet stylesheet = newStylesheet(source, 0, null);
116: return new TemplatesImpl(this, stylesheet);
117: }
118:
119: Stylesheet newStylesheet(Source source, int precedence, Stylesheet parent)
120: throws TransformerConfigurationException
121: {
122: Document doc = null;
123: String systemId = null;
124: if (source != null)
125: {
126: try
127: {
128: DOMSource ds;
129: synchronized (resolver)
130: {
131: resolver.setUserResolver(userResolver);
132: resolver.setUserListener(userListener);
133: ds = resolver.resolveDOM(source, null, null);
134: }
135: Node node = ds.getNode();
136: if (node == null)
137: {
138: throw new TransformerConfigurationException("no source document");
139: }
140: doc = (node instanceof Document) ? (Document) node :
141: node.getOwnerDocument();
142: systemId = ds.getSystemId();
143: }
144: catch (TransformerException e)
145: {
146: throw new TransformerConfigurationException(e);
147: }
148: }
149: return new Stylesheet(this, parent, doc, systemId, precedence);
150: }
151:
152: public Source getAssociatedStylesheet(Source source,
153: String media,
154: String title,
155: String charset)
156: throws TransformerConfigurationException
157: {
158: try
159: {
160: DOMSource ds;
161: synchronized (resolver)
162: {
163: resolver.setUserResolver(userResolver);
164: resolver.setUserListener(userListener);
165: ds = resolver.resolveDOM(source, null, null);
166: }
167: Node node = ds.getNode();
168: if (node == null)
169: {
170: throw new TransformerConfigurationException("no source document");
171: }
172: Document doc = (node instanceof Document) ? (Document) node :
173: node.getOwnerDocument();
174: LinkedList matches = new LinkedList();
175: for (node = doc.getFirstChild();
176: node != null;
177: node = node.getNextSibling())
178: {
179: if (node.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE &&
180: "xml-stylesheet".equals(node.getNodeName()))
181: {
182: Map params = parseParameters(node.getNodeValue());
183: if (media != null && !media.equals(params.get("media")))
184: {
185: continue;
186: }
187: if (title != null && !title.equals(params.get("title")))
188: {
189: continue;
190: }
191: if (charset != null && !charset.equals(params.get("charset")))
192: {
193: continue;
194: }
195: String href = (String) params.get("href");
196: URL url = resolver.resolveURL(null, node.getBaseURI(), href);
197: matches.add(url);
198: }
199: }
200: switch (matches.size())
201: {
202: case 0:
203: return null;
204: case 1:
205: return new StreamSource(((URL) matches.getFirst()).toString());
206: default:
207:
208:
209: DomDocument ssDoc = new DomDocument();
210: ssDoc.setBuilding(true);
211:
212: Node root =
213: ssDoc.createElementNS(Stylesheet.XSL_NS, "stylesheet");
214: Node version =
215: ssDoc.createAttributeNS(null, "version");
216: version.setNodeValue("1.0");
217: root.getAttributes().setNamedItemNS(version);
218: ssDoc.appendChild(root);
219:
220: for (Iterator i = matches.iterator(); i.hasNext(); )
221: {
222: URL url = (URL) i.next();
223: Node imp =
224: ssDoc.createElementNS(Stylesheet.XSL_NS, "import");
225: Node href =
226: ssDoc.createAttributeNS(null, "href");
227: href.setNodeValue(url.toString());
228: imp.getAttributes().setNamedItemNS(href);
229: root.appendChild(imp);
230: }
231: ssDoc.setBuilding(false);
232: return new DOMSource(ssDoc);
233: }
234: }
235: catch (IOException e)
236: {
237: throw new TransformerConfigurationException(e);
238: }
239: catch (TransformerException e)
240: {
241: throw new TransformerConfigurationException(e);
242: }
243: }
244:
245: Map parseParameters(String data)
246: {
247: Map ret = new LinkedHashMap();
248: int len = data.length();
249: String key = null;
250: int start = 0;
251: char quoteChar = '\u0000';
252: for (int i = 0; i < len; i++)
253: {
254: char c = data.charAt(i);
255: if (quoteChar == '\u0000' && c == ' ')
256: {
257: if (key == null && start < i)
258: {
259: key = data.substring(start, i);
260: }
261: else
262: {
263: String val = unquote(data.substring(start, i).trim());
264: ret.put(key, val);
265: key = null;
266: }
267: start = i + 1;
268: }
269: else if (c == '"')
270: {
271: quoteChar = (quoteChar == c) ? '\u0000' : c;
272: }
273: else if (c == '\'')
274: {
275: quoteChar = (quoteChar == c) ? '\u0000' : c;
276: }
277: }
278: if (start < len && key != null)
279: {
280: String val = unquote(data.substring(start, len).trim());
281: ret.put(key, val);
282: }
283: return ret;
284: }
285:
286: String unquote(String text)
287: {
288: int end = text.length() - 1;
289: if (text.charAt(0) == '\'' && text.charAt(end) == '\'')
290: {
291: return text.substring(1, end);
292: }
293: if (text.charAt(0) == '"' && text.charAt(end) == '"')
294: {
295: return text.substring(1, end);
296: }
297: return text;
298: }
299:
300: public void setURIResolver(URIResolver resolver)
301: {
302: userResolver = resolver;
303: }
304:
305: public URIResolver getURIResolver()
306: {
307: return userResolver;
308: }
309:
310: public void setFeature(String name, boolean value)
311: throws TransformerConfigurationException
312: {
313: throw new TransformerConfigurationException("not supported");
314: }
315:
316: public boolean getFeature(String name)
317: {
318: if (SAXSource.FEATURE.equals(name) ||
319: SAXResult.FEATURE.equals(name) ||
320: StreamSource.FEATURE.equals(name) ||
321: StreamResult.FEATURE.equals(name) ||
322: DOMSource.FEATURE.equals(name) ||
323: DOMResult.FEATURE.equals(name) ||
324: SAXTransformerFactory.FEATURE.equals(name))
325: {
326: return true;
327: }
328: return false;
329: }
330:
331: public void setAttribute(String name, Object value)
332: throws IllegalArgumentException
333: {
334: throw new IllegalArgumentException("not supported");
335: }
336:
337: public Object getAttribute(String name)
338: throws IllegalArgumentException
339: {
340: throw new IllegalArgumentException("not supported");
341: }
342:
343: public void setErrorListener(ErrorListener listener)
344: throws IllegalArgumentException
345: {
346: userListener = listener;
347: }
348:
349: public ErrorListener getErrorListener()
350: {
351: return userListener;
352: }
353:
354:
355:
356: public TemplatesHandler newTemplatesHandler()
357: throws TransformerConfigurationException
358: {
359: return new SAXTemplatesHandler(this);
360: }
361:
362: public TransformerHandler newTransformerHandler()
363: throws TransformerConfigurationException
364: {
365: Transformer transformer = newTransformer();
366: return new SAXTransformerHandler(this, transformer);
367: }
368:
369: public TransformerHandler newTransformerHandler(Source source)
370: throws TransformerConfigurationException
371: {
372: Transformer transformer = newTransformer(source);
373: return new SAXTransformerHandler(this, transformer);
374: }
375:
376: public TransformerHandler newTransformerHandler(Templates templates)
377: throws TransformerConfigurationException
378: {
379: Transformer transformer = templates.newTransformer();
380: return new SAXTransformerHandler(this, transformer);
381: }
382:
383: public XMLFilter newXMLFilter(Source source)
384: throws TransformerConfigurationException
385: {
386: throw new UnsupportedOperationException();
387: }
388:
389: public XMLFilter newXMLFilter(Templates templates)
390: throws TransformerConfigurationException
391: {
392: throw new UnsupportedOperationException();
393: }
394:
395:
396:
397:
400: public static void main(String[] args)
401: throws Exception
402: {
403: InputStream stylesheet = null, in = null;
404: OutputStream out = null;
405: try
406: {
407: if (args.length > 0)
408: {
409: stylesheet = new FileInputStream(args[0]);
410: if (args.length > 1)
411: {
412: in = new FileInputStream(args[1]);
413: if (args.length > 2)
414: out = new FileOutputStream(args[2]);
415: }
416: }
417: if (in == null)
418: in = System.in;
419: if (out == null)
420: out = System.out;
421: TransformerFactory f = new TransformerFactoryImpl();
422: Transformer t = (stylesheet != null) ?
423: f.newTransformer(new StreamSource(stylesheet)) :
424: f.newTransformer();
425: t.transform(new StreamSource(in), new StreamResult(out));
426: }
427: finally
428: {
429: if (stylesheet != null)
430: stylesheet.close();
431: if (in != null && in instanceof FileInputStream)
432: in.close();
433: if (out != null && out instanceof FileOutputStream)
434: out.close();
435: }
436: }
437:
438: }