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 org.apache.maven.doxia.macro.AbstractMacro;
23 import org.apache.maven.doxia.macro.Macro;
24 import org.apache.maven.doxia.macro.MacroExecutionException;
25 import org.apache.maven.doxia.macro.MacroRequest;
26 import org.apache.maven.doxia.sink.Sink;
27 import org.apache.maven.doxia.sink.SinkEventAttributeSet;
28 import org.codehaus.plexus.component.annotations.Component;
29 import org.codehaus.plexus.util.StringUtils;
30
31 import java.io.File;
32 import java.io.IOException;
33 import java.net.MalformedURLException;
34 import java.net.URL;
35 import java.util.HashMap;
36 import java.util.Map;
37
38
39
40
41
42
43 @Component( role = Macro.class, hint = "snippet" )
44 public class SnippetMacro
45 extends AbstractMacro
46 {
47
48
49
50 private static Map<String, String> cache = new HashMap<String, String>();
51
52 private static final int HOUR = 60;
53
54
55
56
57 private long timeout = HOUR * HOUR * 1000;
58
59
60
61
62 private static Map<String, Long> timeCached = new HashMap<String, Long>();
63
64
65
66
67 private boolean debug = false;
68
69
70
71
72 private boolean ignoreDownloadError;
73
74
75
76
77 public void execute( Sink sink, MacroRequest request )
78 throws MacroExecutionException
79 {
80 String id = (String) request.getParameter( "id" );
81
82 String urlParam = (String) request.getParameter( "url" );
83
84 String fileParam = (String) request.getParameter( "file" );
85
86 String debugParam = (String) request.getParameter( "debug" );
87
88 if ( debugParam != null )
89 {
90 this.debug = Boolean.parseBoolean( debugParam );
91 }
92
93 String ignoreDownloadErrorParam = (String) request.getParameter( "ignoreDownloadError" );
94
95 if ( ignoreDownloadErrorParam != null )
96 {
97 this.ignoreDownloadError = Boolean.parseBoolean( ignoreDownloadErrorParam );
98 }
99
100 boolean verbatim = true;
101
102 String verbatimParam = (String) request.getParameter( "verbatim" );
103
104 if ( verbatimParam != null && !"".equals( verbatimParam ) )
105 {
106 verbatim = Boolean.valueOf( verbatimParam ).booleanValue();
107 }
108
109 String encoding = (String) request.getParameter( "encoding" );
110
111 URL url;
112
113 if ( !StringUtils.isEmpty( urlParam ) )
114 {
115 try
116 {
117 url = new URL( urlParam );
118 }
119 catch ( MalformedURLException e )
120 {
121 throw new IllegalArgumentException( urlParam + " is a malformed URL" );
122 }
123 }
124 else if ( !StringUtils.isEmpty( fileParam ) )
125 {
126 File f = new File( fileParam );
127
128 if ( !f.isAbsolute() )
129 {
130 f = new File( request.getBasedir(), fileParam );
131 }
132
133 try
134 {
135 url = f.toURI().toURL();
136 }
137 catch ( MalformedURLException e )
138 {
139 throw new IllegalArgumentException( fileParam + " is a malformed URL" );
140 }
141 }
142 else
143 {
144 throw new IllegalArgumentException( "Either the 'url' or the 'file' param has to be given." );
145 }
146
147 StringBuffer snippet;
148
149 try
150 {
151 snippet = getSnippet( url, encoding, id );
152 }
153 catch ( IOException e )
154 {
155 throw new MacroExecutionException( "Error reading snippet", e );
156 }
157
158 if ( verbatim )
159 {
160 sink.verbatim( SinkEventAttributeSet.BOXED );
161
162 sink.text( snippet.toString() );
163
164 sink.verbatim_();
165 }
166 else
167 {
168 sink.rawText( snippet.toString() );
169 }
170 }
171
172
173
174
175
176
177
178
179
180
181 private StringBuffer getSnippet( URL url, String encoding, String id )
182 throws IOException
183 {
184 StringBuffer result;
185
186 String cachedSnippet = getCachedSnippet( url, id );
187
188 if ( cachedSnippet != null )
189 {
190 result = new StringBuffer( cachedSnippet );
191
192 if ( debug )
193 {
194 result.append( "(Served from cache)" );
195 }
196 }
197 else
198 {
199 try
200 {
201 result = new SnippetReader( url, encoding ).readSnippet( id );
202 cacheSnippet( url, id, result.toString() );
203 if ( debug )
204 {
205 result.append( "(Fetched from url, cache content " ).append( cache ).append( ")" );
206 }
207 }
208 catch ( IOException e )
209 {
210 result = new StringBuffer( "Error during retrieving content skip as ignoreDownloadError activated." );
211 }
212
213
214 }
215
216 return result;
217 }
218
219
220
221
222
223
224
225
226 private String getCachedSnippet( URL url, String id )
227 {
228 if ( isCacheTimedout( url, id ) )
229 {
230 removeFromCache( url, id );
231 }
232 return cache.get( globalSnippetId( url, id ) );
233 }
234
235
236
237
238
239
240
241
242
243 boolean isCacheTimedout( URL url, String id )
244 {
245 return timeInCache( url, id ) >= timeout;
246 }
247
248
249
250
251
252
253
254
255 long timeInCache( URL url, String id )
256 {
257 return System.currentTimeMillis() - getTimeCached( url, id );
258 }
259
260
261
262
263
264
265
266
267 long getTimeCached( URL url, String id )
268 {
269 String globalId = globalSnippetId( url, id );
270
271 return timeCached.containsKey( globalId ) ? timeCached.get( globalId ).longValue() : 0;
272 }
273
274
275
276
277
278
279
280 private void removeFromCache( URL url, String id )
281 {
282 String globalId = globalSnippetId( url, id );
283
284 timeCached.remove( globalId );
285
286 cache.remove( globalId );
287 }
288
289
290
291
292
293
294
295
296
297 private String globalSnippetId( URL url, String id )
298 {
299 if ( StringUtils.isEmpty( id ) )
300 {
301 return url.toString();
302 }
303
304 return url + " " + id;
305 }
306
307
308
309
310
311
312
313
314 public void cacheSnippet( URL url, String id, String content )
315 {
316 cache.put( globalSnippetId( url, id ), content );
317
318 timeCached.put( globalSnippetId( url, id ), Long.valueOf( System.currentTimeMillis() ) );
319 }
320
321
322
323
324
325
326 public void setCacheTimeout( int time )
327 {
328 this.timeout = time;
329 }
330 }