|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package com.sun.xml.internal.stream.writers; |
|
|
|
import java.io.FileWriter; |
|
import java.io.IOException; |
|
import java.io.OutputStreamWriter; |
|
import java.io.Writer; |
|
import java.nio.charset.Charset; |
|
import java.nio.charset.CharsetEncoder; |
|
import jdk.xml.internal.SecuritySupport; |
|
|
|
/** |
|
* Implements common xml writer functions. |
|
* |
|
* @author Neeraj Bajaj,K.Venugopal Sun Microsystems. |
|
*/ |
|
|
|
public class WriterUtility { |
|
|
|
|
|
public static final String START_COMMENT = "<!--"; |
|
public static final String END_COMMENT = "-->"; |
|
public static final String DEFAULT_ENCODING = " encoding=\"utf-8\""; |
|
public static final String DEFAULT_XMLDECL ="<?xml version=\"1.0\" ?>"; |
|
public static final String DEFAULT_XML_VERSION ="1.0"; |
|
public static final char CLOSE_START_TAG = '>'; |
|
public static final char OPEN_START_TAG = '<'; |
|
public static final String OPEN_END_TAG ="</"; |
|
public static final char CLOSE_END_TAG = '>'; |
|
public static final String START_CDATA = "<![CDATA["; |
|
public static final String END_CDATA = "]]>"; |
|
public static final String CLOSE_EMPTY_ELEMENT = "/>"; |
|
public static final String SPACE = " "; |
|
public static final String UTF_8 = "utf-8"; |
|
|
|
static final boolean DEBUG_XML_CONTENT = false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
boolean fEscapeCharacters = true ; |
|
|
|
|
|
Writer fWriter = null; |
|
|
|
|
|
CharsetEncoder fEncoder ; |
|
|
|
public WriterUtility(){ |
|
fEncoder = getDefaultEncoder(); |
|
} |
|
|
|
|
|
|
|
public WriterUtility(Writer writer) { |
|
fWriter = writer; |
|
if(writer instanceof OutputStreamWriter){ |
|
String charset = ((OutputStreamWriter)writer).getEncoding(); |
|
if(charset != null){ |
|
fEncoder = Charset.forName(charset).newEncoder(); |
|
} |
|
}else if(writer instanceof FileWriter){ |
|
String charset = ((FileWriter)writer).getEncoding(); |
|
if(charset != null){ |
|
fEncoder = Charset.forName(charset).newEncoder(); |
|
} |
|
} |
|
else{ |
|
|
|
fEncoder = getDefaultEncoder(); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public void setWriter(Writer writer){ |
|
fWriter = writer; |
|
} |
|
|
|
public void setEscapeCharacters(boolean escape){ |
|
fEscapeCharacters = escape ; |
|
} |
|
|
|
public boolean getEscapeCharacters(){ |
|
return fEscapeCharacters; |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public void writeXMLContent(char[] content, int start, int length) throws IOException{ |
|
writeXMLContent(content, start, length, getEscapeCharacters()); |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
private void writeXMLContent(char[] content, int start, int length, boolean escapeCharacter) throws IOException{ |
|
if(DEBUG_XML_CONTENT){ |
|
System.out.println("content to write is " + new String(content, start, length)); |
|
} |
|
int index; |
|
char ch; |
|
int sc; |
|
final int end = start + length ; |
|
//define startWritePos to track the position from where the character array data needs to be written |
|
|
|
int startWritePos = start; |
|
|
|
for ( index = start ; index < end ; index++ ) { |
|
ch = content[ index ]; |
|
|
|
if(fEncoder != null && !fEncoder.canEncode(ch)){ |
|
|
|
fWriter.write(content, startWritePos, index - startWritePos ); |
|
|
|
|
|
fWriter.write( "&#x" ); |
|
fWriter.write(Integer.toHexString(ch)); |
|
fWriter.write( ';' ); |
|
//increase the startWritePos by 1 indicating that next write should start from |
|
|
|
startWritePos = index + 1; |
|
|
|
} |
|
if(DEBUG_XML_CONTENT){ |
|
System.out.println("startWritePos = " + startWritePos); |
|
System.out.println("index = " + index); |
|
System.out.println("start = " + start); |
|
System.out.println("end = " + end); |
|
} |
|
|
|
switch(ch){ |
|
case '<' :{ |
|
if(escapeCharacter){ |
|
|
|
fWriter.write(content, startWritePos, index - startWritePos); |
|
fWriter.write("<"); |
|
if(DEBUG_XML_CONTENT){ |
|
System.out.print(new String(content, startWritePos, index - startWritePos)); |
|
System.out.println("<"); |
|
} |
|
//increase the startWritePos by 1 indicating that next write should start from |
|
|
|
startWritePos = index + 1; |
|
} |
|
break; |
|
} |
|
case '&' :{ |
|
if(escapeCharacter){ |
|
|
|
fWriter.write(content, startWritePos, index - startWritePos); |
|
fWriter.write("&"); |
|
if(DEBUG_XML_CONTENT){ |
|
System.out.print(new String(content,startWritePos, index - startWritePos)); |
|
System.out.println("&"); |
|
} |
|
//increase the startWritePos by 1 indicating that next write should start from |
|
|
|
startWritePos = index + 1; |
|
} |
|
break; |
|
} |
|
|
|
case '>': { |
|
if(escapeCharacter){ |
|
|
|
fWriter.write(content, startWritePos, index - startWritePos); |
|
fWriter.write(">"); |
|
if(DEBUG_XML_CONTENT){ |
|
System.out.print(new String(content,startWritePos, index - startWritePos)); |
|
System.out.println(">"); |
|
} |
|
//increase the startWritePos by 1 indicating that next write should start from |
|
|
|
startWritePos = index + 1; |
|
} |
|
break; |
|
} |
|
} |
|
} |
|
if(DEBUG_XML_CONTENT){ |
|
System.out.println("out of the loop, writing " + new String(content, startWritePos, end - startWritePos)); |
|
} |
|
|
|
fWriter.write(content, startWritePos, end - startWritePos); |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public void writeXMLContent(String content) throws IOException{ |
|
if(content == null || content.length() == 0) return ; |
|
writeXMLContent(content.toCharArray(), 0, content.length()); |
|
} |
|
|
|
|
|
/** |
|
* Write Attribute value to the underlying stream. |
|
* |
|
* @param value |
|
*/ |
|
|
|
public void writeXMLAttributeValue(String value)throws IOException{ |
|
writeXMLContent(value.toCharArray(), 0, value.length(), true); |
|
} |
|
|
|
private CharsetEncoder getDefaultEncoder(){ |
|
try{ |
|
String encoding = SecuritySupport.getSystemProperty("file.encoding"); |
|
if(encoding != null){ |
|
return Charset.forName(encoding).newEncoder(); |
|
} |
|
} |
|
catch(Exception ex){ |
|
//for any exception thrown , catch and continue |
|
} |
|
return null; |
|
} |
|
} |