aQute.bnd.component.MergedRequirement Maven / Gradle / Ivy
The newest version!
package aQute.bnd.component;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import aQute.bnd.header.Attrs;
import aQute.bnd.osgi.Constants;
import aQute.libg.tuple.Pair;
/**
* Merge together requirements having the same filter: and effective:
* directives, but possibly differing in optionality/cardinality. Any mandatory
* requirement will override an optional requirement, and any multiple
* cardinality will override single.
*/
public class MergedRequirement {
private static final String MULTIPLE = "\"multiple\"";
private static final String OPTIONAL = "\"optional\"";
private static class FilterEffectivePair extends Pair {
private static final long serialVersionUID = 1L;
FilterEffectivePair(String filter, String effective) {
super(filter, effective);
}
}
private final Map filterMap = new LinkedHashMap<>();
private final String namespace;
public MergedRequirement(String namespace) {
this.namespace = namespace;
}
/**
* Add a requirement to the mix.
*/
public void put(String filter, String effective, boolean optional, boolean multiple) {
FilterEffectivePair key = new FilterEffectivePair(filter, effective);
Attrs existing = filterMap.get(key);
if (existing != null) {
// any mandatory requirement makes the whole thing mandatory
boolean existingOptional = OPTIONAL.equals(existing.get(Constants.RESOLUTION_DIRECTIVE));
optional = optional && existingOptional;
// any single multiple requirement makes the whole thing multiple
boolean existingMultiple = MULTIPLE.equals(existing.get(Constants.CARDINALITY_DIRECTIVE));
multiple = multiple || existingMultiple;
}
Attrs newAttrs = new Attrs();
newAttrs.put(Constants.FILTER_DIRECTIVE, '"' + filter + '"');
if (effective != null)
newAttrs.put(Constants.EFFECTIVE_DIRECTIVE, '"' + effective + '"');
if (optional)
newAttrs.put(Constants.RESOLUTION_DIRECTIVE, OPTIONAL);
if (multiple)
newAttrs.put(Constants.CARDINALITY_DIRECTIVE, MULTIPLE);
filterMap.put(key, newAttrs);
}
/**
* Generate a list of strings formatted appropriately as entries in the
* Require-Capability header.
*/
public List toStringList() {
List strings = new ArrayList<>(filterMap.size());
for (Entry entry : filterMap.entrySet()) {
Attrs attrs = entry.getValue();
strings.add(new StringBuilder().append(namespace)
.append(';')
.append(attrs)
.toString());
}
return strings;
}
}