blob: ef7100f47dff6d5d8daf02f7ee80dd14fc5abf2c [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.felix.obrplugin;
import java.io.File;
import java.io.FileFilter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import org.apache.felix.bundlerepository.Property;
import org.apache.felix.bundlerepository.Resource;
import org.apache.felix.bundlerepository.impl.DataModelHelperImpl;
import org.apache.felix.bundlerepository.impl.RepositoryImpl;
import org.apache.felix.bundlerepository.impl.ResourceImpl;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
/**
* Index the content of a maven repository using OBR
*
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
@Mojo( name = "index", requiresProject = false )
public final class ObrIndex extends AbstractMojo
{
/**
* OBR Repository.
*/
@Parameter( property = "obrRepository" )
private String obrRepository;
/**
* Template for urls
*/
@Parameter( property = "urlTemplate" )
private String urlTemplate;
/**
* The repository to index
*/
@Parameter( property = "mavenRepository" )
private String mavenRepository;
/**
* Local Repository.
*/
@Parameter( defaultValue = "${localRepository}", readonly = true, required = true )
private ArtifactRepository localRepository;
public void execute() throws MojoExecutionException
{
Log log = getLog();
try
{
log.info( "Indexing..." );
String repo = mavenRepository;
if ( repo == null )
{
repo = localRepository.getBasedir();
}
URI mavenRepoUri = new File( repo ).toURI();
URI repositoryXml = ObrUtils.findRepositoryXml( repo, obrRepository );
log.info( "Repository: " + mavenRepoUri );
log.info( "OBR xml: " + repositoryXml );
log.info( "URL template: " + urlTemplate );
List<File> files = new ArrayList<File>();
findAllJars( new File( repo ), files );
DataModelHelperImpl dmh = new DataModelHelperImpl();
RepositoryImpl repository;
File obrRepoFile = new File( repositoryXml );
if ( obrRepoFile.isFile() )
{
repository = ( RepositoryImpl ) dmh.repository( repositoryXml.toURL() );
}
else
{
repository = new RepositoryImpl();
}
for ( File file : files )
{
try
{
ResourceImpl resource = ( ResourceImpl ) dmh.createResource( file.toURI().toURL() );
if ( resource != null )
{
repository.addResource( resource );
doTemplate( mavenRepoUri, file, resource );
log.info( "Adding resource: " + file );
}
else
{
log.info( "Ignoring non OSGi bundle: " + file );
}
}
catch ( Exception e )
{
log.warn( "Error processing bundle: " + file + " " + e.getMessage() );
}
}
Writer writer = new FileWriter( obrRepoFile );
try
{
dmh.writeRepository( repository, writer );
}
finally
{
writer.close();
}
}
catch ( Exception e )
{
log.warn( "Exception while updating local OBR: " + e.getLocalizedMessage(), e );
}
}
protected void doTemplate( URI root, File path, ResourceImpl resource ) throws IOException, URISyntaxException
{
path = path.getAbsoluteFile().getCanonicalFile();
String finalUri = root.relativize( path.toURI() ).toString();
if ( "maven".equals( urlTemplate ) )
{
String dir = root.relativize( path.toURI() ).toString();
String[] p = dir.split( "/" );
if ( p.length >= 4 && p[p.length - 1].startsWith( p[p.length - 3] + "-" + p[p.length - 2] ) )
{
String artifactId = p[p.length - 3];
String version = p[p.length - 2];
String classifier;
String type;
String artifactIdVersion = artifactId + "-" + version;
StringBuffer sb = new StringBuffer();
if ( p[p.length - 1].charAt( artifactIdVersion.length() ) == '-' )
{
classifier = p[p.length - 1].substring( artifactIdVersion.length() + 1,
p[p.length - 1].lastIndexOf( '.' ) );
}
else
{
classifier = null;
}
type = p[p.length - 1].substring( p[p.length - 1].lastIndexOf( '.' ) + 1 );
sb.append( "mvn:" );
for ( int j = 0; j < p.length - 3; j++ )
{
if ( j > 0 )
{
sb.append( '.' );
}
sb.append( p[j] );
}
sb.append( '/' ).append( artifactId ).append( '/' ).append( version );
if ( !"jar".equals( type ) || classifier != null )
{
sb.append( '/' );
if ( !"jar".equals( type ) )
{
sb.append( type );
}
if ( classifier != null )
{
sb.append( '/' ).append( classifier );
}
}
finalUri = sb.toString();
}
}
else if ( urlTemplate != null )
{
URI parentDir = path.getParentFile().toURI();
String absoluteDir = trim( root.toString(), parentDir.toURL().toString() );
String relativeDir = trim( root.toString(), root.relativize( parentDir ).toString() );
String url = urlTemplate.replaceAll( "%v", "" + resource.getVersion() );
url = url.replaceAll( "%s", resource.getSymbolicName() );
url = url.replaceAll( "%f", path.getName() );
url = url.replaceAll( "%p", absoluteDir );
url = url.replaceAll( "%rp", relativeDir );
finalUri = url;
}
resource.put( Resource.URI, finalUri, Property.URI );
}
private String trim( String prefix, String path )
{
if ( path.endsWith( "/" ) )
path = path.substring( 0, path.length() - 1 );
if ( path.startsWith( prefix ) )
path = path.substring( prefix.length() );
return path;
}
private final FileFilter filter = new FileFilter()
{
public boolean accept( File pathname )
{
return pathname.getName().endsWith( "ar" );
}
};
private void findAllJars( File mainRoot, List<File> files )
{
List<File> roots = new ArrayList<File>();
roots.add( mainRoot );
while ( !roots.isEmpty() )
{
File root = roots.remove( 0 );
File[] children = root.listFiles();
if ( children != null )
{
for ( File child : children )
{
if ( child.isFile() && filter.accept( child ) )
{
files.add( child );
}
else if ( child.isDirectory() )
{
roots.add( child );
}
}
}
}
}
}