]> matita.cs.unibo.it Git - helm.git/blob - helm/uwobo/src/it/unibo/cs/helm/uwobo/Server.java
Initial revision
[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 Templates stylesheet;
67         };
68
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;
75
76         static {
77                 Properties props = new Properties();
78                 try {
79                         InputStream in = Server.class.getResourceAsStream("properties.txt");
80                         props.load(in);
81                         in.close();
82                 } catch (IOException ioe) {
83                         System.err.println("Could not load the version information.");
84                 }
85
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");
91         }
92
93         Server() {
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 +
99                   "\" not found");
100               } else {
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;
107                     try {
108                        istream = new FileInputStream(filename);
109                        ObjectInputStream p = new ObjectInputStream(istream);
110                        Style style = (Style)p.readObject();
111                        istream.close();
112                        hashMap.put(key, style);
113                     } catch (Exception e) {log(e.toString());};
114                  }
115                  log("Serialized stylesheets loaded!");
116               }
117            } else
118               log("Stylesheet serialization is off. Set the property SERIALIZATION_DIR to a non-empty value to turn it on.");
119           
120         }
121
122         private final HashMap hashMap = new HashMap();
123         private static int logCounter = 0;
124         
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);
134                 String res = "";
135                 if(!SERIALIZATION_DIR.equals("")) {
136                    try {
137                       FileOutputStream ostream =
138                          new FileOutputStream(serializationFile);
139                       ObjectOutputStream p = new ObjectOutputStream(ostream);
140                       p.writeObject(style);
141                       p.flush();
142                       ostream.close();
143                       res =
144                        "Stylesheet serialized in \"" + serializationFile + "\"";
145                       log(res);
146                    } catch (FileNotFoundException e) {
147                       res = "Warning: Stylesheet not " +
148                          "serialized. Error opening " + "file \"" +
149                          serializationFile + "\"";
150                       log(res);
151                       res = htmlOfWarning(res);
152                    }
153                 }
154                 return res;
155         }
156
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);
161
162                 if (media != null) {
163                         if (encoding != null)
164                                 return media + "; charset=" + encoding;
165                         return media;
166                 } else {
167                         final String method = oprops.getProperty(OutputKeys.METHOD);
168                         if (method.equals("html"))
169                                 return "text/html";
170                         else if (method.equals("text"))
171                                 return "text/plain";
172                         else 
173                                 return "text/xml";
174                 }
175         }
176
177         private final ContentHandler applyStylesheet(Templates stylesheet, HashMap params, ContentHandler saxOutput)
178         throws TransformerConfigurationException, SAXException
179         {
180                 TransformerHandler th = ((SAXTransformerFactory)TransformerFactory.newInstance()).newTransformerHandler(stylesheet);
181
182                 th.setResult(new SAXResult(saxOutput));
183
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);
191                         }
192                 }
193
194                 return th;
195         }
196
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);
205         }
206
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();
211         }
212
213         public static void log(String msg) {
214                 System.err.println(SERVERNAME + "[" + logCounter++ + "]: " + msg);
215         }
216
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)) {
222                       String msg =
223                          "Warning: Stylesheet already loaded. Request ignored.";
224                       log(msg);
225                       return htmlOfWarning(msg);
226                    } else {
227                       String res =
228                          "Error: There is already a stylesheet with keyword \""+
229                           key + "\" (aborted)";
230                       log(res);
231                       return htmlOfError(res);
232                    }
233                 }
234
235                 Style style = new Style();
236                 style.fileName = filename;
237                 String res = compileStylesheet(style,key);
238                 log("done!");
239
240                 hashMap.put(key, style);
241                 return res;
242         }
243
244         public ArrayList removeAll() throws TransformerConfigurationException, SAXException, IOException {
245                 ArrayList res = new ArrayList();
246                 String log = "";
247                 Iterator i = hashMap.keySet().iterator();
248                 while (i.hasNext()) {
249                         String key = (String)i.next();
250                         Style style = (Style)hashMap.get(key);
251                         String msg =
252                          "removing \"" + key + " (" + style.fileName + ")";
253                         res.add(msg);
254                         log(msg);
255                         msg = partialRemove(key,false);
256                         if(!msg.equals(""))
257                            res.add(msg);
258                 }
259                 hashMap.clear();
260                 return res;
261         }
262
263         private String partialRemove(String key, boolean removeFromHashTable) {
264                 String res = "";
265                 Style style = (Style)hashMap.get(key);
266                 if (style != null) {
267                         log("removing \"" + key + " (" + style.fileName + ")");
268                         if (removeFromHashTable)
269                            hashMap.remove(key);
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";
275                               log(res);
276                               res = htmlOfWarning(res);
277                            }
278                         }
279                 } else {
280                         res = "Error: stylesheet \"" + key + "\" not loaded";
281                         log(res);
282                         res = htmlOfError(res);
283                 }
284                 return res;
285         }
286
287         public String remove(String key) {
288            return partialRemove(key,true);
289         }
290
291         public String getContentType(String key) {
292                 Style style = (Style)hashMap.get(key);
293                 if (style != null) {
294                         return getContentType(style.stylesheet);
295                 } else {
296                         log("Error, stylesheet \"" + key + "\" not loaded");
297                         return null;
298                 }
299         }
300
301         public List list() {
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 + ")");
310                 }
311                 log("done!");
312                 return l;
313         }
314
315         private ContentHandler applyRec(final Key[] keys, int idx, final ContentHandler saxOutput)
316         throws TransformerConfigurationException, SAXException, IOException
317         {
318                 if (idx < 0)
319                         return saxOutput;
320                 else {
321                         final Style style = (Style) hashMap.get(keys[idx].name);
322                         if (style == null) {
323                                 log("cannot apply unknwon stylesheet \"" + keys[idx].name + "\" (aborted)");
324                                 return null;
325                         }
326                         return applyStylesheet(style.stylesheet, keys[idx].params, applyRec(keys, idx - 1, saxOutput));
327                 }
328         }
329
330         public void apply(String inFile, OutputStream outputStream, Key[] keys, Properties userProperties)
331         throws IOException, TransformerConfigurationException, SAXException, Exception
332         {
333 /*              File outFile = new File(outFilename);
334                 if (outFile.exists())
335                         System.out.println("Using cached version\n");
336                 else {
337 */                      
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];
341
342                         Properties outputProperties; 
343                         Properties defaultProperties;
344                         String method;
345
346                         if (keys.length > 0) {
347                                 Style style = (Style) hashMap.get(rkeys[0].name);
348                                 if (style == null) {
349                                         log("Error, stylesheet \"" + rkeys[0].name + "\" not loaded");
350                                         return;
351                                 }
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);
357                         } else {
358                                 method = userProperties.getProperty("method");
359                                 if (method == null) method = "xml";
360                                 outputProperties = org.apache.xalan.templates.OutputProperties.getDefaultMethodProperties(method);
361                                 defaultProperties = outputProperties;
362                         }
363
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));
371                                         else
372                                                 outputProperties.remove(prop);
373                                 } else {
374                                         outputProperties.setProperty(prop, value);
375                                 }
376                         }
377                         
378                         parseFile(inFile, applyRec(rkeys, rkeys.length - 1, saveFile(outputStream, outputProperties)));
379 //              }
380         }
381
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);
388                         String msg =
389                          "reloading \"" + key + " (" + style.fileName + ")";
390                         res.add(msg);
391                         log(msg);
392                         msg = reload(key);
393                         if(!msg.equals(""))
394                            res.add(msg);
395                 }
396                 return res;
397         }
398
399         public String reload(String key) throws TransformerConfigurationException, SAXException, IOException {
400                 String res = "";
401                 Style style = (Style)hashMap.get(key);
402                 if (style != null) {
403                    log("reloading \"" + key + "\"... ");
404                    res= compileStylesheet(style,key);
405                    log("done!");
406                 } else {
407                         res = "Error: stylesheet \"" + key + "\" not loaded";
408                         log(res);
409                         res = htmlOfError(res);
410                 }
411                 return res;
412         }
413
414         private String htmlOfWarning(String message)
415         {
416            return "<b style=\"color: maroon\">" + message+"</b>";
417         }
418
419         private String htmlOfError(String message)
420         {
421            return "<b style=\"color: red\">" + message+"</b>";
422         }
423 }