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