package org.bndtools.builder.indexer; import java.io.File; import java.io.InputStream; import java.io.OutputStream; import java.net.URI; import java.text.MessageFormat; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.bndtools.api.ILogger; import org.bndtools.api.Logger; import org.bndtools.build.api.AbstractBuildListener; import org.bndtools.utils.log.LogServiceAdapter; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.osgi.service.indexer.Builder; import org.osgi.service.indexer.Capability; import org.osgi.service.indexer.Requirement; import org.osgi.service.indexer.Resource; import org.osgi.service.indexer.ResourceAnalyzer; import org.osgi.service.indexer.ResourceIndexer; import org.osgi.service.indexer.impl.RepoIndex; import aQute.bnd.build.Project; import aQute.lib.io.IO; import bndtools.central.Central; import bndtools.central.WorkspaceR5Repository; public class BuiltBundleIndexer extends AbstractBuildListener { private static final String INDEX_FILENAME = ".index"; private final ILogger logger = Logger.getLogger(BuiltBundleIndexer.class); private final LogServiceAdapter logAdapter; public BuiltBundleIndexer() { logAdapter = new LogServiceAdapter(logger); } @Override public void builtBundles(final IProject project, IPath[] paths) { IWorkspaceRoot wsroot = ResourcesPlugin.getWorkspace().getRoot(); final URI workspaceRootUri = wsroot.getLocationURI(); Set<File> files = new HashSet<File>(); for (IPath path : paths) { try { IFile ifile = wsroot.getFile(path); IPath location = ifile.getLocation(); if (location != null) files.add(location.toFile()); } catch (IllegalArgumentException e) { System.err.println("### Error processing path: " + path); e.printStackTrace(); } } // Generate the index file File indexFile; try { Project model = Central.getProject(project); File target = model.getTarget(); indexFile = new File(target, INDEX_FILENAME); IFile indexPath = wsroot.getFile(Central.toPath(indexFile)); // Create the indexer and add ResourceAnalyzers from plugins RepoIndex indexer = new RepoIndex(logAdapter); List<ResourceAnalyzer> analyzers = Central.getWorkspace().getPlugins(ResourceAnalyzer.class); for (ResourceAnalyzer analyzer : analyzers) { indexer.addAnalyzer(analyzer, null); } // Use an analyzer to add a marker capability to workspace resources indexer.addAnalyzer(new ResourceAnalyzer() { @Override public void analyzeResource(Resource resource, List<Capability> capabilities, List<Requirement> requirements) throws Exception { Capability cap = new Builder().setNamespace("bndtools.workspace").addAttribute("bndtools.workspace", workspaceRootUri.toString()).addAttribute("project.path", project.getFullPath().toString()).buildCapability(); capabilities.add(cap); } }, null); Map<String,String> config = new HashMap<String,String>(); config.put(ResourceIndexer.REPOSITORY_NAME, project.getName()); config.put(ResourceIndexer.ROOT_URL, project.getLocation().toFile().toURI().toString()); config.put(ResourceIndexer.PRETTY, "true"); try (OutputStream output = IO.outputStream(indexFile)) { indexer.index(files, output, config); } indexPath.refreshLocal(IResource.DEPTH_ZERO, null); if (indexPath.exists()) indexPath.setDerived(true, null); } catch (Exception e) { logger.logError(MessageFormat.format("Failed to generate index file for bundles in project {0}.", project.getName()), e); return; } // Parse the index and add to the workspace repository try (InputStream input = IO.stream(indexFile)) { WorkspaceR5Repository workspaceRepo = Central.getWorkspaceR5Repository(); workspaceRepo.loadProjectIndex(project, input, project.getLocation().toFile().toURI()); } catch (Exception e) { logger.logError("Failed to update workspace index.", e); } } }