blob: 6bfbb451d3d595f4f678c2721a084940ded39abf [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;
/**
* Index the content of a maven repository using OBR
*
* @goal index
* @requiresProject false
*
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
public final class ObrIndex extends AbstractMojo {
/**
* OBR Repository.
*
* @parameter expression="${obrRepository}"
*/
private String obrRepository;
/**
* Template for urls
*
* @parameter expression="${urlTemplate}"
*/
private String urlTemplate;
/**
* Local Repository.
*
* @parameter expression="${localRepository}"
* @required
* @readonly
*/
private ArtifactRepository localRepository;
public void execute() throws MojoExecutionException {
Log log = getLog();
try
{
log.info("Indexing...");
String mavenRepository = localRepository.getBasedir();
URI mavenRepoUri = new File(mavenRepository).toURI();
URI repositoryXml = ObrUtils.findRepositoryXml( mavenRepository, obrRepository );
log.info("Repository: " + mavenRepoUri);
log.info("OBR xml: " + repositoryXml);
log.info("URL template: " + urlTemplate);
List<File> files = new ArrayList<File>();
findAllJars( new File(mavenRepository), files );
DataModelHelperImpl dmh = new DataModelHelperImpl();
RepositoryImpl repository = (RepositoryImpl) dmh.repository( repositoryXml.toURL() );
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( new File(repositoryXml) );
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)
{
String dir = path.getParentFile().toURI().toURL().toString();
if (dir.endsWith("/"))
dir = dir.substring(0, dir.length() - 1);
if (dir.startsWith(root.toString()))
dir = dir.substring(root.toString().length());
String url = urlTemplate.replaceAll("%v", "" + resource.getVersion());
url = url.replaceAll("%s", resource.getSymbolicName());
url = url.replaceAll("%f", path.getName());
url = url.replaceAll("%p", dir);
finalUri = url;
}
resource.put(Resource.URI, finalUri, Property.URI);
}
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);
}
}
}
}
}
}