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