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.FileInputStream;
24  import java.io.FileOutputStream;
25  import java.io.IOException;
26  import java.io.InputStream;
27  import java.io.OutputStreamWriter;
28  import java.io.Writer;
29  import java.lang.reflect.Method;
30  import java.net.URI;
31  import java.util.regex.Pattern;
32  
33  import org.apache.felix.bundlerepository.Resource;
34  import org.apache.felix.bundlerepository.impl.DataModelHelperImpl;
35  import org.apache.felix.bundlerepository.impl.PullParser;
36  import org.apache.felix.bundlerepository.impl.RepositoryImpl;
37  import org.apache.felix.bundlerepository.impl.RepositoryParser;
38  import org.apache.felix.bundlerepository.impl.ResourceImpl;
39  import org.apache.maven.plugin.MojoExecutionException;
40  import org.apache.maven.plugin.logging.Log;
41  import org.apache.maven.project.MavenProject;
42  import org.codehaus.plexus.util.FileUtils;
43  import org.kxml2.io.KXmlParser;
44  import org.xmlpull.v1.XmlPullParser;
45  
46  
47  
48  
49  
50  
51  public class ObrUpdate
52  {
53      private static Pattern TIMESTAMP = Pattern.compile( "-[0-9]{8}\\.[0-9]{6}-[0-9]+" );
54  
55      private static Method setURI;
56  
57      static
58      {
59          try
60          {
61              setURI = RepositoryImpl.class.getDeclaredMethod( "setURI", String.class );
62              setURI.setAccessible( true );
63          }
64          catch ( Exception e )
65          {
66              setURI = null;
67          }
68      }
69  
70      
71  
72  
73      private Log m_logger;
74  
75      
76  
77  
78      private URI m_repositoryXml;
79  
80      
81  
82  
83      private URI m_obrXml;
84  
85      
86  
87  
88      private MavenProject m_project;
89  
90      
91  
92  
93      private Config m_userConfig;
94  
95      
96  
97  
98      private RepositoryImpl m_repository;
99  
100     
101 
102 
103     private ResourceImpl m_resourceBundle;
104 
105     
106 
107 
108     private URI m_baseURI;
109 
110 
111     
112 
113 
114 
115 
116 
117 
118 
119 
120     public ObrUpdate( URI repositoryXml, URI obrXml, MavenProject project, String mavenRepositoryPath,
121         Config userConfig, Log logger )
122     {
123         m_repositoryXml = repositoryXml;
124         m_obrXml = obrXml;
125         m_project = project;
126         m_logger = logger;
127 
128         m_userConfig = userConfig;
129 
130         if ( userConfig.isRemoteFile() )
131         {
132             m_baseURI = ObrUtils.toFileURI( mavenRepositoryPath );
133         }
134         else
135         {
136             m_baseURI = m_repositoryXml;
137         }
138     }
139 
140 
141     
142 
143 
144 
145 
146 
147 
148 
149 
150 
151 
152     public void updateRepository( URI bundleJar, URI sourceJar, URI docJar ) throws MojoExecutionException
153     {
154         m_logger.debug( " (f) repositoryXml = " + m_repositoryXml );
155         m_logger.debug( " (f) bundleJar = " + bundleJar );
156         m_logger.debug( " (f) sourceJar = " + sourceJar );
157         m_logger.debug( " (f) docJar = " + docJar );
158         m_logger.debug( " (f) obrXml = " + m_obrXml );
159 
160         if ( m_repository == null )
161         {
162             return;
163         }
164 
165         
166         File bundleFile = new File( bundleJar );
167         if ( !bundleFile.exists() )
168         {
169             String snapshot = TIMESTAMP.matcher( bundleFile.getName() ).replaceFirst( "-SNAPSHOT" );
170             bundleFile = new File( bundleFile.getParentFile(), snapshot );
171         }
172         if ( bundleFile.exists() )
173         {
174             URI resourceURI = m_userConfig.getRemoteBundle();
175             if ( null == resourceURI )
176             {
177                 resourceURI = bundleJar;
178                 if ( m_userConfig.isPathRelative() )
179                 {
180                     resourceURI = ObrUtils.getRelativeURI( m_baseURI, resourceURI );
181                 }
182             }
183 
184             if ( m_userConfig.isRemoteFile() )
185             {
186                 m_logger.info( "Deploying " + resourceURI );
187             }
188             else
189             {
190                 m_logger.info( "Installing " + resourceURI );
191             }
192 
193             try
194             {
195                 m_resourceBundle = ( ResourceImpl ) new DataModelHelperImpl().createResource( bundleFile.toURI().toURL() );
196                 if ( m_resourceBundle == null )
197                 {
198                     return;
199                 }
200             }
201             catch ( IOException e )
202             {
203                 throw new MojoExecutionException( "Unable to load resource information", e );
204             }
205 
206             m_resourceBundle.put( Resource.SIZE, String.valueOf( bundleFile.length() ) );
207             m_resourceBundle.put( Resource.URI, resourceURI.toASCIIString() );
208         }
209         else
210         {
211             m_logger.error( "file doesn't exist: " + bundleJar );
212             return;
213         }
214 
215         
216         if ( m_obrXml != null )
217         {
218             m_logger.info( "Adding " + m_obrXml );
219 
220             
221             
222 
223             
224             parseObrXml();
225         }
226 
227         String sourcePath = relativisePath( sourceJar );
228         String docPath = relativisePath( docJar );
229 
230         
231         
232 
233         m_repository.addResource( m_resourceBundle );
234         m_repository.setLastModified( System.currentTimeMillis() );
235     }
236 
237 
238     private String relativisePath( URI uri )
239     {
240         if ( null != uri )
241         {
242             if ( m_userConfig.isPathRelative() )
243             {
244                 return ObrUtils.getRelativeURI( m_baseURI, uri ).toASCIIString();
245             }
246 
247             return uri.toASCIIString();
248         }
249 
250         return null;
251     }
252 
253 
254     public void writeRepositoryXml() throws MojoExecutionException
255     {
256         m_logger.info( "Writing OBR metadata" );
257 
258         File file = null;
259         Writer writer;
260         try
261         {
262             file = File.createTempFile( "repository", ".xml" );
263             writer = new OutputStreamWriter( new FileOutputStream( file ) );
264         }
265         catch ( IOException e )
266         {
267             m_logger.error( "Unable to write to file: " + file.getName() );
268             e.printStackTrace();
269             throw new MojoExecutionException( "Unable to write to file: " + file.getName() + " : " + e.getMessage() );
270         }
271 
272         try
273         {
274             new DataModelHelperImpl().writeRepository( m_repository, writer );
275         }
276         catch ( IOException e )
277         {
278             throw new MojoExecutionException( "Unable to write repository xml", e );
279         }
280 
281         try
282         {
283             writer.flush();
284             writer.close();
285 
286             File outputFile = new File( m_repositoryXml );
287             outputFile.getParentFile().mkdirs();
288             FileUtils.rename( file, outputFile );
289         }
290         catch ( IOException e )
291         {
292             e.printStackTrace();
293             throw new MojoExecutionException( "IOException" );
294         }
295 
296     }
297 
298 
299     
300 
301 
302 
303 
304     public void parseRepositoryXml() throws MojoExecutionException
305     {
306         File fout = new File( m_repositoryXml );
307         if ( !fout.exists() )
308         {
309             m_repository = new RepositoryImpl();
310             writeRepositoryXml();
311         }
312         else
313         {
314             try
315             {
316                 m_repository = ( RepositoryImpl ) new DataModelHelperImpl().repository( m_repositoryXml.toURL() );
317                 if ( setURI != null )
318                 {
319                     setURI.invoke( m_repository, ( String ) null );
320                 }
321             }
322             catch ( Exception e )
323             {
324                 throw new MojoExecutionException( "Unable to read repository xml: " + m_repositoryXml, e );
325             }
326         }
327     }
328 
329 
330     
331 
332 
333     private void parseObrXml() throws MojoExecutionException
334     {
335         try
336         {
337             InputStream is = new FileInputStream( new File( m_obrXml ) );
338             try
339             {
340                 KXmlParser kxp = new KXmlParser();
341                 kxp.setInput( is, null );
342                 kxp.nextTag(); 
343                 kxp.nextTag(); 
344                 parseObrXml( kxp );
345             }
346             finally
347             {
348                 is.close();
349             }
350         }
351         catch ( Exception e )
352         {
353             throw new MojoExecutionException( "Unable to parse obr xml: " + m_obrXml, e );
354         }
355     }
356 
357 
358     private void parseObrXml( KXmlParser kxp ) throws Exception
359     {
360         PullParser parser = new PullParser();
361         while ( kxp.getEventType() == XmlPullParser.START_TAG )
362         {
363             if ( RepositoryParser.CATEGORY.equals( kxp.getName() ) )
364             {
365                 m_resourceBundle.addCategory( parser.parseCategory( kxp ) );
366             }
367             else if ( RepositoryParser.REQUIRE.equals( kxp.getName() ) )
368             {
369                 m_resourceBundle.addRequire( parser.parseRequire( kxp ) );
370             }
371             else if ( RepositoryParser.CAPABILITY.equals( kxp.getName() ) )
372             {
373                 m_resourceBundle.addCapability( parser.parseCapability( kxp ) );
374             }
375             else
376             {
377                 kxp.nextTag();
378                 parseObrXml( kxp );
379             }
380             kxp.nextTag();
381         }
382     }
383 
384 }