X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.cms%2Fsrc%2Forg%2Fargeo%2Fcms%2Finternal%2Fkernel%2FKernel.java;h=199356198e259e7eee547609b0d56cfad04b655b;hb=3cf2ac1853e37c531d3ab402c7a0ad73316e41bd;hp=c6c31ea13a14015dacaea1987828df34561d8127;hpb=3308ca9554a53ccfdb112ce3a15957005a42021c;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/Kernel.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/Kernel.java index c6c31ea13..199356198 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/Kernel.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/Kernel.java @@ -3,6 +3,7 @@ package org.argeo.cms.internal.kernel; 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; @@ -15,17 +16,23 @@ import java.io.ByteArrayOutputStream; 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; @@ -40,6 +47,7 @@ import org.apache.commons.io.FileUtils; 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; @@ -50,11 +58,13 @@ import org.argeo.jackrabbit.ManagedJackrabbitRepository; 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; @@ -62,6 +72,9 @@ import org.osgi.framework.ServiceListener; 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; @@ -202,8 +215,13 @@ final class Kernel implements KernelHeader, KernelConstants, ServiceListener { Configuration nodeConf = conf.getConfiguration(ArgeoJcrConstants.REPO_PID_NODE); if (nodeConf.getProperties() == null) { Dictionary 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) { @@ -218,14 +236,18 @@ final class Kernel implements KernelHeader, KernelConstants, ServiceListener { 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 @@ -257,6 +279,66 @@ final class Kernel implements KernelHeader, KernelConstants, ServiceListener { return props; } + private void prepareDataModel(ManagedJackrabbitRepository nodeRepo) { + Session adminSession = null; + try { + Set processed = new HashSet(); + 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 processed) { + // recursively process requirements first + List requiredWires = wiring.getRequiredWires(CMS_DATA_MODEL_NAMESPACE); + for (BundleWire wire : requiredWires) { + processWiring(adminSession, wire.getProviderWiring(), processed); + // registerCnd(adminSession, wire.getCapability(), processed); + } + List capabilities = wiring.getCapabilities(CMS_DATA_MODEL_NAMESPACE); + for (BundleCapability capability : capabilities) { + registerCnd(adminSession, capability, processed); + } + } + + private void registerCnd(Session adminSession, BundleCapability capability, Set processed) { + Map 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 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) @@ -469,13 +551,13 @@ final class Kernel implements KernelHeader, KernelConstants, ServiceListener { 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); } }