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=a708aadd1d67a6eada7401b8bcf94d3cf95ff8ad;hb=a171094436482fa16e8da47d5501df59ec06e595;hp=e27a473b5e041cf6bd2baa99ec2df943707e2973;hpb=e890c9d9d57069b464b406405797f38e7263f3b1;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 e27a473b5..a708aadd1 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 @@ -30,11 +30,13 @@ 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; import javax.jcr.NoSuchWorkspaceException; +import javax.jcr.Node; import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.Session; @@ -53,6 +55,7 @@ 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; import org.springframework.context.ResourceLoaderAware; import org.springframework.core.io.Resource; @@ -68,16 +71,17 @@ public class JackrabbitContainer implements Repository, ResourceLoaderAware { private Log log = LogFactory.getLog(JackrabbitContainer.class); private Resource configuration; - private String homeDirectory; + private File homeDirectory; private Resource variables; - /** cache home */ - private File home; private Boolean inMemory = false; private String uri = null; + // wrapped repository private Repository repository; + private RepositoryConfig repositoryConfig; + // CND private ResourceLoader resourceLoader; /** Node type definitions in CND format */ @@ -100,7 +104,7 @@ public class JackrabbitContainer implements Repository, ResourceLoaderAware { return; } - repository = createJackrabbitRepository(); + createJackrabbitRepository(); // migrate if needed migrate(); @@ -111,8 +115,8 @@ public class JackrabbitContainer implements Repository, ResourceLoaderAware { } /** Actually creates a new repository. */ - protected JackrabbitRepository createJackrabbitRepository() { - JackrabbitRepository repository; + protected void createJackrabbitRepository() { + long begin = System.currentTimeMillis(); try { // remote repository if (uri != null && !uri.trim().equals("")) { @@ -120,7 +124,7 @@ public class JackrabbitContainer implements Repository, ResourceLoaderAware { params.put( org.apache.jackrabbit.commons.JcrUtils.REPOSITORY_URI, uri); - repository = (JackrabbitRepository) new Jcr2davRepositoryFactory() + repository = new Jcr2davRepositoryFactory() .getRepository(params); if (repository == null) throw new ArgeoException("Remote Davex repository " + uri @@ -130,23 +134,24 @@ public class JackrabbitContainer implements Repository, ResourceLoaderAware { // do not perform further initialization since we assume that // the // remote repository has been properly configured - return repository; + return; } // local repository - if (inMemory && getHome().exists()) { - FileUtils.deleteDirectory(getHome()); - log.warn("Deleted Jackrabbit home directory " + getHome()); + if (inMemory && getHomeDirectory().exists()) { + FileUtils.deleteDirectory(getHomeDirectory()); + log.warn("Deleted Jackrabbit home directory " + + getHomeDirectory()); } - RepositoryConfig config; Properties vars = getConfigurationProperties(); InputStream in = configuration.getInputStream(); try { vars.put( RepositoryConfigurationParser.REPOSITORY_HOME_VARIABLE, - getHome().getCanonicalPath()); - config = RepositoryConfig.create(new InputSource(in), vars); + getHomeDirectory().getCanonicalPath()); + repositoryConfig = RepositoryConfig.create(new InputSource(in), + vars); } catch (Exception e) { throw new RuntimeException("Cannot read configuration", e); } finally { @@ -154,22 +159,26 @@ public class JackrabbitContainer implements Repository, ResourceLoaderAware { } if (inMemory) - repository = new TransientRepository(config); + repository = new TransientRepository(repositoryConfig); else - repository = RepositoryImpl.create(config); + repository = RepositoryImpl.create(repositoryConfig); - log.info("Initialized Jackrabbit repository " + repository + " in " - + getHome() + " with config " + configuration); - - return repository; + 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 " - + getHome(), e); + + getHomeDirectory(), e); } } /** Executes migrations, if needed. */ protected void migrate() { + // No migration to perform + if (dataModelMigrations.size() == 0) + return; + Boolean restartAndClearCaches = false; // migrate data @@ -192,38 +201,65 @@ public class JackrabbitContainer implements Repository, ResourceLoaderAware { // restart repository if (restartAndClearCaches) { + JackrabbitDataModelMigration + .clearRepositoryCaches(repositoryConfig); ((JackrabbitRepository) repository).shutdown(); - JackrabbitDataModelMigration.clearRepositoryCaches(getHome()); - repository = createJackrabbitRepository(); + 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 getHome() { - if (home != null) - return home; - + protected File getHomeDirectory() { try { - String osgiData = System.getProperty("osgi.instance.area"); - if (osgiData != null) - osgiData = osgiData.substring("file:".length()); - String path; - if (homeDirectory == null) - path = "./jackrabbit"; - else - path = homeDirectory; - if (path.startsWith(".") && osgiData != null) { - home = new File(osgiData + '/' + path).getCanonicalFile(); - } else - home = new File(path).getCanonicalFile(); - return home; - } catch (Exception e) { - throw new ArgeoException("Cannot define Jackrabbit home based on " + 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); } } public void dispose() throws Exception { + long begin = System.currentTimeMillis(); if (repository != null) { if (repository instanceof JackrabbitRepository) ((JackrabbitRepository) repository).shutdown(); @@ -234,17 +270,20 @@ public class JackrabbitContainer implements Repository, ResourceLoaderAware { } if (inMemory) - if (getHome().exists()) { - FileUtils.deleteDirectory(getHome()); + if (getHomeDirectory().exists()) { + FileUtils.deleteDirectory(getHomeDirectory()); if (log.isDebugEnabled()) - log.debug("Deleted Jackrabbit home directory " + getHome()); + log.debug("Deleted Jackrabbit home directory " + + getHomeDirectory()); } + double duration = ((double) (System.currentTimeMillis() - begin)) / 1000; if (uri != null && !uri.trim().equals("")) log.info("Destroyed Jackrabbit repository with uri " + uri); else - log.info("Destroyed Jackrabbit repository " + repository + " in " - + getHome() + " with config " + configuration); + log.info("Destroyed Jackrabbit repository in " + duration + + " s, home: " + getHomeDirectory() + ", config " + + configuration); } /** @@ -278,6 +317,13 @@ public class JackrabbitContainer implements Repository, ResourceLoaderAware { } // 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 { @@ -328,15 +374,15 @@ public class JackrabbitContainer implements Repository, ResourceLoaderAware { // JCR REPOSITORY (delegated) public String getDescriptor(String key) { - return repository.getDescriptor(key); + return getRepository().getDescriptor(key); } public String[] getDescriptorKeys() { - return repository.getDescriptorKeys(); + return getRepository().getDescriptorKeys(); } public Session login() throws LoginException, RepositoryException { - Session session = repository.login(); + Session session = getRepository().login(); processNewSession(session); return session; } @@ -346,7 +392,7 @@ public class JackrabbitContainer implements Repository, ResourceLoaderAware { RepositoryException { Session session; try { - session = repository.login(credentials, workspaceName); + session = getRepository().login(credentials, workspaceName); } catch (NoSuchWorkspaceException e) { if (autocreateWorkspaces) session = createWorkspaceAndLogsIn(credentials, workspaceName); @@ -359,7 +405,7 @@ public class JackrabbitContainer implements Repository, ResourceLoaderAware { public Session login(Credentials credentials) throws LoginException, RepositoryException { - Session session = repository.login(credentials); + Session session = getRepository().login(credentials); processNewSession(session); return session; } @@ -368,7 +414,7 @@ public class JackrabbitContainer implements Repository, ResourceLoaderAware { NoSuchWorkspaceException, RepositoryException { Session session; try { - session = repository.login(workspaceName); + session = getRepository().login(workspaceName); } catch (NoSuchWorkspaceException e) { if (autocreateWorkspaces) session = createWorkspaceAndLogsIn(null, workspaceName); @@ -379,6 +425,17 @@ public class JackrabbitContainer implements Repository, ResourceLoaderAware { return session; } + /** 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; + } + protected synchronized void processNewSession(Session session) { try { NamespaceHelper namespaceHelper = new NamespaceHelper(session); @@ -396,10 +453,10 @@ public class JackrabbitContainer implements Repository, ResourceLoaderAware { String workspaceName) throws RepositoryException { if (workspaceName == null) throw new ArgeoException("No workspace specified."); - Session session = repository.login(credentials); + Session session = getRepository().login(credentials); session.getWorkspace().createWorkspace(workspaceName); session.logout(); - return repository.login(credentials, workspaceName); + return getRepository().login(credentials, workspaceName); } public void setResourceLoader(ResourceLoader resourceLoader) { @@ -407,23 +464,23 @@ public class JackrabbitContainer implements Repository, ResourceLoaderAware { } public boolean isStandardDescriptor(String key) { - return repository.isStandardDescriptor(key); + return getRepository().isStandardDescriptor(key); } public boolean isSingleValueDescriptor(String key) { - return repository.isSingleValueDescriptor(key); + return getRepository().isSingleValueDescriptor(key); } public Value getDescriptorValue(String key) { - return repository.getDescriptorValue(key); + return getRepository().getDescriptorValue(key); } public Value[] getDescriptorValues(String key) { - return repository.getDescriptorValues(key); + return getRepository().getDescriptorValues(key); } // BEANS METHODS - public void setHomeDirectory(String homeDirectory) { + public void setHomeDirectory(File homeDirectory) { this.homeDirectory = homeDirectory; }