[CJ-dev] commonjava-projects/commonjava-util/src/java/org/commonjava/util XmlFormatException.java,NO
Brought to you by:
johnqueso
From: <joh...@co...> - 2004-02-16 07:00:27
|
Update of /cvsroot/commonjava/commonjava-projects/commonjava-util/src/java/org/commonjava/util In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30155/src/java/org/commonjava/util Added Files: XmlFormatException.java Base64.java XmlFormatter.java Log Message: added some of the still-good classes from commonjava-codec before that whole project is deprecated. Also, fleshed out a description in the project.xml. --- NEW FILE: XmlFormatException.java --- /* Copyright (c) 2002 John Casey. All rights reserved. SEE licenses/cj-license.txt FOR MORE INFORMATION. */ /* * XmlFormatException.java * * Created on September 29, 2002, 5:03 AM */ package org.commonjava.util; import org.commonjava.lang.CommonJavaException; /** signals an exception during the object formatting process. * * @author John Casey */ public class XmlFormatException extends CommonJavaException{ /** Creates a new instance of XmlFormatException */ public XmlFormatException() { } /** Creates a new instance of XmlFormatException * @param message The message. * @param root The root cause. */ public XmlFormatException(String message, Throwable root) { super(message, root); } /** Creates a new instance of XmlFormatException * @param message The message. */ public XmlFormatException(String message) { super(message); } /** Creates a new instance of XmlFormatException * @param root The root cause. */ public XmlFormatException(Throwable root) { super(root); } } --- NEW FILE: Base64.java --- /* * Created on Apr 7, 2003 */ package org.commonjava.util; import java.io.ByteArrayOutputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** Encode/Decode Base-64... * @author John Casey */ public final class Base64 { private static final Log LOG = LogFactory.getLog(Base64.class); private static final String CRLF = System.getProperty("line.separator"); private static final int LINE_END = 64; public static String encode(byte[] data){ return Base64.encode(data, true); } public static String encode(byte[] data, boolean useLineDelimiter){ if(data == null){ return null; } else if(data.length == 0){ return ""; } int padding = 3 - (data.length % 3); // if(LOG.isDebugEnabled()){LOG.debug("padding = " + padding + " characters.");} StringBuffer buffer = new StringBuffer(); for (int i = 0; i < data.length; i+=3) { // if(LOG.isDebugEnabled()){LOG.debug("iteration base offset = " + i);} int neutral = (data[i] < 0 ? data[i] + 256 : data[i]); int block = (neutral & 0xff); // if(LOG.isDebugEnabled()){LOG.debug("after first byte, block = " + Integer.toBinaryString(block));} boolean inLastSegment = false; block <<= 8; if(i+1 < data.length){ neutral = (data[i+1] < 0 ? data[i+1] + 256 : data[i+1]); block |= (neutral & 0xff); } else{ inLastSegment = true; } // if(LOG.isDebugEnabled()){LOG.debug("after second byte, block = " + Integer.toBinaryString(block) + "; inLastSegment = " + inLastSegment);} block <<= 8; if(i+2 < data.length){ neutral = (data[i+2] < 0 ? data[i+2] + 256 : data[i+2]); block |= (neutral & 0xff); } else{ inLastSegment = true; } // if(LOG.isDebugEnabled()){LOG.debug("after third byte, block = " + Integer.toBinaryString(block) + "; inLastSegment = " + inLastSegment);} char[] encoded = new char[4]; int encIdx = 0; encoded[0] = toBase64Char((block >>> 18) & 0x3f); // if(LOG.isDebugEnabled()){LOG.debug("first character = " + encoded[0]);} encoded[1] = toBase64Char((block >>> 12) & 0x3f); // if(LOG.isDebugEnabled()){LOG.debug("second character = " + encoded[1]);} if(inLastSegment && padding > 1){ encoded[2] = '='; } else{ encoded[2] = toBase64Char((block >>> 6) & 0x3f); } // if(LOG.isDebugEnabled()){LOG.debug("third character = " + encoded[2]);} if(inLastSegment && padding > 0){ encoded[3] = '='; } else{ encoded[3] = toBase64Char(block & 0x3f); } // if(LOG.isDebugEnabled()){LOG.debug("fourth character = " + encoded[3]);} buffer.append(encoded); } if(useLineDelimiter){ return canonicalize(buffer.toString()); } else{ return buffer.toString(); } } public static byte[] decode(String src){ return Base64.decode(src, true); } public static byte[] decode(String src, boolean useLineDelimiter){ if(src == null){ return null; } else if(src.length() < 1){ return new byte[0]; } // if(LOG.isDebugEnabled()){LOG.debug("pre-canonicalization = \n" + src);} String data = src; if(useLineDelimiter){data = deCanonicalize(src);} // if(LOG.isDebugEnabled()){LOG.debug("post-canonicalization = \n" + data);} ByteArrayOutputStream baos = new ByteArrayOutputStream(); char[] input = data.toCharArray(); int index = 0; for (int i = 0; i < input.length; i+=4) { // if(LOG.isDebugEnabled()){LOG.debug("iteration base offset = " + i);} int block = (toBase64Int(input[i]) & 0x3f); // if(LOG.isDebugEnabled()){LOG.debug("block after first char [" + input[i] + "] = " + Integer.toBinaryString(block));} block <<= 6; block |= (toBase64Int(input[i+1]) & 0x3f); // if(LOG.isDebugEnabled()){LOG.debug("block after second char [" + input[i+1] + "] = " + Integer.toBinaryString(block));} boolean inPadding = false; boolean twoCharPadding = false; block <<= 6; if(input[i+2] != '='){ block |= (toBase64Int(input[i+2]) & 0x3f); } else{ twoCharPadding = true; inPadding = true; } // if(LOG.isDebugEnabled()){LOG.debug("block after third char [" + input[i+2] + "] = " + Integer.toBinaryString(block));} block <<= 6; if(input[i+3] != '='){ block |= (toBase64Int(input[i+3]) & 0x3f); } else{ inPadding = true; } // if(LOG.isDebugEnabled()){LOG.debug("block after fourth char [" + input[i+3] + "] = " + Integer.toBinaryString(block));} baos.write((block >>> 16) & 0xff); // if(LOG.isDebugEnabled()){LOG.debug("byte[" + (index++) + "] = " + ((block >>> 16) & 0xff));} if(!inPadding || !twoCharPadding){ baos.write((block >>> 8) & 0xff); // if(LOG.isDebugEnabled()){LOG.debug("byte[" + (index++) + "] = " + ((block >>> 8) & 0xff));} } if(!inPadding){ baos.write(block & 0xff); // if(LOG.isDebugEnabled()){LOG.debug("byte[" + (index++) + "] = " + (block & 0xff));} } } byte[] result = baos.toByteArray(); // if(LOG.isDebugEnabled()){LOG.debug("byte array is " + result.length + " bytes long.");} return result; } private static char toBase64Char(int input){ if(input > -1 && input < 26){ return (char)('A' + input); } else if(input > 25 && input < 52){ return (char)('a' + input - 26); } else if(input > 51 && input < 62){ return (char)('0' + input - 52); } else if(input == 62){ return '+'; } else if(input == 63){ return '/'; } else{ return '?'; } } private static int toBase64Int(char input){ if(input >= 'A' && input <= 'Z'){ return input - 'A'; } else if(input >= 'a' && input <= 'z'){ return input + 26 - 'a'; } else if(input >= '0' && input <= '9'){ return input + 52 - '0'; } else if(input == '+'){ return 62; } else if(input == '/'){ return 63; } else{ return 0; } } private static String deCanonicalize(String data){ if(data == null){return null;} StringBuffer buffer = new StringBuffer(data.length()); for (int i = 0; i < data.length(); i++) { char c = data.charAt(i); if(c != '\r' && c != '\n'){ buffer.append(c); } } return buffer.toString(); } private static String canonicalize(String data){ StringBuffer buffer = new StringBuffer((int)(data.length() * 1.1)); int col = 0; for (int i = 0; i < data.length(); i++) { if(col == LINE_END){ buffer.append(CRLF); col = 0; } buffer.append(data.charAt(i)); col++; } buffer.append(CRLF); return buffer.toString(); } } --- NEW FILE: XmlFormatter.java --- /* Copyright (c) 2002 John Casey. All rights reserved. SEE licenses/cj-license.txt FOR MORE INFORMATION. */ /* * XmlFormatter.java * * Created on September 29, 2002, 4:47 AM */ package org.commonjava.util; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.Iterator; import java.util.Map; import java.util.Stack; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** Formatter for translating objects into XML. * * @author John Casey */ public class XmlFormatter { private static final Log LOG = LogFactory.getLog(XmlFormatter.class); private String indent; private Writer out; private String lineBreak; private Stack nestingLevels; /** Creates a new instance of XmlFormatter * @param indent The String to use as indentation for one level deep. * @param out The Writer to send xml to. * @param lineBreak The lineBreak String to use. */ public XmlFormatter(String indent, Writer out, String lineBreak) { this.indent = indent; this.out = out; this.lineBreak = lineBreak; this.nestingLevels = new Stack(); } /** Creates a new instance of XmlFormatter * @param indent The String to use as indentation for one level deep. * @param out The OutputStream to send xml to. * @param lineBreak The lineBreak String to use. */ public XmlFormatter(String indent, OutputStream out, String lineBreak){ this(indent, new OutputStreamWriter(out), lineBreak); } /** Creates a new instance of XmlFormatter * @param indent The String to use as indentation for one level deep. * @param out The Writer to send xml to. */ public XmlFormatter(String indent, Writer out) { this(indent, out, "\n"); } /** Creates a new instance of XmlFormatter * @param indent The String to use as indentation for one level deep. * @param out The OutputStream to send xml to. */ public XmlFormatter(String indent, OutputStream out){ this(indent, new OutputStreamWriter(out), "\n"); } /** Write the opening document header to the sink. * @throws XmlFormatException in case of an error writing to the sink. */ public void openDocument() throws XmlFormatException{ try{ out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); out.write(lineBreak); } catch(IOException ex){ throw new XmlFormatException(ex); } } /** Write an empty element (no body) to the sink. * @param element The element name to write out. * @param attributes The attributes to write out. * @param namespaces The namespaces for each attribute. * @throws XmlFormatException in case of an error writing to the sink. */ public void writeEmptyElement(String element, Map attributes, Map namespaces) throws XmlFormatException { if(element == null){return;} try{ writeElementStart(element, attributes, namespaces); out.write(" />"); out.write(lineBreak); } catch(IOException ex){ throw new XmlFormatException(ex); } } /** Write an opening element tag to the sink. * @param element The element name to write out. * @param attributes The attributes to write out. * @param namespaces The namespaces for each attribute. * @throws XmlFormatException in case of an error writing to the sink. */ public void openElement(String element, Map attributes, Map namespaces) throws XmlFormatException { if(element == null){return;} try{ writeElementStart(element, attributes, namespaces); out.write(">"); out.write(lineBreak); nestingLevels.push(element); } catch(IOException ex){ throw new XmlFormatException(ex); } } /** Close the latest element on the open element stack, and write to the sink. * @return the name of the element closed. * @throws XmlFormatException in case of an error writing to the sink. */ public String closeLastElement() throws XmlFormatException{ return _closeLastElement(); } /** Write an element's body text to the sink. * @param value The text to write to the element's body. * @throws XmlFormatException in case of an error writing to the sink. */ public void writeElementValue(String value) throws XmlFormatException{ if(value == null){return;} _writeElementValue(value); } /** Write an element's body text to the sink, wrapped in CDATA tags. * @param value The text to write to the element's body. * @throws XmlFormatException in case of an error writing to the sink. */ public void writeCDATAElementValue(String value) throws XmlFormatException{ if(value == null){return;} _writeCDATAElementValue(value); } /** Write a boolean to the element's body text in the sink. * @param value The boolean to write to the element's body. * @throws XmlFormatException in case of an error writing to the sink. */ public void writeElementValue(boolean value) throws XmlFormatException{ _writeElementValue(String.valueOf(value)); } /** Write a boolean to the element's body text in the sink, wrapped in CDATA tags. * @param value The boolean to write to the element's body. * @throws XmlFormatException in case of an error writing to the sink. */ public void writeCDATAElementValue(boolean value) throws XmlFormatException{ _writeCDATAElementValue(String.valueOf(value)); } /** Close all open elements, and write them to the sink. * @throws XmlFormatException in case of an error writing to the sink. */ public void finishDocument() throws XmlFormatException{ for(int i=0, len=nestingLevels.size(); i<len; i++){ _closeLastElement(); } try{ out.flush(); } catch(IOException ex){ throw new XmlFormatException(ex); } } /** Write the beginning of an open element tag, up to the attributes, but not * including the closing bracket. This is used to provide a common piece of * code for the two methods used to open an element, * openElement() and writeEmptyElement(), without creating lateral API dependencies. * * @param element The element name. * @param attributes The element's attributes. * @param namespaces The namespaces for attributes. * @throws XmlFormatException in case of an error writing to the sink. */ private void writeElementStart(String element, Map attributes, Map namespaces) throws XmlFormatException { if(element == null){return;} try{ for(int i=0, len=nestingLevels.size(); i<len; i++){ out.write(indent); } out.write("<"); out.write(element); if(attributes != null){ for(Iterator it = attributes.keySet().iterator(); it != null && it.hasNext(); ){ Object obj = it.next(); String key = String.valueOf(obj); String value = String.valueOf(attributes.get(obj)); out.write(" "); out.write(key); out.write("=\""); out.write(value); out.write("\""); } } if(namespaces != null){ //format elment output for introduction of namespaces. } } catch(IOException ex){ throw new XmlFormatException(ex); } } /** Write a String to the element's body text in the sink. This is provided as * a common piece of code to promote code reuse without causing lateral API * dependencies. * * @param value The String to write to the element's body. * @throws XmlFormatException in case of an error writing to the sink. */ private void _writeElementValue(String value) throws XmlFormatException{ if(value == null){return;} try{ int levelCount = nestingLevels.size(); if(levelCount < 1){ throw new XmlFormatException("Cannot write a value with no parent element declared."); } for(int i=0, len=levelCount; i<len; i++){ out.write(indent); } out.write(indent); out.write(value); out.write(lineBreak); } catch(IOException ex){ throw new XmlFormatException(ex); } } /** Write a String to the element's body text in the sink, wrappered in CDATA. * This is provided as a common piece of code to promote code reuse without * causing lateral API dependencies. * * @param value The String to write to the element's body. * @throws XmlFormatException in case of an error writing to the sink. */ private void _writeCDATAElementValue(String value) throws XmlFormatException{ if(value == null){return;} try{ int levelCount = nestingLevels.size(); if(levelCount < 1){ throw new XmlFormatException("Cannot write a value with no parent element declared."); } for(int i=0, len=levelCount; i<len; i++){ out.write(indent); } out.write("<![CDATA["); if(LOG.isDebugEnabled()){ LOG.debug("value=\'" + value + "\'"); } out.write(value); out.write("]]>"); out.write(lineBreak); } catch(IOException ex){ throw new XmlFormatException(ex); } } /** Close the latest element on the open elements stack. This method is * provided as a common piece of code to promote code reuse between the * closeLastElement() and finishDocument() methods, to avoid lateral API * dependencies. * @throws XmlFormatException in case of an error writing to the sink. */ private String _closeLastElement() throws XmlFormatException{ try{ int levelCount = nestingLevels.size(); if(levelCount < 1){ throw new XmlFormatException("Cannot close a non-existent value."); } if(levelCount > 0){ String element = (String)nestingLevels.pop(); for(int i=0, len=levelCount-1; i<len; i++){ out.write(indent); } out.write("</"); out.write(element); out.write(">"); out.write(lineBreak); return element; } } catch(IOException ex){ throw new XmlFormatException(ex); } return null; } } |