/*******************************************************************************
* Copyright (c) 2010 Neil Bartlett.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Neil Bartlett - initial API and implementation
*******************************************************************************/
package bndtools.tasks;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.bndtools.api.ILogger;
import org.bndtools.api.Logger;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.osgi.resource.Capability;
import aQute.lib.io.IO;
import bndtools.model.resolution.RequirementWrapper;
public class AnalyseBundleResolutionJob extends Job {
private static final ILogger logger = Logger.getLogger(AnalyseBundleResolutionJob.class);
private final Set< ? extends CapReqLoader> loaders;
private Map<String,List<RequirementWrapper>> requirements;
private Map<String,List<Capability>> capabilities;
public AnalyseBundleResolutionJob(String name, Set< ? extends CapReqLoader> loaders) {
super(name);
this.loaders = loaders;
}
private static <K, V> void mergeMaps(Map<K,List<V>> from, Map<K,List<V>> into) {
for (Entry<K,List<V>> entry : from.entrySet()) {
K key = entry.getKey();
List<V> list = into.get(key);
if (list == null) {
list = new ArrayList<V>();
into.put(key, list);
}
list.addAll(entry.getValue());
}
}
@Override
protected IStatus run(IProgressMonitor monitor) {
try {
// Load all the capabilities and requirements
Map<String,List<Capability>> allCaps = new HashMap<String,List<Capability>>();
Map<String,List<RequirementWrapper>> allReqs = new HashMap<String,List<RequirementWrapper>>();
for (CapReqLoader loader : loaders) {
try {
Map<String,List<Capability>> caps = loader.loadCapabilities();
mergeMaps(caps, allCaps);
Map<String,List<RequirementWrapper>> reqs = loader.loadRequirements();
mergeMaps(reqs, allReqs);
} catch (Exception e) {
logger.logError("Error in Bnd resolution analysis.", e);
} finally {
IO.close(loader);
}
}
// Check for resolved requirements
for (String namespace : allReqs.keySet()) {
List<RequirementWrapper> rws = allReqs.get(namespace);
List<Capability> candidates = allCaps.get(namespace);
if (candidates == null)
continue;
for (RequirementWrapper rw : rws) {
String filterStr = rw.requirement.getDirectives().get("filter");
if (filterStr != null) {
aQute.lib.filter.Filter filter = new aQute.lib.filter.Filter(filterStr);
for (Capability cand : candidates) {
if (filter.matchMap(cand.getAttributes())) {
rw.resolved = true;
break;
}
}
}
}
}
// Generate the final results
// Set<File> resultFiles = builderMap.keySet();
// resultFileArray = resultFiles.toArray(new File[0]);
this.requirements = allReqs;
this.capabilities = allCaps;
// showResults(resultFileArray, importResults, exportResults);
return Status.OK_STATUS;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public Map<String,List<RequirementWrapper>> getRequirements() {
return Collections.unmodifiableMap(requirements);
}
public Map<String,List<Capability>> getCapabilities() {
return Collections.unmodifiableMap(capabilities);
}
}