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()
159 Iterator i = hashMap.keySet().iterator();
160 while (i.hasNext()) {
161 key = (String)i.next();
162 style = (Style)hashMap.get(key);
163 log("removing \"" + key + " (" + style.fileName + ")");
168 public void remove(String key) {
169 Style style = (Style)hashMap.get(key);
171 log("removing \"" + key + " (" + style.fileName + ")");
174 log("error, stylesheet \"" + key + "\" not loaded");
178 public String getContentType(String key) {
179 Style style = (Style)hashMap.get(key);
181 return getContentType(style.stylesheet);
183 log("error, stylesheet \"" + key + "\" not loaded");
189 log("listing stylesheets...");
190 ArrayList l = new ArrayList();
191 Iterator i = hashMap.keySet().iterator();
192 while (i.hasNext()) {
193 String key = (String)i.next();
194 Style style = (Style)hashMap.get(key);
195 l.add(" " + key + " (" + style.fileName + "; " + getContentType(style.stylesheet) + ")");
196 System.out.println(" " + key + " (" + style.fileName + ")");
202 private ContentHandler applyRec(final Key[] keys, int idx, final ContentHandler saxOutput)
203 throws TransformerConfigurationException, SAXException, IOException
208 final Style style = (Style) hashMap.get(keys[idx].name);
210 log("cannot apply unknwon stylesheet \"" + keys[idx].name + "\" (aborted)");
213 return applyStylesheet(style.stylesheet, keys[idx].params, applyRec(keys, idx - 1, saxOutput));
216 //FileNotFoundException
217 public void apply(String inFile, OutputStream outputStream, Key[] keys, Properties userProperties)
218 throws IOException, TransformerConfigurationException, SAXException, Exception
220 /* File outFile = new File(outFilename);
221 if (outFile.exists())
222 System.out.println("Using cached version\n");
225 final Key[] rkeys = new Key[keys.length];
226 for (int i = 0; i < keys.length; i++)
227 rkeys[i] = keys[keys.length - i - 1];
229 Properties outputProperties;
230 Properties defaultProperties;
233 if (keys.length > 0) {
234 Style style = (Style) hashMap.get(rkeys[0].name);
236 log("error, stylesheet \"" + rkeys[0].name + "\" not loaded");
239 outputProperties = style.stylesheet.getOutputProperties();
240 method = userProperties.getProperty("method");
241 if (method == null) method = outputProperties.getProperty("method");
242 if (method == null) method = "xml";
243 defaultProperties = org.apache.xalan.templates.OutputProperties.getDefaultMethodProperties(method);
245 method = userProperties.getProperty("method");
246 if (method == null) method = "xml";
247 outputProperties = org.apache.xalan.templates.OutputProperties.getDefaultMethodProperties(method);
248 defaultProperties = outputProperties;
251 for (Enumeration e = userProperties.propertyNames(); e.hasMoreElements(); ) {
252 String prop = (String) e.nextElement();
253 String value = userProperties.getProperty(prop);
254 if (value.equals("")) {
255 String defaultValue = defaultProperties.getProperty(prop);
256 if (defaultValue != null)
257 outputProperties.setProperty(prop, defaultProperties.getProperty(prop));
259 outputProperties.remove(prop);
261 outputProperties.setProperty(prop, value);
265 parseFile(inFile, applyRec(rkeys, rkeys.length - 1, saveFile(outputStream, outputProperties)));
269 public void reloadAll() throws TransformerConfigurationException, SAXException, IOException {
270 Iterator i = hashMap.keySet().iterator();
272 reload((String)i.next());
275 public void reload(String key) throws TransformerConfigurationException, SAXException, IOException {
276 Style style = (Style)hashMap.get(key);
278 log("reloading \"" + key + "\"... ");
279 style.stylesheet = compileStylesheet(style.fileName);
280 style.lastModified = new File(style.fileName).lastModified();
283 log("error, stylesheet \"" + key + "\" not loaded");
287 public void updateAll() throws TransformerConfigurationException, SAXException, IOException {
288 Iterator i = hashMap.keySet().iterator();
290 update((String)i.next());
293 public void update(String key) throws TransformerConfigurationException, SAXException, IOException {
294 Style style = (Style)hashMap.get(key);
296 log("updating \"" + key + "\"... ");
297 File styleFile = new File(style.fileName);
298 if (styleFile.lastModified() > style.lastModified) {
299 style.stylesheet = compileStylesheet(style.fileName);
300 style.lastModified = styleFile.lastModified();
303 log("\"" + key + "\" is up to date");
306 log("error, stylesheet \"" + key + "\" not loaded");