X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=server%2Fruntime%2Forg.argeo.server.jackrabbit%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fjackrabbit%2FJackrabbitContainer.java;h=eb090514f425aa8f3ead1045ec072e78b38a7eda;hb=149023e5969377045847bbecf24b0898b18a67a9;hp=b5170c191867ac2eddc58fdbf27b44eed2789349;hpb=5cbd14f6688e8710bff2f853e9fce3fae68c175e;p=lgpl%2Fargeo-commons.git diff --git a/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitContainer.java b/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitContainer.java index b5170c191..eb090514f 100644 --- a/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitContainer.java +++ b/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitContainer.java @@ -18,13 +18,16 @@ package org.argeo.jackrabbit; import java.io.ByteArrayInputStream; import java.io.File; +import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.Reader; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.concurrent.Executor; import javax.jcr.Credentials; import javax.jcr.LoginException; @@ -39,7 +42,6 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.jackrabbit.api.JackrabbitRepository; -import org.apache.jackrabbit.commons.JcrUtils; import org.apache.jackrabbit.commons.NamespaceHelper; import org.apache.jackrabbit.commons.cnd.CndImporter; import org.apache.jackrabbit.core.RepositoryImpl; @@ -48,11 +50,13 @@ import org.apache.jackrabbit.core.config.RepositoryConfig; import org.apache.jackrabbit.core.config.RepositoryConfigurationParser; import org.apache.jackrabbit.jcr2dav.Jcr2davRepositoryFactory; import org.argeo.ArgeoException; +import org.argeo.jcr.JcrUtils; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ResourceLoaderAware; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; +import org.springframework.util.SystemPropertyUtils; import org.xml.sax.InputSource; /** @@ -75,7 +79,6 @@ public class JackrabbitContainer implements InitializingBean, DisposableBean, private ResourceLoader resourceLoader; /** Node type definitions in CND format */ - private List cnds = new ArrayList(); private List cndFiles = new ArrayList(); /** Namespaces to register: key is prefix, value namespace */ @@ -83,59 +86,131 @@ public class JackrabbitContainer implements InitializingBean, DisposableBean, private Boolean autocreateWorkspaces = false; - public void afterPropertiesSet() throws Exception { - // Load cnds as resources - for (String resUrl : cndFiles) { - Resource res = resourceLoader.getResource(resUrl); - byte[] arr = IOUtils.toByteArray(res.getInputStream()); - cnds.add(arr); - } + private Executor systemExecutor; + private Credentials adminCredentials; + public void afterPropertiesSet() throws Exception { + // remote repository if (uri != null && !uri.trim().equals("")) { Map params = new HashMap(); - params.put(JcrUtils.REPOSITORY_URI, uri); + params.put(org.apache.jackrabbit.commons.JcrUtils.REPOSITORY_URI, + uri); repository = new Jcr2davRepositoryFactory().getRepository(params); if (repository == null) throw new ArgeoException("Remote Davex repository " + uri + " not found"); log.info("Initialized Jackrabbit repository " + repository - + " from uri " + uri); - } else { - if (inMemory && homeDirectory.exists()) { - FileUtils.deleteDirectory(homeDirectory); - log.warn("Deleted Jackrabbit home directory " + homeDirectory); + + " from URI " + uri); + // do not perform further initialization since we assume that the + // remote repository has been properly configured + return; + } + + // local repository + if (inMemory && homeDirectory.exists()) { + FileUtils.deleteDirectory(homeDirectory); + log.warn("Deleted Jackrabbit home directory " + homeDirectory); + } + + RepositoryConfig config; + Properties vars = getConfigurationProperties(); + InputStream in = configuration.getInputStream(); + try { + vars.put(RepositoryConfigurationParser.REPOSITORY_HOME_VARIABLE, + homeDirectory.getCanonicalPath()); + config = RepositoryConfig.create(new InputSource(in), vars); + } catch (Exception e) { + throw new RuntimeException("Cannot read configuration", e); + } finally { + IOUtils.closeQuietly(in); + } + + if (inMemory) + repository = new TransientRepository(config); + else + repository = RepositoryImpl.create(config); + + if (cndFiles != null && cndFiles.size() > 0) + importNodeTypeDefinitions(repository); + + log.info("Initialized Jackrabbit repository " + repository + " in " + + homeDirectory + " with config " + configuration); + } + + protected Properties getConfigurationProperties() { + InputStream propsIn = null; + Properties vars; + try { + vars = new Properties(); + if (variables != null) { + propsIn = variables.getInputStream(); + vars.load(propsIn); + } + // resolve system properties + for (Object key : vars.keySet()) { + // TODO: implement a smarter mechanism to resolve nested ${} + String newValue = SystemPropertyUtils.resolvePlaceholders(vars + .getProperty(key.toString())); + vars.put(key, newValue); } + // override with system properties + vars.putAll(System.getProperties()); + } catch (IOException e) { + throw new ArgeoException("Cannot read configuration properties", e); + } finally { + IOUtils.closeQuietly(propsIn); + } + return vars; + } + + /** + * Import declared node type definitions, trying to update them if they have + * changed. In case of failures an error will be logged but no exception + * will be thrown. + */ + protected void importNodeTypeDefinitions(final Repository repository) { + final Credentials credentialsToUse; + if (systemExecutor == null) { + if (adminCredentials == null) + throw new ArgeoException( + "No system executor or admin credentials found"); + credentialsToUse = adminCredentials; + } else { + credentialsToUse = null; + } - RepositoryConfig config; - InputStream in = configuration.getInputStream(); - InputStream propsIn = null; - try { - Properties vars = new Properties(); - if (variables != null) { - propsIn = variables.getInputStream(); - vars.load(propsIn); + Runnable action = new Runnable() { + public void run() { + Reader reader = null; + Session session = null; + try { + session = repository.login(credentialsToUse); + processNewSession(session); + // Load cnds as resources + for (String resUrl : cndFiles) { + Resource res = resourceLoader.getResource(resUrl); + byte[] arr = IOUtils.toByteArray(res.getInputStream()); + reader = new InputStreamReader( + new ByteArrayInputStream(arr)); + CndImporter.registerNodeTypes(reader, session, true); + } + session.save(); + } catch (Exception e) { + log.error( + "Cannot import node type definitions " + cndFiles, + e); + JcrUtils.discardQuietly(session); + } finally { + IOUtils.closeQuietly(reader); + JcrUtils.logoutQuietly(session); } - // override with system properties - vars.putAll(System.getProperties()); - vars.put( - RepositoryConfigurationParser.REPOSITORY_HOME_VARIABLE, - homeDirectory.getCanonicalPath()); - config = RepositoryConfig.create(new InputSource(in), vars); - } catch (Exception e) { - throw new RuntimeException("Cannot read configuration", e); - } finally { - IOUtils.closeQuietly(in); - IOUtils.closeQuietly(propsIn); } + }; - if (inMemory) - repository = new TransientRepository(config); - else - repository = RepositoryImpl.create(config); - - log.info("Initialized Jackrabbit repository " + repository + " in " - + homeDirectory + " with config " + configuration); - } + if (systemExecutor != null) + systemExecutor.execute(action); + else + action.run(); } public void destroy() throws Exception { @@ -156,7 +231,7 @@ public class JackrabbitContainer implements InitializingBean, DisposableBean, + homeDirectory); } - if (uri != null) + if (uri != null && !uri.trim().equals("")) log.info("Destroyed Jackrabbit repository with uri " + uri); else log.info("Destroyed Jackrabbit repository " + repository + " in " @@ -221,9 +296,6 @@ public class JackrabbitContainer implements InitializingBean, DisposableBean, NamespaceHelper namespaceHelper = new NamespaceHelper(session); namespaceHelper.registerNamespaces(namespaces); - for (byte[] arr : cnds) - CndImporter.registerNodeTypes(new InputStreamReader( - new ByteArrayInputStream(arr)), session, true); } catch (Exception e) { throw new ArgeoException("Cannot process new session", e); } @@ -292,4 +364,12 @@ public class JackrabbitContainer implements InitializingBean, DisposableBean, this.uri = uri; } + public void setSystemExecutor(Executor systemExecutor) { + this.systemExecutor = systemExecutor; + } + + public void setAdminCredentials(Credentials adminCredentials) { + this.adminCredentials = adminCredentials; + } + }