/* * Copyright (c) 2006-2014 Nuxeo SA (http://nuxeo.com/) and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Bogdan Stefanescu * Florent Guillaume */ package org.nuxeo.ecm.core.repository; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.transaction.Transaction; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nuxeo.ecm.core.api.ClientException; import org.nuxeo.ecm.core.api.CoreSession; import org.nuxeo.ecm.core.api.UnrestrictedSessionRunner; import org.nuxeo.ecm.core.api.local.LocalSession; import org.nuxeo.ecm.core.api.repository.RepositoryManager; import org.nuxeo.ecm.core.model.Repository; import org.nuxeo.runtime.RuntimeServiceEvent; import org.nuxeo.runtime.RuntimeServiceListener; import org.nuxeo.runtime.api.Framework; import org.nuxeo.runtime.model.ComponentContext; import org.nuxeo.runtime.model.ComponentName; import org.nuxeo.runtime.model.DefaultComponent; import org.nuxeo.runtime.transaction.TransactionHelper; /** * Component and service managing low-level repository instances. */ public class RepositoryService extends DefaultComponent { public static final ComponentName NAME = new ComponentName("org.nuxeo.ecm.core.repository.RepositoryService"); private static final Log log = LogFactory.getLog(RepositoryService.class); public static final String XP_REPOSITORY = "repository"; // @GuardedBy("itself") private final Map<String, Repository> repositories = new HashMap<String, Repository>(); public void shutdown() { log.info("Shutting down repository manager"); synchronized (repositories) { for (Repository repository : repositories.values()) { repository.shutdown(); } repositories.clear(); } } @Override public int getApplicationStartedOrder() { return 100; } @Override public void applicationStarted(ComponentContext context) throws Exception { Framework.addListener(new RuntimeServiceListener() { @Override public void handleEvent(RuntimeServiceEvent event) { if (event.id != RuntimeServiceEvent.RUNTIME_ABOUT_TO_STOP) { return; } Framework.removeListener(this); shutdown(); } }); RepositoryInitializationHandler handler = RepositoryInitializationHandler.getInstance(); if (handler == null) { return; } RepositoryManager repositoryManager = Framework.getLocalService(RepositoryManager.class); boolean started = false; boolean ok = false; { // open repositories without a tx active Transaction tx = TransactionHelper.suspendTransaction(); try { for (String name : repositoryManager.getRepositoryNames()) { openRepository(name); } } finally { TransactionHelper.resumeTransaction(tx); } } // initialize repositories with a tx active try { started = !TransactionHelper.isTransactionActive() && TransactionHelper.startTransaction(); for (String name : repositoryManager.getRepositoryNames()) { initializeRepository(handler, name); } ok = true; } finally { if (started) { try { if (!ok) { TransactionHelper.setTransactionRollbackOnly(); } } finally { TransactionHelper.commitOrRollbackTransaction(); } } } } @SuppressWarnings("unchecked") @Override public <T> T getAdapter(Class<T> adapter) { if (adapter.isAssignableFrom(getClass())) { return (T) this; } if (adapter.isAssignableFrom(CoreSession.class)) { return (T) LocalSession.createInstance(); } return null; } protected void openRepository(String name) throws ClientException { new UnrestrictedSessionRunner(name) { @Override public void run() throws ClientException { ; } }.runUnrestricted(); } protected void initializeRepository( final RepositoryInitializationHandler handler, String name) { try { new UnrestrictedSessionRunner(name) { @Override public void run() throws ClientException { handler.initializeRepository(session); } }.runUnrestricted(); } catch (ClientException e) { throw new RuntimeException("Failed to initialize repository '" + name + "': " + e.getMessage(), e); } } /** * Gets a repository given its name. * <p> * Null is returned if no repository with that name was registered. * * @param repositoryName the repository name * @return the repository instance or null if no repository with that name * was registered */ public Repository getRepository(String repositoryName) { synchronized (repositories) { Repository repository = repositories.get(repositoryName); if (repository == null) { RepositoryFactory factory = getFactory(repositoryName); if (factory == null) { return null; } repository = (Repository) factory.call(); repositories.put(repositoryName, repository); } return repository; } } protected RepositoryFactory getFactory(String repositoryName) { RepositoryManager repositoryManager = Framework.getLocalService(RepositoryManager.class); if (repositoryManager == null) { // tests with no high-level repository manager return null; } org.nuxeo.ecm.core.api.repository.Repository repo = repositoryManager.getRepository(repositoryName); if (repo == null) { return null; } RepositoryFactory repositoryFactory = (RepositoryFactory) repo.getRepositoryFactory(); if (repositoryFactory == null) { throw new NullPointerException( "Missing repositoryFactory for repository: " + repositoryName); } return repositoryFactory; } public List<String> getRepositoryNames() { RepositoryManager repositoryManager = Framework.getLocalService(RepositoryManager.class); return repositoryManager.getRepositoryNames(); } }