]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/uwobo/src/it/unibo/cs/helm/uwobo/Server.java
This commit was manufactured by cvs2svn to create branch 'start'.
[helm.git] / helm / uwobo / src / it / unibo / cs / helm / uwobo / Server.java
diff --git a/helm/uwobo/src/it/unibo/cs/helm/uwobo/Server.java b/helm/uwobo/src/it/unibo/cs/helm/uwobo/Server.java
new file mode 100644 (file)
index 0000000..da11a07
--- /dev/null
@@ -0,0 +1,301 @@
+package it.unibo.cs.helm.uwobo;
+
+import java.io.*;
+import java.net.URL;
+import java.util.*;
+import javax.xml.transform.*;
+import javax.xml.transform.sax.*;
+import javax.xml.transform.stream.*;
+import org.apache.xalan.serialize.*;
+import org.apache.xalan.xslt.*;
+import org.apache.xalan.templates.*;
+import org.apache.xalan.transformer.*;
+import org.apache.xerces.parsers.*;
+import org.xml.sax.*;
+import org.xml.sax.ext.*;
+import org.xml.sax.helpers.*;
+
+/**
+// This file is part of UWOBO, a small and simple XSLT server.
+// 
+// UWOBO is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// UWOBO is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with UWOBO; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+// 
+// For details, send a mail to <luca.padovani@cs.unibo.it>
+* @author Luca Padovani, Riccardo Solmi
+*/
+
+public class Server {
+       private static class Style {
+               public String fileName;
+               public long lastModified;
+               public Templates stylesheet;
+       };
+
+       public static final String SERVERNAME = "uwobo-XSLT-server";
+       public static final String PACKAGE;
+       public static final String VERSION;
+       public static final String DATE;
+       public static final String TIME;
+
+       static {
+               Properties props = new Properties();
+               try {
+                       InputStream in = Server.class.getResourceAsStream("properties.txt");
+                       props.load(in);
+                       in.close();
+               } catch (IOException ioe) {
+                       System.err.println("Could not load the version information.");
+               }
+
+               PACKAGE = props.getProperty("PACKAGE");
+               VERSION = props.getProperty("VERSION");
+               DATE = props.getProperty("DATE");
+               TIME = props.getProperty("TIME");
+       }
+
+       private final HashMap hashMap = new HashMap();
+       private static int logCounter = 0;
+       
+       private final Templates compileStylesheet(String xsl_file) throws TransformerConfigurationException, SAXException, IOException {
+               StreamSource streamsource =
+                       new StreamSource(new URL(xsl_file).openStream());
+               streamsource.setSystemId(xsl_file);
+               return ((SAXTransformerFactory)TransformerFactory.newInstance())
+                       .newTemplates(streamsource);
+       }
+
+       private String getContentType(Templates templates) {
+               final Properties oprops = templates.getOutputProperties();
+               final String encoding = oprops.getProperty(OutputKeys.ENCODING);  
+               final String media = oprops.getProperty(OutputKeys.MEDIA_TYPE);
+
+               if (media != null) {
+                       if (encoding != null)
+                               return media + "; charset=" + encoding;
+                       return media;
+               } else {
+                       final String method = oprops.getProperty(OutputKeys.METHOD);
+                       if (method.equals("html"))
+                               return "text/html";
+                       else if (method.equals("text"))
+                               return "text/plain";
+                       else 
+                               return "text/xml";
+               }
+       }
+
+       private final ContentHandler applyStylesheet(Templates stylesheet, HashMap params, ContentHandler saxOutput)
+       throws TransformerConfigurationException, SAXException
+       {
+               TransformerHandler th = ((SAXTransformerFactory)TransformerFactory.newInstance()).newTransformerHandler(stylesheet);
+
+               th.setResult(new SAXResult(saxOutput));
+
+               if (params != null) {
+                       final Transformer transformer = th.getTransformer();
+                       Iterator i = params.keySet().iterator();
+                       while (i.hasNext()) {
+                               final String name = (String) i.next();
+                               final String value = (String) params.get(name);
+                               transformer.setParameter(name, value);
+                       }
+               }
+
+               return th;
+       }
+
+       private final void parseFile(String datasheet, ContentHandler saxOutput) throws SAXException, IOException, Exception {
+               final XMLReader reader = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
+               reader.setFeature("http://xml.org/sax/features/namespaces", true);
+               reader.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
+               reader.setContentHandler(saxOutput);
+               if (saxOutput instanceof LexicalHandler)
+                       reader.setProperty("http://xml.org/sax/properties/lexical-handler", (LexicalHandler)saxOutput);
+               reader.parse(datasheet);
+       }
+
+       private final ContentHandler saveFile(OutputStream outputStream, Properties props) throws IOException {
+               final Serializer ser = SerializerFactory.getSerializer(props);
+               ser.setOutputStream(outputStream);
+               return ser.asContentHandler();
+       }
+
+       public static void log(String msg) {
+               System.err.println(SERVERNAME + "[" + logCounter++ + "]: " + msg);
+       }
+
+       public void add(String filename, String key) throws TransformerConfigurationException, SAXException, IOException {
+               if (hashMap.containsKey(key)) {
+                       log("there is already a stylesheet with keyword \"" + key + "\" (aborted)");
+                       return;
+               }
+
+               Style style = new Style();
+               style.fileName = filename;
+               style.lastModified = new File(filename).lastModified();
+               log("processing stylesheet \"" + filename + "\"... ");
+               style.stylesheet = compileStylesheet(filename);
+               log("done!");
+
+               hashMap.put(key, style);
+       }
+
+       public void removeAll() throws TransformerConfigurationException, SAXException, IOException {
+               String key;
+               Style style;
+               Iterator i = hashMap.keySet().iterator();
+               while (i.hasNext()) {
+                       key = (String)i.next();
+                       style = (Style)hashMap.get(key);
+                       log("removing \"" + key + " (" + style.fileName + ")");
+               }
+               hashMap.clear();
+       }
+
+       public void remove(String key) {
+               Style style = (Style)hashMap.get(key);
+               if (style != null) {
+                       log("removing \"" + key + " (" + style.fileName + ")");
+                       hashMap.remove(key);
+               } else {
+                       log("error, stylesheet \"" + key + "\" not loaded");
+               }
+       }
+
+       public String getContentType(String key) {
+               Style style = (Style)hashMap.get(key);
+               if (style != null) {
+                       return getContentType(style.stylesheet);
+               } else {
+                       log("error, stylesheet \"" + key + "\" not loaded");
+                       return null;
+               }
+       }
+
+       public List list() {
+               log("listing stylesheets...");
+               ArrayList l = new ArrayList();
+               Iterator i = hashMap.keySet().iterator();
+               while (i.hasNext()) {
+                       String key  = (String)i.next();
+                       Style style = (Style)hashMap.get(key);
+                       l.add("  " + key + " (" + style.fileName + "; " + getContentType(style.stylesheet) + ")");
+                       System.out.println("  " + key + " (" + style.fileName + ")");
+               }
+               log("done!");
+               return l;
+       }
+
+       private ContentHandler applyRec(final Key[] keys, int idx, final ContentHandler saxOutput)
+       throws TransformerConfigurationException, SAXException, IOException
+       {
+               if (idx < 0)
+                       return saxOutput;
+               else {
+                       final Style style = (Style) hashMap.get(keys[idx].name);
+                       if (style == null) {
+                               log("cannot apply unknwon stylesheet \"" + keys[idx].name + "\" (aborted)");
+                               return null;
+                       }
+                       return applyStylesheet(style.stylesheet, keys[idx].params, applyRec(keys, idx - 1, saxOutput));
+               }
+       }
+
+       public void apply(String inFile, OutputStream outputStream, Key[] keys, Properties userProperties)
+       throws FileNotFoundException, IOException, TransformerConfigurationException, SAXException, Exception
+       {
+/*             File outFile = new File(outFilename);
+               if (outFile.exists())
+                       System.out.println("Using cached version\n");
+               else {
+*/                     
+                       final Key[] rkeys = new Key[keys.length];
+                       for (int i = 0; i < keys.length; i++)
+                               rkeys[i] = keys[keys.length - i - 1];
+
+                       Properties outputProperties; 
+                       Properties defaultProperties;
+                       String method;
+
+                       if (keys.length > 0) {
+                               Style style = (Style) hashMap.get(rkeys[0].name);
+                               if (style == null) {
+                                       log("error, stylesheet \"" + rkeys[0].name + "\" not loaded");
+                                       return;
+                               }
+                               outputProperties = style.stylesheet.getOutputProperties();
+                               method = userProperties.getProperty("method");
+                               if (method == null) method = outputProperties.getProperty("method");
+                               if (method == null) method = "xml";
+                               defaultProperties = org.apache.xalan.templates.OutputProperties.getDefaultMethodProperties(method);
+                       } else {
+                               method = userProperties.getProperty("method");
+                               if (method == null) method = "xml";
+                               outputProperties = org.apache.xalan.templates.OutputProperties.getDefaultMethodProperties(method);
+                               defaultProperties = outputProperties;
+                       }
+
+                       for (Enumeration e = userProperties.propertyNames(); e.hasMoreElements(); ) {
+                               String prop = (String) e.nextElement();
+                               String value = userProperties.getProperty(prop);
+                               if (value.equals("")) {
+                                       String defaultValue = defaultProperties.getProperty(prop);
+                                       if (defaultValue != null)
+                                               outputProperties.setProperty(prop, defaultProperties.getProperty(prop));
+                                       else
+                                               outputProperties.remove(prop);
+                               } else {
+                                       outputProperties.setProperty(prop, value);
+                               }
+                       }
+                       
+                       parseFile(inFile, applyRec(rkeys, rkeys.length - 1, saveFile(outputStream, outputProperties)));
+//             }
+       }
+
+       public void reloadAll() throws TransformerConfigurationException, SAXException, IOException {
+               Iterator i = hashMap.keySet().iterator();
+               while (i.hasNext())
+                       reload((String)i.next());
+       }
+
+       public void reload(String key) throws TransformerConfigurationException, SAXException, IOException {
+               Style style = (Style)hashMap.get(key);
+
+               log("reloading \"" + key + "\"... ");
+               style.stylesheet = compileStylesheet(style.fileName);
+               style.lastModified = new File(style.fileName).lastModified();
+               log("done!");
+       }
+
+       public void updateAll() throws TransformerConfigurationException, SAXException, IOException {
+               Iterator i = hashMap.keySet().iterator();
+               while (i.hasNext())
+                       update((String)i.next());
+       }
+
+       public void update(String key) throws TransformerConfigurationException, SAXException, IOException {
+               Style style = (Style)hashMap.get(key);
+
+               log("updating \"" + key + "\"... ");
+               File styleFile = new File(style.fileName);
+               if (styleFile.lastModified() > style.lastModified) {
+                       style.stylesheet = compileStylesheet(style.fileName);
+                       style.lastModified = styleFile.lastModified();
+                       log("done!");
+               } else
+                       log("\"" + key + "\" is up to date");
+       }
+}