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 URL url;
110
111 if ( !StringUtils.isEmpty( urlParam ) )
112 {
113 try
114 {
115 url = new URL( urlParam );
116 }
117 catch ( MalformedURLException e )
118 {
119 throw new IllegalArgumentException( urlParam + " is a malformed URL" );
120 }
121 }
122 else if ( !StringUtils.isEmpty( fileParam ) )
123 {
124 File f = new File( fileParam );
125
126 if ( !f.isAbsolute() )
127 {
128 f = new File( request.getBasedir(), fileParam );
129 }
130
131 try
132 {
133 url = f.toURI().toURL();
134 }
135 catch ( MalformedURLException e )
136 {
137 throw new IllegalArgumentException( fileParam + " is a malformed URL" );
138 }
139 }
140 else
141 {
142 throw new IllegalArgumentException( "Either the 'url' or the 'file' param has to be given." );
143 }
144
145 StringBuffer snippet;
146
147 try
148 {
149 snippet = getSnippet( url, id );
150 }
151 catch ( IOException e )
152 {
153 throw new MacroExecutionException( "Error reading snippet", e );
154 }
155
156 if ( verbatim )
157 {
158 sink.verbatim( SinkEventAttributeSet.BOXED );
159
160 sink.text( snippet.toString() );
161
162 sink.verbatim_();
163 }
164 else
165 {
166 sink.rawText( snippet.toString() );
167 }
168 }
169
170
171
172
173
174
175
176
177
178 private StringBuffer getSnippet( URL url, String id )
179 throws IOException
180 {
181 StringBuffer result;
182
183 String cachedSnippet = getCachedSnippet( url, id );
184
185 if ( cachedSnippet != null )
186 {
187 result = new StringBuffer( cachedSnippet );
188
189 if ( debug )
190 {
191 result.append( "(Served from cache)" );
192 }
193 }
194 else
195 {
196 try
197 {
198 result = new SnippetReader( url ).readSnippet( id );
199 cacheSnippet( url, id, result.toString() );
200 if ( debug )
201 {
202 result.append( "(Fetched from url, cache content " ).append( cache ).append( ")" );
203 }
204 }
205 catch ( IOException e )
206 {
207 result = new StringBuffer( "Error during retrieving content skip as ignoreDownloadError activated." );
208 }
209
210
211 }
212
213 return result;
214 }
215
216
217
218
219
220
221
222
223 private String getCachedSnippet( URL url, String id )
224 {
225 if ( isCacheTimedout( url, id ) )
226 {
227 removeFromCache( url, id );
228 }
229 return cache.get( globalSnippetId( url, id ) );
230 }
231
232
233
234
235
236
237
238
239
240 boolean isCacheTimedout( URL url, String id )
241 {
242 return timeInCache( url, id ) >= timeout;
243 }
244
245
246
247
248
249
250
251
252 long timeInCache( URL url, String id )
253 {
254 return System.currentTimeMillis() - getTimeCached( url, id );
255 }
256
257
258
259
260
261
262
263
264 long getTimeCached( URL url, String id )
265 {
266 String globalId = globalSnippetId( url, id );
267
268 return timeCached.containsKey( globalId ) ? timeCached.get( globalId ).longValue() : 0;
269 }
270
271
272
273
274
275
276
277 private void removeFromCache( URL url, String id )
278 {
279 String globalId = globalSnippetId( url, id );
280
281 timeCached.remove( globalId );
282
283 cache.remove( globalId );
284 }
285
286
287
288
289
290
291
292
293
294 private String globalSnippetId( URL url, String id )
295 {
296 if ( StringUtils.isEmpty( id ) )
297 {
298 return url.toString();
299 }
300
301 return url + " " + id;
302 }
303
304
305
306
307
308
309
310
311 public void cacheSnippet( URL url, String id, String content )
312 {
313 cache.put( globalSnippetId( url, id ), content );
314
315 timeCached.put( globalSnippetId( url, id ), Long.valueOf( System.currentTimeMillis() ) );
316 }
317
318
319
320
321
322
323 public void setCacheTimeout( int time )
324 {
325 this.timeout = time;
326 }
327 }