/*
* File : XUXmlWriter.java
* Created : 23-Oct-2003
* By : parg
*
* Azureus - a Java Bittorrent client
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details ( see the LICENSE file ).
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.gudy.azureus2.core3.xml.util;
/**
* @author parg
*/
import java.io.*;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.gudy.azureus2.core3.util.*;
public class
XUXmlWriter
{
private static final int INDENT_AMOUNT = 4;
private String current_indent_string;
private PrintWriter writer;
private boolean generic_simple;
protected
XUXmlWriter()
{
resetIndent();
}
protected
XUXmlWriter(
OutputStream _output_stream )
{
setOutputStream( _output_stream );
resetIndent();
}
protected void
setOutputStream(
OutputStream _output_stream )
{
try{
writer = new PrintWriter( new OutputStreamWriter(_output_stream , Constants.DEFAULT_ENCODING ));
}catch( UnsupportedEncodingException e ){
Debug.printStackTrace( e );
writer = new PrintWriter( _output_stream );
}
}
protected void
setOutputWriter(
Writer _writer )
{
if ( _writer instanceof PrintWriter ){
writer = (PrintWriter)_writer;
}else{
writer = new PrintWriter( _writer );
}
}
protected void
setGenericSimple(
boolean simple )
{
generic_simple = simple;
}
protected void
writeTag(
String tag,
String content )
{
writeLineRaw( "<" + tag + ">" + escapeXML( content ) + "</" + tag + ">" );
}
protected void
writeTag(
String tag,
long content )
{
writeLineRaw( "<" + tag + ">" + content + "</" + tag + ">" );
}
protected void
writeTag(
String tag,
boolean content )
{
writeLineRaw( "<" + tag + ">" + (content?"YES":"NO") + "</" + tag + ">" );
}
protected void
writeLineRaw(
String str )
{
writer.println( current_indent_string + str );
}
protected void
writeLineEscaped(
String str )
{
writer.println( current_indent_string + escapeXML(str));
}
protected void
resetIndent()
{
current_indent_string = "";
}
protected void
indent()
{
for (int i=0;i<INDENT_AMOUNT;i++){
current_indent_string += " ";
}
}
protected void
exdent()
{
if ( current_indent_string.length() >= INDENT_AMOUNT ){
current_indent_string = current_indent_string.substring(0,current_indent_string.length()-INDENT_AMOUNT);
}else{
current_indent_string = "";
}
}
public static String
escapeXML(
String str )
{
if ( str == null ){
return( "" );
}
str = str.replaceAll( "&", "&" );
str = str.replaceAll( ">", ">" );
str = str.replaceAll( "<", "<" );
str = str.replaceAll( "\"", """ );
str = str.replaceAll( "'", "'" );
str = str.replaceAll( "--", "--" );
return( str );
}
public static String
unescapeXML(
String str )
{
if ( str == null ){
return( "" );
}
str = str.replaceAll( ">", ">" );
str = str.replaceAll( "<", "<" );
str = str.replaceAll( """, "\"" );
str = str.replaceAll( "'", "'" );
str = str.replaceAll( "--", "--" );
str = str.replaceAll( "&", "&" );
return( str );
}
protected void
flushOutputStream()
{
if ( writer != null ){
writer.flush();
}
}
protected void
closeOutputStream()
{
if ( writer != null ){
writer.flush();
writer.close();
writer = null;
}
}
// generic Map encoder
protected void
writeGenericMapEntry(
String name,
Object value )
{
if ( generic_simple ){
name = name.replace(' ', '_' ).toUpperCase();
writeLineRaw( "<" + name + ">" );
try{
indent();
writeGeneric( value );
}finally{
exdent();
}
writeLineRaw( "</" + name + ">" );
}else{
writeLineRaw( "<KEY name=\"" + escapeXML( name ) + "\">");
try{
indent();
writeGeneric( value );
}finally{
exdent();
}
writeLineRaw( "</KEY>");
}
}
protected void
writeGeneric(
Object obj )
{
if ( obj instanceof Map ){
writeGeneric((Map)obj);
}else if( obj instanceof List ){
writeGeneric((List)obj);
}else if ( obj instanceof byte[] ){
writeGeneric((byte[])obj);
}else{
writeGeneric((Long)obj);
}
}
protected void
writeGeneric(
Map map )
{
writeLineRaw( "<MAP>" );
try{
indent();
Iterator it = map.keySet().iterator();
while(it.hasNext()){
String key = (String)it.next();
writeGenericMapEntry( key, map.get( key ));
}
}finally{
exdent();
}
writeLineRaw( "</MAP>" );
}
protected void
writeGeneric(
List list )
{
writeLineRaw( "<LIST>" );
try{
indent();
for (int i=0;i<list.size();i++){
writeGeneric( list.get(i));
}
}finally{
exdent();
}
writeLineRaw( "</LIST>" );
}
protected void
writeGeneric(
byte[] bytes )
{
if ( generic_simple ){
try{
writeLineRaw( escapeXML( new String(bytes, "UTF-8" )));
}catch( Throwable e ){
e.printStackTrace();
}
}else{
writeTag( "BYTES", encodeBytes( bytes ));
}
}
protected void
writeGeneric(
Long l )
{
if ( generic_simple ){
writeLineRaw( l.toString());
}else{
writeTag( "LONG", ""+l );
}
}
protected void
writeTag(
String tag,
byte[] content )
{
writeLineRaw( "<" + tag + ">" + encodeBytes( content ) + "</" + tag + ">" );
}
protected void
writeLocalisableTag(
String tag,
byte[] content )
{
boolean use_bytes = true;
String utf_string = null;
try{
utf_string = new String(content,Constants.DEFAULT_ENCODING);
if ( Arrays.equals(
content,
utf_string.getBytes( Constants.DEFAULT_ENCODING))){
use_bytes = false;
}
}catch( UnsupportedEncodingException e ){
}
writeLineRaw( "<" + tag + " encoding=\""+(use_bytes?"bytes":"utf8") + "\">" +
(use_bytes?encodeBytes( content ):escapeXML(utf_string)) + "</" + tag + ">" );
}
protected String
encodeBytes(
byte[] bytes )
{
String data = ByteFormatter.nicePrint( bytes, true );
return( data );
/*
try{
return( URLEncoder.encode(new String( bytes, Constants.DEFAULT_ENCODING ), Constants.DEFAULT_ENCODING));
}catch( UnsupportedEncodingException e ){
throw( new TOTorrentException( "TOTorrentXMLSerialiser: unsupported encoding for '" + new String(bytes) + "'",
TOTorrentException.RT_UNSUPPORTED_ENCODING));
}
*/
}
protected String
getUTF(
byte[] bytes )
{
try{
return( new String(bytes,Constants.DEFAULT_ENCODING));
}catch( UnsupportedEncodingException e ){
Debug.printStackTrace( e );
return( "" );
}
}
}