From: Luca Padovani Date: Thu, 18 Oct 2001 20:32:41 +0000 (+0000) Subject: Initial revision X-Git-Tag: v0_1_3~58 X-Git-Url: http://matita.cs.unibo.it/gitweb/?p=helm.git;a=commitdiff_plain;h=02bc1a8c06b2d2c5169c9f1beecf9daa94a85247 Initial revision --- diff --git a/helm/uwobo/.cvsignore b/helm/uwobo/.cvsignore new file mode 100644 index 000000000..2fd79ea45 --- /dev/null +++ b/helm/uwobo/.cvsignore @@ -0,0 +1,5 @@ +build +docs +resources +backup +dist diff --git a/helm/uwobo/.cvswrappers b/helm/uwobo/.cvswrappers new file mode 100644 index 000000000..0140b5545 --- /dev/null +++ b/helm/uwobo/.cvswrappers @@ -0,0 +1 @@ +*.jar -k 'b' -m 'COPY' diff --git a/helm/uwobo/ant/ant.jar b/helm/uwobo/ant/ant.jar new file mode 100644 index 000000000..9a14d89f0 Binary files /dev/null and b/helm/uwobo/ant/ant.jar differ diff --git a/helm/uwobo/ant/jaxp.jar b/helm/uwobo/ant/jaxp.jar new file mode 100644 index 000000000..9cfa2319e Binary files /dev/null and b/helm/uwobo/ant/jaxp.jar differ diff --git a/helm/uwobo/ant/parser.jar b/helm/uwobo/ant/parser.jar new file mode 100644 index 000000000..eb858322b Binary files /dev/null and b/helm/uwobo/ant/parser.jar differ diff --git a/helm/uwobo/antRun b/helm/uwobo/antRun new file mode 100755 index 000000000..5894f4483 --- /dev/null +++ b/helm/uwobo/antRun @@ -0,0 +1,8 @@ +#! /bin/sh + +if [ "$JAVA_HOME" != "" ] ; then + $JAVA_HOME/bin/java -cp ant/ant.jar:ant/jaxp.jar:ant/parser.jar:$JAVA_HOME/lib/tools.jar -Dant.home=. $ANT_OPTS org.apache.tools.ant.Main $@ +else + echo "Warning: JAVA_HOME environment variable is not set." +fi + diff --git a/helm/uwobo/antRun.bat b/helm/uwobo/antRun.bat new file mode 100644 index 000000000..e83ce36bd --- /dev/null +++ b/helm/uwobo/antRun.bat @@ -0,0 +1,17 @@ +@echo off +set ANT_CMD_LINE_ARGS= + +:setupArgs +if %1a==a goto checkJavaHome +set ANT_CMD_LINE_ARGS=%ANT_CMD_LINE_ARGS% %1 +shift +goto setupArgs + +:checkJavaHome +if not "%JAVA_HOME%" == "" goto runAnt +echo Warning: JAVA_HOME environment variable is not set. + +:runAnt +java -cp ant\ant.jar;ant\jaxp.jar;ant\parser.jar;%JAVA_HOME%\lib\tools.jar -Dant.home=.\ org.apache.tools.ant.Main %ANT_CMD_LINE_ARGS% + +set ANT_CMD_LINE_ARGS= diff --git a/helm/uwobo/build.xml b/helm/uwobo/build.xml new file mode 100644 index 000000000..c021b0b46 --- /dev/null +++ b/helm/uwobo/build.xml @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/helm/uwobo/src/it/unibo/cs/helm/uwobo/Key.java b/helm/uwobo/src/it/unibo/cs/helm/uwobo/Key.java new file mode 100644 index 000000000..22df4a44f --- /dev/null +++ b/helm/uwobo/src/it/unibo/cs/helm/uwobo/Key.java @@ -0,0 +1,9 @@ +package it.unibo.cs.helm.uwobo; + +import java.util.*; + +public class Key { + public String name; + public HashMap params; +}; + 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 index 000000000..da11a070c --- /dev/null +++ b/helm/uwobo/src/it/unibo/cs/helm/uwobo/Server.java @@ -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 +* @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"); + } +} diff --git a/helm/uwobo/src/it/unibo/cs/helm/uwobo/Servlet.java b/helm/uwobo/src/it/unibo/cs/helm/uwobo/Servlet.java new file mode 100644 index 000000000..0e28877fd --- /dev/null +++ b/helm/uwobo/src/it/unibo/cs/helm/uwobo/Servlet.java @@ -0,0 +1,247 @@ +package it.unibo.cs.helm.uwobo; + +import java.io.*; +import java.util.*; +import javax.servlet.*; +import javax.servlet.http.*; +import javax.xml.transform.*; +import org.xml.sax.*; + +/* +* +* usage: +* http://aristotele/helm/servlet/uwobo/help +* http://aristotele/helm/servlet/uwobo/add?xsluri=&key= +* http://aristotele/helm/servlet/uwobo/remove[?key=] +* http://aristotele/helm/servlet/uwobo/list +* http://aristotele/helm/servlet/uwobo/reload[?key=] +* http://aristotele/helm/servlet/uwobo/update[?key=] +* http://aristotele/helm/servlet/uwobo/apply?xmluri=&keys=[¶m.=]* +* +* example: +* http://aristotele/helm/servlet/uwobo/add?xsluri=file:///D:/Archivio/Progetti/helm/resources/xsl/foo1.xsl&key=foo1 +* http://aristotele/helm/servlet/uwobo/add?xsluri=file:///D:/Archivio/Progetti/helm/resources/xsl/foo2.xsl&key=foo2 +* http://aristotele/helm/servlet/uwobo/apply?xmluri=file:///D:/Archivio/Progetti/helm/resources/xsl/foo.xml&key=foo1&key=foo2 +* +* installation notes (Tomcat): +* replace parser.jar and jaxp.jar from /lib with xerces.jar +* +* add in conf/server.xml +* +* +* +* add in uriworkermap.properties +* /helm/*=ajp12 +* +* bugs: +* directory base stylesheet inclusi +* +* @author Riccardo Solmi +*/ +public class Servlet extends HttpServlet { + public static final String[] usage = { + "http://hostname/helm/servlet/uwobo/help", + "http://hostname/helm/servlet/uwobo/add?xsluri=stylesheet&key=name", + "http://hostname/helm/servlet/uwobo/remove[?key=name]", + "http://hostname/helm/servlet/uwobo/list", + "http://hostname/helm/servlet/uwobo/reload[?key=name]", + "http://hostname/helm/servlet/uwobo/update[?key=name]", + "http://hostname/helm/servlet/uwobo/apply?xmluri=xmldata&keys=key_1,...,key_n[¶m.name=value]*" + }; + public static final String help; + + static { + StringBuffer sb = new StringBuffer(); + sb.append(""); + help = sb.toString(); + } + + private Server server; + + public void init(ServletConfig config) throws ServletException + { + super.init(config); + + System.out.println("UWOBO init"); + server = new Server(); + } + + public static String[] split(final String s, final String delim) + { + StringTokenizer st = new StringTokenizer(s, delim); + String[] res = new String[st.countTokens()]; + for (int i = 0; i < res.length; i++) res[i] = st.nextToken(); + return res; + } + + public void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException + { + System.out.println("UWOBO "+request.getPathInfo()); + ServletOutputStream out; + + try { + final String cmd = request.getPathInfo(); + if (cmd == null) { + sendError(response, HttpServletResponse.SC_NOT_FOUND, "unknown command", help); + return; + } + if (cmd.equals("/add")) { + final String filename = request.getParameter("xsluri"); + if (filename == null) { + sendError(response, HttpServletResponse.SC_BAD_REQUEST, "bad parameters", usage[1]); + return; + } + final String key = request.getParameter("key"); + server.add(filename, key); + } else if (cmd.equals("/apply")) { + final String infile = request.getParameter("xmluri"); + final String keys = request.getParameter("keys"); + + if (infile == null || keys == null) { + sendError(response, HttpServletResponse.SC_BAD_REQUEST, "bad parameters", usage[6]); + return; + } + + final String[] keyName = split(keys, ","); + final Key[] keySeq = new Key[keyName.length]; + for (int i = 0; i < keySeq.length; i++) { + keySeq[i] = new Key(); + keySeq[i].name = keyName[i]; + keySeq[i].params = new HashMap(); + } + + final Properties props = new Properties(); + final Enumeration e = request.getParameterNames(); + while (e.hasMoreElements()) { + String param = (String) e.nextElement(); + if (param.startsWith("param.")) { + final String name = param.substring(6); + final String value = request.getParameter(param); + final String[] keyParam = split(name, "."); + if (keyParam.length == 1) { + // this is a global parameter + Server.log("global parameter: " + keyParam[0] + " = " + value); + for (int i = 0; i < keySeq.length; i++) + // we add the global parameter only if there is no + // local parameter with the same name + if (!keySeq[i].params.containsKey(keyParam[0])) + keySeq[i].params.put(keyParam[0], value); + } else if (keyParam.length == 2) { + // this is a local parameter + Server.log("local parameter: " + keyParam[0] + "." + keyParam[1] + " = " + value); + for (int i = 0; i < keySeq.length; i++) { + if (keySeq[i].name.equals(keyParam[0])) + keySeq[i].params.put(keyParam[1], value); + } + } else { + sendError(response, HttpServletResponse.SC_BAD_REQUEST, "bad parameters", usage[6]); + return; + } + } else if (param.startsWith("prop.")) { + final String name = param.substring(5); + final String value = request.getParameter(param); + Server.log("property: " + name + " = " + value); + props.setProperty(name, value); + } + } + + String contentType = props.getProperty(OutputKeys.MEDIA_TYPE); + if (contentType == null && keySeq.length > 0) + contentType = server.getContentType(keySeq[keySeq.length - 1].name); + else if (contentType == null) + contentType = "text/xml"; + response.setContentType(contentType); + Server.log("content type: " + contentType); + + out = response.getOutputStream(); + server.apply(infile, out, keySeq, props); + out.close(); + return; + } else if (cmd.equals("/remove")) { + final String key = request.getParameter("key"); + if (key == null) + server.removeAll(); + else + server.remove(key); + } else if (cmd.equals("/list")) { + Iterator i = server.list().iterator(); + + response.setContentType("text/html"); + out = response.getOutputStream(); + out.println("

