import static bitronix.tm.TransactionManagerServices.getTransactionManager;
import static bitronix.tm.TransactionManagerServices.getTransactionSynchronizationRegistry;
import static java.util.Locale.ENGLISH;
+import static org.argeo.cms.internal.kernel.DataModelNamespace.CMS_DATA_MODEL_NAMESPACE;
import static org.argeo.cms.internal.kernel.KernelUtils.getFrameworkProp;
import static org.argeo.cms.internal.kernel.KernelUtils.getOsgiInstanceDir;
import static org.argeo.jcr.ArgeoJcrConstants.ALIAS_NODE;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
import java.lang.management.ManagementFactory;
+import java.net.URL;
import java.security.PrivilegedAction;
import java.util.Dictionary;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Set;
import javax.jcr.ImportUUIDBehavior;
import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
import javax.jcr.RepositoryFactory;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.jackrabbit.api.JackrabbitRepository;
+import org.apache.jackrabbit.commons.cnd.CndImporter;
import org.apache.jackrabbit.util.TransientFileFactory;
import org.argeo.ArgeoException;
import org.argeo.ArgeoLogger;
import org.argeo.jackrabbit.OsgiJackrabbitRepositoryFactory;
import org.argeo.jcr.ArgeoJcrConstants;
import org.argeo.jcr.ArgeoJcrUtils;
+import org.argeo.jcr.JcrUtils;
import org.argeo.jcr.RepoConf;
import org.eclipse.equinox.http.jetty.JettyConfigurator;
import org.eclipse.equinox.http.jetty.JettyConstants;
import org.eclipse.equinox.http.servlet.ExtendedHttpService;
import org.eclipse.rap.rwt.application.ApplicationConfiguration;
+import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.framework.startlevel.BundleStartLevel;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleWire;
+import org.osgi.framework.wiring.BundleWiring;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.cm.ManagedService;
ClassLoader currentContextCl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(Kernel.class.getClassLoader());
try {
+ // Listen to service publication (also ours)
+ bc.addServiceListener(Kernel.this);
+
if (nodeSecurity.isFirstInit())
firstInit();
// HTTP
initWebServer(conf);
- ServiceReference<ExtendedHttpService> sr = bc.getServiceReference(ExtendedHttpService.class);
- if (sr != null)
- addHttpService(sr);
+ // ServiceReference<ExtendedHttpService> sr =
+ // bc.getServiceReference(ExtendedHttpService.class);
+ // if (sr != null)
+ // addHttpService(sr);
+ // else
+ // log.warn("No http service found");
// Initialise services
initTransactionManager();
Configuration nodeConf = conf.getConfiguration(ArgeoJcrConstants.REPO_PID_NODE);
if (nodeConf.getProperties() == null) {
Dictionary<String, ?> props = getNodeConfigFromFrameworkProperties();
- if(props==null)// TODO interactive configuration
+ if (props == null) {
+ // TODO interactive configuration
+ if (log.isDebugEnabled())
+ log.debug("No argeo.node.repo.type=localfs|h2|postgresql|memory"
+ + " property defined, entering interactive mode...");
return;
+ }
nodeConf.update(props);
}
} catch (IOException e) {
serviceProps.put(ArgeoJcrConstants.JCR_REPOSITORY_ALIAS, ArgeoJcrConstants.ALIAS_NODE);
ServiceRegistration<?> nodeSr = bc.registerService(clazzes, nodeRepo, serviceProps);
nodeRepo.waitForInit();
+
new JackrabbitDataModel(bc).prepareDataModel(nodeRepo);
+ prepareDataModel(nodeRepo);
repository = (JackrabbitRepository) bc.getService(nodeSr.getReference());
if (repository == null)
repository = new NodeRepository();
- if (repositoryFactory == null)
+ if (repositoryFactory == null) {
repositoryFactory = new OsgiJackrabbitRepositoryFactory();
+ repositoryFactory.setBundleContext(bc);
+ }
userAdmin = new NodeUserAdmin(transactionManager, repository);
// ADMIN UIs
}
private Dictionary<String, ?> getNodeConfigFromFrameworkProperties() {
- String repoType = KernelUtils
- .getFrameworkProp(KernelConstants.NODE_REPO_PROP_PREFIX + RepoConf.type.name());
+ String repoType = KernelUtils.getFrameworkProp(KernelConstants.NODE_REPO_PROP_PREFIX + RepoConf.type.name());
if (repoType == null)
return null;
-
+
Hashtable<String, Object> props = new Hashtable<String, Object>();
for (RepoConf repoConf : RepoConf.values()) {
String value = KernelUtils.getFrameworkProp(KernelConstants.NODE_REPO_PROP_PREFIX + repoConf.name());
return props;
}
+ private void prepareDataModel(ManagedJackrabbitRepository nodeRepo) {
+ Session adminSession = null;
+ try {
+ Set<String> processed = new HashSet<String>();
+ adminSession = nodeRepo.login();
+ bundles: for (Bundle bundle : bc.getBundles()) {
+ BundleWiring wiring = bundle.adapt(BundleWiring.class);
+ if (wiring == null) {
+ if (log.isTraceEnabled())
+ log.error("No wiring for " + bundle.getSymbolicName());
+ continue bundles;
+ }
+ processWiring(adminSession, wiring, processed);
+ }
+ } catch (RepositoryException e) {
+ throw new CmsException("Cannot prepare data model", e);
+ } finally {
+ JcrUtils.logoutQuietly(adminSession);
+ }
+ }
+
+ private void processWiring(Session adminSession, BundleWiring wiring, Set<String> processed) {
+ // recursively process requirements first
+ List<BundleWire> requiredWires = wiring.getRequiredWires(CMS_DATA_MODEL_NAMESPACE);
+ for (BundleWire wire : requiredWires) {
+ processWiring(adminSession, wire.getProviderWiring(), processed);
+ // registerCnd(adminSession, wire.getCapability(), processed);
+ }
+ List<BundleCapability> capabilities = wiring.getCapabilities(CMS_DATA_MODEL_NAMESPACE);
+ for (BundleCapability capability : capabilities) {
+ registerCnd(adminSession, capability, processed);
+ }
+ }
+
+ private void registerCnd(Session adminSession, BundleCapability capability, Set<String> processed) {
+ Map<String, Object> attrs = capability.getAttributes();
+ String name = attrs.get(DataModelNamespace.CAPABILITY_NAME_ATTRIBUTE).toString();
+ if (processed.contains(name)) {
+ if (log.isTraceEnabled())
+ log.trace("Data model " + name + " has already been processed");
+ return;
+ }
+ String path = attrs.get(DataModelNamespace.CAPABILITY_CND_ATTRIBUTE).toString();
+ URL url = capability.getRevision().getBundle().getResource(path);
+ try (Reader reader = new InputStreamReader(url.openStream())) {
+ CndImporter.registerNodeTypes(reader, adminSession, true);
+ processed.add(name);
+ if (log.isDebugEnabled())
+ log.debug("Registered CND " + url);
+ } catch (Exception e) {
+ throw new CmsException("Cannot read cnd " + url, e);
+ }
+
+ Hashtable<String, Object> properties = new Hashtable<>();
+ properties.put(ArgeoJcrConstants.JCR_REPOSITORY_ALIAS, name);
+ bc.registerService(Repository.class, adminSession.getRepository(), properties);
+ if (log.isDebugEnabled())
+ log.debug("Published data model " + name);
+ }
+
private boolean isMaintenance() {
String startLevel = KernelUtils.getFrameworkProp("osgi.startLevel");
if (startLevel == null)
@SuppressWarnings("unchecked")
private void publish() {
- // Listen to service publication (also ours)
- bc.addServiceListener(Kernel.this);
// Logging
loggerReg = bc.registerService(ArgeoLogger.class, logger, null);
props.put(key, sr.getProperty(key));
if (ServiceEvent.REGISTERED == event.getType()) {
try {
- repositoryFactory.register(repository, props);
+ // repositoryFactory.register(repository, props);
dataHttp.registerRepositoryServlets(alias, repository);
} catch (Exception e) {
throw new CmsException("Could not publish JCR repository " + alias, e);
}
} else if (ServiceEvent.UNREGISTERING == event.getType()) {
- repositoryFactory.unregister(repository, props);
+ // repositoryFactory.unregister(repository, props);
dataHttp.unregisterRepositoryServlets(alias);
}
}
Object httpPort = sr.getProperty("http.port");
Object httpsPort = sr.getProperty("https.port");
dataHttp = new DataHttp(httpService);
- nodeHttp = new NodeHttp(httpService, repository);
+ nodeHttp = new NodeHttp(httpService, bc);
if (log.isDebugEnabled())
log.debug(httpPortsMsg(httpPort, httpsPort));
}