blob: 6c9fe01c621b84e3deba2f9eaa05f96a2c78e32d [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 McCullochbb8b9fa2008-02-17 16:07:14 +000029import java.net.URI;
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +000030
Guillaume Nodet8d5faf62010-03-19 15:32:17 +000031import org.apache.felix.bundlerepository.Resource;
32import org.apache.felix.bundlerepository.impl.DataModelHelperImpl;
33import org.apache.felix.bundlerepository.impl.PullParser;
34import org.apache.felix.bundlerepository.impl.RepositoryImpl;
35import org.apache.felix.bundlerepository.impl.RepositoryParser;
36import org.apache.felix.bundlerepository.impl.ResourceImpl;
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +000037import org.apache.maven.plugin.MojoExecutionException;
38import org.apache.maven.plugin.logging.Log;
39import org.apache.maven.project.MavenProject;
Stuart McCulloch88129022009-09-03 02:52:58 +000040import org.codehaus.plexus.util.FileUtils;
Guillaume Nodet8d5faf62010-03-19 15:32:17 +000041import org.kxml2.io.KXmlParser;
42import org.xmlpull.v1.XmlPullParser;
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +000043
44
45/**
46 * this class parse the old repository.xml file build the bundle resource description and update the repository.
47 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
48 */
49public class ObrUpdate
50{
51 /**
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +000052 * logger for this plugin.
53 */
54 private Log m_logger;
55
56 /**
57 * name and path to the repository descriptor file.
58 */
59 private URI m_repositoryXml;
60
61 /**
62 * name and path to the obr.xml file.
63 */
64 private URI m_obrXml;
65
66 /**
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +000067 * maven project description.
68 */
69 private MavenProject m_project;
70
71 /**
72 * user configuration information.
73 */
74 private Config m_userConfig;
75
76 /**
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +000077 * root on parent document.
78 */
Guillaume Nodet8d5faf62010-03-19 15:32:17 +000079 private RepositoryImpl m_repository;
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +000080
81 /**
82 * used to store bundle information.
83 */
Guillaume Nodet8d5faf62010-03-19 15:32:17 +000084 private ResourceImpl m_resourceBundle;
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +000085
86 /**
87 * base URI used to relativize bundle URIs.
88 */
89 private URI m_baseURI;
90
91
92 /**
93 * initialize information.
94 * @param repositoryXml path to the repository descriptor file
95 * @param obrXml path and filename to the obr.xml file
96 * @param project maven project description
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +000097 * @param mavenRepositoryPath path to the local maven repository
98 * @param userConfig user information
99 * @param logger plugin logger
100 */
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000101 public ObrUpdate( URI repositoryXml, URI obrXml, MavenProject project, String mavenRepositoryPath,
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000102 Config userConfig, Log logger )
103 {
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000104 m_repositoryXml = repositoryXml;
105 m_obrXml = obrXml;
106 m_project = project;
107 m_logger = logger;
108
109 m_userConfig = userConfig;
110
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000111 if ( userConfig.isRemoteFile() )
112 {
113 m_baseURI = ObrUtils.toFileURI( mavenRepositoryPath );
114 }
115 else
116 {
117 m_baseURI = m_repositoryXml;
118 }
119 }
120
121
122 /**
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000123 * update the repository descriptor file. parse the old repository descriptor file,
124 * get the old reference of the bundle or determine the id for a new bundle, extract
125 * information from bindex set the new information in descriptor file and save it.
126 *
127 * @param bundleJar path to the bundle jar file
128 * @param sourceJar path to the source jar file
Stuart McCullocha1d3a292008-02-20 00:53:52 +0000129 * @param docJar path to the docs jar file
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000130 *
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000131 * @throws MojoExecutionException if the plugin failed
132 */
Stuart McCullocha1d3a292008-02-20 00:53:52 +0000133 public void updateRepository( URI bundleJar, URI sourceJar, URI docJar ) throws MojoExecutionException
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000134 {
135 m_logger.debug( " (f) repositoryXml = " + m_repositoryXml );
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000136 m_logger.debug( " (f) bundleJar = " + bundleJar );
137 m_logger.debug( " (f) sourceJar = " + sourceJar );
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000138 m_logger.debug( " (f) obrXml = " + m_obrXml );
139
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000140 if ( m_repository == null )
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000141 {
142 return;
143 }
144
145 // get the file size
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000146 File bundleFile = new File( bundleJar );
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000147 if ( bundleFile.exists() )
148 {
149 URI resourceURI = m_userConfig.getRemoteBundle();
150 if ( null == resourceURI )
151 {
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000152 resourceURI = bundleJar;
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000153 if ( m_userConfig.isPathRelative() )
154 {
155 resourceURI = ObrUtils.getRelativeURI( m_baseURI, resourceURI );
156 }
157 }
158
Stuart McCulloch7b6f5912008-02-18 17:30:36 +0000159 if ( m_userConfig.isRemoteFile() )
160 {
161 m_logger.info( "Deploying " + resourceURI );
162 }
163 else
164 {
165 m_logger.info( "Installing " + resourceURI );
166 }
167
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000168 try
169 {
170 m_resourceBundle = (ResourceImpl) new DataModelHelperImpl().createResource( bundleJar.toURL() );
Guillaume Nodet127d5572010-03-19 18:24:02 +0000171 if (m_resourceBundle == null)
172 {
173 return;
174 }
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000175 }
176 catch (IOException e)
177 {
178 throw new MojoExecutionException("Unable to load resource information", e);
179 }
180
181 m_resourceBundle.put( Resource.SIZE, String.valueOf( bundleFile.length() ) );
182 m_resourceBundle.put( Resource.URI, resourceURI.toASCIIString() );
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000183 }
184 else
185 {
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000186 m_logger.error( "file doesn't exist: " + bundleJar );
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000187 return;
188 }
189
190 // parse the obr.xml file
191 if ( m_obrXml != null )
192 {
193 m_logger.info( "Adding " + m_obrXml );
194
195 // URL url = getClass().getResource("/SchemaObr.xsd");
196 // TODO validate obr.xml file
197
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000198 // add contents to resource bundle
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000199 parseObrXml();
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000200 }
201
Stuart McCullocha1d3a292008-02-20 00:53:52 +0000202 String sourcePath = relativisePath( sourceJar );
203 String docPath = relativisePath( docJar );
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000204
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000205// m_resourceBundle.construct( m_project, bindexExtractor, sourcePath, docPath );
206// TODO: rebuild wrt m_project
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000207
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000208 m_repository.addResource( m_resourceBundle );
209 m_repository.setLastModified(System.currentTimeMillis());
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000210 }
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000211
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000212
Stuart McCullocha1d3a292008-02-20 00:53:52 +0000213 private String relativisePath( URI uri )
214 {
215 if ( null != uri )
216 {
217 if ( m_userConfig.isPathRelative() )
218 {
219 return ObrUtils.getRelativeURI( m_baseURI, uri ).toASCIIString();
220 }
221
222 return uri.toASCIIString();
223 }
224
225 return null;
226 }
227
228
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000229 public void writeRepositoryXml() throws MojoExecutionException
230 {
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000231 m_logger.info( "Writing OBR metadata" );
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000232
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000233 File file = null;
234 Writer writer;
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000235 try
236 {
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000237 file = File.createTempFile( "repository", ".xml" );
238 writer = new OutputStreamWriter( new FileOutputStream( file ) );
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000239 }
240 catch ( IOException e )
241 {
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000242 m_logger.error( "Unable to write to file: " + file.getName() );
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000243 e.printStackTrace();
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000244 throw new MojoExecutionException( "Unable to write to file: " + file.getName() + " : " + e.getMessage() );
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000245 }
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000246
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000247 try
248 {
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000249 new DataModelHelperImpl().writeRepository(m_repository, writer);
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000250 }
Stuart McCulloch88129022009-09-03 02:52:58 +0000251 catch ( IOException e )
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000252 {
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000253 throw new MojoExecutionException( "Unable to write repository xml", e );
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000254 }
255
256 try
257 {
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000258 writer.flush();
259 writer.close();
Stuart McCulloch88129022009-09-03 02:52:58 +0000260
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000261 File outputFile = new File( m_repositoryXml );
Stuart McCulloch88129022009-09-03 02:52:58 +0000262 outputFile.getParentFile().mkdirs();
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000263 FileUtils.rename( file, outputFile );
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000264 }
265 catch ( IOException e )
266 {
267 e.printStackTrace();
268 throw new MojoExecutionException( "IOException" );
269 }
270
271 }
272
273
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000274 /**
275 * Parse the repository descriptor file.
276 *
277 * @throws MojoExecutionException if the plugin failed
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000278 */
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000279 public void parseRepositoryXml() throws MojoExecutionException
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000280 {
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000281 File fout = new File( m_repositoryXml );
282 if ( !fout.exists() )
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000283 {
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000284 m_repository = new RepositoryImpl();
285 writeRepositoryXml();
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000286 }
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000287 else
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000288 {
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000289 try
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000290 {
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000291 m_repository = (RepositoryImpl) new DataModelHelperImpl().repository( m_repositoryXml.toURL() );
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000292 }
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000293 catch ( Exception e )
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000294 {
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000295 throw new MojoExecutionException( "Unable to read repository xml: " + m_repositoryXml, e );
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000296 }
297 }
298 }
299
300
301 /**
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000302 * put the information from obr.xml into ressourceBundle object.
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000303 */
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000304 private void parseObrXml() throws MojoExecutionException {
305 try
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000306 {
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000307 InputStream is = new FileInputStream(new File(m_obrXml));
308 try
309 {
310 KXmlParser kxp = new KXmlParser();
311 kxp.setInput(is, null);
Guillaume Nodetbdc13752010-03-25 08:21:15 +0000312 kxp.nextTag(); // skip top level element
313 kxp.nextTag(); // go to first child element
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000314 parseObrXml(kxp);
315 }
316 finally
317 {
318 is.close();
319 }
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000320 }
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000321 catch (Exception e)
322 {
323 throw new MojoExecutionException("Unable to parse obr xml: " + m_obrXml, e);
324 }
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000325 }
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000326
327 private void parseObrXml(KXmlParser kxp) throws Exception
328 {
329 PullParser parser = new PullParser();
330 while (kxp.getEventType() == XmlPullParser.START_TAG)
331 {
332 if (RepositoryParser.CATEGORY.equals(kxp.getName()))
333 {
334 m_resourceBundle.addCategory(parser.parseCategory(kxp));
335 }
336 else if (RepositoryParser.REQUIRE.equals(kxp.getName()))
337 {
338 m_resourceBundle.addRequire(parser.parseRequire(kxp));
339 }
340 else if (RepositoryParser.CAPABILITY.equals(kxp.getName()))
341 {
342 m_resourceBundle.addCapability(parser.parseCapability(kxp));
343 }
344 else
345 {
346 kxp.nextTag();
347 parseObrXml(kxp);
348 }
349 kxp.nextTag();
350 }
351 }
352
353
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000354}