Coverage Report - org.apache.maven.plugin.resources.util.InterpolationFilterReader
 
Classes in this File Line Coverage Branch Coverage Complexity
InterpolationFilterReader
68% 
68% 
6.4
 
 1  
 /*
 2  
  * The Apache Software License, Version 1.1
 3  
  *
 4  
  * Copyright (c) 2002-2003 The Apache Software Foundation.  All rights
 5  
  * reserved.
 6  
  *
 7  
  * Redistribution and use in source and binary forms, with or without
 8  
  * modification, are permitted provided that the following conditions
 9  
  * are met:
 10  
  *
 11  
  * 1. Redistributions of source code must retain the above copyright
 12  
  *    notice, this list of conditions and the following disclaimer.
 13  
  *
 14  
  * 2. Redistributions in binary form must reproduce the above copyright
 15  
  *    notice, this list of conditions and the following disclaimer in
 16  
  *    the documentation and/or other materials provided with the
 17  
  *    distribution.
 18  
  *
 19  
  * 3. The end-user documentation included with the redistribution, if
 20  
  *    any, must include the following acknowlegement:
 21  
  *       "This product includes software developed by the
 22  
  *        Apache Software Foundation (http://www.codehaus.org/)."
 23  
  *    Alternately, this acknowlegement may appear in the software itself,
 24  
  *    if and wherever such third-party acknowlegements normally appear.
 25  
  *
 26  
  * 4. The names "Ant" and "Apache Software
 27  
  *    Foundation" must not be used to endorse or promote products derived
 28  
  *    from this software without prior written permission. For written
 29  
  *    permission, please contact codehaus@codehaus.org.
 30  
  *
 31  
  * 5. Products derived from this software may not be called "Apache"
 32  
  *    nor may "Apache" appear in their names without prior written
 33  
  *    permission of the Apache Group.
 34  
  *
 35  
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 36  
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 37  
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 38  
  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 39  
  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 40  
  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 41  
  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 42  
  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 43  
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 44  
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 45  
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 46  
  * SUCH DAMAGE.
 47  
  * ====================================================================
 48  
  *
 49  
  * This software consists of voluntary contributions made by many
 50  
  * individuals on behalf of the Apache Software Foundation.  For more
 51  
  * information on the Apache Software Foundation, please see
 52  
  * <http://www.codehaus.org/>.
 53  
  */
 54  
 
 55  
 package org.apache.maven.plugin.resources.util;
 56  
 
 57  
 import java.io.FilterReader;
 58  
 import java.io.IOException;
 59  
 import java.io.Reader;
 60  
 import java.util.HashMap;
 61  
 import java.util.Map;
 62  
 
 63  
 /**
 64  
  */
 65  
 public class InterpolationFilterReader
 66  
     extends FilterReader
 67  
 {
 68  
     /** replacement text from a token */
 69  18
     private String replaceData = null;
 70  
 
 71  
     /** Index into replacement data */
 72  18
     private int replaceIndex = -1;
 73  
 
 74  
     /** Hashtable to hold the replacee-replacer pairs (String to String). */
 75  18
     private Map variables = new HashMap();
 76  
 
 77  
     /** Character marking the beginning of a token. */
 78  
     private String beginToken;
 79  
 
 80  
     /** Character marking the end of a token. */
 81  
     private String endToken;
 82  
 
 83  
     /** Length of begin token. */
 84  
     private int beginTokenLength;
 85  
 
 86  
     /** Length of end token. */
 87  
     private int endTokenLength;
 88  
 
 89  
     /** Default begin token. */
 90  1
     private static String DEFAULT_BEGIN_TOKEN = "${";
 91  
 
 92  
     /** Default end token. */
 93  1
     private static String DEFAULT_END_TOKEN = "}";
 94  
 
 95  
     public InterpolationFilterReader( Reader in, Map variables, String beginToken, String endToken )
 96  
     {
 97  18
         super( in );
 98  
 
 99  18
         this.variables = variables;
 100  18
         this.beginToken = beginToken;
 101  18
         this.endToken = endToken;
 102  
 
 103  18
         beginTokenLength = beginToken.length();
 104  18
         endTokenLength = endToken.length();
 105  18
     }
 106  
 
 107  
     public InterpolationFilterReader( Reader in, Map variables )
 108  
     {
 109  0
         this( in, variables, DEFAULT_BEGIN_TOKEN, DEFAULT_END_TOKEN );
 110  0
     }
 111  
 
 112  
     /**
 113  
      * Skips characters.  This method will block until some characters are
 114  
      * available, an I/O error occurs, or the end of the stream is reached.
 115  
      *
 116  
      * @param  n  The number of characters to skip
 117  
      *
 118  
      * @return    the number of characters actually skipped
 119  
      *
 120  
      * @exception  IllegalArgumentException  If <code>n</code> is negative.
 121  
      * @exception  IOException  If an I/O error occurs
 122  
      */
 123  
     public long skip( long n ) throws IOException
 124  
     {
 125  0
         if ( n < 0L )
 126  
         {
 127  0
             throw new IllegalArgumentException( "skip value is negative" );
 128  
         }
 129  
 
 130  0
         for ( long i = 0; i < n; i++ )
 131  
         {
 132  0
             if ( read() == -1 )
 133  
             {
 134  0
                 return i;
 135  
             }
 136  
         }
 137  0
         return n;
 138  
     }
 139  
 
 140  
     /**
 141  
      * Reads characters into a portion of an array.  This method will block
 142  
      * until some input is available, an I/O error occurs, or the end of the
 143  
      * stream is reached.
 144  
      *
 145  
      * @param      cbuf  Destination buffer to write characters to.
 146  
      *                   Must not be <code>null</code>.
 147  
      * @param      off   Offset at which to start storing characters.
 148  
      * @param      len   Maximum number of characters to read.
 149  
      *
 150  
      * @return     the number of characters read, or -1 if the end of the
 151  
      *             stream has been reached
 152  
      *
 153  
      * @exception  IOException  If an I/O error occurs
 154  
      */
 155  
     public int read( char cbuf[],
 156  
                      int off,
 157  
                      int len )
 158  
         throws IOException
 159  
     {
 160  215
         for ( int i = 0; i < len; i++ )
 161  
         {
 162  215
             int ch = read();
 163  215
             if ( ch == -1 )
 164  
             {
 165  11
                 if ( i == 0 )
 166  
                 {
 167  6
                     return -1;
 168  
                 }
 169  
                 else
 170  
                 {
 171  5
                     return i;
 172  
                 }
 173  
             }
 174  204
             cbuf[off + i] = (char) ch;
 175  
         }
 176  0
         return len;
 177  
     }
 178  
 
 179  
     /**
 180  
      * Returns the next character in the filtered stream, replacing tokens
 181  
      * from the original stream.
 182  
      *
 183  
      * @return the next character in the resulting stream, or -1
 184  
      * if the end of the resulting stream has been reached
 185  
      *
 186  
      * @exception IOException if the underlying stream throws an IOException
 187  
      * during reading
 188  
      */
 189  
     public int read() throws IOException
 190  
     {
 191  629
         if ( replaceIndex != -1 )
 192  
         {
 193  98
             int ch = replaceData.charAt( replaceIndex++ );
 194  98
             if ( replaceIndex >= replaceData.length() )
 195  
             {
 196  5
                 replaceIndex = -1;
 197  
             }
 198  98
             return ch;
 199  
         }
 200  
 
 201  531
         int ch = in.read();
 202  
 
 203  531
         if ( ch == beginToken.charAt( 0 ) )
 204  
         {
 205  5
             StringBuffer key = new StringBuffer();
 206  
 
 207  5
             int beginTokenMatchPos = 1;
 208  
 
 209  
             do
 210  
             {
 211  51
                 ch = in.read();
 212  51
                 if ( ch != -1 )
 213  
                 {
 214  51
                     key.append( (char) ch );
 215  
 
 216  51
                     if ( ( beginTokenMatchPos < beginTokenLength ) &&
 217  
                             ( ch != beginToken.charAt( beginTokenMatchPos++ ) ) )
 218  
                     {
 219  0
                         ch = -1; // not really EOF but to trigger code below
 220  0
                         break;
 221  
                     }
 222  
                 }
 223  
                 else
 224  
                 {
 225  
                     break;
 226  
                 }
 227  
             }
 228  51
             while ( ch != endToken.charAt( 0 ) );
 229  
 
 230  
             // now test endToken
 231  5
             if ( ch != -1 && endTokenLength > 1 )
 232  
             {
 233  0
                 int endTokenMatchPos = 1;
 234  
 
 235  
                 do
 236  
                 {
 237  0
                     ch = in.read();
 238  
                     
 239  0
                     if ( ch != -1 )
 240  
                     {
 241  0
                         key.append( (char) ch );
 242  
 
 243  0
                         if ( ch != endToken.charAt( endTokenMatchPos++ ) )
 244  
                         {
 245  0
                             ch = -1; // not really EOF but to trigger code below
 246  0
                             break;
 247  
                         }
 248  
 
 249  
                     }
 250  
                     else
 251  
                     {
 252  
                         break;
 253  
                     }
 254  
                 }
 255  0
                 while ( endTokenMatchPos < endTokenLength );
 256  
             }
 257  
 
 258  
             // There is nothing left to read so we have the situation where the begin/end token
 259  
             // are in fact the same and as there is nothing left to read we have got ourselves
 260  
             // end of a token boundary so let it pass through.
 261  5
             if ( ch == -1 )
 262  
             {
 263  0
                 replaceData = key.toString();
 264  0
                 replaceIndex = 0;
 265  0
                 return beginToken.charAt( 0 );
 266  
             }
 267  
 
 268  5
             String variableKey = key.substring( beginTokenLength - 1, key.length() - endTokenLength );
 269  
 
 270  5
             Object o = variables.get(variableKey);
 271  5
             if ( o != null )
 272  
             {
 273  4
                 String value = o.toString();
 274  4
                 if ( value.length() != 0 )
 275  
                 {
 276  4
                     replaceData = value;
 277  4
                     replaceIndex = 0;
 278  
                 }
 279  4
                 return read();
 280  
             }
 281  
             else
 282  
             {
 283  1
                 replaceData = key.toString();
 284  1
                 replaceIndex = 0;
 285  1
                 return beginToken.charAt(0);
 286  
             }
 287  
         }
 288  
 
 289  526
         return ch;
 290  
     }
 291  
 }