| /* |
| * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code 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 |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| 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 com.sun.org.apache.xerces.internal.util.XMLChar; |
| import com.sun.org.apache.xerces.internal.utils.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; |
| |
| /**XXX: This feature is only used when writing element content values. |
| * default value is 'true' however, if the feature is set to false |
| * characters wont be escaped. |
| * This feature has no effect when writing Attribute values, character would still be escaped. |
| * I can't think of any reason why this would be useful when writing attribute values. |
| * However, this can be reconsidered if there is any usecase. |
| */ |
| boolean fEscapeCharacters = true ; |
| |
| /** Writer object*/ |
| Writer fWriter = null; |
| |
| //CharsetEncoder |
| CharsetEncoder fEncoder ; |
| |
| public WriterUtility(){ |
| fEncoder = getDefaultEncoder(); |
| } |
| |
| |
| /** Creates a new instance of WriterUtility */ |
| 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{ |
| //attempt to retreive default fEncoderoder |
| fEncoder = getDefaultEncoder(); |
| } |
| } |
| |
| /** |
| * sets the writer object |
| * @param writer file to write into |
| */ |
| public void setWriter(Writer writer){ |
| fWriter = writer; |
| } |
| |
| public void setEscapeCharacters(boolean escape){ |
| fEscapeCharacters = escape ; |
| } |
| |
| public boolean getEscapeCharacters(){ |
| return fEscapeCharacters; |
| } |
| |
| /** |
| * writes xml content (characters and element content |
| * @param content |
| */ |
| public void writeXMLContent(char[] content, int start, int length) throws IOException{ |
| writeXMLContent(content, start, length, getEscapeCharacters()); |
| } |
| |
| /** |
| * writes xml content (characters and element content |
| * @param content |
| */ |
| 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 |
| //initialize this variable to start pos. indicating that no data has been written |
| int startWritePos = start; |
| |
| for ( index = start ; index < end ; index++ ) { |
| ch = content[ index ]; |
| |
| if(fEncoder != null && !fEncoder.canEncode(ch)){ |
| //- write the data to the point we get this character |
| fWriter.write(content, startWritePos, index - startWritePos ); |
| |
| //escape this character |
| fWriter.write( "&#x" ); |
| fWriter.write(Integer.toHexString(ch)); |
| fWriter.write( ';' ); |
| //increase the startWritePos by 1 indicating that next write should start from |
| //one position ahead |
| 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){ |
| //this character needs to be escaped, write the data from the last write pos |
| 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 |
| //one position ahead |
| startWritePos = index + 1; |
| } |
| break; |
| } |
| case '&' :{ |
| if(escapeCharacter){ |
| //this character needs to be escaped, write the data from the last write pos |
| 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 |
| //one position ahead |
| startWritePos = index + 1; |
| } |
| break; |
| } |
| |
| case '>': { |
| if(escapeCharacter){ |
| //this character needs to be escaped, write the data from the last write pos |
| 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 |
| //one position ahead |
| startWritePos = index + 1; |
| } |
| break; |
| } |
| } |
| } |
| if(DEBUG_XML_CONTENT){ |
| System.out.println("out of the loop, writing " + new String(content, startWritePos, end - startWritePos)); |
| } |
| //write any pending data |
| fWriter.write(content, startWritePos, end - startWritePos); |
| } |
| |
| /** |
| * writes xml content (characters and element content |
| * @param content |
| */ |
| 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; |
| } |
| } |