1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.felix.obrplugin;
20
21
22 import java.io.File;
23 import java.io.FileOutputStream;
24 import java.io.IOException;
25 import java.net.URI;
26 import java.text.SimpleDateFormat;
27 import java.util.ArrayList;
28 import java.util.Date;
29 import java.util.List;
30 import java.util.Properties;
31
32 import javax.xml.parsers.DocumentBuilder;
33 import javax.xml.parsers.DocumentBuilderFactory;
34 import javax.xml.parsers.ParserConfigurationException;
35 import javax.xml.transform.Result;
36 import javax.xml.transform.Transformer;
37 import javax.xml.transform.TransformerConfigurationException;
38 import javax.xml.transform.TransformerException;
39 import javax.xml.transform.TransformerFactory;
40 import javax.xml.transform.dom.DOMSource;
41 import javax.xml.transform.stream.StreamResult;
42
43 import org.apache.maven.artifact.repository.ArtifactRepository;
44 import org.apache.maven.plugin.AbstractMojo;
45 import org.apache.maven.plugin.MojoExecutionException;
46 import org.codehaus.plexus.util.FileUtils;
47 import org.w3c.dom.Document;
48 import org.w3c.dom.Element;
49 import org.w3c.dom.Node;
50 import org.w3c.dom.NodeList;
51 import org.xml.sax.SAXException;
52
53
54
55
56
57
58
59
60
61
62
63 public class ObrCleanRepo extends AbstractMojo
64 {
65
66
67
68
69
70 private String obrRepository;
71
72
73
74
75
76
77
78
79 private ArtifactRepository localRepository;
80
81
82 public void execute()
83 {
84 if ( "NONE".equalsIgnoreCase( obrRepository ) || "false".equalsIgnoreCase( obrRepository ) )
85 {
86 getLog().info( "Local OBR clean disabled (enable with -DobrRepository)" );
87 return;
88 }
89
90 try
91 {
92
93 URI repositoryXml = ObrUtils.findRepositoryXml( localRepository.getBasedir(), obrRepository );
94 if ( !"file".equals( repositoryXml.getScheme() ) )
95 {
96 getLog().error( "The repository URI " + repositoryXml + " is not a local file" );
97 return;
98 }
99
100 File repositoryFile = new File( repositoryXml );
101
102
103 if ( !repositoryFile.exists() )
104 {
105 getLog().error( "The repository file " + repositoryFile + " does not exist" );
106 return;
107 }
108
109 getLog().info( "Cleaning..." );
110
111 Document doc = parseFile( repositoryFile, initConstructor() );
112 Node finalDocument = cleanDocument( doc.getDocumentElement() );
113
114 if ( finalDocument == null )
115 {
116 getLog().info( "Nothing to clean in " + repositoryFile );
117 }
118 else
119 {
120 writeToFile( repositoryXml, finalDocument );
121 getLog().info( "Repository " + repositoryFile + " cleaned" );
122 }
123 }
124 catch ( Exception e )
125 {
126 getLog().error( "Exception while cleaning local OBR: " + e.getLocalizedMessage(), e );
127 }
128 }
129
130
131
132
133
134
135
136
137 private Element cleanDocument( Element elem )
138 {
139 String localRepoPath = localRepository.getBasedir();
140 URI baseURI = new File( localRepoPath + '/' ).toURI();
141 NodeList nodes = elem.getElementsByTagName( "resource" );
142 List toRemove = new ArrayList();
143
144
145 for ( int i = 0; i < nodes.getLength(); i++ )
146 {
147 Element n = ( Element ) nodes.item( i );
148 String value = n.getAttribute( "uri" );
149
150 URI resource;
151 try
152 {
153 resource = baseURI.resolve( value );
154 }
155 catch ( IllegalArgumentException e )
156 {
157 getLog().error( "Malformed URL when creating the resource absolute URI : " + e.getMessage() );
158 return null;
159 }
160
161 if ( "file".equals( resource.getScheme() ) && !new File( resource ).exists() )
162 {
163 getLog().info(
164 "The bundle " + n.getAttribute( "presentationname" ) + " - " + n.getAttribute( "version" )
165 + " will be removed" );
166 toRemove.add( n );
167 }
168 }
169
170 Date d = new Date();
171 if ( toRemove.size() > 0 )
172 {
173
174 for ( int i = 0; i < toRemove.size(); i++ )
175 {
176 elem.removeChild( ( Node ) toRemove.get( i ) );
177 }
178
179
180 SimpleDateFormat format = new SimpleDateFormat( "yyyyMMddHHmmss.SSS" );
181 d.setTime( System.currentTimeMillis() );
182 elem.setAttribute( "lastmodified", format.format( d ) );
183 return elem;
184 }
185
186 return null;
187 }
188
189
190
191
192
193
194
195
196 private DocumentBuilder initConstructor() throws MojoExecutionException
197 {
198 DocumentBuilder constructor = null;
199 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
200 try
201 {
202 constructor = factory.newDocumentBuilder();
203 }
204 catch ( ParserConfigurationException e )
205 {
206 getLog().error( "Unable to create a new xml document" );
207 throw new MojoExecutionException( "Cannot create the Document Builder : " + e.getMessage() );
208 }
209 return constructor;
210 }
211
212
213
214
215
216
217
218
219
220
221 private Document parseFile( File file, DocumentBuilder constructor ) throws MojoExecutionException
222 {
223 if ( constructor == null )
224 {
225 return null;
226 }
227
228 File targetFile = file.getAbsoluteFile();
229 getLog().info( "Parsing " + targetFile );
230 Document doc = null;
231 try
232 {
233 doc = constructor.parse( targetFile );
234 }
235 catch ( SAXException e )
236 {
237 getLog().error( "Cannot parse " + targetFile + " : " + e.getMessage() );
238 throw new MojoExecutionException( "Cannot parse " + targetFile + " : " + e.getMessage() );
239 }
240 catch ( IOException e )
241 {
242 getLog().error( "Cannot open " + targetFile + " : " + e.getMessage() );
243 throw new MojoExecutionException( "Cannot open " + targetFile + " : " + e.getMessage() );
244 }
245 return doc;
246 }
247
248
249
250
251
252
253
254
255
256 private void writeToFile( URI outputFilename, Node treeToBeWrite ) throws MojoExecutionException
257 {
258
259 Transformer transformer = null;
260 TransformerFactory tfabrique = TransformerFactory.newInstance();
261 try
262 {
263 transformer = tfabrique.newTransformer();
264 }
265 catch ( TransformerConfigurationException e )
266 {
267 getLog().error( "Unable to write to file: " + outputFilename.toString() );
268 throw new MojoExecutionException( "Unable to write to file: " + outputFilename.toString() + " : "
269 + e.getMessage() );
270 }
271 Properties proprietes = new Properties();
272 proprietes.put( "method", "xml" );
273 proprietes.put( "version", "1.0" );
274 proprietes.put( "encoding", "ISO-8859-1" );
275 proprietes.put( "standalone", "yes" );
276 proprietes.put( "indent", "yes" );
277 proprietes.put( "omit-xml-declaration", "no" );
278 transformer.setOutputProperties( proprietes );
279
280 DOMSource input = new DOMSource( treeToBeWrite );
281
282 File fichier = null;
283 FileOutputStream flux = null;
284 try
285 {
286 fichier = File.createTempFile( "repository", ".xml" );
287 flux = new FileOutputStream( fichier );
288 }
289 catch ( IOException e )
290 {
291 getLog().error( "Unable to write to file: " + fichier.getName() );
292 throw new MojoExecutionException( "Unable to write to file: " + fichier.getName() + " : " + e.getMessage() );
293 }
294 Result output = new StreamResult( flux );
295 try
296 {
297 transformer.transform( input, output );
298 }
299 catch ( TransformerException e )
300 {
301 throw new MojoExecutionException( "Unable to write to file: " + outputFilename.toString() + " : "
302 + e.getMessage() );
303 }
304
305 try
306 {
307 flux.flush();
308 flux.close();
309
310 FileUtils.rename( fichier, new File( outputFilename ) );
311 }
312 catch ( IOException e )
313 {
314 throw new MojoExecutionException( "IOException when closing file : " + e.getMessage() );
315 }
316 }
317 }