package votorola.g.sql; // Copyright 2007-2009, 2011-2012, Michael Allan. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Votorola Software"), to deal in the Votorola Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicence, and/or sell copies of the Votorola Software, and to permit persons to whom the Votorola Software is furnished to do so, subject to the following conditions: The preceding copyright notice and this permission notice shall be included in all copies or substantial portions of the Votorola Software. THE VOTOROLA SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE VOTOROLA SOFTWARE OR THE USE OR OTHER DEALINGS IN THE VOTOROLA SOFTWARE. import java.io.*; import javax.xml.stream.*; import votorola.g.lang.*; import votorola.g.xml.stream.*; import static votorola.g.xml.stream.XMLInputFactoryX.SIMPLE_INPUT_FACTORY; /** An XML serializer for the storage of non-relational data in an 'xml' table column. */ public @ThreadSafe class XMLColumnAppender { /** Constructs an XMLColumnAppender. * * @see #sink() */ public XMLColumnAppender( Appendable _sink ) { sink = _sink; } // ------------------------------------------------------------------------------------ /** Serializes the specified datum as a space character followed by an attribute * declaration and appends it to the sink, or does nothing if the value is null. * * @param name a valid XML name for the attribute. * @param value the value of the datum, or null to append nothing. * * @throws IllegalArgumentException if the value is empty, as currently that is * not supported. */ public void appendAttribute( final String name, final String value ) throws IOException { if( value == null ) return; if( value.length() == 0 ) throw new IllegalArgumentException( "empty value" ); sink.append( ' ' ).append( name ).append( '=' ); final char quote; final String quoteEscaped; // if( value.contains( "'" )) // { quote = '"'; quoteEscaped = """; // } // else // { // quote = '\''; // quoteEscaped = "'"; // } ///// dubious optimization, assumes time is less valuable than space sink.append( quote ); for( int c = 0, cN = value.length(); c < cN; ++c ) { char ch = value.charAt( c ); if( ch == quote ) sink.append( quoteEscaped ); else if( ch == '\t' ) sink.append( " " ); else if( ch == '\n' ) sink.append( " " ); else if( ch == '\r' ) sink.append( " " ); else if( ch == '&' ) sink.append( "&" ); else if( ch == '<' ) sink.append( "<" ); else sink.append( ch ); } sink.append( quote ); } /** Returns a non-empty string if b is true, or null otherwise. * * @see #stringToBoolean(String) */ public static String booleanToString( final boolean b ) { return b? "t": null; } /** Returns true if s is non-null and non-empty, or false otherwise. * * @see #booleanToString(boolean) */ public static boolean stringToBoolean( final String s ) { return s != null && s.length() > 0; } /** Returns null if n is 0, otherwise the standard string representation of n. * * @see #stringToByte(String) */ public static String byteToString( final byte n ) { return n == 0? null: Byte.toString( n ); } /** Returns 0 if s is null or empty, otherwise the parsed value of s. * * @see #byteToString(byte) */ public static byte stringToByte( final String s ) { return s == null || s.length() == 0? 0: Byte.parseByte( s ); } /** Returns null if n is 0L, otherwise the standard string representation of n. * * @see #stringToLong(String) */ public static String longToString( final long n ) { return n == 0L? null: Long.toString( n ); } /** Returns 0L if s is null or empty, otherwise the parsed value of s. * * @see #longToString(long) */ public static long stringToLong( final String s ) { return s == null || s.length() == 0? 0L: Long.parseLong( s ); } /** Constructs a stream reader configured to read the serialized XML. */ public static XMLStreamReader newStreamReader( final Reader reader ) throws XMLStreamException { synchronized( XMLInputFactoryX.class ) { return SIMPLE_INPUT_FACTORY.createXMLStreamReader( reader ); } } /** Constructs a stream reader configured to read the serialized XML. */ public static XMLStreamReader newStreamReader( final String systemId, final InputStream in ) throws XMLStreamException { synchronized( XMLInputFactoryX.class ) { return SIMPLE_INPUT_FACTORY.createXMLStreamReader( systemId, in ); } } /** Constructs a stream reader configured to read the serialized XML. */ public static XMLStreamReader newStreamReader( final String systemId, final Reader reader ) throws XMLStreamException { synchronized( XMLInputFactoryX.class ) { return SIMPLE_INPUT_FACTORY.createXMLStreamReader( systemId, reader ); } } /** The underlying sink for the XML serialization. */ public Appendable sink() { return sink; } private final Appendable sink; }