]> matita.cs.unibo.it Git - helm.git/blob - helm/uwobo/src/it/unibo/cs/helm/uwobo/Server.java
GPL licence added.
[helm.git] / helm / uwobo / src / it / unibo / cs / helm / uwobo / Server.java
1 /* Copyright (C) 2001, HELM Team
2  *
3  * This file is part of UWOBO, developed at the Computer Science
4  * Department, University of Bologna, Italy.
5  * 
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.
10  *
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.
15  *
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,
19  * MA  02111-1307, USA.
20  *
21  * For details, see the UWOBO World-Wide-Web page,
22  * http://cs.unibo.it/helm/uwobo
23  */
24
25 package it.unibo.cs.helm.uwobo;
26
27 import java.io.*;
28 import java.net.URL;
29 import java.util.*;
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.*;
38 import org.xml.sax.*;
39 import org.xml.sax.ext.*;
40 import org.xml.sax.helpers.*;
41
42 /**
43 // This file is part of UWOBO, a small and simple XSLT server.
44 // 
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.
49 //
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.
54 //
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.
58 // 
59 // For details, send a mail to <luca.padovani@cs.unibo.it>
60 * @author Luca Padovani, Riccardo Solmi
61 */
62
63 public class Server {
64         private static class Style implements Serializable {
65                 public String fileName;
66                 public long lastModified;
67                 public Templates stylesheet;
68         };
69
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;
76
77         static {
78                 Properties props = new Properties();
79                 try {
80                         InputStream in = Server.class.getResourceAsStream("properties.txt");
81                         props.load(in);
82                         in.close();
83                 } catch (IOException ioe) {
84                         System.err.println("Could not load the version information.");
85                 }
86
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");
92         }
93
94         Server() {
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 +
100                   "\" not found");
101               } else {
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;
108                     try {
109                        istream = new FileInputStream(filename);
110                        ObjectInputStream p = new ObjectInputStream(istream);
111                        Style style = (Style)p.readObject();
112                        istream.close();
113                        hashMap.put(key, style);
114                     } catch (Exception e) {log(e.toString());};
115                  }
116                  log("Serialized stylesheets loaded!");
117               }
118            } else
119               log("Stylesheet serialization is off. Set the property SERIALIZATION_DIR to a non-empty value to turn it on.");
120           
121         }
122
123         private final HashMap hashMap = new HashMap();
124         private static int logCounter = 0;
125         
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);
135                 String res = "";
136                 if(!SERIALIZATION_DIR.equals("")) {
137                    try {
138                       FileOutputStream ostream =
139                          new FileOutputStream(serializationFile);
140                       ObjectOutputStream p = new ObjectOutputStream(ostream);
141                       p.writeObject(style);
142                       p.flush();
143                       ostream.close();
144                       res =
145                        "Stylesheet serialized in \"" + serializationFile + "\"";
146                       log(res);
147                    } catch (FileNotFoundException e) {
148                       res = "Warning: Stylesheet not " +
149                          "serialized. Error opening " + "file \"" +
150                          serializationFile + "\"";
151                       log(res);
152                       res = htmlOfWarning(res);
153                    }
154                 }
155                 return res;
156         }
157
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);
162
163                 if (media != null) {
164                         if (encoding != null)
165                                 return media + "; charset=" + encoding;
166                         return media;
167                 } else {
168                         final String method = oprops.getProperty(OutputKeys.METHOD);
169                         if (method.equals("html"))
170                                 return "text/html";
171                         else if (method.equals("text"))
172                                 return "text/plain";
173                         else 
174                                 return "text/xml";
175                 }
176         }
177
178         private final ContentHandler applyStylesheet(Templates stylesheet, HashMap params, ContentHandler saxOutput)
179         throws TransformerConfigurationException, SAXException
180         {
181                 TransformerHandler th = ((SAXTransformerFactory)TransformerFactory.newInstance()).newTransformerHandler(stylesheet);
182
183                 th.setResult(new SAXResult(saxOutput));
184
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);
192                         }
193                 }
194
195                 return th;
196         }
197
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);
206         }
207
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();
212         }
213
214         public static void log(String msg) {
215                 System.err.println(SERVERNAME + "[" + logCounter++ + "]: " + msg);
216         }
217
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)) {
223                       String msg =
224                          "Warning: Stylesheet already loaded. Reloading...";
225                       log(msg);
226                       String msg2 = reload(key);
227                       return htmlOfWarning(msg) +
228                          (msg2.equals("") ? "" : "<br />" + msg2);
229                    } else {
230                       String res =
231                          "Error: There is already a stylesheet with keyword \""+
232                           key + "\" (aborted)";
233                       log(res);
234                       return htmlOfError(res);
235                    }
236                 }
237
238                 Style style = new Style();
239                 style.fileName = filename;
240                 style.lastModified = new File(filename).lastModified();
241                 String res = compileStylesheet(style,key);
242                 log("done!");
243
244                 hashMap.put(key, style);
245                 return res;
246         }
247
248         public ArrayList removeAll() throws TransformerConfigurationException, SAXException, IOException {
249                 ArrayList res = new ArrayList();
250                 String log = "";
251                 Iterator i = hashMap.keySet().iterator();
252                 while (i.hasNext()) {
253                         String key = (String)i.next();
254                         Style style = (Style)hashMap.get(key);
255                         String msg =
256                          "removing \"" + key + " (" + style.fileName + ")";
257                         res.add(msg);
258                         log(msg);
259                         msg = partialRemove(key,false);
260                         if(!msg.equals(""))
261                            res.add(msg);
262                 }
263                 hashMap.clear();
264                 return res;
265         }
266
267         private String partialRemove(String key, boolean removeFromHashTable) {
268                 String res = "";
269                 Style style = (Style)hashMap.get(key);
270                 if (style != null) {
271                         log("removing \"" + key + " (" + style.fileName + ")");
272                         if (removeFromHashTable)
273                            hashMap.remove(key);
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";
279                               log(res);
280                               res = htmlOfWarning(res);
281                            }
282                         }
283                 } else {
284                         res = "Error: stylesheet \"" + key + "\" not loaded";
285                         log(res);
286                         res = htmlOfError(res);
287                 }
288                 return res;
289         }
290
291         public String remove(String key) {
292            return partialRemove(key,true);
293         }
294
295         public String getContentType(String key) {
296                 Style style = (Style)hashMap.get(key);
297                 if (style != null) {
298                         return getContentType(style.stylesheet);
299                 } else {
300                         log("Error, stylesheet \"" + key + "\" not loaded");
301                         return null;
302                 }
303         }
304
305         public List list() {
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 + ")");
314                 }
315                 log("done!");
316                 return l;
317         }
318
319         private ContentHandler applyRec(final Key[] keys, int idx, final ContentHandler saxOutput)
320         throws TransformerConfigurationException, SAXException, IOException
321         {
322                 if (idx < 0)
323                         return saxOutput;
324                 else {
325                         final Style style = (Style) hashMap.get(keys[idx].name);
326                         if (style == null) {
327                                 log("cannot apply unknwon stylesheet \"" + keys[idx].name + "\" (aborted)");
328                                 return null;
329                         }
330                         return applyStylesheet(style.stylesheet, keys[idx].params, applyRec(keys, idx - 1, saxOutput));
331                 }
332         }
333
334         public void apply(String inFile, OutputStream outputStream, Key[] keys, Properties userProperties)
335         throws IOException, TransformerConfigurationException, SAXException, Exception
336         {
337 /*              File outFile = new File(outFilename);
338                 if (outFile.exists())
339                         System.out.println("Using cached version\n");
340                 else {
341 */                      
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];
345
346                         Properties outputProperties; 
347                         Properties defaultProperties;
348                         String method;
349
350                         if (keys.length > 0) {
351                                 Style style = (Style) hashMap.get(rkeys[0].name);
352                                 if (style == null) {
353                                         log("Error, stylesheet \"" + rkeys[0].name + "\" not loaded");
354                                         return;
355                                 }
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);
361                         } else {
362                                 method = userProperties.getProperty("method");
363                                 if (method == null) method = "xml";
364                                 outputProperties = org.apache.xalan.templates.OutputProperties.getDefaultMethodProperties(method);
365                                 defaultProperties = outputProperties;
366                         }
367
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));
375                                         else
376                                                 outputProperties.remove(prop);
377                                 } else {
378                                         outputProperties.setProperty(prop, value);
379                                 }
380                         }
381                         
382                         parseFile(inFile, applyRec(rkeys, rkeys.length - 1, saveFile(outputStream, outputProperties)));
383 //              }
384         }
385
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);
392                         String msg =
393                          "reloading \"" + key + " (" + style.fileName + ")";
394                         res.add(msg);
395                         log(msg);
396                         msg = reload(key);
397                         if(!msg.equals(""))
398                            res.add(msg);
399                 }
400                 return res;
401         }
402
403         public String reload(String key) throws TransformerConfigurationException, SAXException, IOException {
404                 String res = "";
405                 Style style = (Style)hashMap.get(key);
406                 if (style != null) {
407                    log("reloading \"" + key + "\"... ");
408                    style.lastModified = new File(style.fileName).lastModified();
409                    res= compileStylesheet(style,key);
410                    log("done!");
411                 } else {
412                         res = "Error: stylesheet \"" + key + "\" not loaded";
413                         log(res);
414                         res = htmlOfError(res);
415                 }
416                 return res;
417         }
418
419         private String htmlOfWarning(String message)
420         {
421            return "<b style=\"color: maroon\">" + message+"</b>";
422         }
423
424         private String htmlOfError(String message)
425         {
426            return "<b style=\"color: red\">" + message+"</b>";
427         }
428 }