Java tutorial
/********************************************************************************** * $URL$ * $Id$ *********************************************************************************** * * Copyright (c) 2006, 2007, 2008 The Sakai Foundation * * Licensed under the Educational Community License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.opensource.org/licenses/ECL-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * **********************************************************************************/ package org.sakaibrary.xserver; import java.io.*; import org.xml.sax.*; import org.xml.sax.helpers.DefaultHandler; import javax.xml.parsers.SAXParserFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; public class XMLCleanup extends DefaultHandler { private static final org.apache.commons.logging.Log LOG = org.apache.commons.logging.LogFactory .getLog("org.sakaibrary.xserver.XMLCleanup"); private ByteArrayOutputStream bytes; private Writer out; private InputStream inputXml; StringBuilder textBuffer; private String indentString = " "; // Amount to indent private int indentLevel = 0; // X-Server error handling private boolean error = false; private boolean error_codeFlag = false; private boolean error_textFlag = false; private String error_code; private String error_text; public XMLCleanup() { bytes = new ByteArrayOutputStream(); try { out = new OutputStreamWriter(bytes, "UTF8"); } catch (UnsupportedEncodingException e) { LOG.warn("XMLCleanup() unsupported encoding: " + e.getMessage()); } } public ByteArrayOutputStream cleanup(InputStream xml) throws XServerException { inputXml = xml; // Use the default (non-validating) parser SAXParserFactory factory = SAXParserFactory.newInstance(); try { // Parse the input SAXParser saxParser = factory.newSAXParser(); saxParser.parse(inputXml, this); // close the stream inputXml.close(); } catch (SAXParseException spe) { // Use the contained exception, if any Exception x = spe; if (spe.getException() != null) { x = spe.getException(); } // Error generated by the parser LOG.warn("XMLCleanup.cleanup() parsing exception: " + spe.getMessage() + " - xml line " + spe.getLineNumber() + ", uri " + spe.getSystemId(), x); } catch (SAXException sxe) { // Error generated by this application // (or a parser-initialization error) Exception x = sxe; if (sxe.getException() != null) { x = sxe.getException(); } LOG.warn("XMLCleanup.cleanup() SAX exception: " + sxe.getMessage(), x); } catch (ParserConfigurationException pce) { // Parser with specified options can't be built LOG.warn("XMLCleanup.cleanup() SAX parser cannot be built with " + "specified options"); } catch (IOException ioe) { // I/O error LOG.warn("XMLCleanup.cleanup() IO exception", ioe); } catch (Throwable t) { LOG.warn("XMLCleanup.cleanup() exception", t); } if (error) { throw new XServerException(error_code, error_text); } return bytes; } //=========================================================== // SAX DocumentHandler methods //=========================================================== public void setDocumentLocator(Locator l) { // Save this to resolve relative URIs or to give diagnostics. try { out.flush(); } catch (IOException e) { // Ignore errors } } public void startDocument() throws SAXException { emit("<?xml version='1.0' encoding='UTF-8'?>"); } public void endDocument() throws SAXException { nl(); try { out.flush(); } catch (IOException e) { throw new SAXException("I/O error", e); } } public void startElement(String namespaceURI, String sName, // simple name String qName, // qualified name Attributes attrs) throws SAXException { echoText(); indentLevel++; nl(); String eName = sName; // element name if ("".equals(eName)) { eName = qName; // not namespaceAware } emit("<" + eName); if (eName.equals("error_code")) { // hit an error error = true; error_codeFlag = true; } else if (eName.equals("error_text")) { error_textFlag = true; } if (attrs != null) { for (int i = 0; i < attrs.getLength(); i++) { String aName = attrs.getLocalName(i); // Attr name if ("".equals(aName)) { aName = attrs.getQName(i); } if (!aName.equals("xmlns") && !aName.equals("xmlns:xsi") && !aName.equals("xsi:schemaLocation")) { emit(" "); emit(aName); emit(" = \""); emit(attrs.getValue(i)); emit("\""); } } } emit(">"); } public void endElement(String namespaceURI, String sName, // simple name String qName // qualified name ) throws SAXException { echoText(); nl(); // X-Server error handling if (error_codeFlag) error_codeFlag = false; if (error_textFlag) error_textFlag = false; String eName = sName; // element name if ("".equals(eName)) { eName = qName; // not namespaceAware } emit("</" + eName + ">"); indentLevel--; } public void characters(char[] buf, int offset, int len) throws SAXException { String s = new String(buf, offset, len); // take care of basic entity references before printing s = s.replaceAll("&", "&"); s = s.replaceAll("<", "<"); s = s.replaceAll(">", ">"); // s = s.replaceAll( "'", "'" ); // s = s.replaceAll( "\"", """ ); if (textBuffer == null) { textBuffer = new StringBuilder(s); } else { textBuffer.append(s); } if (error_codeFlag) error_code = textBuffer.toString(); if (error_textFlag) error_text = textBuffer.toString(); } public void ignorableWhitespace(char[] buf, int offset, int len) throws SAXException { // Ignore it } //=========================================================== // SAX ErrorHandler methods //=========================================================== public void error(SAXParseException e) throws SAXParseException { throw e; } // dump warnings too public void warning(SAXParseException err) throws SAXParseException { LOG.warn("SAXParser warning" + ", xml line " + err.getLineNumber() + ", uri " + err.getSystemId()); LOG.warn(" " + err.getMessage()); } //=========================================================== // Utility Methods //=========================================================== private void echoText() throws SAXException { if (textBuffer == null) { return; } String s = "" + textBuffer; if (!s.trim().equals("")) { emit(s); } textBuffer = null; } // Wrap I/O exceptions in SAX exceptions, to // suit handler signature requirements private void emit(String s) throws SAXException { try { out.write(s); out.flush(); } catch (IOException e) { throw new SAXException("I/O error", e); } } // Start a new line // and indent the next line appropriately private void nl() throws SAXException { String lineEnd = System.getProperty("line.separator"); try { out.write(lineEnd); for (int i = 0; i < indentLevel; i++) out.write(indentString); } catch (IOException e) { throw new SAXException("I/O error", e); } } }