001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.io.unsync;
016    
017    import java.io.IOException;
018    import java.io.Writer;
019    
020    /**
021     * <p>
022     * See http://issues.liferay.com/browse/LPS-6648.
023     * </p>
024     *
025     * @author Shuyang Zhou
026     */
027    public class UnsyncBufferedWriter extends Writer {
028    
029            public UnsyncBufferedWriter(Writer writer) {
030                    this(writer, _DEFAULT_BUFFER_SIZE);
031            }
032    
033            public UnsyncBufferedWriter(Writer writer, int size) {
034                    if (size <= 0) {
035                            throw new IllegalArgumentException("Size is less than 0");
036                    }
037    
038                    this.writer = writer;
039                    this.size = size;
040    
041                    buffer = new char[size];
042            }
043    
044            @Override
045            public void close() throws IOException {
046                    if (writer == null) {
047                            return;
048                    }
049    
050                    if (count > 0) {
051                            writer.write(buffer, 0, count);
052    
053                            count = 0;
054                    }
055    
056                    writer.flush();
057                    writer.close();
058    
059                    writer = null;
060                    buffer = null;
061            }
062    
063            @Override
064            public void flush() throws IOException {
065                    if (writer == null) {
066                            throw new IOException("Writer is null");
067                    }
068    
069                    if (count > 0) {
070                            writer.write(buffer, 0, count);
071    
072                            count = 0;
073                    }
074    
075                    writer.flush();
076            }
077    
078            public void newLine() throws IOException {
079                    write(_LINE_SEPARATOR);
080            }
081    
082            @Override
083            public void write(char[] chars, int offset, int length)
084                    throws IOException {
085    
086                    if (writer == null) {
087                            throw new IOException("Writer is null");
088                    }
089    
090                    if (length >= size) {
091                            if (count > 0) {
092                                    writer.write(buffer, 0, count);
093    
094                                    count = 0;
095                            }
096    
097                            writer.write(chars, offset, length);
098    
099                            return;
100                    }
101    
102                    if ((count > 0) && (length > (size - count))) {
103                            writer.write(buffer, 0, count);
104    
105                            count = 0;
106                    }
107    
108                    System.arraycopy(chars, offset, buffer, count, length);
109    
110                    count += length;
111            }
112    
113            @Override
114            public void write(int c) throws IOException {
115                    if (writer == null) {
116                            throw new IOException("Writer is null");
117                    }
118    
119                    if (count >= size) {
120                            writer.write(buffer);
121    
122                            count = 0;
123                    }
124    
125                    buffer[count++] = (char)c;
126            }
127    
128            @Override
129            public void write(String string, int offset, int length)
130                    throws IOException {
131    
132                    if (writer == null) {
133                            throw new IOException("Writer is null");
134                    }
135    
136                    int x = offset;
137                    int y = offset + length;
138    
139                    while (x < y) {
140                            if (count >= size) {
141                                    writer.write(buffer);
142    
143                                    count = 0;
144                            }
145    
146                            int leftFreeSpace = size - count;
147                            int leftDataSize = y - x;
148    
149                            if (leftFreeSpace > leftDataSize) {
150                                    string.getChars(x, y, buffer, count);
151    
152                                    count += leftDataSize;
153    
154                                    break;
155                            }
156                            else {
157                                    int copyEnd = x + leftFreeSpace;
158    
159                                    string.getChars(x, copyEnd, buffer, count);
160    
161                                    count += leftFreeSpace;
162    
163                                    x = copyEnd;
164                            }
165                    }
166            }
167    
168            protected char[] buffer;
169            protected int count;
170            protected int size;
171            protected Writer writer;
172    
173            private static final int _DEFAULT_BUFFER_SIZE = 8192;
174    
175            private static final String _LINE_SEPARATOR = System.getProperty(
176                    "line.separator");
177    
178    }