ObrUpdate xref

    1   /*
    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   */
    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.net.URI;
    30
    31  import org.apache.felix.bundlerepository.Resource;
    32  import org.apache.felix.bundlerepository.impl.DataModelHelperImpl;
    33  import org.apache.felix.bundlerepository.impl.PullParser;
    34  import org.apache.felix.bundlerepository.impl.RepositoryImpl;
    35  import org.apache.felix.bundlerepository.impl.RepositoryParser;
    36  import org.apache.felix.bundlerepository.impl.ResourceImpl;
    37  import org.apache.maven.plugin.MojoExecutionException;
    38  import org.apache.maven.plugin.logging.Log;
    39  import org.apache.maven.project.MavenProject;
    40  import org.codehaus.plexus.util.FileUtils;
    41  import org.kxml2.io.KXmlParser;
    42  import org.xmlpull.v1.XmlPullParser;
    43
    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   */
    49  public class ObrUpdate
    50  {
    51      /**
    52       * 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      /**
    67       * maven project description.
    68       */
    69      private MavenProject m_project;
    70
    71      /**
    72       * user configuration information.
    73       */
    74      private Config m_userConfig;
    75
    76      /**
    77       * root on parent document.
    78       */
    79      private RepositoryImpl m_repository;
    80
    81      /**
    82       * used to store bundle information.
    83       */
    84      private ResourceImpl m_resourceBundle;
    85
    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
    97       * @param mavenRepositoryPath path to the local maven repository
    98       * @param userConfig user information
    99       * @param logger plugin logger
    100      */
    101     public ObrUpdate( URI repositoryXml, URI obrXml, MavenProject project, String mavenRepositoryPath,
    102         Config userConfig, Log logger )
    103     {
    104         m_repositoryXml = repositoryXml;
    105         m_obrXml = obrXml;
    106         m_project = project;
    107         m_logger = logger;
    108
    109         m_userConfig = userConfig;
    110
    111         if ( userConfig.isRemoteFile() )
    112         {
    113             m_baseURI = ObrUtils.toFileURI( mavenRepositoryPath );
    114         }
    115         else
    116         {
    117             m_baseURI = m_repositoryXml;
    118         }
    119     }
    120
    121
    122     /**
    123      * 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
    129      * @param docJar path to the docs jar file
    130      *
    131      * @throws MojoExecutionException if the plugin failed
    132      */
    133     public void updateRepository( URI bundleJar, URI sourceJar, URI docJar ) throws MojoExecutionException
    134     {
    135         m_logger.debug( " (f) repositoryXml = " + m_repositoryXml );
    136         m_logger.debug( " (f) bundleJar = " + bundleJar );
    137         m_logger.debug( " (f) sourceJar = " + sourceJar );
    138         m_logger.debug( " (f) obrXml = " + m_obrXml );
    139
    140         if ( m_repository == null )
    141         {
    142             return;
    143         }
    144
    145         // get the file size
    146         File bundleFile = new File( bundleJar );
    147         if ( bundleFile.exists() )
    148         {
    149             URI resourceURI = m_userConfig.getRemoteBundle();
    150             if ( null == resourceURI )
    151             {
    152                 resourceURI = bundleJar;
    153                 if ( m_userConfig.isPathRelative() )
    154                 {
    155                     resourceURI = ObrUtils.getRelativeURI( m_baseURI, resourceURI );
    156                 }
    157             }
    158
    159             if ( m_userConfig.isRemoteFile() )
    160             {
    161                 m_logger.info( "Deploying " + resourceURI );
    162             }
    163             else
    164             {
    165                 m_logger.info( "Installing " + resourceURI );
    166             }
    167
    168             try
    169             {
    170                 m_resourceBundle = ( ResourceImpl ) new DataModelHelperImpl().createResource( bundleJar.toURL() );
    171                 if ( m_resourceBundle == null )
    172                 {
    173                     return;
    174                 }
    175             }
    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() );
    183         }
    184         else
    185         {
    186             m_logger.error( "file doesn't exist: " + bundleJar );
    187             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
    198             // add contents to resource bundle
    199             parseObrXml();
    200         }
    201
    202         String sourcePath = relativisePath( sourceJar );
    203         String docPath = relativisePath( docJar );
    204
    205         //        m_resourceBundle.construct( m_project, bindexExtractor, sourcePath, docPath );
    206         //         TODO: rebuild wrt m_project
    207
    208         m_repository.addResource( m_resourceBundle );
    209         m_repository.setLastModified( System.currentTimeMillis() );
    210     }
    211
    212
    213     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
    229     public void writeRepositoryXml() throws MojoExecutionException
    230     {
    231         m_logger.info( "Writing OBR metadata" );
    232
    233         File file = null;
    234         Writer writer;
    235         try
    236         {
    237             file = File.createTempFile( "repository", ".xml" );
    238             writer = new OutputStreamWriter( new FileOutputStream( file ) );
    239         }
    240         catch ( IOException e )
    241         {
    242             m_logger.error( "Unable to write to file: " + file.getName() );
    243             e.printStackTrace();
    244             throw new MojoExecutionException( "Unable to write to file: " + file.getName() + " : " + e.getMessage() );
    245         }
    246
    247         try
    248         {
    249             new DataModelHelperImpl().writeRepository( m_repository, writer );
    250         }
    251         catch ( IOException e )
    252         {
    253             throw new MojoExecutionException( "Unable to write repository xml", e );
    254         }
    255
    256         try
    257         {
    258             writer.flush();
    259             writer.close();
    260
    261             File outputFile = new File( m_repositoryXml );
    262             outputFile.getParentFile().mkdirs();
    263             FileUtils.rename( file, outputFile );
    264         }
    265         catch ( IOException e )
    266         {
    267             e.printStackTrace();
    268             throw new MojoExecutionException( "IOException" );
    269         }
    270
    271     }
    272
    273
    274     /**
    275       * Parse the repository descriptor file.
    276       *
    277       * @throws MojoExecutionException if the plugin failed
    278       */
    279     public void parseRepositoryXml() throws MojoExecutionException
    280     {
    281         File fout = new File( m_repositoryXml );
    282         if ( !fout.exists() )
    283         {
    284             m_repository = new RepositoryImpl();
    285             writeRepositoryXml();
    286         }
    287         else
    288         {
    289             try
    290             {
    291                 m_repository = ( RepositoryImpl ) new DataModelHelperImpl().repository( m_repositoryXml.toURL() );
    292             }
    293             catch ( Exception e )
    294             {
    295                 throw new MojoExecutionException( "Unable to read repository xml: " + m_repositoryXml, e );
    296             }
    297         }
    298     }
    299
    300
    301     /**
    302      * put the information from obr.xml into ressourceBundle object.
    303      */
    304     private void parseObrXml() throws MojoExecutionException
    305     {
    306         try
    307         {
    308             InputStream is = new FileInputStream( new File( m_obrXml ) );
    309             try
    310             {
    311                 KXmlParser kxp = new KXmlParser();
    312                 kxp.setInput( is, null );
    313                 kxp.nextTag(); // skip top level element
    314                 kxp.nextTag(); // go to first child element
    315                 parseObrXml( kxp );
    316             }
    317             finally
    318             {
    319                 is.close();
    320             }
    321         }
    322         catch ( Exception e )
    323         {
    324             throw new MojoExecutionException( "Unable to parse obr xml: " + m_obrXml, e );
    325         }
    326     }
    327
    328
    329     private void parseObrXml( KXmlParser kxp ) throws Exception
    330     {
    331         PullParser parser = new PullParser();
    332         while ( kxp.getEventType() == XmlPullParser.START_TAG )
    333         {
    334             if ( RepositoryParser.CATEGORY.equals( kxp.getName() ) )
    335             {
    336                 m_resourceBundle.addCategory( parser.parseCategory( kxp ) );
    337             }
    338             else if ( RepositoryParser.REQUIRE.equals( kxp.getName() ) )
    339             {
    340                 m_resourceBundle.addRequire( parser.parseRequire( kxp ) );
    341             }
    342             else if ( RepositoryParser.CAPABILITY.equals( kxp.getName() ) )
    343             {
    344                 m_resourceBundle.addCapability( parser.parseCapability( kxp ) );
    345             }
    346             else
    347             {
    348                 kxp.nextTag();
    349                 parseObrXml( kxp );
    350             }
    351             kxp.nextTag();
    352         }
    353     }
    354
    355 }