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 }