View Javadoc

1   package org.codehaus.plexus.util.xml;
2   
3   import java.io.File;
4   import java.io.FileNotFoundException;
5   import java.io.FileOutputStream;
6   import java.io.IOException;
7   import java.io.OutputStream;
8   import java.io.OutputStreamWriter;
9   import java.io.StringWriter;
10  import java.io.Writer;
11  import java.util.regex.Matcher;
12  import java.util.regex.Pattern;
13  
14  /*
15   * Licensed to the Apache Software Foundation (ASF) under one
16   * or more contributor license agreements.  See the NOTICE file
17   * distributed with this work for additional information
18   * regarding copyright ownership.  The ASF licenses this file
19   * to you under the Apache License, Version 2.0 (the
20   * "License"); you may not use this file except in compliance
21   * with the License.  You may obtain a copy of the License at
22   *
23   *  http://www.apache.org/licenses/LICENSE-2.0
24   *
25   * Unless required by applicable law or agreed to in writing,
26   * software distributed under the License is distributed on an
27   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
28   * KIND, either express or implied.  See the License for the
29   * specific language governing permissions and limitations
30   * under the License.
31   */
32  
33  /**
34   * Character stream that handles (or at least attemtps to) all the necessary Voodo to figure out the charset encoding of
35   * the XML document written to the stream.
36   * @author <a href="mailto:hboutemy@codehaus.org">Herve Boutemy</a>
37   * @version $Id: XmlStreamWriter.java 630430 2008-02-23 13:16:25Z olamy $
38   * @since 1.4.4
39   * @deprecated TO BE REMOVED from here when plexus-utils is upgraded to 1.4.5+ (and prerequisite upgraded to Maven 2.0.6)
40   */
41  public class XmlStreamWriter
42  extends Writer
43  {
44      private static final int BUFFER_SIZE = 4096;
45      
46      private StringWriter xmlPrologWriter = new StringWriter( BUFFER_SIZE );
47      
48      private OutputStream out;
49  
50      private Writer writer;
51  
52      private String encoding;
53      
54      public XmlStreamWriter( OutputStream out )
55      {
56          this.out = out;
57      }
58      
59      public XmlStreamWriter( File file )
60      throws FileNotFoundException
61      {
62          this( new FileOutputStream( file ) );
63      }
64      
65      public String getEncoding()
66      {
67          return encoding;
68      }
69  
70      public void close()
71      throws IOException
72      {
73          if ( writer == null )
74          {
75              encoding = "UTF-8";
76              writer = new OutputStreamWriter( out, encoding );
77              writer.write( xmlPrologWriter.toString() );
78          }
79          writer.close();
80      }
81  
82      public void flush()
83      throws IOException
84      {
85          if ( writer != null )
86          {
87              writer.flush();
88          }
89      }
90  
91      private void detectEncoding( char[] cbuf, int off, int len )
92      throws IOException
93      {
94          int size = len;
95          StringBuffer xmlProlog = xmlPrologWriter.getBuffer();
96          if ( xmlProlog.length() + len > BUFFER_SIZE )
97          {
98              size = BUFFER_SIZE - xmlProlog.length();
99          }
100         xmlPrologWriter.write( cbuf, off, size );
101         
102         // try to determine encoding
103         if ( xmlProlog.length() >= 5 )
104         {
105             if ( xmlProlog.substring( 0, 5 ).equals( "<?xml" ) )
106             {
107                 // try to extract encoding from XML prolog
108                 int xmlPrologEnd = xmlProlog.indexOf( "?>" );
109                 if ( xmlPrologEnd > 0 )
110                 {
111                     // ok, full XML prolog written: let's extract encoding
112                     Matcher m = ENCODING_PATTERN.matcher( xmlProlog.substring( 0, xmlPrologEnd ) );
113                     if ( m.find() )
114                     {
115                         encoding = m.group( 1 ).toUpperCase();
116                         encoding = encoding.substring( 1, encoding.length() - 1 );
117                     }
118                     else
119                     {
120                         // no encoding found in XML prolog: using default encoding
121                         encoding = "UTF-8";
122                     }
123                 }
124                 else
125                 {
126                     if ( xmlProlog.length() >= BUFFER_SIZE )
127                     {
128                         // no encoding found in first characters: using default encoding
129                         encoding = "UTF-8";
130                     }
131                 }
132             }
133             else
134             {
135                 // no XML prolog: using default encoding
136                 encoding = "UTF-8";
137             }
138             if ( encoding != null )
139             {
140                 // encoding has been chosen: let's do it
141                 xmlPrologWriter = null;
142                 writer = new OutputStreamWriter( out, encoding );
143                 writer.write( xmlProlog.toString() );
144                 if ( len > size )
145                 {
146                     writer.write( cbuf, off + size, len - size );
147                 }
148             }
149         }
150     }
151     
152     public void write( char[] cbuf, int off, int len )
153     throws IOException
154     {
155         if ( xmlPrologWriter != null )
156         {
157             detectEncoding( cbuf, off, len );
158         }
159         else
160         {
161             writer.write( cbuf, off, len );
162         }
163     }
164 
165     static final Pattern ENCODING_PATTERN = XmlReader.ENCODING_PATTERN;
166 }