001package org.apache.maven.doxia.util;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022/*
023 * Originally from org.apache.doxia.module.apt.AptReaderSource. It was modified
024 * to get unget support
025 */
026
027import java.io.IOException;
028import java.io.LineNumberReader;
029import java.io.Reader;
030
031import org.apache.maven.doxia.parser.ParseException;
032import org.codehaus.plexus.util.IOUtil;
033
034/**
035 * {@link ByLineSource} default implementation
036 *
037 * @version $Id: ByLineReaderSource.html 979316 2016-02-02 21:51:43Z hboutemy $
038 */
039public class ByLineReaderSource implements ByLineSource
040{
041    /**
042     * reader
043     */
044    private LineNumberReader reader;
045
046    /**
047     * current line number
048     */
049    private int lineNumber;
050
051    /**
052     * holds the last line returned by getNextLine()
053     */
054    private String lastLine;
055
056    /**
057     * <code>true</code> if ungetLine() was called and no getNextLine() was
058     * called
059     */
060    private boolean ungetted = false;
061    
062    private String name;
063
064    /**
065     * Creates the ByLineReaderSource.
066     *
067     * @param in real source :)
068     */
069    public ByLineReaderSource( final Reader in )
070    {
071        this( in, "" );
072    }
073    
074    public ByLineReaderSource( final Reader in, final String name )
075    {
076        this.reader = new LineNumberReader( in );
077        
078        this.name = name;
079
080        this.lineNumber = -1;
081    }
082
083    /** {@inheritDoc} */
084    public final String getNextLine() throws ParseException
085    {
086        if ( reader == null )
087        {
088            return null;
089        }
090
091        if ( ungetted )
092        {
093            ungetted = false;
094            return lastLine;
095        }
096
097        String line;
098
099        try
100        {
101            line = reader.readLine();
102            if ( line == null )
103            {
104                reader.close();
105                reader = null;
106            }
107            else
108            {
109                lineNumber = reader.getLineNumber();
110            }
111        }
112        catch ( IOException e )
113        {
114            throw new ParseException( e, lineNumber, 0 );
115        }
116
117        lastLine = line;
118
119        return line;
120    }
121
122    /** {@inheritDoc} */
123    public final String getName()
124    {
125        return name;
126    }
127
128    /** {@inheritDoc} */
129    public final int getLineNumber()
130    {
131        return lineNumber;
132    }
133
134    /** {@inheritDoc} */
135    public final void close()
136    {
137        IOUtil.close( reader );
138        reader = null;
139    }
140
141    /** {@inheritDoc} */
142    public final void ungetLine()
143    {
144        if ( ungetted )
145        {
146            throw new IllegalStateException( "we support only one level of ungetLine()" );
147        }
148        ungetted = true;
149    }
150
151    /** {@inheritDoc} */
152    public final void unget( final String s )
153    {
154        if ( s == null )
155        {
156            throw new IllegalArgumentException( "argument can't be null" );
157        }
158        if ( s.length() != 0 )
159        {
160            ungetLine();
161            lastLine = s;
162        }
163    }
164}