Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
aQute.bnd.runtime.gogo.DS Maven / Gradle / Ivy
package aQute.bnd.runtime.gogo;
import java.io.Closeable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.felix.service.command.Descriptor;
import org.apache.felix.service.command.Parameter;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.dto.ServiceReferenceDTO;
import org.osgi.service.component.runtime.ServiceComponentRuntime;
import org.osgi.service.component.runtime.dto.ComponentConfigurationDTO;
import org.osgi.service.component.runtime.dto.ComponentDescriptionDTO;
import org.osgi.service.component.runtime.dto.ReferenceDTO;
import org.osgi.service.component.runtime.dto.SatisfiedReferenceDTO;
import org.osgi.service.component.runtime.dto.UnsatisfiedReferenceDTO;
import org.osgi.util.tracker.ServiceTracker;
import aQute.lib.dtoformatter.DTOFormatter;
import aQute.lib.dtoformatter.Wrapper;
import aQute.lib.strings.Strings;
public class DS implements Closeable {
final ServiceTracker scr;
final BundleContext context;
final AtomicLong componentDescriptionNextIndex = new AtomicLong(
-1);
final Map descriptionToIndex = new HashMap<>();
public DS(BundleContext context, DTOFormatter formatter) {
this.context = context;
dtos(formatter);
scr = new ServiceTracker<>(context, ServiceComponentRuntime.class, null);
scr.open();
}
@Descriptor("Show the list of available components")
public Object ds(@Parameter(names = {
"-c", "--config"
}, presentValue = "true", absentValue = "false") boolean configs, @Parameter(names = {
"-b", "--bundle"
}, absentValue = "0") Bundle bs[]) {
if (bs == null || bs.length == 1 && bs[0].getBundleId() == 0)
bs = new Bundle[0];
if (configs) {
return getScr().getComponentDescriptionDTOs(bs);
} else {
return getScr().getComponentDescriptionDTOs(bs)
.stream()
.flatMap(d -> getScr().getComponentConfigurationDTOs(d)
.stream())
.collect(Collectors.toList());
}
}
//
// The SCR overrides the formatter
//
@Descriptor("Show ds components")
public Wrapper ds(long component) {
if (component >= 0)
return new Wrapper(dsConfig(component));
else
return new Wrapper(getDescription(component));
}
private ComponentConfigurationDTO dsConfig(long component) {
return getScr().getComponentDescriptionDTOs()
.stream()
.flatMap(d -> getScr().getComponentConfigurationDTOs(d)
.stream())
.filter(c -> component == c.id)
.findFirst()
.orElse(null);
}
public static class Why {
public ComponentDescriptionDTO description;
public ComponentConfigurationDTO configuration;
public String reason;
public List references = new ArrayList<>();
}
public static class WhyReference {
public WhyReference(String name, List candidates) {
this.name = name;
this.candidates = candidates;
}
public String name;
public List candidates;
}
@Descriptor("show a dependency tree if not satisfied")
public List why(long component) {
ComponentConfigurationDTO ds = dsConfig(component);
if (ds == null)
return null;
Why why = why(ds, new HashSet<>());
return why.references;
}
Why why(ComponentConfigurationDTO ds, Set set) {
if (!set.add(ds))
return null;
Why why = new Why();
why.description = ds.description;
why.configuration = ds;
for (UnsatisfiedReferenceDTO unsatisfiedReference : ds.unsatisfiedReferences) {
ReferenceDTO ref = getReference(ds.description, unsatisfiedReference.name);
why.references.add(new WhyReference(ref.name, candidates(ref, set)));
}
return why;
}
private List candidates(ReferenceDTO ref, Set set) {
List candidates = new ArrayList<>();
List collect = getScr().getComponentDescriptionDTOs()
.stream()
.filter(cd -> Strings.in(cd.serviceInterfaces, ref.interfaceName))
.collect(Collectors.toList());
for (ComponentDescriptionDTO d : collect) {
if ("REQUIRE".equals(d.configurationPolicy)) {
Why required = new Why();
required.description = d;
required.reason = "may require configuration";
candidates.add(required);
}
for (ComponentConfigurationDTO c : getScr().getComponentConfigurationDTOs(d)) {
Why why = why(c, set);
if (why == null) {
Why cycle = new Why();
cycle.description = d;
cycle.configuration = c;
cycle.reason = "cycle";
candidates.add(cycle);
} else
candidates.add(why);
}
}
return candidates;
}
private ReferenceDTO getReference(ComponentDescriptionDTO description, String name) {
return Stream.of(description.references)
.filter(r -> r.name.equals(name))
.findFirst()
.orElseThrow(() -> new IllegalStateException(
"the description " + description + " does not have the reference named " + name));
}
private ServiceComponentRuntime getScr() {
return scr.getService();
}
@Override
public void close() throws IOException {
scr.close();
}
void dtos(DTOFormatter formatter) {
formatter.build(ComponentDescriptionDTO.class)
.inspect()
.fields("*")
.line()
.format("id", this::getId)
.format("bundle", cd -> cd.bundle.id)
.field("name")
.field("defaultEnabled")
.field("immediate")
.field("activate")
.field("modified")
.field("deactivate")
.field("configurationPolicy")
.field("configurationPid")
.field("references")
.count()
.part()
.as(cdd -> String.format("[%s] %s", cdd.bundle.id, cdd.name));
formatter.build(ComponentConfigurationDTO.class)
.inspect()
.format("state", this::state)
.fields("*")
.line()
.field("id")
.format("state", this::state)
.format("service", c -> DisplayUtil.objectClass(c.description.serviceInterfaces))
.fields("*")
.remove("properties")
.remove("description")
.format("unsatisfiedReferences", this::unsatisfied)
.part()
.as(c -> "<" + c.id + "> " + c.description.name);
formatter.build(SatisfiedReferenceDTO.class)
.inspect()
.fields("*")
.line()
.fields("*")
.format("boundServices", u -> shortend(u.boundServices))
.part()
.as(sr -> sr.name);
formatter.build(ServiceReferenceDTO.class)
.inspect()
.fields("*")
.line()
.format("id", srd -> srd.id + "")
.format("service", srd -> DisplayUtil.objectClass(srd.properties))
.part()
.as(sr -> "(" + sr.id + ")" + DisplayUtil.objectClass(sr.properties));
formatter.build(UnsatisfiedReferenceDTO.class)
.inspect()
.fields("*")
.line()
.fields("*")
.part()
.as(sr -> sr.name);
formatter.build(ReferenceDTO.class)
.inspect()
.fields("*")
.line()
.fields("*")
.part()
.field("name");
formatter.build(Unsatisfied.class)
.inspect()
.fields("*")
.line()
.fields("*")
.part()
.as(u -> u.name);
formatter.build(Why.class)
.inspect()
.fields("*")
.line()
.format("description", w -> getId(w.description))
.format("configuration", w -> w.configuration == null ? "" : w.configuration.id)
.field("reason")
.field("references")
.part()
.as(w -> "<<" + getId(w.description) + ">>");
formatter.build(WhyReference.class)
.inspect()
.fields("*")
.line()
.field("name")
.field("candidates")
.part()
.field("name");
}
static class ComponentDescriptionId {
private final String name;
private final Bundle bundle;
ComponentDescriptionId(String name, Bundle bundle) {
this.name = name;
this.bundle = bundle;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((bundle == null) ? 0 : bundle.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ComponentDescriptionId other = (ComponentDescriptionId) obj;
return Objects.equals(bundle, other.bundle) && Objects.equals(name, other.name);
}
}
long getId(ComponentDescriptionDTO description) {
return descriptionToIndex.computeIfAbsent(
new ComponentDescriptionId(description.name, context.getBundle(description.bundle.id)),
d -> componentDescriptionNextIndex.getAndDecrement());
}
ComponentDescriptionDTO getDescription(long id) {
return descriptionToIndex.entrySet()
.stream()
.filter(e -> e.getValue() == id)
.map(Entry::getKey)
.findFirst()
.map(cdi -> getScr().getComponentDescriptionDTO(cdi.bundle, cdi.name))
.orElse(null);
}
public static class Unsatisfied {
public String name;
public String interfaceName;
public String cardinality;
public String target;
public List candidates;
public String remark;
}
private List unsatisfied(ComponentConfigurationDTO c) {
return Stream.of(c.unsatisfiedReferences)
.map(ur -> unsatisfied(c.description, ur))
.collect(Collectors.toList());
}
private Unsatisfied unsatisfied(ComponentDescriptionDTO description, UnsatisfiedReferenceDTO r) {
Unsatisfied u = new Unsatisfied();
try {
ReferenceDTO ref = find(description, r.name);
u.name = r.name;
u.target = r.target;
u.interfaceName = DisplayUtil.shorten(ref.interfaceName);
u.cardinality = ref.cardinality;
u.candidates = getServiceCandidates(r, ref);
} catch (InvalidSyntaxException e) {
u.remark = e.toString();
}
return u;
}
private List getServiceCandidates(UnsatisfiedReferenceDTO r, ReferenceDTO ref) throws InvalidSyntaxException {
ServiceReference>[] serviceReferences = context.getServiceReferences(ref.interfaceName, r.target);
if (serviceReferences == null)
serviceReferences = new ServiceReference>[0];
return Stream.of(serviceReferences)
.map(x -> (Long) x.getProperty(Constants.SERVICE_ID))
.collect(Collectors.toList());
}
private ReferenceDTO find(ComponentDescriptionDTO description, String name) {
for (ReferenceDTO r : description.references) {
if (r.name.equals(name))
return r;
}
throw new IllegalStateException("Not supposed to happen");
}
private List shortend(ServiceReferenceDTO[] refs) {
return Stream.of(refs)
.map(r -> "<" + r.id + "> " + DisplayUtil.objectClass(r.properties))
.collect(Collectors.toList());
}
private String state(ComponentConfigurationDTO c) {
switch (c.state) {
case ComponentConfigurationDTO.ACTIVE :
return "ACTIVE";
case ComponentConfigurationDTO.UNSATISFIED_CONFIGURATION :
return "CONFG?";
case ComponentConfigurationDTO.UNSATISFIED_REFERENCE :
return "REFRN?";
case ComponentConfigurationDTO.SATISFIED :
return "SATSFD";
default :
return c.state + "?";
}
}
}