1 package it.unibo.cs.helm.uwobo;
6 import javax.xml.transform.*;
7 import javax.xml.transform.sax.*;
8 import javax.xml.transform.stream.*;
9 import org.apache.xalan.serialize.*;
10 import org.apache.xalan.xslt.*;
11 import org.apache.xalan.templates.*;
12 import org.apache.xalan.transformer.*;
13 import org.apache.xerces.parsers.*;
15 import org.xml.sax.ext.*;
16 import org.xml.sax.helpers.*;
19 // This file is part of UWOBO, a small and simple XSLT server.
21 // UWOBO is free software; you can redistribute it and/or
22 // modify it under the terms of the GNU General Public License
23 // as published by the Free Software Foundation; either version 2
24 // of the License, or (at your option) any later version.
26 // UWOBO is distributed in the hope that it will be useful,
27 // but WITHOUT ANY WARRANTY; without even the implied warranty of
28 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 // GNU General Public License for more details.
31 // You should have received a copy of the GNU General Public License
32 // along with UWOBO; if not, write to the Free Software
33 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
35 // For details, send a mail to <luca.padovani@cs.unibo.it>
36 * @author Luca Padovani, Riccardo Solmi
40 private static class Style {
41 public String fileName;
42 public long lastModified;
43 public Templates stylesheet;
46 public static final String SERVERNAME = "uwobo-XSLT-server";
47 public static final String PACKAGE;
48 public static final String VERSION;
49 public static final String DATE;
50 public static final String TIME;
53 Properties props = new Properties();
55 InputStream in = Server.class.getResourceAsStream("properties.txt");
58 } catch (IOException ioe) {
59 System.err.println("Could not load the version information.");
62 PACKAGE = props.getProperty("PACKAGE");
63 VERSION = props.getProperty("VERSION");
64 DATE = props.getProperty("DATE");
65 TIME = props.getProperty("TIME");
68 private final HashMap hashMap = new HashMap();
69 private static int logCounter = 0;
71 private final Templates compileStylesheet(String xsl_file) throws TransformerConfigurationException, SAXException, IOException {
72 StreamSource streamsource =
73 new StreamSource(new URL(xsl_file).openStream());
74 streamsource.setSystemId(xsl_file);
75 return ((SAXTransformerFactory)TransformerFactory.newInstance())
76 .newTemplates(streamsource);
79 private String getContentType(Templates templates) {
80 final Properties oprops = templates.getOutputProperties();
81 final String encoding = oprops.getProperty(OutputKeys.ENCODING);
82 final String media = oprops.getProperty(OutputKeys.MEDIA_TYPE);
86 return media + "; charset=" + encoding;
89 final String method = oprops.getProperty(OutputKeys.METHOD);
90 if (method.equals("html"))
92 else if (method.equals("text"))
99 private final ContentHandler applyStylesheet(Templates stylesheet, HashMap params, ContentHandler saxOutput)
100 throws TransformerConfigurationException, SAXException
102 TransformerHandler th = ((SAXTransformerFactory)TransformerFactory.newInstance()).newTransformerHandler(stylesheet);
104 th.setResult(new SAXResult(saxOutput));
106 if (params != null) {
107 final Transformer transformer = th.getTransformer();
108 Iterator i = params.keySet().iterator();
109 while (i.hasNext()) {
110 final String name = (String) i.next();
111 final String value = (String) params.get(name);
112 transformer.setParameter(name, value);
119 private final void parseFile(String datasheet, ContentHandler saxOutput) throws SAXException, IOException, Exception {
120 final XMLReader reader = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
121 reader.setFeature("http://xml.org/sax/features/namespaces", true);
122 reader.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
123 reader.setContentHandler(saxOutput);
124 if (saxOutput instanceof LexicalHandler)
125 reader.setProperty("http://xml.org/sax/properties/lexical-handler", (LexicalHandler)saxOutput);
126 reader.parse(datasheet);
129 private final ContentHandler saveFile(OutputStream outputStream, Properties props) throws IOException {
130 final Serializer ser = SerializerFactory.getSerializer(props);
131 ser.setOutputStream(outputStream);
132 return ser.asContentHandler();
135 public static void log(String msg) {
136 System.err.println(SERVERNAME + "[" + logCounter++ + "]: " + msg);
139 public void add(String filename, String key) throws TransformerConfigurationException, SAXException, IOException {
140 if (hashMap.containsKey(key)) {
141 log("there is already a stylesheet with keyword \"" + key + "\" (aborted)");
145 Style style = new Style();
146 style.fileName = filename;
147 style.lastModified = new File(filename).lastModified();
148 log("processing stylesheet \"" + filename + "\"... ");
149 style.stylesheet = compileStylesheet(filename);
152 hashMap.put(key, style);
155 public void removeAll() throws TransformerConfigurationException, SAXException, IOException {
158 Iterator i = hashMap.keySet().iterator();
159 while (i.hasNext()) {
160 key = (String)i.next();
161 style = (Style)hashMap.get(key);
162 log("removing \"" + key + " (" + style.fileName + ")");
167 public void remove(String key) {
168 Style style = (Style)hashMap.get(key);
170 log("removing \"" + key + " (" + style.fileName + ")");
173 log("error, stylesheet \"" + key + "\" not loaded");
177 public String getContentType(String key) {
178 Style style = (Style)hashMap.get(key);
180 return getContentType(style.stylesheet);
182 log("error, stylesheet \"" + key + "\" not loaded");
188 log("listing stylesheets...");
189 ArrayList l = new ArrayList();
190 Iterator i = hashMap.keySet().iterator();
191 while (i.hasNext()) {
192 String key = (String)i.next();
193 Style style = (Style)hashMap.get(key);
194 l.add(" " + key + " (" + style.fileName + "; " + getContentType(style.stylesheet) + ")");
195 System.out.println(" " + key + " (" + style.fileName + ")");
201 private ContentHandler applyRec(final Key[] keys, int idx, final ContentHandler saxOutput)
202 throws TransformerConfigurationException, SAXException, IOException
207 final Style style = (Style) hashMap.get(keys[idx].name);
209 log("cannot apply unknwon stylesheet \"" + keys[idx].name + "\" (aborted)");
212 return applyStylesheet(style.stylesheet, keys[idx].params, applyRec(keys, idx - 1, saxOutput));
216 public void apply(String inFile, OutputStream outputStream, Key[] keys, Properties userProperties)
217 throws FileNotFoundException, IOException, TransformerConfigurationException, SAXException, Exception
219 /* File outFile = new File(outFilename);
220 if (outFile.exists())
221 System.out.println("Using cached version\n");
224 final Key[] rkeys = new Key[keys.length];
225 for (int i = 0; i < keys.length; i++)
226 rkeys[i] = keys[keys.length - i - 1];
228 Properties outputProperties;
229 Properties defaultProperties;
232 if (keys.length > 0) {
233 Style style = (Style) hashMap.get(rkeys[0].name);
235 log("error, stylesheet \"" + rkeys[0].name + "\" not loaded");
238 outputProperties = style.stylesheet.getOutputProperties();
239 method = userProperties.getProperty("method");
240 if (method == null) method = outputProperties.getProperty("method");
241 if (method == null) method = "xml";
242 defaultProperties = org.apache.xalan.templates.OutputProperties.getDefaultMethodProperties(method);
244 method = userProperties.getProperty("method");
245 if (method == null) method = "xml";
246 outputProperties = org.apache.xalan.templates.OutputProperties.getDefaultMethodProperties(method);
247 defaultProperties = outputProperties;
250 for (Enumeration e = userProperties.propertyNames(); e.hasMoreElements(); ) {
251 String prop = (String) e.nextElement();
252 String value = userProperties.getProperty(prop);
253 if (value.equals("")) {
254 String defaultValue = defaultProperties.getProperty(prop);
255 if (defaultValue != null)
256 outputProperties.setProperty(prop, defaultProperties.getProperty(prop));
258 outputProperties.remove(prop);
260 outputProperties.setProperty(prop, value);
264 parseFile(inFile, applyRec(rkeys, rkeys.length - 1, saveFile(outputStream, outputProperties)));
268 public void reloadAll() throws TransformerConfigurationException, SAXException, IOException {
269 Iterator i = hashMap.keySet().iterator();
271 reload((String)i.next());
274 public void reload(String key) throws TransformerConfigurationException, SAXException, IOException {
275 Style style = (Style)hashMap.get(key);
277 log("reloading \"" + key + "\"... ");
278 style.stylesheet = compileStylesheet(style.fileName);
279 style.lastModified = new File(style.fileName).lastModified();
283 public void updateAll() throws TransformerConfigurationException, SAXException, IOException {
284 Iterator i = hashMap.keySet().iterator();
286 update((String)i.next());
289 public void update(String key) throws TransformerConfigurationException, SAXException, IOException {
290 Style style = (Style)hashMap.get(key);
292 log("updating \"" + key + "\"... ");
293 File styleFile = new File(style.fileName);
294 if (styleFile.lastModified() > style.lastModified) {
295 style.stylesheet = compileStylesheet(style.fileName);
296 style.lastModified = styleFile.lastModified();
299 log("\"" + key + "\" is up to date");