1 /* Copyright (C) 2001, HELM Team
3 * This file is part of UWOBO, developed at the Computer Science
4 * Department, University of Bologna, Italy.
6 * UWOBO is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * UWOBO is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with UWOBO; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21 * For details, see the UWOBO World-Wide-Web page,
22 * http://cs.unibo.it/helm/uwobo
25 package it.unibo.cs.helm.uwobo;
30 import javax.xml.transform.*;
31 import javax.xml.transform.sax.*;
32 import javax.xml.transform.stream.*;
33 import org.apache.xalan.serialize.*;
34 import org.apache.xalan.xslt.*;
35 import org.apache.xalan.templates.*;
36 import org.apache.xalan.transformer.*;
37 import org.apache.xerces.parsers.*;
39 import org.xml.sax.ext.*;
40 import org.xml.sax.helpers.*;
43 // This file is part of UWOBO, a small and simple XSLT server.
45 // UWOBO is free software; you can redistribute it and/or
46 // modify it under the terms of the GNU General Public License
47 // as published by the Free Software Foundation; either version 2
48 // of the License, or (at your option) any later version.
50 // UWOBO is distributed in the hope that it will be useful,
51 // but WITHOUT ANY WARRANTY; without even the implied warranty of
52 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
53 // GNU General Public License for more details.
55 // You should have received a copy of the GNU General Public License
56 // along with UWOBO; if not, write to the Free Software
57 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
59 // For details, send a mail to <luca.padovani@cs.unibo.it>
60 * @author Luca Padovani, Riccardo Solmi
64 private static class Style implements Serializable {
65 public String fileName;
66 public long lastModified;
67 public Templates stylesheet;
70 public static final String SERVERNAME = "uwobo-XSLT-server";
71 public static final String PACKAGE;
72 public static final String VERSION;
73 public static final String DATE;
74 public static final String TIME;
75 public static final String SERIALIZATION_DIR;
78 Properties props = new Properties();
80 InputStream in = Server.class.getResourceAsStream("properties.txt");
83 } catch (IOException ioe) {
84 System.err.println("Could not load the version information.");
87 PACKAGE = props.getProperty("PACKAGE");
88 VERSION = props.getProperty("VERSION");
89 DATE = props.getProperty("DATE");
90 TIME = props.getProperty("TIME");
91 SERIALIZATION_DIR = props.getProperty("SERIALIZATION_DIR");
95 if(!SERIALIZATION_DIR.equals("")) {
96 log("Looking for serialized stylesheets");
97 File [] serialized = new File(SERIALIZATION_DIR).listFiles();
98 if (serialized == null) {
99 log("Serialized stylesheets directory \"" + SERIALIZATION_DIR +
102 for (int i = 0; i < serialized.length ; i++) {
103 File filename = serialized[i];
104 String key = filename.getName();
105 log("Found serialized stylesheet " + key);
106 log("Reloading serialized stylesheet \"" + filename + "\"... ");
107 FileInputStream istream;
109 istream = new FileInputStream(filename);
110 ObjectInputStream p = new ObjectInputStream(istream);
111 Style style = (Style)p.readObject();
113 hashMap.put(key, style);
114 } catch (Exception e) {log(e.toString());};
116 log("Serialized stylesheets loaded!");
119 log("Stylesheet serialization is off. Set the property SERIALIZATION_DIR to a non-empty value to turn it on.");
123 private final HashMap hashMap = new HashMap();
124 private static int logCounter = 0;
126 private final String compileStylesheet(Style style, String key) throws TransformerConfigurationException, SAXException, IOException {
127 StreamSource streamsource =
128 new StreamSource(new URL(style.fileName).openStream());
129 streamsource.setSystemId(style.fileName);
130 Templates templates =
131 ((SAXTransformerFactory)TransformerFactory.newInstance())
132 .newTemplates(streamsource);
133 style.stylesheet = templates;
134 File serializationFile = new File(SERIALIZATION_DIR,key);
136 if(!SERIALIZATION_DIR.equals("")) {
138 FileOutputStream ostream =
139 new FileOutputStream(serializationFile);
140 ObjectOutputStream p = new ObjectOutputStream(ostream);
141 p.writeObject(style);
145 "Stylesheet serialized in \"" + serializationFile + "\"";
147 } catch (FileNotFoundException e) {
148 res = "Warning: Stylesheet not " +
149 "serialized. Error opening " + "file \"" +
150 serializationFile + "\"";
152 res = htmlOfWarning(res);
158 private String getContentType(Templates templates) {
159 final Properties oprops = templates.getOutputProperties();
160 final String encoding = oprops.getProperty(OutputKeys.ENCODING);
161 final String media = oprops.getProperty(OutputKeys.MEDIA_TYPE);
164 if (encoding != null)
165 return media + "; charset=" + encoding;
168 final String method = oprops.getProperty(OutputKeys.METHOD);
169 if (method.equals("html"))
171 else if (method.equals("text"))
178 private final ContentHandler applyStylesheet(Templates stylesheet, HashMap params, ContentHandler saxOutput)
179 throws TransformerConfigurationException, SAXException
181 TransformerHandler th = ((SAXTransformerFactory)TransformerFactory.newInstance()).newTransformerHandler(stylesheet);
183 th.setResult(new SAXResult(saxOutput));
185 if (params != null) {
186 final Transformer transformer = th.getTransformer();
187 Iterator i = params.keySet().iterator();
188 while (i.hasNext()) {
189 final String name = (String) i.next();
190 final String value = (String) params.get(name);
191 transformer.setParameter(name, value);
198 private final void parseFile(String datasheet, ContentHandler saxOutput) throws SAXException, IOException, Exception {
199 final XMLReader reader = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
200 reader.setFeature("http://xml.org/sax/features/namespaces", true);
201 reader.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
202 reader.setContentHandler(saxOutput);
203 if (saxOutput instanceof LexicalHandler)
204 reader.setProperty("http://xml.org/sax/properties/lexical-handler", (LexicalHandler)saxOutput);
205 reader.parse(datasheet);
208 private final ContentHandler saveFile(OutputStream outputStream, Properties props) throws IOException {
209 final Serializer ser = SerializerFactory.getSerializer(props);
210 ser.setOutputStream(outputStream);
211 return ser.asContentHandler();
214 public static void log(String msg) {
215 System.err.println(SERVERNAME + "[" + logCounter++ + "]: " + msg);
218 public String add(String filename, String key) throws TransformerConfigurationException, SAXException, IOException {
219 log("processing stylesheet \"" + filename + "\" using key " + key + "... ");
220 if (hashMap.containsKey(key)) {
221 Style style = (Style)hashMap.get(key);
222 if (style.fileName.equals(filename)) {
224 "Warning: Stylesheet already loaded. Reloading...";
226 String msg2 = reload(key);
227 return htmlOfWarning(msg) +
228 (msg2.equals("") ? "" : "<br />" + msg2);
231 "Error: There is already a stylesheet with keyword \""+
232 key + "\" (aborted)";
234 return htmlOfError(res);
238 Style style = new Style();
239 style.fileName = filename;
240 style.lastModified = new File(filename).lastModified();
241 String res = compileStylesheet(style,key);
244 hashMap.put(key, style);
248 public ArrayList removeAll() throws TransformerConfigurationException, SAXException, IOException {
249 ArrayList res = new ArrayList();
251 Iterator i = hashMap.keySet().iterator();
252 while (i.hasNext()) {
253 String key = (String)i.next();
254 Style style = (Style)hashMap.get(key);
256 "removing \"" + key + " (" + style.fileName + ")";
259 msg = partialRemove(key,false);
267 private String partialRemove(String key, boolean removeFromHashTable) {
269 Style style = (Style)hashMap.get(key);
271 log("removing \"" + key + " (" + style.fileName + ")");
272 if (removeFromHashTable)
274 if(!SERIALIZATION_DIR.equals("")) {
275 File to_delete = new File(SERIALIZATION_DIR,key);
276 if (!to_delete.delete()) {
277 res = "Warning: Serialized stylesheet \"" +
278 to_delete + "\" to remove not found";
280 res = htmlOfWarning(res);
284 res = "Error: stylesheet \"" + key + "\" not loaded";
286 res = htmlOfError(res);
291 public String remove(String key) {
292 return partialRemove(key,true);
295 public String getContentType(String key) {
296 Style style = (Style)hashMap.get(key);
298 return getContentType(style.stylesheet);
300 log("Error, stylesheet \"" + key + "\" not loaded");
306 log("listing stylesheets...");
307 ArrayList l = new ArrayList();
308 Iterator i = hashMap.keySet().iterator();
309 while (i.hasNext()) {
310 String key = (String)i.next();
311 Style style = (Style)hashMap.get(key);
312 l.add(" " + key + " (" + style.fileName + "; " + getContentType(style.stylesheet) + ")");
313 System.out.println(" " + key + " (" + style.fileName + ")");
319 private ContentHandler applyRec(final Key[] keys, int idx, final ContentHandler saxOutput)
320 throws TransformerConfigurationException, SAXException, IOException
325 final Style style = (Style) hashMap.get(keys[idx].name);
327 log("cannot apply unknwon stylesheet \"" + keys[idx].name + "\" (aborted)");
330 return applyStylesheet(style.stylesheet, keys[idx].params, applyRec(keys, idx - 1, saxOutput));
334 public void apply(String inFile, OutputStream outputStream, Key[] keys, Properties userProperties)
335 throws IOException, TransformerConfigurationException, SAXException, Exception
337 /* File outFile = new File(outFilename);
338 if (outFile.exists())
339 System.out.println("Using cached version\n");
342 final Key[] rkeys = new Key[keys.length];
343 for (int i = 0; i < keys.length; i++)
344 rkeys[i] = keys[keys.length - i - 1];
346 Properties outputProperties;
347 Properties defaultProperties;
350 if (keys.length > 0) {
351 Style style = (Style) hashMap.get(rkeys[0].name);
353 log("Error, stylesheet \"" + rkeys[0].name + "\" not loaded");
356 outputProperties = style.stylesheet.getOutputProperties();
357 method = userProperties.getProperty("method");
358 if (method == null) method = outputProperties.getProperty("method");
359 if (method == null) method = "xml";
360 defaultProperties = org.apache.xalan.templates.OutputProperties.getDefaultMethodProperties(method);
362 method = userProperties.getProperty("method");
363 if (method == null) method = "xml";
364 outputProperties = org.apache.xalan.templates.OutputProperties.getDefaultMethodProperties(method);
365 defaultProperties = outputProperties;
368 for (Enumeration e = userProperties.propertyNames(); e.hasMoreElements(); ) {
369 String prop = (String) e.nextElement();
370 String value = userProperties.getProperty(prop);
371 if (value.equals("")) {
372 String defaultValue = defaultProperties.getProperty(prop);
373 if (defaultValue != null)
374 outputProperties.setProperty(prop, defaultProperties.getProperty(prop));
376 outputProperties.remove(prop);
378 outputProperties.setProperty(prop, value);
382 parseFile(inFile, applyRec(rkeys, rkeys.length - 1, saveFile(outputStream, outputProperties)));
386 public ArrayList reloadAll() throws TransformerConfigurationException, SAXException, IOException {
387 ArrayList res = new ArrayList();
388 Iterator i = hashMap.keySet().iterator();
389 while (i.hasNext()) {
390 String key = (String)i.next();
391 Style style = (Style)hashMap.get(key);
393 "reloading \"" + key + " (" + style.fileName + ")";
403 public String reload(String key) throws TransformerConfigurationException, SAXException, IOException {
405 Style style = (Style)hashMap.get(key);
407 log("reloading \"" + key + "\"... ");
408 style.lastModified = new File(style.fileName).lastModified();
409 res= compileStylesheet(style,key);
412 res = "Error: stylesheet \"" + key + "\" not loaded";
414 res = htmlOfError(res);
419 private String htmlOfWarning(String message)
421 return "<b style=\"color: maroon\">" + message+"</b>";
424 private String htmlOfError(String message)
426 return "<b style=\"color: red\">" + message+"</b>";