/*
* ModeShape (http://www.modeshape.org)
*
* 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.modeshape.jcr;
import java.io.InputStream;
import java.net.URL;
import java.security.Principal;
import java.util.Properties;
import javax.jcr.Credentials;
import javax.jcr.ImportUUIDBehavior;
import javax.jcr.NamespaceRegistry;
import javax.jcr.Session;
import org.apache.jackrabbit.test.RepositoryStub;
import org.modeshape.jcr.api.nodetype.NodeTypeManager;
import org.modeshape.jcr.security.SimplePrincipal;
/**
* Concrete implementation of {@link RepositoryStub} based on ModeShape-specific configuration.
*/
public class ModeShapeRepositoryStub extends RepositoryStub {
public static final String MODE_SHAPE_SKIP_IMPORT = "javax.jcr.tck.modeSkipImport";
public static final String MODE_SHAPE_NODE_TYPE_PATH = "javax.jcr.tck.modeNodeTypePath";
/**
* System views can distinguis multi-valued properties that happen to have only one value. Document views cannot experss this,
* so import using the system view.
*/
// public static final String MODE_SHAPE_IMPORTED_CONTENT = "/tck/documentViewForTckTests.xml";
public static final String MODE_SHAPE_IMPORTED_CONTENT = "/tck/systemViewForTckTests.xml";
private static String currentConfigurationName = "default";
private static boolean reloadRepositoryInstance = false;
private static ModeShapeEngine engine;
private Properties configProps;
private String repositoryConfigurationName;
private JcrRepository repository;
static {
// Initialize the JAAS configuration to allow for an admin login later
JaasTestUtil.initJaas("security/jaas.conf.xml");
}
public ModeShapeRepositoryStub( Properties env ) {
super(env);
configureRepository();
}
private void configureRepository() {
repositoryConfigurationName = currentConfigurationName;
// Clean up from a previous invocation ...
if (engine != null) {
try {
// Terminate any existing engine and destroy any content used by the repositories ...
TestingUtil.killEngine(engine);
} finally {
engine = null;
}
}
// Read the configuration file and setup the engine ...
RepositoryConfiguration configuration = null;
try {
configProps = new Properties();
String propsFileName = "/tck/" + repositoryConfigurationName + "/repositoryOverlay.properties";
InputStream propsStream = getClass().getResourceAsStream(propsFileName);
configProps.load(propsStream);
String configFileName = "/tck/" + repositoryConfigurationName + "/repo-config.json";
InputStream configStream = getClass().getResourceAsStream(configFileName);
configuration = RepositoryConfiguration.read(configStream, configFileName);
if (configuration == null) {
throw new IllegalStateException(
"Problems starting JCR repository: unable to find ModeShape configuration file \""
+ configFileName + "\" on the classpath");
}
engine = new ModeShapeEngine();
engine.start();
// Deploy and start the repository, and block until started...
repository = engine.deploy(configuration);
engine.startRepository(repository.getName()).get();
// Set up the repository content (for all workspaces) ...
Session session = repository.login(superuser);
Credentials superuser = getSuperuserCredentials();
try {
// Register the test namespaces in the repository ...
NamespaceRegistry registry = session.getWorkspace().getNamespaceRegistry();
registry.registerNamespace(TestLexicon.Namespace.PREFIX, TestLexicon.Namespace.URI);
// Register the node types needed in our tests ...
String cndFileName = "/tck/tck_test_types.cnd";
URL cndUrl = getClass().getResource(cndFileName);
NodeTypeManager nodeTypeManager = (NodeTypeManager)session.getWorkspace().getNodeTypeManager();
nodeTypeManager.registerNodeTypes(cndUrl, true);
// This needs to check configProps directly to avoid an infinite loop
String skipImport = (String)configProps.get(MODE_SHAPE_SKIP_IMPORT);
if (!Boolean.valueOf(skipImport)) {
// Set up some sample nodes in the "default" workspace to match the expected test configuration ...
InputStream xmlStream = getClass().getResourceAsStream(MODE_SHAPE_IMPORTED_CONTENT);
session.getWorkspace().importXML("/", xmlStream, ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING);
// Switch workspaces ...
session.logout();
session = repository.login(superuser, "otherWorkspace");
// Set up some sample nodes in the "otherWorkspace" workspace to match the expected test configuration ...
xmlStream = getClass().getResourceAsStream(MODE_SHAPE_IMPORTED_CONTENT);
session.getWorkspace().importXML("/", xmlStream, ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING);
session.save();
}
} finally {
session.logout();
}
} catch (Exception ex) {
// The TCK tries to quash this exception. Print it out to be more obvious.
ex.printStackTrace();
throw new IllegalStateException("Failed to initialize the repository with text content.", ex);
}
}
public static void setCurrentConfigurationName( String newConfigName ) {
ModeShapeRepositoryStub.currentConfigurationName = newConfigName;
}
public static void reloadRepositoryInstance() {
reloadRepositoryInstance = true;
}
public static void shutdownEngine() {
if (engine != null && engine.checkRunning()) {
engine.shutdown();
engine = null;
reloadRepositoryInstance = true;
}
}
@Override
public JcrRepository getRepository() {
if (!currentConfigurationName.equals(repositoryConfigurationName) || reloadRepositoryInstance) {
reloadRepositoryInstance = false;
configureRepository();
}
return repository;
}
@Override
public String getProperty( String name ) {
String value = configProps.getProperty(name);
if (value != null) return value;
return super.getProperty(name);
}
@Override
public Principal getKnownPrincipal( Session session ) {
return SimplePrincipal.newInstance(session.getUserID());
}
@Override
public Principal getUnknownPrincipal( Session session ) {
return SimplePrincipal.newInstance("unknown");
}
}