/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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.apache.jackrabbit.core; import java.io.InputStream; import java.util.Map; import javax.jcr.Credentials; import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.Session; import org.apache.commons.collections.BeanMap; import org.apache.jackrabbit.commons.repository.ProxyRepository; import org.apache.jackrabbit.commons.repository.RepositoryFactory; import org.apache.jackrabbit.core.config.ConfigurationException; import org.apache.jackrabbit.core.config.RepositoryConfig; /** * Utility class for easy handling a test repository. This class contains * a static test repository instance for use by test cases. The * {@link javax.jcr.Repository#login()} method of the test repository * instance should return a session with full read-write access. */ public class TestRepository { /** * Name of the resource containing the test repository configuration. * The test repository configuration is located inside the Jackrabbit * jar file to enforce a standard test environment. */ private static final String CONF_RESOURCE = "repository.xml"; /** * Name of the system property that can be used to override the * default test repository location. */ private static final String HOME_PROPERTY = "org.apache.jackrabbit.test.repository.home"; /** * Default test repository location. */ private static final String HOME_DEFAULT = "jackrabbit-test-repository"; /** * The test repository instance. */ private static Repository instance = null; /** * Returns the test repository instance. If a repository instance has * not yet been registered using {@link #setInstance(Repository)} as * the test repostitory, then a simple {@link TransientRepository} * instance is created with the standard test repository configuration * and the test repository location (either "jackrabbit-test-repository" * or the value of the "org.apache.jackrabbit.test.repository.home" * system property). * * @return test repository instance * @throws RepositoryException if a test repository can not be instantiated */ public static synchronized Repository getInstance() throws RepositoryException { try { if (instance == null) { try { // Try to get the main test suite repository instance = getIntegratedInstance(); } catch (RepositoryException e) { throw e; } catch (Exception e) { // Not running within the main test suite InputStream xml = TestRepository.class.getResourceAsStream(CONF_RESOURCE); String home = System.getProperty(HOME_PROPERTY, HOME_DEFAULT); RepositoryConfig config = RepositoryConfig.create(xml, home); instance = new TransientRepository(config); } } return instance; } catch (ConfigurationException e) { throw new RepositoryException( "Error in test repository configuration", e); } } /** * Attempts to retrieve the test repository instance used by the * Jackrabbit main test suite without having a direct dependency to any * of the classes in src/test/java. This method assumes that we are * running within the Jackrabbit main test suite if the AbstractJCRTest * class is available. The initialized RepositoryHelper instance is * retrieved from the static "helper" field of the AbstractJCRTest class, * and the underlying repository and configured superuser credentials are * extracted from the helper instance. This information is in turn used * to create a custom Repository adapter that delegates calls to the * underlying repository and uses the superuser credentials for the login * methods where no credentials are passed by the client. * * @return test repository instance * @throws Exception if the test repository could not be retrieved */ private static Repository getIntegratedInstance() throws Exception { Class test = Class.forName("org.apache.jackrabbit.test.AbstractJCRTest"); Map helper = new BeanMap(test.getField("helper").get(null)); final Repository repository = (Repository) helper.get("repository"); final Credentials superuser = (Credentials) helper.get("superuserCredentials"); return new ProxyRepository(new RepositoryFactory() { public Repository getRepository() throws RepositoryException { return repository; } }) { public Session login(String workspace) throws RepositoryException { return repository.login(superuser, workspace); } public Session login() throws RepositoryException { return repository.login(superuser); } }; } /** * Sets the given repository as the test repository instance. This method * is designed for use by the main Jackrabbit test suite to facilitate * smooth integration of standalone test cases. * * @param repository test repository */ public static synchronized void setInstance(Repository repository) { instance = repository; } /** * Private constructor to prevent instantiation of this class. */ private TestRepository() { } }