package org.osgi.impl.bundle.repoindex.ant;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.Reader;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.FileSet;
import org.osgi.framework.BundleContext;
import org.osgi.framework.launch.Framework;
import org.osgi.service.indexer.ResourceAnalyzer;
import org.osgi.service.indexer.ResourceIndexer;
import org.osgi.service.indexer.impl.KnownBundleAnalyzer;
import org.osgi.util.tracker.ServiceTracker;
import de.kalpatec.pojosr.framework.PojoServiceRegistryFactoryImpl;
import de.kalpatec.pojosr.framework.launch.ClasspathScanner;
import de.kalpatec.pojosr.framework.launch.PojoServiceRegistryFactory;
@SuppressWarnings("restriction")
public class RepoIndexTask extends Task {
private final List<FileSet> fileSets = new LinkedList<FileSet>();
private final Map<String,String> config = new HashMap<String,String>();
private File repositoryFile = null;
private boolean knownBundles;
private boolean builtInknownBundles = true;
private String additionalKnownBundles;
public void setName(String name) {
config.put(ResourceIndexer.REPOSITORY_NAME, name);
}
public void setVerbose(boolean verbose) {
config.put(ResourceIndexer.VERBOSE, Boolean.toString(verbose));
}
public void setPretty(boolean pretty) {
config.put(ResourceIndexer.PRETTY, Boolean.toString(pretty));
}
public void setCompressed(boolean compressed) {
config.put(ResourceIndexer.COMPRESSED, Boolean.toString(compressed));
}
public void setRootURL(String root) {
config.put(ResourceIndexer.ROOT_URL, root);
}
public void setOut(String outFile) {
this.repositoryFile = new File(outFile);
}
public void addFileset(FileSet fs) {
fileSets.add(fs);
}
public void setKnownBundles(boolean knownBundles) {
this.knownBundles = knownBundles;
}
public void setBuiltInKnownBundles(boolean builtInknownBundles) {
this.builtInknownBundles = builtInknownBundles;
}
public void setAdditionalKnownBundles(String additionalKnownBundles) {
this.additionalKnownBundles = additionalKnownBundles;
}
@Override
public void execute() throws BuildException {
printCopyright(System.err);
if (repositoryFile == null)
throw new BuildException("Output file not specified");
try {
// Configure PojoSR
Map<String,Object> pojoSrConfig = new HashMap<String,Object>();
pojoSrConfig.put(PojoServiceRegistryFactory.BUNDLE_DESCRIPTORS, new ClasspathScanner());
// Start PojoSR 'framework'
Framework framework = new PojoServiceRegistryFactoryImpl().newFramework(pojoSrConfig);
framework.init();
framework.start();
if (knownBundles) {
registerKnownBundles(framework.getBundleContext());
}
// Look for indexer and run index generation
ServiceTracker<ResourceIndexer,ResourceIndexer> tracker = new ServiceTracker<ResourceIndexer,ResourceIndexer>(
framework.getBundleContext(), ResourceIndexer.class, null);
tracker.open();
ResourceIndexer index = tracker.waitForService(1000);
if (index == null)
throw new IllegalStateException("Timed out waiting for ResourceIndexer service.");
// Flatten the file sets into a single list
Set<File> fileList = new LinkedHashSet<File>();
for (FileSet fileSet : fileSets) {
DirectoryScanner ds = fileSet.getDirectoryScanner(getProject());
File basedir = ds.getBasedir();
String[] files = ds.getIncludedFiles();
for (int i = 0; i < files.length; i++)
fileList.add(new File(basedir, files[i]));
}
// Run
try (OutputStream fos = Files.newOutputStream(repositoryFile.toPath())) {
index.index(fileList, fos, config);
}
} catch (Exception e) {
throw new BuildException(e);
}
}
private void registerKnownBundles(BundleContext bundleContext) {
KnownBundleAnalyzer kba = builtInknownBundles ? new KnownBundleAnalyzer()
: new KnownBundleAnalyzer(new Properties());
if (additionalKnownBundles != null) {
File extras = new File(additionalKnownBundles);
if (extras.exists()) {
Properties props = new Properties();
try (Reader r = new FileReader(extras)) {
props.load(r);
kba.setKnownBundlesExtra(props);
} catch (IOException e) {
throw new BuildException("Unable to load the additional known bundles " + additionalKnownBundles,
e);
}
} else {
throw new BuildException(
"The additional known bundles file " + additionalKnownBundles + " does not exist.");
}
}
bundleContext.registerService(ResourceAnalyzer.class, kba, null);
}
public static void printCopyright(PrintStream out) {
out.println("Bindex2 | Resource Indexer v1.0");
out.println("(c) 2012 OSGi, All Rights Reserved");
}
}