001: /*
002:
003: This software is OSI Certified Open Source Software.
004: OSI Certified is a certification mark of the Open Source Initiative.
005:
006: The license (Mozilla version 1.0) can be read at the MMBase site.
007: See http://www.MMBase.org/license
008:
009: */
010: package org.mmbase.util;
011:
012: import java.io.*;
013:
014: /**
015: * Like {@link java.io.OutputStreamWriter} but it tries to autodetect the encoding of the
016: * OutputStream. This works at least if the OutputStream is XML, which is a very common thing to be for Resources.
017: *
018: * For this to work at least the first part (e.g. the first 100 bytes) need to be buffered.
019: *
020: * If determining the encoding did not succeed it is supposed to be 'UTF-8', which is (should be) an
021: * acceptable encoding, and also the default encoding for XML streams.
022: *
023: * @author Michiel Meeuwissen
024: * @since MMBase-1.8
025: * @version $Id: EncodingDetectingOutputStreamWriter.java,v 1.3 2007/12/06 08:20:09 michiel Exp $
026: * @todo Is it named correctly?
027: */
028: public class EncodingDetectingOutputStreamWriter extends Writer {
029:
030: private OutputStream outputStream;
031:
032: // Either wrapped or buffer is null, and the other one is currenlty in use.
033: private Writer wrapped = null;
034: private StringBuilder buffer = new StringBuilder(100);
035:
036: EncodingDetectingOutputStreamWriter(OutputStream os) {
037: outputStream = os;
038: }
039:
040: /**
041: * Stop buffering, determine encoding, and start behaving as a normal OutputStreamWriter (by
042: * wrapping one). Unless, this happened already.
043: */
044: private void wrap() throws IOException {
045: if (wrapped == null) {
046: String encoding = GenericResponseWrapper
047: .getXMLEncoding(buffer.toString());
048: if (encoding == null) {
049: encoding = "UTF-8";
050: }
051: try {
052: wrapped = new OutputStreamWriter(outputStream, encoding);
053: } catch (UnsupportedEncodingException uee) {
054: }
055: wrapped.write(buffer.toString());
056: buffer = null;
057: }
058: }
059:
060: public void close() throws IOException {
061: wrap();
062: wrapped.close();
063: }
064:
065: public void flush() throws IOException {
066: wrap();
067: wrapped.flush();
068: }
069:
070: public void write(char[] cbuf) throws IOException {
071: if (wrapped != null) {
072: wrapped.write(cbuf);
073: } else {
074: write(cbuf, 0, cbuf.length);
075: }
076: }
077:
078: public void write(int c) throws IOException {
079: if (wrapped != null) {
080: wrapped.write(c);
081: } else {
082: super .write(c);
083: }
084: }
085:
086: public void write(String str) throws IOException {
087: if (wrapped != null) {
088: wrapped.write(str);
089: } else {
090: super .write(str);
091: }
092: }
093:
094: public void write(String str, int off, int len) throws IOException {
095: if (wrapped != null) {
096: wrapped.write(str, off, len);
097: } else {
098: super .write(str, off, len);
099: }
100:
101: }
102:
103: public void write(char[] cbuf, int off, int len) throws IOException {
104: if (wrapped != null) {
105: wrapped.write(cbuf, off, len);
106: } else {
107: for (int i = off; i < len + off; i++) {
108: buffer.append(cbuf[i]);
109: if (buffer.length() == 100) {
110: wrap();
111: i++;
112: if (i < len) {
113: wrapped.write(cbuf, i, len - (i - off));
114: }
115: break;
116: }
117: }
118: }
119: }
120: }
|