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 Templates stylesheet;
69 public static final String SERVERNAME = "uwobo-XSLT-server";
70 public static final String PACKAGE;
71 public static final String VERSION;
72 public static final String DATE;
73 public static final String TIME;
74 public static final String SERIALIZATION_DIR;
77 Properties props = new Properties();
79 InputStream in = Server.class.getResourceAsStream("properties.txt");
82 } catch (IOException ioe) {
83 System.err.println("Could not load the version information.");
86 PACKAGE = props.getProperty("PACKAGE");
87 VERSION = props.getProperty("VERSION");
88 DATE = props.getProperty("DATE");
89 TIME = props.getProperty("TIME");
90 SERIALIZATION_DIR = props.getProperty("SERIALIZATION_DIR");
94 if(!SERIALIZATION_DIR.equals("")) {
95 log("Looking for serialized stylesheets");
96 File [] serialized = new File(SERIALIZATION_DIR).listFiles();
97 if (serialized == null) {
98 log("Serialized stylesheets directory \"" + SERIALIZATION_DIR +
101 for (int i = 0; i < serialized.length ; i++) {
102 File filename = serialized[i];
103 String key = filename.getName();
104 log("Found serialized stylesheet " + key);
105 log("Reloading serialized stylesheet \"" + filename + "\"... ");
106 FileInputStream istream;
108 istream = new FileInputStream(filename);
109 ObjectInputStream p = new ObjectInputStream(istream);
110 Style style = (Style)p.readObject();
112 hashMap.put(key, style);
113 } catch (Exception e) {log(e.toString());};
115 log("Serialized stylesheets loaded!");
118 log("Stylesheet serialization is off. Set the property SERIALIZATION_DIR to a non-empty value to turn it on.");
122 private final HashMap hashMap = new HashMap();
123 private static int logCounter = 0;
125 private final String compileStylesheet(Style style, String key) throws TransformerConfigurationException, SAXException, IOException {
126 StreamSource streamsource =
127 new StreamSource(new URL(style.fileName).openStream());
128 streamsource.setSystemId(style.fileName);
129 Templates templates =
130 ((SAXTransformerFactory)TransformerFactory.newInstance())
131 .newTemplates(streamsource);
132 style.stylesheet = templates;
133 File serializationFile = new File(SERIALIZATION_DIR,key);
135 if(!SERIALIZATION_DIR.equals("")) {
137 FileOutputStream ostream =
138 new FileOutputStream(serializationFile);
139 ObjectOutputStream p = new ObjectOutputStream(ostream);
140 p.writeObject(style);
144 "Stylesheet serialized in \"" + serializationFile + "\"";
146 } catch (FileNotFoundException e) {
147 res = "Warning: Stylesheet not " +
148 "serialized. Error opening " + "file \"" +
149 serializationFile + "\"";
151 res = htmlOfWarning(res);
157 private String getContentType(Templates templates) {
158 final Properties oprops = templates.getOutputProperties();
159 final String encoding = oprops.getProperty(OutputKeys.ENCODING);
160 final String media = oprops.getProperty(OutputKeys.MEDIA_TYPE);
163 if (encoding != null)
164 return media + "; charset=" + encoding;
167 final String method = oprops.getProperty(OutputKeys.METHOD);
168 if (method.equals("html"))
170 else if (method.equals("text"))
177 private final ContentHandler applyStylesheet(Templates stylesheet, HashMap params, ContentHandler saxOutput)
178 throws TransformerConfigurationException, SAXException
180 TransformerHandler th = ((SAXTransformerFactory)TransformerFactory.newInstance()).newTransformerHandler(stylesheet);
182 th.setResult(new SAXResult(saxOutput));
184 if (params != null) {
185 final Transformer transformer = th.getTransformer();
186 Iterator i = params.keySet().iterator();
187 while (i.hasNext()) {
188 final String name = (String) i.next();
189 final String value = (String) params.get(name);
190 transformer.setParameter(name, value);
197 private final void parseFile(String datasheet, ContentHandler saxOutput) throws SAXException, IOException, Exception {
198 final XMLReader reader = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
199 reader.setFeature("http://xml.org/sax/features/namespaces", true);
200 reader.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
201 reader.setContentHandler(saxOutput);
202 if (saxOutput instanceof LexicalHandler)
203 reader.setProperty("http://xml.org/sax/properties/lexical-handler", (LexicalHandler)saxOutput);
204 reader.parse(datasheet);
207 private final ContentHandler saveFile(OutputStream outputStream, Properties props) throws IOException {
208 final Serializer ser = SerializerFactory.getSerializer(props);
209 ser.setOutputStream(outputStream);
210 return ser.asContentHandler();
213 public static void log(String msg) {
214 System.err.println(SERVERNAME + "[" + logCounter++ + "]: " + msg);
217 public String add(String filename, String key) throws TransformerConfigurationException, SAXException, IOException {
218 log("processing stylesheet \"" + filename + "\" using key " + key + "... ");
219 if (hashMap.containsKey(key)) {
220 Style style = (Style)hashMap.get(key);
221 if (style.fileName.equals(filename)) {
223 "Warning: Stylesheet already loaded. Request ignored.";
225 return htmlOfWarning(msg);
228 "Error: There is already a stylesheet with keyword \""+
229 key + "\" (aborted)";
231 return htmlOfError(res);
235 Style style = new Style();
236 style.fileName = filename;
237 String res = compileStylesheet(style,key);
240 hashMap.put(key, style);
244 public ArrayList removeAll() throws TransformerConfigurationException, SAXException, IOException {
245 ArrayList res = new ArrayList();
247 Iterator i = hashMap.keySet().iterator();
248 while (i.hasNext()) {
249 String key = (String)i.next();
250 Style style = (Style)hashMap.get(key);
252 "removing \"" + key + " (" + style.fileName + ")";
255 msg = partialRemove(key,false);
263 private String partialRemove(String key, boolean removeFromHashTable) {
265 Style style = (Style)hashMap.get(key);
267 log("removing \"" + key + " (" + style.fileName + ")");
268 if (removeFromHashTable)
270 if(!SERIALIZATION_DIR.equals("")) {
271 File to_delete = new File(SERIALIZATION_DIR,key);
272 if (!to_delete.delete()) {
273 res = "Warning: Serialized stylesheet \"" +
274 to_delete + "\" to remove not found";
276 res = htmlOfWarning(res);
280 res = "Error: stylesheet \"" + key + "\" not loaded";
282 res = htmlOfError(res);
287 public String remove(String key) {
288 return partialRemove(key,true);
291 public String getContentType(String key) {
292 Style style = (Style)hashMap.get(key);
294 return getContentType(style.stylesheet);
296 log("Error, stylesheet \"" + key + "\" not loaded");
302 log("listing stylesheets...");
303 ArrayList l = new ArrayList();
304 Iterator i = hashMap.keySet().iterator();
305 while (i.hasNext()) {
306 String key = (String)i.next();
307 Style style = (Style)hashMap.get(key);
308 l.add(" " + key + " (" + style.fileName + "; " + getContentType(style.stylesheet) + ")");
309 System.out.println(" " + key + " (" + style.fileName + ")");
315 private ContentHandler applyRec(final Key[] keys, int idx, final ContentHandler saxOutput)
316 throws TransformerConfigurationException, SAXException, IOException
321 final Style style = (Style) hashMap.get(keys[idx].name);
323 log("cannot apply unknwon stylesheet \"" + keys[idx].name + "\" (aborted)");
326 return applyStylesheet(style.stylesheet, keys[idx].params, applyRec(keys, idx - 1, saxOutput));
330 public void apply(String inFile, OutputStream outputStream, Key[] keys, Properties userProperties)
331 throws IOException, TransformerConfigurationException, SAXException, Exception
333 /* File outFile = new File(outFilename);
334 if (outFile.exists())
335 System.out.println("Using cached version\n");
338 final Key[] rkeys = new Key[keys.length];
339 for (int i = 0; i < keys.length; i++)
340 rkeys[i] = keys[keys.length - i - 1];
342 Properties outputProperties;
343 Properties defaultProperties;
346 if (keys.length > 0) {
347 Style style = (Style) hashMap.get(rkeys[0].name);
349 log("Error, stylesheet \"" + rkeys[0].name + "\" not loaded");
352 outputProperties = style.stylesheet.getOutputProperties();
353 method = userProperties.getProperty("method");
354 if (method == null) method = outputProperties.getProperty("method");
355 if (method == null) method = "xml";
356 defaultProperties = org.apache.xalan.templates.OutputProperties.getDefaultMethodProperties(method);
358 method = userProperties.getProperty("method");
359 if (method == null) method = "xml";
360 outputProperties = org.apache.xalan.templates.OutputProperties.getDefaultMethodProperties(method);
361 defaultProperties = outputProperties;
364 for (Enumeration e = userProperties.propertyNames(); e.hasMoreElements(); ) {
365 String prop = (String) e.nextElement();
366 String value = userProperties.getProperty(prop);
367 if (value.equals("")) {
368 String defaultValue = defaultProperties.getProperty(prop);
369 if (defaultValue != null)
370 outputProperties.setProperty(prop, defaultProperties.getProperty(prop));
372 outputProperties.remove(prop);
374 outputProperties.setProperty(prop, value);
378 parseFile(inFile, applyRec(rkeys, rkeys.length - 1, saveFile(outputStream, outputProperties)));
382 public ArrayList reloadAll() throws TransformerConfigurationException, SAXException, IOException {
383 ArrayList res = new ArrayList();
384 Iterator i = hashMap.keySet().iterator();
385 while (i.hasNext()) {
386 String key = (String)i.next();
387 Style style = (Style)hashMap.get(key);
389 "reloading \"" + key + " (" + style.fileName + ")";
399 public String reload(String key) throws TransformerConfigurationException, SAXException, IOException {
401 Style style = (Style)hashMap.get(key);
403 log("reloading \"" + key + "\"... ");
404 res= compileStylesheet(style,key);
407 res = "Error: stylesheet \"" + key + "\" not loaded";
409 res = htmlOfError(res);
414 private String htmlOfWarning(String message)
416 return "<b style=\"color: maroon\">" + message+"</b>";
419 private String htmlOfError(String message)
421 return "<b style=\"color: red\">" + message+"</b>";