org.olat.core.gui.render.StringOutput.java Source code

Java tutorial

Introduction

Here is the source code for org.olat.core.gui.render.StringOutput.java

Source

/**
* OLAT - Online Learning and Training<br>
* http://www.olat.org
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br>
* University of Zurich, Switzerland.
* <hr>
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* This file has been modified by the OpenOLAT community. Changes are licensed
* under the Apache 2.0 license as the original file.  
* <p>
*/

package org.olat.core.gui.render;

import java.io.IOException;
import java.io.Reader;
import java.io.Writer;

import org.apache.commons.lang.StringEscapeUtils;
import org.olat.core.logging.OLog;
import org.olat.core.logging.Tracing;
import org.olat.core.util.filter.impl.OWASPAntiSamyXSSFilter;

/**
 * @author Felix Jost
 */
public class StringOutput extends Writer {

    private static final OLog log = Tracing.createLoggerFor(StringOutput.class);

    private final StringBuilder sb;

    /**
     * @param len
     */
    public StringOutput(int len) {
        sb = new StringBuilder(len);
    }

    /**
     * 
     */
    public StringOutput() {
        sb = new StringBuilder();
    }

    /**
     * @param val
     * @return Itself
     */
    public StringOutput append(String val) {
        sb.append(val);
        return this;
    }

    /**
     * 
     * @param val The value to append
     * @param append If true append happens, if false not
     * @return Itself
     */
    public StringOutput append(String val, boolean append) {
        if (append) {
            sb.append(val);
        }
        return this;
    }

    /**
     * @param val
     * @return Itself
     */
    public StringOutput append(boolean val) {
        sb.append(val);
        return this;
    }

    /**
     * @param i
     * @return Itself
     */
    public StringOutput append(int i) {
        sb.append(i);
        return this;
    }

    /**
     * @param stringOutput
     * @return Itself
     */
    public StringOutput append(StringOutput stringOutput) {
        sb.append(stringOutput.sb);
        return this;
    }

    @Override
    public void write(char[] cbuf, int off, int len) throws IOException {
        sb.append(cbuf, off, len);
    }

    /**
     * @param sMin
     * @return Itself
     */
    public StringOutput append(long val) {
        sb.append(val);
        return this;
    }

    /**
     * @param buffer
     * @return Itself
     */
    public StringOutput append(StringBuilder buffer) {
        sb.append(buffer);
        return this;
    }

    /**
     * @param buffer
     * @return Itself
     */
    public StringOutput appendScanned(String str) {
        sb.append(new OWASPAntiSamyXSSFilter().filter(str));
        return this;
    }

    /**
     * @param buffer
     * @return Itself
     */
    public StringOutput appendHtmlEscaped(String str) {
        try {
            StringEscapeUtils.escapeHtml(this, str);
        } catch (IOException e) {
            log.error("Error escaping HTML", e);
        }
        return this;
    }

    public void ensureCapacity(int minimumCapacity) {
        sb.ensureCapacity(minimumCapacity);
    }

    public int capacity() {
        return sb.capacity();
    }

    public void setLength(int newLength) {
        sb.setLength(newLength);
    }

    /**
     * @return The length of the string output
     */
    public int length() {
        return sb.length();
    }

    public Reader getReader() {
        return new StringOutputReader();
    }

    @Override
    public void flush() throws IOException {
        //
    }

    @Override
    public void close() throws IOException {
        //
    }

    /**
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return sb.toString();
    }

    private class StringOutputReader extends Reader {

        private int length;
        private int next = 0;
        private int mark = 0;

        /**
         * Creates a new string reader.
         *
         * @param s  String providing the character stream.
         */
        public StringOutputReader() {
            this.length = sb.length();
        }

        /**
         * Reads a single character.
         *
         * @return     The character read, or -1 if the end of the stream has been
         *             reached
         *
         * @exception  IOException  If an I/O error occurs
         */
        public int read() throws IOException {
            synchronized (lock) {
                if (next >= length)
                    return -1;

                char[] dst = new char[1];
                sb.getChars(next++, next, dst, 0);
                return dst[0];
            }
        }

        public int read(char cbuf[], int off, int len) throws IOException {
            synchronized (lock) {
                if ((off < 0) || (off > cbuf.length) || (len < 0) || ((off + len) > cbuf.length)
                        || ((off + len) < 0)) {
                    throw new IndexOutOfBoundsException();
                } else if (len == 0) {
                    return 0;
                }
                if (next >= length)
                    return -1;

                int n = Math.min(length - next, len);
                sb.getChars(next, next + n, cbuf, off);
                next += n;
                return n;
            }
        }

        /**
         * Skips the specified number of characters in the stream. Returns
         * the number of characters that were skipped.
         *
         * <p>The <code>ns</code> parameter may be negative, even though the
         * <code>skip</code> method of the {@link Reader} superclass throws
         * an exception in this case. Negative values of <code>ns</code> cause the
         * stream to skip backwards. Negative return values indicate a skip
         * backwards. It is not possible to skip backwards past the beginning of
         * the string.
         *
         * <p>If the entire string has been read or skipped, then this method has
         * no effect and always returns 0.
         *
         * @exception  IOException  If an I/O error occurs
         */
        public long skip(long ns) throws IOException {
            synchronized (lock) {
                if (next >= length)
                    return 0;
                // Bound skip by beginning and end of the source
                long n = Math.min(length - next, ns);
                n = Math.max(-next, n);
                next += n;
                return n;
            }
        }

        public boolean ready() throws IOException {
            synchronized (lock) {
                return true;
            }
        }

        public boolean markSupported() {
            return true;
        }

        public void mark(int readAheadLimit) throws IOException {
            if (readAheadLimit < 0) {
                throw new IllegalArgumentException("Read-ahead limit < 0");
            }
            synchronized (lock) {
                mark = next;
            }
        }

        public void reset() throws IOException {
            synchronized (lock) {
                next = mark;
            }
        }

        public void close() {
            //
        }
    }
}