1 package org
.argeo
.cms
.internal
.kernel
;
3 import static org
.argeo
.node
.DataModelNamespace
.CMS_DATA_MODEL_NAMESPACE
;
5 import java
.util
.ArrayList
;
6 import java
.util
.Collections
;
9 import java
.util
.TreeMap
;
11 import org
.argeo
.cms
.CmsException
;
12 import org
.argeo
.node
.DataModelNamespace
;
13 import org
.osgi
.framework
.Bundle
;
14 import org
.osgi
.framework
.BundleContext
;
15 import org
.osgi
.framework
.BundleEvent
;
16 import org
.osgi
.framework
.BundleListener
;
17 import org
.osgi
.framework
.wiring
.BundleCapability
;
18 import org
.osgi
.framework
.wiring
.BundleWire
;
19 import org
.osgi
.framework
.wiring
.BundleWiring
;
21 class DataModels
implements BundleListener
{
22 private Map
<String
, DataModel
> dataModels
= new TreeMap
<>();
24 public DataModels(BundleContext bc
) {
25 for (Bundle bundle
: bc
.getBundles())
26 processBundle(bundle
);
27 bc
.addBundleListener(this);
30 public List
<DataModel
> getNonAbstractDataModels() {
31 List
<DataModel
> res
= new ArrayList
<>();
32 for (String name
: dataModels
.keySet()) {
33 DataModel dataModel
= dataModels
.get(name
);
34 if (!dataModel
.isAbstract())
42 public void bundleChanged(BundleEvent event
) {
43 if (event
.getType() == Bundle
.RESOLVED
) {
44 processBundle(event
.getBundle());
45 } else if (event
.getType() == Bundle
.UNINSTALLED
) {
46 BundleWiring wiring
= event
.getBundle().adapt(BundleWiring
.class);
47 List
<BundleCapability
> providedDataModels
= wiring
.getCapabilities(CMS_DATA_MODEL_NAMESPACE
);
48 if (providedDataModels
.size() == 0)
50 for (BundleCapability bundleCapability
: providedDataModels
) {
51 dataModels
.remove(bundleCapability
.getAttributes().get(DataModelNamespace
.NAME
));
57 protected void processBundle(Bundle bundle
) {
58 BundleWiring wiring
= bundle
.adapt(BundleWiring
.class);
59 List
<BundleCapability
> providedDataModels
= wiring
.getCapabilities(CMS_DATA_MODEL_NAMESPACE
);
60 if (providedDataModels
.size() == 0)
62 List
<BundleWire
> requiredDataModels
= wiring
.getRequiredWires(CMS_DATA_MODEL_NAMESPACE
);
63 // process requirements first
64 for (BundleWire bundleWire
: requiredDataModels
) {
65 processBundle(bundleWire
.getProvider().getBundle());
67 for (BundleCapability bundleCapability
: providedDataModels
) {
68 String name
= (String
) bundleCapability
.getAttributes().get(DataModelNamespace
.NAME
);
70 if (!dataModels
.containsKey(name
)) {
71 DataModel dataModel
= new DataModel(name
, bundleCapability
, requiredDataModels
);
72 dataModels
.put(dataModel
.getName(), dataModel
);
77 /** Return a negative depth if dataModel is required by ref, 0 otherwise. */
78 static int required(DataModel ref
, DataModel dataModel
, int depth
) {
79 for (DataModel dm
: ref
.getRequired()) {
80 if (dm
.equals(dataModel
))// found here
82 int d
= required(dm
, dataModel
, depth
- 1);
83 if (d
!= 0)// found deeper
90 private final String name
;
91 private final boolean abstrct
;
92 // private final boolean standalone;
93 private final String cnd
;
94 private final List
<DataModel
> required
;
96 private DataModel(String name
, BundleCapability bundleCapability
, List
<BundleWire
> requiredDataModels
) {
97 assert CMS_DATA_MODEL_NAMESPACE
.equals(bundleCapability
.getNamespace());
99 Map
<String
, Object
> attrs
= bundleCapability
.getAttributes();
100 abstrct
= KernelUtils
.asBoolean((String
) attrs
.get(DataModelNamespace
.ABSTRACT
));
101 // standalone = KernelUtils.asBoolean((String)
102 // attrs.get(DataModelNamespace.CAPABILITY_STANDALONE_ATTRIBUTE));
103 cnd
= (String
) attrs
.get(DataModelNamespace
.CND
);
104 List
<DataModel
> req
= new ArrayList
<>();
105 for (BundleWire wire
: requiredDataModels
) {
106 String requiredDataModelName
= (String
) wire
.getCapability().getAttributes()
107 .get(DataModelNamespace
.NAME
);
108 assert requiredDataModelName
!= null;
109 DataModel requiredDataModel
= dataModels
.get(requiredDataModelName
);
110 if (requiredDataModel
== null)
111 throw new CmsException("No required data model " + requiredDataModelName
);
112 req
.add(requiredDataModel
);
114 required
= Collections
.unmodifiableList(req
);
117 public String
getName() {
121 public boolean isAbstract() {
125 // public boolean isStandalone() {
126 // return !isAbstract();
129 public String
getCnd() {
133 public List
<DataModel
> getRequired() {
138 // public int compareTo(DataModel o) {
141 // int res = required(this, o, 0);
144 // // the other way round
145 // res = required(o, this, 0);
152 public int hashCode() {
153 return name
.hashCode();
157 public boolean equals(Object obj
) {
158 if (obj
instanceof DataModel
)
159 return ((DataModel
) obj
).name
.equals(name
);
164 public String
toString() {
165 return "Data model " + name
;