]> git.argeo.org Git - lgpl/argeo-commons.git/blob - CmsDeployment.java
b36e0f4c56b293b9391493bbb53aa550666548e2
[lgpl/argeo-commons.git] / CmsDeployment.java
1 package org.argeo.cms.internal.kernel;
2
3 import static org.argeo.node.DataModelNamespace.CMS_DATA_MODEL_NAMESPACE;
4
5 import java.io.InputStreamReader;
6 import java.io.Reader;
7 import java.net.URL;
8 import java.util.Dictionary;
9 import java.util.HashSet;
10 import java.util.Hashtable;
11 import java.util.List;
12 import java.util.Map;
13 import java.util.Set;
14
15 import javax.jcr.Repository;
16 import javax.jcr.Session;
17
18 import org.apache.commons.logging.Log;
19 import org.apache.commons.logging.LogFactory;
20 import org.apache.jackrabbit.commons.cnd.CndImporter;
21 import org.argeo.cms.CmsException;
22 import org.argeo.jcr.ArgeoJcrConstants;
23 import org.argeo.jcr.JcrUtils;
24 import org.argeo.node.DataModelNamespace;
25 import org.argeo.node.NodeDeployment;
26 import org.osgi.framework.Bundle;
27 import org.osgi.framework.BundleContext;
28 import org.osgi.framework.FrameworkUtil;
29 import org.osgi.framework.wiring.BundleCapability;
30 import org.osgi.framework.wiring.BundleWire;
31 import org.osgi.framework.wiring.BundleWiring;
32 import org.osgi.service.cm.ConfigurationException;
33 import org.osgi.service.cm.ManagedService;
34
35 public class CmsDeployment implements NodeDeployment, ManagedService {
36 private final Log log = LogFactory.getLog(getClass());
37 private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext();
38
39 private Repository deployedNodeRepository;
40 private HomeRepository homeRepository;
41
42 private Long availableSince;
43
44 @Override
45 public void updated(Dictionary<String, ?> properties) throws ConfigurationException {
46 if (properties == null)
47 return;
48
49 if (deployedNodeRepository != null) {
50 if (availableSince != null) {
51 throw new CmsException("Deployment is already available");
52 }
53
54 availableSince = System.currentTimeMillis();
55
56 prepareDataModel(KernelUtils.openAdminSession(deployedNodeRepository));
57 Hashtable<String, String> regProps = new Hashtable<String, String>();
58 regProps.put(ArgeoJcrConstants.JCR_REPOSITORY_ALIAS, ArgeoJcrConstants.ALIAS_HOME);
59 homeRepository = new HomeRepository(deployedNodeRepository);
60 // register
61 bc.registerService(Repository.class, homeRepository, regProps);
62
63 } else {
64 throw new CmsException("No node repository available");
65 }
66 }
67
68 /** Session is logged out. */
69 private void prepareDataModel(Session adminSession) {
70 try {
71 Set<String> processed = new HashSet<String>();
72 bundles: for (Bundle bundle : bc.getBundles()) {
73 BundleWiring wiring = bundle.adapt(BundleWiring.class);
74 if (wiring == null) {
75 if (log.isTraceEnabled())
76 log.error("No wiring for " + bundle.getSymbolicName());
77 continue bundles;
78 }
79 processWiring(adminSession, wiring, processed);
80 }
81 } finally {
82 JcrUtils.logoutQuietly(adminSession);
83 }
84 }
85
86 private void processWiring(Session adminSession, BundleWiring wiring, Set<String> processed) {
87 // recursively process requirements first
88 List<BundleWire> requiredWires = wiring.getRequiredWires(CMS_DATA_MODEL_NAMESPACE);
89 for (BundleWire wire : requiredWires) {
90 processWiring(adminSession, wire.getProviderWiring(), processed);
91 // registerCnd(adminSession, wire.getCapability(), processed);
92 }
93 List<BundleCapability> capabilities = wiring.getCapabilities(CMS_DATA_MODEL_NAMESPACE);
94 for (BundleCapability capability : capabilities) {
95 registerCnd(adminSession, capability, processed);
96 }
97 }
98
99 private void registerCnd(Session adminSession, BundleCapability capability, Set<String> processed) {
100 Map<String, Object> attrs = capability.getAttributes();
101 String name = attrs.get(DataModelNamespace.CAPABILITY_NAME_ATTRIBUTE).toString();
102 if (processed.contains(name)) {
103 if (log.isTraceEnabled())
104 log.trace("Data model " + name + " has already been processed");
105 return;
106 }
107 String path = attrs.get(DataModelNamespace.CAPABILITY_CND_ATTRIBUTE).toString();
108 URL url = capability.getRevision().getBundle().getResource(path);
109 try (Reader reader = new InputStreamReader(url.openStream())) {
110 CndImporter.registerNodeTypes(reader, adminSession, true);
111 processed.add(name);
112 if (log.isDebugEnabled())
113 log.debug("Registered CND " + url);
114 } catch (Exception e) {
115 throw new CmsException("Cannot import CND " + url, e);
116 }
117
118 Hashtable<String, Object> properties = new Hashtable<>();
119 properties.put(ArgeoJcrConstants.JCR_REPOSITORY_ALIAS, name);
120 bc.registerService(Repository.class, adminSession.getRepository(), properties);
121 if (log.isDebugEnabled())
122 log.debug("Published data model " + name);
123 }
124
125 public void setDeployedNodeRepository(Repository deployedNodeRepository) {
126 this.deployedNodeRepository = deployedNodeRepository;
127 }
128
129 @Override
130 public long getAvailableSince() {
131 return availableSince;
132 }
133
134 }