blob: 58b4a33c9a06cc8f3115f56157b74f86dd3b2bec [file] [log] [blame]
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
Stuart McCullochc792b372008-02-17 16:12:24 +000019package org.apache.felix.obrplugin;
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +000020
21
22import java.io.File;
Guillaume Nodet8d5faf62010-03-19 15:32:17 +000023import java.io.FileInputStream;
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +000024import java.io.FileOutputStream;
25import java.io.IOException;
Guillaume Nodet8d5faf62010-03-19 15:32:17 +000026import java.io.InputStream;
27import java.io.OutputStreamWriter;
28import java.io.Writer;
Stuart McCullochcfbac7a2011-10-16 19:56:22 +000029import java.lang.reflect.Method;
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +000030import java.net.URI;
Stuart McCullochf8437802011-10-16 19:20:39 +000031import java.util.regex.Pattern;
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +000032
Guillaume Nodet8d5faf62010-03-19 15:32:17 +000033import org.apache.felix.bundlerepository.Resource;
34import org.apache.felix.bundlerepository.impl.DataModelHelperImpl;
35import org.apache.felix.bundlerepository.impl.PullParser;
36import org.apache.felix.bundlerepository.impl.RepositoryImpl;
37import org.apache.felix.bundlerepository.impl.RepositoryParser;
38import org.apache.felix.bundlerepository.impl.ResourceImpl;
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +000039import org.apache.maven.plugin.MojoExecutionException;
40import org.apache.maven.plugin.logging.Log;
41import org.apache.maven.project.MavenProject;
Stuart McCulloch88129022009-09-03 02:52:58 +000042import org.codehaus.plexus.util.FileUtils;
Guillaume Nodet8d5faf62010-03-19 15:32:17 +000043import org.kxml2.io.KXmlParser;
44import org.xmlpull.v1.XmlPullParser;
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +000045
46
47/**
48 * this class parse the old repository.xml file build the bundle resource description and update the repository.
49 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
50 */
51public class ObrUpdate
52{
Stuart McCullochcfbac7a2011-10-16 19:56:22 +000053 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 }
Stuart McCullochf8437802011-10-16 19:20:39 +000069
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +000070 /**
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +000071 * logger for this plugin.
72 */
73 private Log m_logger;
74
75 /**
76 * name and path to the repository descriptor file.
77 */
78 private URI m_repositoryXml;
79
80 /**
81 * name and path to the obr.xml file.
82 */
83 private URI m_obrXml;
84
85 /**
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +000086 * maven project description.
87 */
88 private MavenProject m_project;
89
90 /**
91 * user configuration information.
92 */
93 private Config m_userConfig;
94
95 /**
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +000096 * root on parent document.
97 */
Guillaume Nodet8d5faf62010-03-19 15:32:17 +000098 private RepositoryImpl m_repository;
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +000099
100 /**
101 * used to store bundle information.
102 */
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000103 private ResourceImpl m_resourceBundle;
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000104
105 /**
106 * base URI used to relativize bundle URIs.
107 */
108 private URI m_baseURI;
109
110
111 /**
112 * initialize information.
113 * @param repositoryXml path to the repository descriptor file
114 * @param obrXml path and filename to the obr.xml file
115 * @param project maven project description
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000116 * @param mavenRepositoryPath path to the local maven repository
117 * @param userConfig user information
118 * @param logger plugin logger
119 */
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000120 public ObrUpdate( URI repositoryXml, URI obrXml, MavenProject project, String mavenRepositoryPath,
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000121 Config userConfig, Log logger )
122 {
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000123 m_repositoryXml = repositoryXml;
124 m_obrXml = obrXml;
125 m_project = project;
126 m_logger = logger;
127
128 m_userConfig = userConfig;
129
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000130 if ( userConfig.isRemoteFile() )
131 {
132 m_baseURI = ObrUtils.toFileURI( mavenRepositoryPath );
133 }
134 else
135 {
136 m_baseURI = m_repositoryXml;
137 }
138 }
139
140
141 /**
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000142 * update the repository descriptor file. parse the old repository descriptor file,
143 * get the old reference of the bundle or determine the id for a new bundle, extract
144 * information from bindex set the new information in descriptor file and save it.
145 *
146 * @param bundleJar path to the bundle jar file
147 * @param sourceJar path to the source jar file
Stuart McCullocha1d3a292008-02-20 00:53:52 +0000148 * @param docJar path to the docs jar file
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000149 *
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000150 * @throws MojoExecutionException if the plugin failed
151 */
Stuart McCullocha1d3a292008-02-20 00:53:52 +0000152 public void updateRepository( URI bundleJar, URI sourceJar, URI docJar ) throws MojoExecutionException
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000153 {
154 m_logger.debug( " (f) repositoryXml = " + m_repositoryXml );
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000155 m_logger.debug( " (f) bundleJar = " + bundleJar );
156 m_logger.debug( " (f) sourceJar = " + sourceJar );
Stuart McCullochf8437802011-10-16 19:20:39 +0000157 m_logger.debug( " (f) docJar = " + docJar );
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000158 m_logger.debug( " (f) obrXml = " + m_obrXml );
159
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000160 if ( m_repository == null )
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000161 {
162 return;
163 }
164
165 // get the file size
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000166 File bundleFile = new File( bundleJar );
Stuart McCullochf8437802011-10-16 19:20:39 +0000167 if ( !bundleFile.exists() )
168 {
169 String snapshot = TIMESTAMP.matcher( bundleFile.getName() ).replaceFirst( "-SNAPSHOT" );
170 bundleFile = new File( bundleFile.getParentFile(), snapshot );
171 }
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000172 if ( bundleFile.exists() )
173 {
174 URI resourceURI = m_userConfig.getRemoteBundle();
175 if ( null == resourceURI )
176 {
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000177 resourceURI = bundleJar;
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000178 if ( m_userConfig.isPathRelative() )
179 {
180 resourceURI = ObrUtils.getRelativeURI( m_baseURI, resourceURI );
181 }
182 }
183
Stuart McCulloch7b6f5912008-02-18 17:30:36 +0000184 if ( m_userConfig.isRemoteFile() )
185 {
186 m_logger.info( "Deploying " + resourceURI );
187 }
188 else
189 {
190 m_logger.info( "Installing " + resourceURI );
191 }
192
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000193 try
194 {
Stuart McCulloch0eb99992011-10-23 20:16:48 +0000195 m_resourceBundle = ( ResourceImpl ) new DataModelHelperImpl().createResource( bundleFile.toURI().toURL() );
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000196 if ( m_resourceBundle == null )
Guillaume Nodet127d5572010-03-19 18:24:02 +0000197 {
198 return;
199 }
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000200 }
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000201 catch ( IOException e )
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000202 {
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000203 throw new MojoExecutionException( "Unable to load resource information", e );
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000204 }
205
206 m_resourceBundle.put( Resource.SIZE, String.valueOf( bundleFile.length() ) );
207 m_resourceBundle.put( Resource.URI, resourceURI.toASCIIString() );
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000208 }
209 else
210 {
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000211 m_logger.error( "file doesn't exist: " + bundleJar );
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000212 return;
213 }
214
215 // parse the obr.xml file
216 if ( m_obrXml != null )
217 {
218 m_logger.info( "Adding " + m_obrXml );
219
220 // URL url = getClass().getResource("/SchemaObr.xsd");
221 // TODO validate obr.xml file
222
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000223 // add contents to resource bundle
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000224 parseObrXml();
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000225 }
226
Stuart McCullocha1d3a292008-02-20 00:53:52 +0000227 String sourcePath = relativisePath( sourceJar );
228 String docPath = relativisePath( docJar );
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000229
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000230 // m_resourceBundle.construct( m_project, bindexExtractor, sourcePath, docPath );
231 // TODO: rebuild wrt m_project
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000232
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000233 m_repository.addResource( m_resourceBundle );
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000234 m_repository.setLastModified( System.currentTimeMillis() );
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000235 }
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000236
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000237
Stuart McCullocha1d3a292008-02-20 00:53:52 +0000238 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
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000254 public void writeRepositoryXml() throws MojoExecutionException
255 {
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000256 m_logger.info( "Writing OBR metadata" );
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000257
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000258 File file = null;
259 Writer writer;
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000260 try
261 {
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000262 file = File.createTempFile( "repository", ".xml" );
263 writer = new OutputStreamWriter( new FileOutputStream( file ) );
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000264 }
265 catch ( IOException e )
266 {
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000267 m_logger.error( "Unable to write to file: " + file.getName() );
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000268 e.printStackTrace();
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000269 throw new MojoExecutionException( "Unable to write to file: " + file.getName() + " : " + e.getMessage() );
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000270 }
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000271
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000272 try
273 {
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000274 new DataModelHelperImpl().writeRepository( m_repository, writer );
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000275 }
Stuart McCulloch88129022009-09-03 02:52:58 +0000276 catch ( IOException e )
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000277 {
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000278 throw new MojoExecutionException( "Unable to write repository xml", e );
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000279 }
280
281 try
282 {
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000283 writer.flush();
284 writer.close();
Stuart McCulloch88129022009-09-03 02:52:58 +0000285
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000286 File outputFile = new File( m_repositoryXml );
Stuart McCulloch88129022009-09-03 02:52:58 +0000287 outputFile.getParentFile().mkdirs();
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000288 FileUtils.rename( file, outputFile );
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000289 }
290 catch ( IOException e )
291 {
292 e.printStackTrace();
293 throw new MojoExecutionException( "IOException" );
294 }
295
296 }
297
298
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000299 /**
300 * Parse the repository descriptor file.
301 *
302 * @throws MojoExecutionException if the plugin failed
303 */
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000304 public void parseRepositoryXml() throws MojoExecutionException
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000305 {
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000306 File fout = new File( m_repositoryXml );
307 if ( !fout.exists() )
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000308 {
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000309 m_repository = new RepositoryImpl();
310 writeRepositoryXml();
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000311 }
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000312 else
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000313 {
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000314 try
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000315 {
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000316 m_repository = ( RepositoryImpl ) new DataModelHelperImpl().repository( m_repositoryXml.toURL() );
Stuart McCullochcfbac7a2011-10-16 19:56:22 +0000317 if ( setURI != null )
318 {
319 setURI.invoke( m_repository, ( String ) null );
320 }
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000321 }
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000322 catch ( Exception e )
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000323 {
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000324 throw new MojoExecutionException( "Unable to read repository xml: " + m_repositoryXml, e );
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000325 }
326 }
327 }
328
329
330 /**
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000331 * put the information from obr.xml into ressourceBundle object.
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000332 */
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000333 private void parseObrXml() throws MojoExecutionException
334 {
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000335 try
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000336 {
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000337 InputStream is = new FileInputStream( new File( m_obrXml ) );
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000338 try
339 {
340 KXmlParser kxp = new KXmlParser();
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000341 kxp.setInput( is, null );
Guillaume Nodetbdc13752010-03-25 08:21:15 +0000342 kxp.nextTag(); // skip top level element
343 kxp.nextTag(); // go to first child element
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000344 parseObrXml( kxp );
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000345 }
346 finally
347 {
348 is.close();
349 }
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000350 }
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000351 catch ( Exception e )
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000352 {
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000353 throw new MojoExecutionException( "Unable to parse obr xml: " + m_obrXml, e );
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000354 }
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000355 }
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000356
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000357
358 private void parseObrXml( KXmlParser kxp ) throws Exception
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000359 {
360 PullParser parser = new PullParser();
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000361 while ( kxp.getEventType() == XmlPullParser.START_TAG )
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000362 {
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000363 if ( RepositoryParser.CATEGORY.equals( kxp.getName() ) )
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000364 {
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000365 m_resourceBundle.addCategory( parser.parseCategory( kxp ) );
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000366 }
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000367 else if ( RepositoryParser.REQUIRE.equals( kxp.getName() ) )
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000368 {
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000369 m_resourceBundle.addRequire( parser.parseRequire( kxp ) );
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000370 }
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000371 else if ( RepositoryParser.CAPABILITY.equals( kxp.getName() ) )
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000372 {
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000373 m_resourceBundle.addCapability( parser.parseCapability( kxp ) );
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000374 }
375 else
376 {
377 kxp.nextTag();
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000378 parseObrXml( kxp );
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000379 }
380 kxp.nextTag();
381 }
382 }
383
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000384}