/*
 */
/*
 * This is a Java servlet that allows you to transform
 * a WSDL file using XSL. In a general sense, it will
 * actually allow you to transform any file using XSL,
 * as long as both the source file and the XSL file are
 * available via HTTP. Just compile it and add it to
 * the servlet directory on your server.
 *
 * MAKE SURE you either modify the defaultXslFile variable
 * to make it point to a valid file on your server, or
 * provide an initialization parameter to override it 
 * with a valid file (see the code for details).
 * 
 * I've compiled and tested this on an R5 Domino server,
 * using the Domino Servlet Manager. To compile and run it 
 * properly, you should have the following in your classpath 
 * (these files should already be in your Domino data directory, 
 * as they come with R5.03+ by default):
 *   jsdk.jar  (servlet stuff)
 *   LotusXSL.jar  (XSL stuff)
 *   XML4j.jar  (the Node class)
 *
 * Naturally, this should also work with other servers that
 * support servlets.
 *
 * version 1.0
 * Julian Robichaux -- http://www.nsftools.com
 */
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;

import org.w3c.dom.Node;
import com.lotus.xsl.XSLTInputSource;
import com.lotus.xsl.XSLTResultTarget;
import com.lotus.xsl.XSLProcessor;
import org.xml.sax.SAXException;


public class TransformWSDL extends HttpServlet {
	
	// these are the parameter names we're looking for
	// (remember that they're case-sensitive, in case
	// you want to pass them with the Query String of
	// the URL)
	private static String wsdlParam = "wsdlfile";
	private static String xslParam = "xslfile";
	
	// this is the default XSL file we'll use for
	// transformation, which I got from:
	// http://community.jedit.org/modules.php?op=modload&name=news&file=article&sid=202
	// there's also an interesting one at:
	// http://www.capescience.com/simplifiedwsdl.xslt
	// MAKE SURE YOU CHANGE THIS TO A VALID PATH/FILE
	// ON YOUR SERVER, OR SET IT USING THE servlets.properties
	// FILE ON THE DOMINO SERVER!
	private static String defaultXslFile = "d:\\notes5\\data\\domino\\servlet\\Soap.xsl";
	