Uwobo servlet

stylesheet list:

"); + out.close(); + return; + } else if (cmd.equals("/reload")) { + final String key = request.getParameter("key"); + if (key == null) + server.reloadAll(); + else + server.reload(key); + } else if (cmd.equals("/update")) { + final String key = request.getParameter("key"); + if (key == null) + server.updateAll(); + else + server.update(key); + } else if (cmd.equals("/help")) { + response.setContentType("text/html"); + out = response.getOutputStream(); + out.println("

"+server.PACKAGE+" servlet - version "+server.VERSION+"

"); + out.println("compiled "+server.DATE+" at "+server.TIME.substring(0,2)+":"+server.TIME.substring(2)+""); + out.println("

usage:

"+help+""); + out.close(); + return; + } else { + sendError(response, HttpServletResponse.SC_NOT_FOUND, "unknown command", help); + return; + } + } catch (TransformerConfigurationException tce) { + sendError(response, HttpServletResponse.SC_BAD_REQUEST, "stylesheet error", tce); + return; + } catch (SAXException se) { + sendError(response, HttpServletResponse.SC_BAD_REQUEST, "SAX Exception", se); + return; + } catch (Exception e) { + sendError(response, HttpServletResponse.SC_BAD_REQUEST, "exception", e); + return; + } + + response.setContentType("text/html"); + response.setHeader("Cache-Control", "no-cache"); + response.setHeader("Pragma", "no-cache"); + response.setHeader("Expires", "0"); + out = response.getOutputStream(); + out.println("

