001    /*
002     *   Copyright (c) 2009 The JOMC Project
003     *   Copyright (c) 2005 Christian Schulte <cs@jomc.org>
004     *   All rights reserved.
005     *
006     *   Redistribution and use in source and binary forms, with or without
007     *   modification, are permitted provided that the following conditions
008     *   are met:
009     *
010     *     o Redistributions of source code must retain the above copyright
011     *       notice, this list of conditions and the following disclaimer.
012     *
013     *     o Redistributions in binary form must reproduce the above copyright
014     *       notice, this list of conditions and the following disclaimer in
015     *       the documentation and/or other materials provided with the
016     *       distribution.
017     *
018     *   THIS SOFTWARE IS PROVIDED BY THE JOMC PROJECT AND CONTRIBUTORS "AS IS"
019     *   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
020     *   THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
021     *   PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JOMC PROJECT OR
022     *   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023     *   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024     *   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
025     *   OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
026     *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
027     *   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
028     *   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029     *
030     *   $Id: LineEditor.java 543 2009-09-21 21:28:09Z schulte2005 $
031     *
032     */
033    package org.jomc.util;
034    
035    import java.io.BufferedReader;
036    import java.io.IOException;
037    import java.io.StringReader;
038    
039    /**
040     * Interface to line based editing.
041     *
042     * @author <a href="mailto:cs@jomc.org">Christian Schulte</a>
043     * @version $Id: LineEditor.java 543 2009-09-21 21:28:09Z schulte2005 $
044     *
045     * @see #edit(java.lang.String)
046     */
047    public class LineEditor
048    {
049    
050        /** Editor to chain. */
051        private LineEditor editor;
052    
053        /** Line separator. */
054        private String lineSeparator;
055    
056        /** Creates a new {@code LineEditor} instance. */
057        public LineEditor()
058        {
059            super();
060        }
061    
062        /**
063         * Creates a new {@code LineEditor} instance taking a string to use for separating lines.
064         *
065         * @param lineSeparator String to use for separating lines.
066         */
067        public LineEditor( final String lineSeparator )
068        {
069            super();
070            this.lineSeparator = lineSeparator;
071        }
072    
073        /**
074         * Creates a new {@code LineEditor} instance taking an editor to chain.
075         *
076         * @param editor The editor to chain.
077         */
078        public LineEditor( final LineEditor editor )
079        {
080            super();
081            this.editor = editor;
082        }
083    
084        /**
085         * Creates a new {@code LineEditor} instance taking an editor to chain and a string to use for separating lines.
086         *
087         * @param editor The editor to chain.
088         * @param lineSeparator String to use for separating lines.
089         */
090        public LineEditor( final LineEditor editor, final String lineSeparator )
091        {
092            super();
093            this.editor = editor;
094            this.lineSeparator = lineSeparator;
095        }
096    
097        /**
098         * Gets the line separator of the editor.
099         *
100         * @return The line separator of the editor.
101         */
102        protected final String getLineSeparator()
103        {
104            if ( this.lineSeparator == null )
105            {
106                this.lineSeparator = System.getProperty( "line.separator" );
107            }
108    
109            return this.lineSeparator;
110        }
111    
112        /**
113         * Edits texts.
114         * <p>This method splits the given string into lines and passes every line to method {@code editLine} in order of
115         * occurrence. On end of input, method {@code editLine} is called with a {@code null} argument.</p>
116         *
117         * @param text The text to edit or {@code null}.
118         *
119         * @return The edited text or {@code null}.
120         */
121        public final String edit( final String text )
122        {
123            String edited = text;
124    
125            if ( text != null )
126            {
127                try
128                {
129                    final BufferedReader reader = new BufferedReader( new StringReader( text ) );
130                    final StringBuilder buf = new StringBuilder();
131    
132                    String line = null;
133                    while ( ( line = reader.readLine() ) != null )
134                    {
135                        final String replacement = this.editLine( line );
136                        if ( replacement != null )
137                        {
138                            buf.append( replacement ).append( this.getLineSeparator() );
139                        }
140                    }
141    
142                    final String replacement = this.editLine( null );
143                    if ( replacement != null )
144                    {
145                        buf.append( replacement );
146                    }
147    
148                    edited = buf.toString();
149    
150                    if ( this.editor != null )
151                    {
152                        edited = this.editor.edit( edited );
153                    }
154                }
155                catch ( final IOException e )
156                {
157                    throw new AssertionError( e );
158                }
159            }
160    
161            return edited;
162        }
163    
164        /**
165         * Edits a line.
166         *
167         * @param line The line to edit or {@code null} indicating the end of input.
168         *
169         * @return The string to replace {@code line} with, or {@code null} to replace {@code line} with nothing.
170         */
171        protected String editLine( final String line )
172        {
173            return line;
174        }
175    
176    }