Java tutorial
/* * Returns the XML text verbatim, doesn't encode it as swf */ /* ***************************************************************************** * XMLConverter.java * ****************************************************************************/ /* J_LZ_COPYRIGHT_BEGIN ******************************************************* * Copyright 2001-2008, 2011 Laszlo Systems, Inc. All Rights Reserved. * * Use is subject to license terms. * * J_LZ_COPYRIGHT_END *********************************************************/ package org.openlaszlo.data; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.io.Reader; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HttpMethodBase; import org.apache.log4j.Logger; import org.openlaszlo.utils.ContentEncoding; import org.openlaszlo.utils.FileUtils; import org.openlaszlo.utils.LZHttpUtils; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserFactory; import org.xmlpull.v1.XmlSerializer; /** * XML Converter * */ public class XMLGrabber extends Converter { private static Logger mLogger = Logger.getLogger(XMLGrabber.class); private static XmlPullParserFactory factory = null; private static XmlPullParserFactory getXPPFactory() { if (factory == null) { // Set up the XML Parser factory try { String sys = null; try { sys = System.getProperty(XmlPullParserFactory.PROPERTY_NAME); } catch (SecurityException se) { } factory = XmlPullParserFactory.newInstance(sys, null); factory.setNamespaceAware(false); factory.setValidating(false); } catch (XmlPullParserException e) { throw new RuntimeException(e.getMessage()); } } return factory; } /** * Convert incoming XML to ... XML * * This method is called convertToSWF for historical reasons, and nobody * has changed the API call name yet. * * A dataset will look like this: * <resultset> * <body> * <weather sourceurl="http://www.srh.noaa.gov/zipcity.php?inputstring=02460"> * <radar src="http://www.laszlosystems.com:80/weather/small/kbox.jpg"/> * <satellite src="http://www.laszlosystems.com:80/weather/thumbs/ECI8.JPG"/> * </weather> * </body> * <headers> * <header name="Date" value="Thu, 29 Dec 2005 03:49:46 GMT"/> * <header name="Server" value="Apache/2.0.44 (Unix) mod_ssl/2.0.44 OpenSSL/0.9.6b DAV/2 mod_jk/1.2.1 PHP/4.3.0"/> * </headers> * </resultset> */ @Override public InputStream convertToSWF(Data data, HttpServletRequest req, HttpServletResponse res) throws ConversionException, IOException { try { PipedOutputStream pout = new PipedOutputStream(); PipedInputStream in = new PipedInputStream(pout); XmlSerializer serializer; XmlPullParser parser; parser = getXPPFactory().newPullParser(); InputStream dstream = data.getInputStream(); Reader reader = FileUtils.getXMLStreamReader(dstream, "UTF-8"); parser.setInput(reader); serializer = factory.newSerializer(); serializer.setOutput(pout, "UTF-8"); HttpMethodBase request = ((HttpData) data).getRequest(); final String sendheaders = req.getParameter("sendheaders"); XMLCopyThread worker = new XMLCopyThread(pout, parser, serializer, request, sendheaders); worker.start(); return in; } catch (XmlPullParserException ex) { throw new ConversionException("Parsing XML: " + ex.getMessage()); } } // Worker thread to parse XML (which serves to translate obscure // charsets to UTF-8) and wrap it in <resultset>, possibly adding // proxied HTTP headers from backedn response. // This is written to the PipedOutputStream which we were passed. class XMLCopyThread extends Thread implements Runnable { OutputStream pout = null; XmlPullParser parser; XmlSerializer serializer; HttpMethodBase request; String sendheaders = null; XMLCopyThread(OutputStream pout, XmlPullParser parser, XmlSerializer serializer, HttpMethodBase request, String sendheaders) { this.pout = pout; this.parser = parser; this.serializer = serializer; this.request = request; this.sendheaders = sendheaders; } @Override public void run() { try { writeXMLDataToOutputStream(); } catch (Exception e) { mLogger.warn(XMLCopyThread.class.getName(), e); } finally { try { pout.flush(); pout.close(); } catch (Exception e) { } } } // Generates an XML document with this structure // <resultset> // <body> [PROXIED_XMLDOC] </body> // <headers> ... </headers> // </resultset> void writeXMLDataToOutputStream() throws XmlPullParserException, IOException { //Run through XML PULL parser, to convert to UTF8, and // wrap in <resultset> tag, plus optional headers // Start a standalone document; //serializer.startDocument("UTF-8", Boolean.TRUE); serializer.startTag("", "resultset"); serializer.startTag("", "body"); parser.nextToken(); // read first token while (parser.getEventType() != XmlPullParser.END_DOCUMENT) { writeToken(parser.getEventType()); parser.nextToken(); } serializer.endTag("", "body"); // <headers> ... </headers> serializer.startTag("", "headers"); // Get headers if (sendheaders == null || sendheaders.equals("true")) { Header[] hedz = request.getResponseHeaders(); for (int i = 0; i < hedz.length; i++) { String name = hedz[i].getName(); if (LZHttpUtils.allowForward(name, null)) { serializer.startTag("", "header"); serializer.attribute(null, "name", name); serializer.attribute(null, "value", hedz[i].getValue()); serializer.endTag("", "header"); } } } serializer.endTag("", "headers"); serializer.endTag("", "resultset"); serializer.endDocument(); } private void writeStartTag() throws XmlPullParserException, IOException { if (!parser.getFeature(XmlPullParser.FEATURE_REPORT_NAMESPACE_ATTRIBUTES)) { for (int i = parser.getNamespaceCount(parser.getDepth() - 1); i <= parser .getNamespaceCount(parser.getDepth()) - 1; i++) { serializer.setPrefix(parser.getNamespacePrefix(i), parser.getNamespaceUri(i)); } } serializer.startTag(parser.getNamespace(), parser.getName()); for (int i = 0; i < parser.getAttributeCount(); i++) { serializer.attribute(parser.getAttributeNamespace(i), parser.getAttributeName(i), parser.getAttributeValue(i)); } } private void writeToken(int eventType) throws XmlPullParserException, IOException { switch (eventType) { case XmlPullParser.START_TAG: writeStartTag(); break; case XmlPullParser.END_TAG: serializer.endTag(parser.getNamespace(), parser.getName()); break; case XmlPullParser.START_DOCUMENT: //use Boolean.TRUE to make it standalone //Boolean standalone = (Boolean) parser.getProperty(PROPERTY_XMLDECL_STANDALONE); //serializer.startDocument(parser.getInputEncoding(), standalone); break; case XmlPullParser.END_DOCUMENT: //serializer.endDocument(); break; case XmlPullParser.IGNORABLE_WHITESPACE: //comment it to remove ignorable whtespaces from XML infoset String s = parser.getText(); serializer.ignorableWhitespace(s); break; case XmlPullParser.TEXT: serializer.text(parser.getText()); break; case XmlPullParser.ENTITY_REF: serializer.entityRef(parser.getName()); break; case XmlPullParser.CDSECT: serializer.cdsect(parser.getText()); break; case XmlPullParser.PROCESSING_INSTRUCTION: // serializer.processingInstruction( parser.getText ()); break; case XmlPullParser.COMMENT: //serializer.comment (parser.getText ()); break; case XmlPullParser.DOCDECL: // serializer.docdecl (parser.getText ()); break; } } } /** * @return the encoding that should be used when responding * to this request or null for no encoding. For now, the only * acceptable values besides null are "gzip" and "deflate". */ @Override public String chooseEncoding(HttpServletRequest req) { String e = req.getParameter("enc"); if (e == null || e.equals("false")) { return null; } String enc = ContentEncoding.chooseEncoding(req); mLogger.debug("Encoding: " + enc); return enc; } }