Uwobo servlet

done

"); + out.close(); + } + + private void sendError(HttpServletResponse response, int code, String msg, Exception e) throws IOException { + String err; + if (e != null) + err = "

"+e.getMessage()+"

"; + else + err = ""; + response.setContentType("text/html"); + response.sendError(code, "

Uwobo servlet

"+msg+"

"+err+""); + } + + private void sendError(HttpServletResponse response, int code, String msg, String usage) throws IOException { + response.setContentType("text/html"); + response.sendError(code, "

Uwobo servlet

"+msg+"

usage: "+usage+""); + } + + public String getServletInfo() { + return "The UWOBO servlet"; + } +} diff --git a/helm/uwobo/src/it/unibo/cs/helm/uwobo/properties.txt b/helm/uwobo/src/it/unibo/cs/helm/uwobo/properties.txt new file mode 100644 index 000000000..eb2861132 --- /dev/null +++ b/helm/uwobo/src/it/unibo/cs/helm/uwobo/properties.txt @@ -0,0 +1,4 @@ +PACKAGE=@PACKAGE@ +VERSION=@VERSION@ +DATE=@DATE@ +TIME=@TIME@ diff --git a/helm/uwobo/web.xml b/helm/uwobo/web.xml new file mode 100644 index 000000000..badb809d2 --- /dev/null +++ b/helm/uwobo/web.xml @@ -0,0 +1,22 @@ + + + + + Uwobo Application + + This is an xslt web application + + + + uwobo + it.unibo.cs.helm.uwobo.Servlet + + + + uwobo + /helm/* + + +