1 package org.apache.maven.doxia.macro.snippet;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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.regex.Pattern;
29
30 import org.codehaus.plexus.util.StringUtils;
31 import org.codehaus.plexus.util.IOUtil;
32
33
34
35
36
37
38 public class SnippetReader
39 {
40
41 private static final String EOL = System.getProperty( "line.separator" );
42
43
44 private URL source;
45
46
47 private String encoding;
48
49
50
51
52
53
54
55 public SnippetReader( URL src, String encoding )
56 {
57 this.source = src;
58 this.encoding = encoding;
59 }
60
61
62
63
64
65
66 public SnippetReader( URL src )
67 {
68 this( src, null ) ;
69 }
70
71
72
73
74
75
76
77
78 public StringBuffer readSnippet( String snippetId )
79 throws IOException
80 {
81 List<String> lines = readLines( snippetId );
82 int minIndent = minIndent( lines );
83 StringBuffer result = new StringBuffer();
84 for ( String line : lines )
85 {
86 result.append( line.substring( minIndent ) );
87 result.append( EOL );
88 }
89 return result;
90 }
91
92
93
94
95
96
97
98 int minIndent( List<String> lines )
99 {
100 int minIndent = Integer.MAX_VALUE;
101 for ( String line : lines )
102 {
103 minIndent = Math.min( minIndent, indent( line ) );
104 }
105 return minIndent;
106 }
107
108
109
110
111
112
113
114 int indent( String line )
115 {
116 char[] chars = line.toCharArray();
117 int indent = 0;
118 for ( ; indent < chars.length; indent++ )
119 {
120 if ( chars[indent] != ' ' )
121 {
122 break;
123 }
124 }
125 return indent;
126 }
127
128
129
130
131
132
133
134
135 private List<String> readLines( String snippetId )
136 throws IOException
137 {
138 BufferedReader reader;
139 if ( encoding == null || "".equals( encoding ) )
140 {
141 reader = new BufferedReader( new InputStreamReader( source.openStream() ) );
142 }
143 else
144 {
145 reader = new BufferedReader( new InputStreamReader( source.openStream(), encoding ) );
146 }
147
148 List<String> lines = new ArrayList<>();
149 try
150 {
151 boolean capture = false;
152 String line;
153 boolean foundStart = false;
154 boolean foundEnd = false;
155 boolean hasSnippetId = StringUtils.isNotEmpty( snippetId );
156 while ( ( line = reader.readLine() ) != null )
157 {
158 if ( !hasSnippetId )
159 {
160 lines.add( line );
161 }
162 else
163 {
164 if ( isStart( snippetId, line ) )
165 {
166 capture = true;
167 foundStart = true;
168 }
169 else if ( isEnd( snippetId, line ) )
170 {
171 foundEnd = true;
172 break;
173 }
174 else if ( capture )
175 {
176 lines.add( line );
177 }
178 }
179 }
180
181 if ( hasSnippetId && !foundStart )
182 {
183 throw new IOException( "Failed to find START of snippet " + snippetId + " in file at URL: " + source );
184 }
185 if ( hasSnippetId && !foundEnd )
186 {
187 throw new IOException( "Failed to find END of snippet " + snippetId + " in file at URL: " + source );
188 }
189 }
190 finally
191 {
192 IOUtil.close( reader );
193 }
194 return lines;
195 }
196
197
198
199
200
201
202
203
204 protected boolean isStart( String snippetId, String line )
205 {
206 return isDemarcator( snippetId, "START", line );
207 }
208
209
210
211
212
213
214
215
216
217 protected static boolean isDemarcator( String snippetId, String what, String line )
218 {
219
220
221 String snippetRegExp = "(^|\\W)(?i:SNIPPET)($|\\W)";
222 String snippetIdRegExp = "(^|\\W)" + snippetId + "($|\\W)";
223 String whatRegExp = "(^|\\W)(?i:" + what + ")($|\\W)";
224
225 return Pattern.compile( snippetRegExp ).matcher( line ).find()
226 && Pattern.compile( whatRegExp ).matcher( line ).find()
227 && Pattern.compile( snippetIdRegExp ).matcher( line ).find();
228 }
229
230
231
232
233
234
235
236
237 protected boolean isEnd( String snippetId, String line )
238 {
239 return isDemarcator( snippetId, "END", line );
240 }
241 }