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 }