	// this is the name of the initialization parameter
	// you can use to override the defaultXslFile setting
	private static String defaultXslParam = "xslParam";
	
	
	/*
	 * In case anyone asks, here's a short description of
	 * our servlet (not a necessary method, but nice to
	 * include).
	 */
	public String getServletInfo() {
		return "A servlet that transforms WSDL files based on a given XSL file.";
	}
	
	
	/*
	 * The init method runs once, when the servlet starts.
	 * It's not necessary to override this method, but you'll
	 * need it if you're going to read in any initialization
	 * parameters on startup (like to initialize your global
	 * variables). It's used here so you can optionally
	 * override the default XSL file. On R5 Domino servers,
	 * the initialization parameters can normally be set in
	 * the servlets.properties file (see the Notes Designer Help
	 * for more information).
	 */
	public void init(ServletConfig config) throws ServletException
	{
		// do the standard initialization routines first
		super.init(config);
		
		// Get initialization parameters, if any
		String xslParam = getInitParameter(defaultXslParam);
		if ((xslParam != null) && (xslParam.length() > 0))
			defaultXslFile = xslParam;
		
		// If we end up with no defaultXslFile for some reason,
		// don't run the servlet, and say why
		if ((defaultXslFile == null) || (defaultXslFile.length() == 0)) {
			Enumeration initParams = getInitParameterNames();
			StringBuffer sb = new StringBuffer("The parameters that were used were:\n");
			while (initParams.hasMoreElements()) {
				String param = (String)initParams.nextElement();
				sb.append(param + "=" + getInitParameter(param) + "\n");
			}
			
			// write all the parameters we did find to the servlet log
			config.getServletContext().log(sb.toString());
			
			// the UnavailableException should keep the servlet from running
			throw new UnavailableException (this,
				"Servlet Initialization Error: Required parameter " + 
				xslParam + " was not available on servlet startup.");
		}
	}
	
	
	/*
	 * Here's where we process the HTTP GET request. For this
	 * servlet, we're doing two things: first we check to see if
	 * there's a query string that we recognize, in which case
	 * we can just send the request to the doPost method for
	 * processing (this way you can use this servlet as a link,
	 * for automation). If the query string doesn't exist or
	 * doesn't have parameters we're interested in, we display
	 * an HTML form to the user to get some input.
	 */
	public void doGet (HttpServletRequest request, HttpServletResponse response) 
			throws ServletException, IOException
	{
		// if someone sent this request with a query string
		// that we recognize, send it to the doPost method
		// for processing (for example: 
		//   http://thisserver/servlet/TransformWSDL?wsdlfile=http://someserver/somefile.wsdl)
		if (request.getParameter(wsdlParam) != null)  {
			doPost(request, response);
			return;
		}
		
		// construct the HTML form we'll use for input
		StringBuffer sb = new StringBuffer("");
		
		sb.append("\n");
		sb.append("Transform WSDL\n");
		sb.append("\n");
		sb.append("

Transform a WSDL file using XSLT


\n"); sb.append("
\n"); sb.append("WSDL File URL:
\n"); sb.append("

\n"); sb.append("XSL File URL (leave blank to use the default):
\n"); sb.append("

\n"); sb.append("\n"); sb.append("\n"); sb.append("

"); // remember to set the response headers BEFORE // you get the output stream response.setContentType("text/html"); response.setContentLength(sb.length()); ServletOutputStream out = response.getOutputStream(); // and send the HTML to the browser out.print(sb.toString()); // it's always polite to close your output stream // when you're done writing... out.close(); } /* * This is where we process the HTTP POST request. Just to * mix things up a little, we'll send the output information * through a PrintWriter instead of a ServletOutputStream. * We're taking the WSDL file that the user entered (probably * a URL, although it could also be a file that's local to * the server if the user knows the path), and either an XSL * file path that the user entered or the default one we're * using for this servlet. We then do an XSL transformation * with the XSLProcessor class that's in the LotusXSL jar that * ships with Domino, and send the output to the client. */ public void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // set the response headers before you get the writer // (in this case we're not going to know the Content-length // of the response, but that's not stricly necessary) response.setContentType("text/html"); PrintWriter out = response.getWriter(); try { /* // do this if you want to get the whole request, // but keep in mind that after you call a getInputStream // you can't use the getParameterXXX calls -- it's // either one or the other (you could also use getReader // to use a BufferedReader, if that's easier) int bytesin; byte[] buf = new byte[1024]; ServletInputStream sis = request.getInputStream(); while ((bytesin = sis.read(buf)) >= 0) out.print(new String(buf, 0, bytesin)); */ // for debugging, display the parameters we have available Enumeration enum = request.getParameterNames(); out.println("Request Parameters were:
"); while (enum.hasMoreElements()) { String param = (String)enum.nextElement(); out.println(param + " = " + request.getParameterValues(param)[0] + "
"); } out.println("
"); // try to get the values entered by the user String wsdlfile = ""; String xslfile = ""; try { wsdlfile = request.getParameterValues(wsdlParam)[0]; xslfile = request.getParameterValues(xslParam)[0]; } catch (Exception ee) { } // and do the magical transformation transform(wsdlfile, xslfile, out); } catch (Exception e) { out.println(e.getMessage() + "
"); e.printStackTrace(out); } out.close(); } /* * This is the method that actually does the XSL transformation. * It's a separate method for portability, and so we can call it * from our main method, if we're so inclined (which is also why * it's declared as a static method). You can use any kind of * Writer for the outWriter parameter: BufferedWriter, PrintWriter, * StringWriter... */ public static void transform (String xmlfile, String xslfile, Writer outWriter) { // make sure our writer is a PrintWriter, because // that's what XSLTResultTarget and printStackTrace // wants PrintWriter out = new PrintWriter(outWriter); try { // if there's no XML file, we can't go on if ((xmlfile == null) || (xmlfile.length() == 0)) { out.println("Error: No XML File specified"); return; } // if there's no XSL file, just use the default one here // on the server if ((xslfile == null) || (xslfile.length() == 0)) xslfile = defaultXslFile; // process the XML file and send it straight to the output stream XSLProcessor proc = new XSLProcessor("com.lotus.xml.xml4j2dom.XML4JLiaison4dom"); proc.process(new XSLTInputSource(xmlfile), new XSLTInputSource(xslfile), new XSLTResultTarget(out)); out.flush(); } catch (SAXException se) { out.println(se.getMessage() + "
"); se.printStackTrace(out); } catch (Exception e) { out.println(e.getMessage() + "
"); e.printStackTrace(out); } } /* * This isn't really standard, but I added a main method * here, in case you feel like running this as a stand-alone * Java application instead of a servlet. Handy for testing. */ public static void main (String[] args) { if (args.length < 1) System.out.println("USAGE: TransformWSDL WSDLFileName [XSLFileName]"); else if (args.length == 1) transform(args[0], "", new PrintWriter(System.out)); else transform(args[0], args[1], new PrintWriter(System.out)); } }