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