View Javadoc

1   package org.apache.maven.doxia.macro.snippet;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.BufferedReader;
23  import java.io.IOException;
24  import java.io.InputStreamReader;
25  import java.net.URL;
26  import java.util.ArrayList;
27  import java.util.List;
28  import java.util.Locale;
29  
30  import org.codehaus.plexus.util.IOUtil;
31  
32  /**
33   * Utility class for reading snippets.
34   *
35   * @version $Id: SnippetReader.java 1172204 2011-09-18 06:46:17Z hboutemy $
36   */
37  public class SnippetReader
38  {
39      /** System-dependent EOL. */
40      private static final String EOL = System.getProperty( "line.separator" );
41  
42      /** The source. */
43      private URL source;
44  
45      /**
46       * Constructor.
47       *
48       * @param src The source.
49       */
50      public SnippetReader( URL src )
51      {
52          this.source = src;
53      }
54  
55      /**
56       * Reads the snippet with given id.
57       *
58       * @param snippetId The id of the snippet.
59       * @return The snippet.
60       * @throws java.io.IOException if something goes wrong.
61       */
62      public StringBuffer readSnippet( String snippetId )
63          throws IOException
64      {
65          List<String> lines = readLines( snippetId );
66          int minIndent = minIndent( lines );
67          StringBuffer result = new StringBuffer();
68          for ( String line : lines )
69          {
70              result.append( line.substring( minIndent ) );
71              result.append( EOL );
72          }
73          return result;
74      }
75  
76      /**
77       * Returns the minimal indent of all the lines in the given List.
78       *
79       * @param lines A List of lines.
80       * @return the minimal indent.
81       */
82      int minIndent( List<String> lines )
83      {
84          int minIndent = Integer.MAX_VALUE;
85          for ( String line : lines )
86          {
87              minIndent = Math.min( minIndent, indent( line ) );
88          }
89          return minIndent;
90      }
91  
92      /**
93       * Returns the indent of the given line.
94       *
95       * @param line A line.
96       * @return the indent.
97       */
98      int indent( String line )
99      {
100         char[] chars = line.toCharArray();
101         int indent = 0;
102         for ( ; indent < chars.length; indent++ )
103         {
104             if ( chars[indent] != ' ' )
105             {
106                 break;
107             }
108         }
109         return indent;
110     }
111 
112     /**
113      * Reads the snippet and returns the lines in a List.
114      *
115      * @param snippetId The id of the snippet.
116      * @return A List of lines.
117      * @throws IOException if something goes wrong.
118      */
119     private List<String> readLines( String snippetId )
120         throws IOException
121     {
122         // TODO: DOXIA-386, use InputStreamReader(InputStream in, Charset cs)
123         BufferedReader reader = new BufferedReader( new InputStreamReader( source.openStream() ) );
124         List<String> lines = new ArrayList<String>();
125         try
126         {
127             boolean capture = false;
128             String line;
129             while ( ( line = reader.readLine() ) != null )
130             {
131                 if ( snippetId == null || "".equals( snippetId.trim() ) )
132                 {
133                     lines.add( line );
134                 }
135                 else
136                 {
137                     if ( isStart( snippetId, line ) )
138                     {
139                         capture = true;
140                     }
141                     else if ( isEnd( snippetId, line ) )
142                     {
143                         break;
144                     }
145                     else if ( capture )
146                     {
147                         lines.add( line );
148                     }
149                 }
150             }
151         }
152         finally
153         {
154             IOUtil.close( reader );
155         }
156         return lines;
157     }
158 
159     /**
160      * Determines if the given line is a start demarcator.
161      *
162      * @param snippetId the id of the snippet.
163      * @param line the line.
164      * @return True, if the line is a start demarcator.
165      */
166     protected boolean isStart( String snippetId, String line )
167     {
168         return isDemarcator( snippetId, "START", line );
169     }
170 
171     /**
172      * Determines if the given line is a demarcator.
173      *
174      * @param snippetId the id of the snippet.
175      * @param what Identifier for the demarcator.
176      * @param line the line.
177      * @return True, if the line is a start demarcator.
178      */
179     protected boolean isDemarcator( String snippetId, String what, String line )
180     {
181         String upper = line.toUpperCase( Locale.ENGLISH );
182         return upper.contains( what.toUpperCase( Locale.ENGLISH ) )
183             && upper.contains( "SNIPPET" )
184             && line.contains( snippetId );
185     }
186 
187     /**
188      * Determines if the given line is an end demarcator.
189      *
190      * @param snippetId the id of the snippet.
191      * @param line the line.
192      * @return True, if the line is an end demarcator.
193      */
194     protected boolean isEnd( String snippetId, String line )
195     {
196         return isDemarcator( snippetId, "END", line );
197     }
198 }