Index: docs/reference/src/main/docbook/en-US/content/connectors/infinispan.xml =================================================================== --- docs/reference/src/main/docbook/en-US/content/connectors/infinispan.xml (revision 1811) +++ docs/reference/src/main/docbook/en-US/content/connectors/infinispan.xml (working copy) @@ -59,8 +59,16 @@ cacheConfigurationName - Optional property that, if used, specifies the name of the configuration that is supplied to the cache manager - when creating a new Infinispan CacheManager instance. + + Optional property that, if used, specifies the name of the configuration resource or file that is supplied to the cache manager + when creating a new Infinispan DefaultCacheManager instance. The configuration name is first treated as a resource name and will be attempted + to be loaded from the &ClassLoader;. If that is unsuccessful, the configuration name is assumed to be a file name and will be loaded + from the file system. This initialization happens the first time that the source is used. + + Note that the cacheManagerJndiName property is checked first as a pointer to the Infinispan CacheManager. + If the JNDI name points to a CacheManager, the cacheConfigurationName property will not be considered. + + defaultCachePolicy Index: extensions/modeshape-connector-infinispan/src/main/java/org/modeshape/connector/infinispan/InfinispanConnectorI18n.java =================================================================== --- extensions/modeshape-connector-infinispan/src/main/java/org/modeshape/connector/infinispan/InfinispanConnectorI18n.java (revision 1811) +++ extensions/modeshape-connector-infinispan/src/main/java/org/modeshape/connector/infinispan/InfinispanConnectorI18n.java (working copy) @@ -14,6 +14,8 @@ public final class InfinispanConnectorI18n { public static I18n errorSerializingCachePolicyInSource; public static I18n objectFoundInJndiWasNotCacheManager; public static I18n unableToCreateWorkspace; + public static I18n configFileNotFound; + public static I18n configFileNotValid; static { try { Index: extensions/modeshape-connector-infinispan/src/main/java/org/modeshape/connector/infinispan/InfinispanSource.java =================================================================== --- extensions/modeshape-connector-infinispan/src/main/java/org/modeshape/connector/infinispan/InfinispanSource.java (revision 1811) +++ extensions/modeshape-connector-infinispan/src/main/java/org/modeshape/connector/infinispan/InfinispanSource.java (working copy) @@ -25,7 +25,9 @@ package org.modeshape.connector.infinispan; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Enumeration; @@ -416,25 +418,44 @@ public class InfinispanSource implements BaseRepositorySource, ObjectFactory { throw new RepositorySourceException(getName(), err); } } - if (cacheManager == null) cacheManager = new DefaultCacheManager(); + if (cacheManager == null) { + String configName = getCacheConfigurationName(); + if (configName == null) { + cacheManager = new DefaultCacheManager(); + } + else { + /* + * First try treating the config name as a classpath resource, then as a file name. + */ + InputStream configStream = getClass().getResourceAsStream(configName); + try { + if (configStream == null) { + configStream = new FileInputStream(configName); + } + } catch (IOException ioe) { + I18n msg = InfinispanConnectorI18n.configFileNotFound; + throw new RepositorySourceException(this.name, msg.text(configName), ioe); + } + + try { + cacheManager = new DefaultCacheManager(configStream); + } catch (IOException ioe) { + I18n msg = InfinispanConnectorI18n.configFileNotValid; + throw new RepositorySourceException(this.name, msg.text(configName), ioe); + } finally { + try { + configStream.close(); + } catch (IOException ioe) { + } + } + + } + } // Now create the repository ... ExecutionContext execContext = repositoryContext.getExecutionContext(); this.repository = new InfinispanRepository(execContext, this.name, this.rootNodeUuid, this.defaultWorkspace, cacheManager, this.predefinedWorkspaces); - - // // Create the set of initial workspaces ... - // String[] workspaceNames = getPredefinedWorkspaceNames(); - // if (workspaceNames.length != 0) { - // InfinispanTransaction txn = repository.startTransaction(execContext, false); - // try { - // for (String initialName : getPredefinedWorkspaceNames()) { - // repository.createWorkspace(txn, initialName, CreateConflictBehavior.DO_NOT_CREATE, null); - // } - // } finally { - // txn.commit(); - // } - // } } return new Connection(this, repository); Index: extensions/modeshape-connector-infinispan/src/main/resources/org/modeshape/connector/infinispan/InfinispanConnectorI18n.properties =================================================================== --- extensions/modeshape-connector-infinispan/src/main/resources/org/modeshape/connector/infinispan/InfinispanConnectorI18n.properties (revision 1811) +++ extensions/modeshape-connector-infinispan/src/main/resources/org/modeshape/connector/infinispan/InfinispanConnectorI18n.properties (working copy) @@ -26,4 +26,6 @@ connectorName = Infinispan Connector propertyIsRequired = The {0} property is required but has no value errorSerializingCachePolicyInSource = Error serializing a {0} instance owned by the {1} InfinispanSource objectFoundInJndiWasNotCacheManager = Object in JNDI at {0} found by InfinispanSource {1} was expected to be a org.infinispan.CacheManager but instead was {2} -unableToCreateWorkspace = Unable to create the Infinispan cache for the "{0}" workspace in the {1} InfinispanSource \ No newline at end of file +unableToCreateWorkspace = Unable to create the Infinispan cache for the "{0}" workspace in the {1} InfinispanSource +configFileNotFound = Could not find the configuration file "{0}" on the classpath or file system +configFileNotValid = Could not initialize Infinispan from the configuration file at "{0}" Index: extensions/modeshape-connector-infinispan/src/test/java/org/modeshape/connector/infinispan/PersistentInfinispanConnectorTest.java =================================================================== --- extensions/modeshape-connector-infinispan/src/test/java/org/modeshape/connector/infinispan/PersistentInfinispanConnectorTest.java (revision 1811) +++ extensions/modeshape-connector-infinispan/src/test/java/org/modeshape/connector/infinispan/PersistentInfinispanConnectorTest.java (working copy) @@ -42,6 +42,7 @@ import org.modeshape.graph.Graph; import org.modeshape.graph.Subgraph; import org.modeshape.graph.connector.RepositoryConnection; import org.modeshape.graph.connector.RepositoryContext; +import org.modeshape.graph.connector.RepositorySourceException; /** * @@ -52,8 +53,6 @@ public class PersistentInfinispanConnectorTest { private ExecutionContext context; private InfinispanSource source; - private CacheManager cacheManager; - private Context mockJndi; private RepositoryContext mockRepositoryContext; private Graph graph; @@ -61,13 +60,6 @@ public class PersistentInfinispanConnectorTest { public void beforeEach() throws Exception { context = new ExecutionContext(); - // Create the cache manager ... - cacheManager = new DefaultCacheManager("infinispan_persistent_config.xml"); // looks on classpath first - // Set up the mock JNDI ... - mockJndi = mock(Context.class); - when(mockJndi.lookup(anyString())).thenReturn(null); - when(mockJndi.lookup(JNDI_NAME)).thenReturn(cacheManager); - mockRepositoryContext = mock(RepositoryContext.class); when(mockRepositoryContext.getExecutionContext()).thenReturn(context); @@ -77,8 +69,6 @@ public class PersistentInfinispanConnectorTest { source.setPredefinedWorkspaceNames(predefinedWorkspaceNames); source.setDefaultWorkspaceName(predefinedWorkspaceNames[0]); source.setCreatingWorkspacesAllowed(true); - source.setContext(mockJndi); - source.setCacheManagerJndiName(JNDI_NAME); source.initialize(mockRepositoryContext); } @@ -101,24 +91,27 @@ public class PersistentInfinispanConnectorTest { return graph; } - @Test - public void shouldShutdownWithoutOpeningConnections() { + private void setupCacheThroughJndi() throws Exception { + // Create the cache manager ... + CacheManager cacheManager = new DefaultCacheManager("infinispan_persistent_config.xml"); // looks on classpath first + // Set up the mock JNDI ... + Context mockJndi = mock(Context.class); + when(mockJndi.lookup(anyString())).thenReturn(null); + when(mockJndi.lookup(JNDI_NAME)).thenReturn(cacheManager); + source.setContext(mockJndi); + source.setCacheManagerJndiName(JNDI_NAME); } - @Test - public void shouldShutdownAfterOpeningConnections() { - RepositoryConnection connection = source.getConnection(); - connection.close(); + private void setupCacheThroughClasspath() throws Exception { + source.setCacheConfigurationName("/infinispan_persistent_config.xml"); } - @Test - public void shouldHaveRootNode() { - assertThat(graph().getNodeAt("/"), is(notNullValue())); + private void setupCacheThroughFile() throws Exception { + source.setCacheConfigurationName("./src/test/resources/infinispan_persistent_config.xml"); } - @Test - public void shouldAllowCreatingAndReReadingNodes() { + private void testWriteAndRead() { Subgraph subgraph = graph().getSubgraphOfDepth(10).at("/"); assertThat(subgraph.getNode("/"), is(notNullValue())); // System.out.println(subgraph); @@ -127,5 +120,50 @@ public class PersistentInfinispanConnectorTest { assertThat(subgraph.getNode("/"), is(notNullValue())); assertThat(subgraph.getNode("/a").getProperty("prop1").getFirstValue(), is((Object)"value1")); // System.out.println(subgraph); + + } + + @Test + public void shouldShutdownWithoutOpeningConnections() throws Exception { + setupCacheThroughJndi(); + source.close(); + } + + @Test + public void shouldShutdownAfterOpeningConnections() throws Exception { + setupCacheThroughJndi(); + RepositoryConnection connection = source.getConnection(); + connection.close(); + } + + @Test + public void shouldHaveRootNode() throws Exception { + setupCacheThroughJndi(); + assertThat(graph().getNodeAt("/"), is(notNullValue())); + } + + @Test + public void shouldAllowCreatingAndReReadingNodesFromJndiCache() throws Exception { + setupCacheThroughJndi(); + testWriteAndRead(); + } + + @Test + public void shouldAllowCreatingAndReReadingNodesFromClasspathConfig() throws Exception { + setupCacheThroughClasspath(); + testWriteAndRead(); + } + + @Test + public void shouldAllowCreatingAndReReadingNodesFromFileConfig() throws Exception { + setupCacheThroughFile(); + testWriteAndRead(); + } + + @Test( expected = RepositorySourceException.class ) + public void shouldThrowExceptionIfBadConfigFileSpecified() { + source.setCacheConfigurationName("./thisFileIsNotOnTheClasspathOrTheFileSystem.xml"); + source.getConnection(); + } }