From 2054b40150d0def0ac299ffb3b08054d7b239f54 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Fri, 13 Jan 2012 18:21:47 +0000 Subject: [PATCH] Start refactoring Jackrabbit container git-svn-id: https://svn.argeo.org/commons/trunk@4972 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- .../argeo/jackrabbit/JackrabbitContainer.java | 486 +++++------------- .../argeo/jackrabbit/JackrabbitWrapper.java | 388 ++++++++++++++ 2 files changed, 513 insertions(+), 361 deletions(-) create mode 100644 server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitWrapper.java 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 70bc300a1..82648998b 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 @@ -16,7 +16,6 @@ package org.argeo.jackrabbit; -import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -27,11 +26,8 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Properties; import java.util.Set; import java.util.TreeSet; -import java.util.UUID; -import java.util.concurrent.Executor; import javax.jcr.Credentials; import javax.jcr.LoginException; @@ -41,9 +37,7 @@ import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.SimpleCredentials; -import javax.jcr.Value; -import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -51,9 +45,6 @@ import org.apache.jackrabbit.api.JackrabbitRepository; import org.apache.jackrabbit.commons.NamespaceHelper; import org.apache.jackrabbit.commons.cnd.CndImporter; import org.apache.jackrabbit.core.RepositoryImpl; -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.ArgeoNames; import org.argeo.jcr.JcrUtils; @@ -68,28 +59,20 @@ import org.springframework.security.Authentication; import org.springframework.security.context.SecurityContextHolder; import org.springframework.security.providers.UsernamePasswordAuthenticationToken; import org.springframework.util.SystemPropertyUtils; -import org.xml.sax.InputSource; /** * Wrapper around a Jackrabbit repository which allows to configure it in Spring * and expose it as a {@link Repository}. */ -public class JackrabbitContainer implements Repository { +public class JackrabbitContainer extends JackrabbitWrapper { private Log log = LogFactory.getLog(JackrabbitContainer.class); // remote - private String uri = null; private Credentials remoteSystemCredentials = null; // local private Resource configuration; - private RepositoryConfig repositoryConfig; - private File homeDirectory; private Resource variables; - private Boolean inMemory = false; - - // wrapped repository - private Repository repository; // data model /** Node type definitions in CND format */ @@ -101,8 +84,6 @@ public class JackrabbitContainer implements Repository { /** Namespaces to register: key is prefix, value namespace */ private Map namespaces = new HashMap(); - private Boolean autocreateWorkspaces = false; - private BundleContext bundleContext; /** @@ -122,15 +103,13 @@ public class JackrabbitContainer implements Repository { init(); } - /** Initializes */ - public void init() { - if (repository != null) { - // we are just wrapping another repository - prepareDataModel(); - return; - } + @Override + protected void postInitWrapped() { + prepareDataModel(); + } - createJackrabbitRepository(); + @Override + protected void postInitNew() { // migrate if needed migrate(); @@ -139,218 +118,10 @@ public class JackrabbitContainer implements Repository { prepareDataModel(); } - /** Actually creates the new repository. */ - protected void createJackrabbitRepository() { - long begin = System.currentTimeMillis(); - InputStream configurationIn = null; - try { - if (uri != null && !uri.trim().equals("")) {// remote - Map params = new HashMap(); - 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); - // we assume that the remote repository has been properly - // configured - } else {// local - // reset uri to null in order to optimize isRemote() - uri = null; - - // temporary - if (inMemory && getHomeDirectory().exists()) { - FileUtils.deleteDirectory(getHomeDirectory()); - log.warn("Deleted Jackrabbit home directory " - + getHomeDirectory()); - } - - // process configuration file - Properties vars = getConfigurationProperties(); - configurationIn = configuration.getInputStream(); - vars.put( - RepositoryConfigurationParser.REPOSITORY_HOME_VARIABLE, - getHomeDirectory().getCanonicalPath()); - repositoryConfig = RepositoryConfig.create(new InputSource( - configurationIn), vars); - - // - // Actual repository creation - // - repository = RepositoryImpl.create(repositoryConfig); - - double duration = ((double) (System.currentTimeMillis() - begin)) / 1000; - log.info("Initialized Jackrabbit repository in " + duration - + " s, home: " + getHomeDirectory() + ", config: " - + configuration); - } - } catch (Exception e) { - throw new ArgeoException("Cannot create Jackrabbit repository " - + getHomeDirectory(), e); - } finally { - IOUtils.closeQuietly(configurationIn); - } - } - - /** Executes migrations, if needed. */ - protected void migrate() { - // Remote migration not supported - if (isRemote()) - return; - - // No migration to perform - if (dataModelMigrations.size() == 0) - return; - - Boolean restartAndClearCaches = false; - - // migrate data - Session session = null; - try { - session = login(); - for (JackrabbitDataModelMigration dataModelMigration : new TreeSet( - dataModelMigrations)) { - if (dataModelMigration.migrate(session)) { - restartAndClearCaches = true; - } - } - } catch (ArgeoException e) { - throw e; - } catch (Exception e) { - throw new ArgeoException("Cannot migrate", e); - } finally { - JcrUtils.logoutQuietly(session); - } - - // restart repository - if (restartAndClearCaches) { - JackrabbitDataModelMigration - .clearRepositoryCaches(repositoryConfig); - ((JackrabbitRepository) repository).shutdown(); - createJackrabbitRepository(); - } - - // set data model version - try { - session = login(); - } catch (RepositoryException e) { - throw new ArgeoException("Cannot login to migrated repository", e); - } - - for (JackrabbitDataModelMigration dataModelMigration : new TreeSet( - dataModelMigrations)) { - try { - if (session.itemExists(dataModelMigration - .getDataModelNodePath())) { - Node dataModelNode = session.getNode(dataModelMigration - .getDataModelNodePath()); - dataModelNode.setProperty( - ArgeoNames.ARGEO_DATA_MODEL_VERSION, - dataModelMigration.getTargetVersion()); - session.save(); - } - } catch (Exception e) { - log.error("Cannot set model version", e); - } - } - JcrUtils.logoutQuietly(session); - - } - - /** Lazy init. */ - protected File getHomeDirectory() { - try { - if (homeDirectory == null) { - if (inMemory) { - homeDirectory = new File( - System.getProperty("java.io.tmpdir") - + File.separator - + System.getProperty("user.name") - + File.separator + "jackrabbit-" - + UUID.randomUUID()); - homeDirectory.mkdirs(); - // will it work if directory is not empty?? - homeDirectory.deleteOnExit(); - } - } - - return homeDirectory.getCanonicalFile(); - } catch (IOException e) { - throw new ArgeoException("Cannot get canonical file for " - + homeDirectory, e); - } - } - - /** Shutdown the repository */ - public void destroy() throws Exception { - if (repository != null && repository instanceof RepositoryImpl) { - long begin = System.currentTimeMillis(); - ((RepositoryImpl) repository).shutdown(); - if (inMemory) - if (getHomeDirectory().exists()) { - FileUtils.deleteDirectory(getHomeDirectory()); - if (log.isDebugEnabled()) - log.debug("Deleted Jackrabbit home directory " - + getHomeDirectory()); - } - double duration = ((double) (System.currentTimeMillis() - begin)) / 1000; - log.info("Destroyed Jackrabbit repository in " + duration - + " s, home: " + getHomeDirectory() + ", config " - + configuration); - } - } - - /** - * @deprecated explicitly declare {@link #destroy()} as destroy-method - * instead. - */ - public void dispose() throws Exception { - log.error("## Declare destroy-method=\"destroy\". in the Jackrabbit container bean"); - destroy(); - } - /* - * UTILITIES + * DATA MODEL */ - /** Generates the properties to use in the 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()); - - if (log.isTraceEnabled()) { - log.trace("Jackrabbit config variables:"); - for (Object key : new TreeSet(vars.keySet())) - log.trace(key + "=" + vars.getProperty(key.toString())); - } - - } catch (IOException e) { - throw new ArgeoException("Cannot read configuration properties", e); - } finally { - IOUtils.closeQuietly(propsIn); - } - return vars; - } - /** * Import declared node type definitions and register namespaces. Tries to * update the node definitions if they have changed. In case of failures an @@ -454,54 +225,78 @@ public class JackrabbitContainer implements Repository { } - /** Find which OSGi bundle provided the data model resource */ - protected Bundle findDataModelBundle(String resUrl) { - if (resUrl.startsWith("/")) - resUrl = resUrl.substring(1); - String pkg = resUrl.substring(0, resUrl.lastIndexOf('/')).replace('/', - '.'); - ServiceReference paSr = bundleContext - .getServiceReference(PackageAdmin.class.getName()); - PackageAdmin packageAdmin = (PackageAdmin) bundleContext - .getService(paSr); + /** Executes migrations, if needed. */ + protected void migrate() { + // Remote migration not supported + if (isRemote()) + return; - // find exported package - ExportedPackage exportedPackage = null; - ExportedPackage[] exportedPackages = packageAdmin - .getExportedPackages(pkg); - if (exportedPackages == null) - throw new ArgeoException("No exported package found for " + pkg); - for (ExportedPackage ep : exportedPackages) { - for (Bundle b : ep.getImportingBundles()) { - if (b.getBundleId() == bundleContext.getBundle().getBundleId()) { - exportedPackage = ep; - break; + // No migration to perform + if (dataModelMigrations.size() == 0) + return; + + Boolean restartAndClearCaches = false; + + // migrate data + Session session = null; + try { + session = login(); + for (JackrabbitDataModelMigration dataModelMigration : new TreeSet( + dataModelMigrations)) { + if (dataModelMigration.migrate(session)) { + restartAndClearCaches = true; } } + } catch (ArgeoException e) { + throw e; + } catch (Exception e) { + throw new ArgeoException("Cannot migrate", e); + } finally { + JcrUtils.logoutQuietly(session); } - Bundle exportingBundle = null; - if (exportedPackage != null) { - exportingBundle = exportedPackage.getExportingBundle(); - } else { - throw new ArgeoException("No OSGi exporting package found for " - + resUrl); + // restart repository + if (restartAndClearCaches) { + Repository repository = getRepository(); + if (repository instanceof RepositoryImpl) { + JackrabbitDataModelMigration + .clearRepositoryCaches(((RepositoryImpl) repository) + .getConfig()); + } + ((JackrabbitRepository) repository).shutdown(); + createJackrabbitRepository(); } - return exportingBundle; - } - /* - * DELEGATED JCR REPOSITORY METHODS - */ + // set data model version + try { + session = login(); + } catch (RepositoryException e) { + throw new ArgeoException("Cannot login to migrated repository", e); + } - public String getDescriptor(String key) { - return getRepository().getDescriptor(key); - } + for (JackrabbitDataModelMigration dataModelMigration : new TreeSet( + dataModelMigrations)) { + try { + if (session.itemExists(dataModelMigration + .getDataModelNodePath())) { + Node dataModelNode = session.getNode(dataModelMigration + .getDataModelNodePath()); + dataModelNode.setProperty( + ArgeoNames.ARGEO_DATA_MODEL_VERSION, + dataModelMigration.getTargetVersion()); + session.save(); + } + } catch (Exception e) { + log.error("Cannot set model version", e); + } + } + JcrUtils.logoutQuietly(session); - public String[] getDescriptorKeys() { - return getRepository().getDescriptorKeys(); } + /* + * REPOSITORY INTERCEPTOR + */ /** Central login method */ public Session login(Credentials credentials, String workspaceName) throws LoginException, NoSuchWorkspaceException, @@ -523,98 +318,83 @@ public class JackrabbitContainer implements Repository { } } - Session session; - try { - session = getRepository().login(credentials, workspaceName); - } catch (NoSuchWorkspaceException e) { - if (autocreateWorkspaces && workspaceName != null) - session = createWorkspaceAndLogsIn(credentials, workspaceName); - else - throw e; - } - processNewSession(session); - return session; - } - - public Session login() throws LoginException, RepositoryException { - return login(null, null); - } - - public Session login(Credentials credentials) throws LoginException, - RepositoryException { - return login(credentials, null); - } - - public Session login(String workspaceName) throws LoginException, - NoSuchWorkspaceException, RepositoryException { - return login(null, workspaceName); - } - - /** Called after a session has been created, does nothing by default. */ - protected void processNewSession(Session session) { + return super.login(credentials, workspaceName); } - public Boolean isRemote() { - return uri != null; - } + /* + * UTILITIES + */ - /** Wraps access to the repository, making sure it is available. */ - protected Repository getRepository() { - if (repository == null) { - throw new ArgeoException( - "No repository initialized." - + " Was the init() method called?" - + " The dispose() method should also be called on shutdown."); + @Override + protected InputStream readConfiguration() { + try { + return configuration != null ? configuration.getInputStream() + : null; + } catch (IOException e) { + throw new ArgeoException("Cannot read Jackrabbit configuration " + + configuration, e); } - return repository; } - /** - * Logs in to the default workspace, creates the required workspace, logs - * out, logs in to the required workspace. - */ - protected Session createWorkspaceAndLogsIn(Credentials credentials, - String workspaceName) throws RepositoryException { - if (workspaceName == null) - throw new ArgeoException("No workspace specified."); - Session session = getRepository().login(credentials); - session.getWorkspace().createWorkspace(workspaceName); - session.logout(); - return getRepository().login(credentials, workspaceName); + @Override + protected InputStream readVariables() { + try { + return variables != null ? variables.getInputStream() : null; + } catch (IOException e) { + throw new ArgeoException("Cannot read Jackrabbit variables " + + variables, e); + } } - public boolean isStandardDescriptor(String key) { - return getRepository().isStandardDescriptor(key); + @Override + protected String resolvePlaceholders(String string, + Map variables) { + return SystemPropertyUtils.resolvePlaceholders(string); } - public boolean isSingleValueDescriptor(String key) { - return getRepository().isSingleValueDescriptor(key); - } + /** Find which OSGi bundle provided the data model resource */ + protected Bundle findDataModelBundle(String resUrl) { + if (resUrl.startsWith("/")) + resUrl = resUrl.substring(1); + String pkg = resUrl.substring(0, resUrl.lastIndexOf('/')).replace('/', + '.'); + ServiceReference paSr = bundleContext + .getServiceReference(PackageAdmin.class.getName()); + PackageAdmin packageAdmin = (PackageAdmin) bundleContext + .getService(paSr); - public Value getDescriptorValue(String key) { - return getRepository().getDescriptorValue(key); - } + // find exported package + ExportedPackage exportedPackage = null; + ExportedPackage[] exportedPackages = packageAdmin + .getExportedPackages(pkg); + if (exportedPackages == null) + throw new ArgeoException("No exported package found for " + pkg); + for (ExportedPackage ep : exportedPackages) { + for (Bundle b : ep.getImportingBundles()) { + if (b.getBundleId() == bundleContext.getBundle().getBundleId()) { + exportedPackage = ep; + break; + } + } + } - public Value[] getDescriptorValues(String key) { - return getRepository().getDescriptorValues(key); + Bundle exportingBundle = null; + if (exportedPackage != null) { + exportingBundle = exportedPackage.getExportingBundle(); + } else { + throw new ArgeoException("No OSGi exporting package found for " + + resUrl); + } + return exportingBundle; } /* * FIELDS ACCESS */ - - public void setHomeDirectory(File homeDirectory) { - this.homeDirectory = homeDirectory; - } - public void setConfiguration(Resource configuration) { this.configuration = configuration; } - public void setInMemory(Boolean inMemory) { - this.inMemory = inMemory; - } - public void setNamespaces(Map namespaces) { this.namespaces = namespaces; } @@ -627,26 +407,10 @@ public class JackrabbitContainer implements Repository { this.variables = variables; } - public void setUri(String uri) { - this.uri = uri; - } - public void setRemoteSystemCredentials(Credentials remoteSystemCredentials) { this.remoteSystemCredentials = remoteSystemCredentials; } - public void setSystemExecutor(Executor systemExecutor) { - throw new IllegalArgumentException( - "systemExecutor is not supported anymore, use:\n" - + "\n" - + "\t\n" - + ""); - } - - public void setRepository(Repository repository) { - this.repository = repository; - } - public void setDataModelMigrations( Set dataModelMigrations) { this.dataModelMigrations = dataModelMigrations; diff --git a/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitWrapper.java b/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitWrapper.java new file mode 100644 index 000000000..0dd94bc51 --- /dev/null +++ b/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitWrapper.java @@ -0,0 +1,388 @@ +/* + * Copyright (C) 2010 Mathieu Baudier + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.argeo.jackrabbit; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.TreeSet; +import java.util.UUID; + +import javax.jcr.Credentials; +import javax.jcr.LoginException; +import javax.jcr.NoSuchWorkspaceException; +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.Value; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.jackrabbit.core.RepositoryImpl; +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.xml.sax.InputSource; + +/** + * Wrapper around a Jackrabbit repository which allows to simplify configuration + * and intercept some actions. It exposes itself as a {@link Repository}. + */ +public abstract class JackrabbitWrapper implements Repository { + private Log log = LogFactory.getLog(JackrabbitWrapper.class); + + // remote + private String uri = null; + + // local + private RepositoryConfig repositoryConfig; + private File homeDirectory; + private Boolean inMemory = false; + + // wrapped repository + private Repository repository; + + private Boolean autocreateWorkspaces = false; + + /** + * Empty constructor, {@link #init()} should be called after properties have + * been set + */ + public JackrabbitWrapper() { + } + + /** + * Reads the configuration which will initialize a {@link RepositoryConfig}. + */ + protected abstract InputStream readConfiguration(); + + /** + * Reads the variables which will initialize a {@link Properties}. Returns + * null by default, to be overridden. + * + * @return a new stream or null if no variables available + */ + protected InputStream readVariables() { + return null; + } + + /** + * Resolves ${} placeholders in the provided string. Based on system + * properties if no map is provided. + */ + protected abstract String resolvePlaceholders(String string, + Map variables); + + /** Initializes */ + public void init() { + long begin = System.currentTimeMillis(); + + if (repository != null) { + // we are just wrapping another repository + postInitWrapped(); + } else { + createJackrabbitRepository(); + postInitNew(); + } + + double duration = ((double) (System.currentTimeMillis() - begin)) / 1000; + log.info("Initialized Jackrabbit wrapper in " + duration + " s"); + } + + /** + * Called after initialization of an already existing {@link Repository} + * which is being wrapped (e.g. in order to impact its data model). To be + * overridden, does nothing by default. + */ + protected void postInitWrapped() { + + } + + /** + * Called after initialization of a new {@link Repository} either local or + * remote. To be overridden, does nothing by default. + */ + protected void postInitNew() { + + } + + /** Actually creates the new repository. */ + protected void createJackrabbitRepository() { + long begin = System.currentTimeMillis(); + InputStream configurationIn = null; + try { + if (uri != null && !uri.trim().equals("")) {// remote + Map params = new HashMap(); + 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"); + double duration = ((double) (System.currentTimeMillis() - begin)) / 1000; + log.info("Created Jackrabbit repository in " + duration + + " s from URI " + uri); + // we assume that the data model of the remote repository has + // been properly initialized + } else {// local + // force uri to null in order to optimize isRemote() + uri = null; + + // temporary + if (inMemory && getHomeDirectory().exists()) { + FileUtils.deleteDirectory(getHomeDirectory()); + log.warn("Deleted Jackrabbit home directory " + + getHomeDirectory()); + } + + // process configuration file + Properties vars = getConfigurationProperties(); + configurationIn = readConfiguration(); + vars.put( + RepositoryConfigurationParser.REPOSITORY_HOME_VARIABLE, + getHomeDirectory().getCanonicalPath()); + repositoryConfig = RepositoryConfig.create(new InputSource( + configurationIn), vars); + + // + // Actual repository creation + // + repository = RepositoryImpl.create(repositoryConfig); + + double duration = ((double) (System.currentTimeMillis() - begin)) / 1000; + if (log.isDebugEnabled()) + log.debug("Created Jackrabbit repository in " + duration + + " s, home: " + getHomeDirectory()); + } + } catch (Exception e) { + throw new ArgeoException("Cannot create Jackrabbit repository " + + getHomeDirectory(), e); + } finally { + IOUtils.closeQuietly(configurationIn); + } + } + + /** Lazy init. */ + protected File getHomeDirectory() { + try { + if (homeDirectory == null) { + if (inMemory) { + homeDirectory = new File( + System.getProperty("java.io.tmpdir") + + File.separator + + System.getProperty("user.name") + + File.separator + "jackrabbit-" + + UUID.randomUUID()); + homeDirectory.mkdirs(); + // will it work if directory is not empty?? + homeDirectory.deleteOnExit(); + } + } + + return homeDirectory.getCanonicalFile(); + } catch (IOException e) { + throw new ArgeoException("Cannot get canonical file for " + + homeDirectory, e); + } + } + + /** Shutdown the repository */ + public void destroy() throws Exception { + if (repository != null && repository instanceof RepositoryImpl) { + long begin = System.currentTimeMillis(); + ((RepositoryImpl) repository).shutdown(); + if (inMemory) + if (getHomeDirectory().exists()) { + FileUtils.deleteDirectory(getHomeDirectory()); + if (log.isDebugEnabled()) + log.debug("Deleted Jackrabbit home directory " + + getHomeDirectory()); + } + double duration = ((double) (System.currentTimeMillis() - begin)) / 1000; + log.info("Destroyed Jackrabbit repository in " + duration + + " s, home: " + getHomeDirectory()); + } + } + + /** + * @deprecated explicitly declare {@link #destroy()} as destroy-method + * instead. + */ + public void dispose() throws Exception { + log.error("## Declare destroy-method=\"destroy\". in the Jackrabbit container bean"); + destroy(); + } + + /* + * UTILITIES + */ + + /** Generates the properties to use in the configuration. */ + protected Properties getConfigurationProperties() { + InputStream propsIn = null; + Properties vars; + try { + vars = new Properties(); + propsIn = readVariables(); + if (propsIn != null) { + vars.load(propsIn); + } + // resolve system properties + for (Object key : vars.keySet()) { + // TODO: implement a smarter mechanism to resolve nested ${} + String newValue = resolvePlaceholders( + vars.getProperty(key.toString()), null); + vars.put(key, newValue); + } + // override with system properties + vars.putAll(System.getProperties()); + + if (log.isTraceEnabled()) { + log.trace("Jackrabbit config variables:"); + for (Object key : new TreeSet(vars.keySet())) + log.trace(key + "=" + vars.getProperty(key.toString())); + } + + } catch (IOException e) { + throw new ArgeoException("Cannot read configuration properties", e); + } finally { + IOUtils.closeQuietly(propsIn); + } + return vars; + } + + /* + * DELEGATED JCR REPOSITORY METHODS + */ + + public String getDescriptor(String key) { + return getRepository().getDescriptor(key); + } + + public String[] getDescriptorKeys() { + return getRepository().getDescriptorKeys(); + } + + /** Central login method */ + public Session login(Credentials credentials, String workspaceName) + throws LoginException, NoSuchWorkspaceException, + RepositoryException { + Session session; + try { + session = getRepository().login(credentials, workspaceName); + } catch (NoSuchWorkspaceException e) { + if (autocreateWorkspaces && workspaceName != null) + session = createWorkspaceAndLogsIn(credentials, workspaceName); + else + throw e; + } + processNewSession(session); + return session; + } + + public Session login() throws LoginException, RepositoryException { + return login(null, null); + } + + public Session login(Credentials credentials) throws LoginException, + RepositoryException { + return login(credentials, null); + } + + public Session login(String workspaceName) throws LoginException, + NoSuchWorkspaceException, RepositoryException { + return login(null, workspaceName); + } + + /** Called after a session has been created, does nothing by default. */ + protected void processNewSession(Session session) { + } + + public Boolean isRemote() { + return uri != null; + } + + /** Wraps access to the repository, making sure it is available. */ + protected Repository getRepository() { + if (repository == null) { + throw new ArgeoException( + "No repository initialized." + + " Was the init() method called?" + + " The dispose() method should also be called on shutdown."); + } + return repository; + } + + /** + * Logs in to the default workspace, creates the required workspace, logs + * out, logs in to the required workspace. + */ + protected Session createWorkspaceAndLogsIn(Credentials credentials, + String workspaceName) throws RepositoryException { + if (workspaceName == null) + throw new ArgeoException("No workspace specified."); + Session session = getRepository().login(credentials); + session.getWorkspace().createWorkspace(workspaceName); + session.logout(); + return getRepository().login(credentials, workspaceName); + } + + public boolean isStandardDescriptor(String key) { + return getRepository().isStandardDescriptor(key); + } + + public boolean isSingleValueDescriptor(String key) { + return getRepository().isSingleValueDescriptor(key); + } + + public Value getDescriptorValue(String key) { + return getRepository().getDescriptorValue(key); + } + + public Value[] getDescriptorValues(String key) { + return getRepository().getDescriptorValues(key); + } + + /* + * FIELDS ACCESS + */ + + public void setHomeDirectory(File homeDirectory) { + this.homeDirectory = homeDirectory; + } + + public void setInMemory(Boolean inMemory) { + this.inMemory = inMemory; + } + + public void setUri(String uri) { + this.uri = uri; + } + + public void setRepository(Repository repository) { + this.repository = repository; + } + +} -- 2.30.2