Author: rhauch
Date: 2008-09-11 19:33:03 -0400 (Thu, 11 Sep 2008)
New Revision: 515
Added:
trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/BasicExecutionContextFactory.java
trunk/docs/examples/gettingstarted/repositories/src/main/java/org/jboss/example/dna/repository/ConsoleInput.java
trunk/docs/examples/gettingstarted/repositories/src/main/java/org/jboss/example/dna/repository/UserInterface.java
trunk/docs/examples/gettingstarted/repositories/src/main/resources/aircraft.xml
trunk/docs/examples/gettingstarted/repositories/src/main/resources/cars.xml
trunk/docs/examples/gettingstarted/repositories/src/main/resources/configRepository.xml
trunk/docs/examples/gettingstarted/repositories/src/test/java/org/
trunk/docs/examples/gettingstarted/repositories/src/test/java/org/jboss/
trunk/docs/examples/gettingstarted/repositories/src/test/java/org/jboss/example/
trunk/docs/examples/gettingstarted/repositories/src/test/java/org/jboss/example/dna/
trunk/docs/examples/gettingstarted/repositories/src/test/java/org/jboss/example/dna/repository/
trunk/docs/examples/gettingstarted/repositories/src/test/java/org/jboss/example/dna/repository/RepositoryClientTest.java
trunk/extensions/dna-connector-inmemory/src/test/resources/log4j.properties
Modified:
trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryImporter.java
trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryService.java
trunk/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/xml/XmlSequencer.java
trunk/dna-repository/src/test/java/org/jboss/dna/repository/RepositoryImporterTest.java
trunk/dna-repository/src/test/java/org/jboss/dna/repository/RepositoryServiceTest.java
trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositoryConnectionPool.java
trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/BasicName.java
trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/BasicNamespaceRegistry.java
trunk/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/BasicNameTest.java
trunk/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/BasicNamespaceRegistryTest.java
trunk/docs/examples/gettingstarted/repositories/pom.xml
trunk/docs/examples/gettingstarted/repositories/src/main/assembly/basic.xml
trunk/docs/examples/gettingstarted/repositories/src/main/java/org/jboss/example/dna/repository/RepositoryClient.java
trunk/docs/examples/gettingstarted/repositories/src/main/resources/log4j.properties
trunk/extensions/dna-connector-inmemory/src/main/java/org/jboss/dna/connector/inmemory/InMemoryConnectorI18n.java
trunk/extensions/dna-connector-inmemory/src/main/java/org/jboss/dna/connector/inmemory/InMemoryRepository.java
trunk/extensions/dna-connector-inmemory/src/main/java/org/jboss/dna/connector/inmemory/InMemoryRepositoryConnection.java
trunk/extensions/dna-connector-inmemory/src/main/java/org/jboss/dna/connector/inmemory/InMemoryRepositorySource.java
trunk/extensions/dna-connector-inmemory/src/main/resources/org/jboss/dna/connector/inmemory/InMemoryConnectorI18n.properties
Log:
DNA-222 - Create Getting Started example application for repositories
http://jira.jboss.com/jira/browse/DNA-222
Created a simple application (subproject under getting started examples) that allows a
user to pick from a list of repositories so they can interactively navigate and explore
them. Currently, only a console user interface is implemented. Several repositories are
used: a configuration repository (which defines the others), two in-memory repositories
("Cars" and "Airplanes"), a federated repository ("Vehicles"
that federates "Cars" and "Airplanes" below a "vehicles"
root), and a cache repository used by "Vehicles".
Most of the unit testing is complete, and several issues have been fixed in other
components. However, there still are a few outstanding issues as well as testing of the
interactive mode. So, still a bit more work to do.
Modified:
trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryImporter.java
===================================================================
---
trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryImporter.java 2008-09-10
18:05:54 UTC (rev 514)
+++
trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryImporter.java 2008-09-11
23:33:03 UTC (rev 515)
@@ -21,6 +21,7 @@
*/
package org.jboss.dna.repository;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
@@ -33,11 +34,13 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import net.jcip.annotations.Immutable;
import org.jboss.dna.common.i18n.I18n;
import org.jboss.dna.common.monitor.ProgressMonitor;
import org.jboss.dna.common.monitor.SimpleProgressMonitor;
import org.jboss.dna.common.util.ArgCheck;
import org.jboss.dna.common.util.Logger;
+import org.jboss.dna.repository.sequencers.xml.DnaXmlLexicon;
import org.jboss.dna.repository.sequencers.xml.XmlSequencer;
import org.jboss.dna.spi.ExecutionContext;
import org.jboss.dna.spi.connector.RepositoryConnection;
@@ -69,27 +72,110 @@
*/
public class RepositoryImporter {
+ public interface ImportSpecification {
+ /**
+ * Specify the location where the content is to be imported, and then perform the
import. This is equivalent to calling
+ * <code>{@link #into(String, Path)
into(sourceName,rootPath)}</code>.
+ *
+ * @param sourceName the name of the source into which the content is to be
imported
+ * @throws IllegalArgumentException if the <code>uri</code> or path
are null
+ * @throws IOException if there is a problem reading the content
+ * @throws RepositorySourceException if there is a problem while writing the
content to the {@link RepositorySource
+ * repository source}
+ */
+ void into( String sourceName ) throws IOException, RepositorySourceException;
+
+ /**
+ * Specify the location where the content is to be imported, and then perform the
import.
+ *
+ * @param sourceName the name of the source into which the content is to be
imported
+ * @param pathInSource the path in the {@link RepositorySource repository source}
named <code>sourceName</code> where the
+ * content is to be written; may not be null
+ * @throws IllegalArgumentException if the <code>uri</code> or path
are null
+ * @throws IOException if there is a problem reading the content
+ * @throws RepositorySourceException if there is a problem while writing the
content to the {@link RepositorySource
+ * repository source}
+ */
+ void into( String sourceName,
+ Path pathInSource ) throws IOException, RepositorySourceException;
+ }
+
+ @Immutable
+ protected abstract class ImportedContentUsingSequencer implements ImportSpecification
{
+ private final StreamSequencer sequencer;
+
+ protected ImportedContentUsingSequencer( StreamSequencer sequencer ) {
+ this.sequencer = sequencer;
+ }
+
+ protected StreamSequencer getSequencer() {
+ return this.sequencer;
+ }
+
+ protected NodeConflictBehavior getConflictBehavior() {
+ return NodeConflictBehavior.UPDATE;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.RepositoryImporter.ImportSpecification#into(java.lang.String)
+ */
+ public void into( String sourceName ) throws IOException,
RepositorySourceException {
+ Path root =
getContext().getValueFactories().getPathFactory().createRootPath();
+ into(sourceName, root);
+ }
+ }
+
+ @Immutable
+ protected class UriImportedContent extends ImportedContentUsingSequencer {
+ private final URI uri;
+ private final String mimeType;
+
+ protected UriImportedContent( StreamSequencer sequencer,
+ URI uri,
+ String mimeType ) {
+ super(sequencer);
+ this.uri = uri;
+ this.mimeType = mimeType;
+ }
+
+ /**
+ * @return mimeType
+ */
+ public String getMimeType() {
+ return mimeType;
+ }
+
+ /**
+ * @return uri
+ */
+ public URI getUri() {
+ return uri;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.RepositoryImporter.ImportSpecification#into(java.lang.String,
+ * org.jboss.dna.spi.graph.Path)
+ */
+ public void into( String sourceName,
+ Path pathInSource ) throws IOException,
RepositorySourceException {
+ ArgCheck.isNotNull(sourceName, "sourceName");
+ ArgCheck.isNotNull(pathInSource, "pathInSource");
+ importWithSequencer(getSequencer(), uri, mimeType, sourceName, pathInSource,
getConflictBehavior());
+ }
+ }
+
private final RepositoryConnectionFactory sources;
- private final String sourceName;
private final ExecutionContext context;
- public RepositoryImporter( RepositorySource source,
- ExecutionContext context ) {
- ArgCheck.isNotNull(source, "source");
- ArgCheck.isNotNull(context, "context");
- this.sources = new SingleRepositorySourceConnectionFactory(source);
- this.sourceName = source.getName();
- this.context = context;
- }
-
public RepositoryImporter( RepositoryConnectionFactory sources,
- String sourceName,
ExecutionContext context ) {
ArgCheck.isNotNull(sources, "sources");
- ArgCheck.isNotEmpty(sourceName, "sourceName");
ArgCheck.isNotNull(context, "context");
this.sources = sources;
- this.sourceName = sourceName;
this.context = context;
}
@@ -103,23 +189,68 @@
}
/**
+ * Import the content from the XML file at the supplied URI, specifying on the
returned {@link ImportSpecification} where the
+ * content is to be imported.
+ *
+ * @param uri the URI where the importer can read the content that is to be imported
+ * @return the object that should be used to specify into which the content is to be
imported
+ * @throws IllegalArgumentException if the <code>uri</code> or
destination path are null
+ */
+ public ImportSpecification importXml( URI uri ) {
+ ArgCheck.isNotNull(uri, "uri");
+
+ // Create the sequencer ...
+ StreamSequencer sequencer = new XmlSequencer();
+ return new UriImportedContent(sequencer, uri, "text/xml");
+ }
+
+ /**
+ * Import the content from the XML file at the supplied file location, specifying on
the returned {@link ImportSpecification}
+ * where the content is to be imported.
+ *
+ * @param pathToFile the path to the XML file that should be imported.
+ * @return the object that should be used to specify into which the content is to be
imported
+ * @throws IllegalArgumentException if the <code>uri</code> or
destination path are null
+ */
+ public ImportSpecification importXml( String pathToFile ) {
+ ArgCheck.isNotNull(pathToFile, "pathToFile");
+ return importXml(new File(pathToFile).toURI());
+ }
+
+ /**
+ * Import the content from the supplied XML file, specifying on the returned {@link
ImportSpecification} where the content is
+ * to be imported.
+ *
+ * @param file the XML file that should be imported.
+ * @return the object that should be used to specify into which the content is to be
imported
+ * @throws IllegalArgumentException if the <code>uri</code> or
destination path are null
+ */
+ public ImportSpecification importXml( File file ) {
+ ArgCheck.isNotNull(file, "file");
+ return importXml(file.toURI());
+ }
+
+ /**
* Read the content from the supplied URI and import into the repository at the
supplied location.
*
* @param uri the URI where the importer can read the content that is to be imported
- * @param destinationPathInSource
+ * @param sourceName the name of the source into which the content is to be imported
+ * @param destinationPathInSource the path in the {@link RepositorySource repository
source} where the content is to be
+ * written; may not be null
* @throws IllegalArgumentException if the <code>uri</code> or
destination path are null
* @throws IOException if there is a problem reading the content
* @throws RepositorySourceException if there is a problem while writing the content
to the {@link RepositorySource repository
* source}
*/
public void importXml( URI uri,
+ String sourceName,
Path destinationPathInSource ) throws IOException,
RepositorySourceException {
ArgCheck.isNotNull(uri, "uri");
ArgCheck.isNotNull(destinationPathInSource,
"destinationPathInSource");
// Create the sequencer ...
StreamSequencer sequencer = new XmlSequencer();
- importWithSequencer(sequencer, uri, "text/xml",
destinationPathInSource, NodeConflictBehavior.UPDATE);
+ importWithSequencer(sequencer, uri, "text/xml", sourceName,
destinationPathInSource, NodeConflictBehavior.UPDATE);
}
/**
@@ -129,6 +260,7 @@
* @param sequencer the sequencer that should be used; may not be null
* @param contentUri the URI where the content can be found; may not be null
* @param mimeType the MIME type for the content; may not be null
+ * @param sourceName the name of the source into which the content is to be imported
* @param destinationPathInSource the path in the {@link RepositorySource repository
source} where the content is to be
* written; may not be null
* @param conflictBehavior the behavior when a node is to be created when an existing
node already exists; defaults to
@@ -140,11 +272,13 @@
protected void importWithSequencer( StreamSequencer sequencer,
URI contentUri,
String mimeType,
+ String sourceName,
Path destinationPathInSource,
NodeConflictBehavior conflictBehavior ) throws
IOException, RepositorySourceException {
assert sequencer != null;
assert contentUri != null;
assert mimeType != null;
+ assert sourceName != null;
assert destinationPathInSource != null;
conflictBehavior = conflictBehavior != null ? conflictBehavior :
NodeConflictBehavior.UPDATE;
@@ -183,7 +317,11 @@
// Now execute the commands against the repository ...
RepositoryConnection connection = null;
try {
- connection = sources.createConnection(this.sourceName);
+ connection = sources.createConnection(sourceName);
+ if (connection == null) {
+ I18n msg = RepositoryI18n.unableToFindRepositorySourceWithName;
+ throw new RepositorySourceException(msg.text(sourceName));
+ }
connection.execute(context, commands);
} finally {
if (connection != null) {
@@ -237,6 +375,8 @@
private final Map<Path, BasicCreateNodeCommand> createNodeCommands = new
HashMap<Path, BasicCreateNodeCommand>();
private final NodeConflictBehavior conflictBehavior;
private final Path destinationPath;
+ private final NameFactory nameFactory;
+ private final Name primaryTypeName;
protected ImporterCommands( Path destinationPath,
NodeConflictBehavior conflictBehavior ) {
@@ -244,6 +384,8 @@
ArgCheck.isNotNull(conflictBehavior, "conflictBehavior");
this.conflictBehavior = conflictBehavior;
this.destinationPath = destinationPath;
+ this.nameFactory = getContext().getValueFactories().getNameFactory();
+ this.primaryTypeName = this.nameFactory.create("jcr:primaryType");
}
/**
@@ -287,6 +429,11 @@
public void setProperty( Path nodePath,
Name propertyName,
Object... values ) {
+ // Ignore the property value if the "jcr:primaryType" is
"dnaxml:document" ...
+ if (this.primaryTypeName.equals(propertyName) && values.length == 1)
{
+ Name typeName = this.nameFactory.create(values[0]);
+ if (DnaXmlLexicon.DOCUMENT.equals(typeName)) return;
+ }
PathFactory pathFactory = getFactories().getPathFactory();
if (nodePath.isAbsolute())
nodePath.relativeTo(pathFactory.createRootPath());
nodePath = pathFactory.create(destinationPath,
nodePath).getNormalizedPath();
Modified:
trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryService.java
===================================================================
---
trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryService.java 2008-09-10
18:05:54 UTC (rev 514)
+++
trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryService.java 2008-09-11
23:33:03 UTC (rev 515)
@@ -134,7 +134,7 @@
* @param sources the source manager
* @param configurationSourceName the name of the {@link RepositorySource} that is
the configuration repository
* @param pathToConfigurationRoot the path of the node in the configuration source
repository that should be treated by this
- * service as the root of the service's configuration; if null, then
"/" is used
+ * service as the root of the service's configuration; if null, then
"/dna:system" is used
* @param context the execution context in which this service should run
* @param classLoaderFactory the class loader factory used to instantiate {@link
RepositorySource} instances; may be null if
* this instance should use a default factory that attempts to load classes
first from the
@@ -150,7 +150,7 @@
ArgCheck.isNotNull(configurationSourceName,
"configurationSourceName");
ArgCheck.isNotNull(sources, "sources");
ArgCheck.isNotNull(context, "context");
- if (pathToConfigurationRoot == null) pathToConfigurationRoot =
context.getValueFactories().getPathFactory().createRootPath();
+ if (pathToConfigurationRoot == null) pathToConfigurationRoot =
context.getValueFactories().getPathFactory().create("/dna:system");
this.sources = sources;
this.pathToConfigurationRoot = pathToConfigurationRoot;
this.configurationSourceName = configurationSourceName;
@@ -245,6 +245,8 @@
}
} catch (Throwable err) {
throw new
FederationException(RepositoryI18n.errorStartingRepositoryService.text());
+ } finally {
+ executor.close();
}
this.started.set(true);
}
Modified:
trunk/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/xml/XmlSequencer.java
===================================================================
---
trunk/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/xml/XmlSequencer.java 2008-09-10
18:05:54 UTC (rev 514)
+++
trunk/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/xml/XmlSequencer.java 2008-09-11
23:33:03 UTC (rev 515)
@@ -568,8 +568,21 @@
String name,
Attributes attributes ) throws SAXException {
stopIfCancelled();
- startElement(nameFactory.create(name));
- output.setProperty(path, getPrimaryTypeName(), getDefaultPrimaryType());
+ // Look for the "jcr:name" attribute, and use that if it's
there
+ Name type = getDefaultPrimaryType();
+ Name nameObj = nameFactory.create(name);
+ for (int ndx = 0, len = attributes.getLength(); ndx < len; ++ndx) {
+ String ns = attributes.getURI(ndx);
+ String attrLocalName = attributes.getLocalName(ndx);
+ Object value = attributes.getValue(ndx);
+ String jcrNsUri =
context.getNamespaceRegistry().getNamespaceForPrefix("jcr");
+ if (jcrNsUri != null && jcrNsUri.equals(ns) &&
attrLocalName.equals("name")) {
+ nameObj = nameFactory.create(value);
+ break;
+ }
+ }
+ startElement(nameObj);
+ output.setProperty(path, getPrimaryTypeName(), type);
// Output this element's attributes using the attribute's namespace,
if supplied, or the current namespace in scope.
String inheritedNs = nsStack.getFirst();
for (int ndx = 0, len = attributes.getLength(); ndx < len; ++ndx) {
@@ -580,6 +593,9 @@
if (jcrNsUri != null && jcrNsUri.equals(ns) &&
attrLocalName.equals("primaryType")) {
value = nameFactory.create(value);
}
+ if (jcrNsUri != null && jcrNsUri.equals(ns) &&
attrLocalName.equals("name")) {
+ continue;
+ }
output.setProperty(path, nameFactory.create(ns.length() == 0 ?
inheritedNs : ns, attrLocalName), value);
}
updateProgress();
Modified:
trunk/dna-repository/src/test/java/org/jboss/dna/repository/RepositoryImporterTest.java
===================================================================
---
trunk/dna-repository/src/test/java/org/jboss/dna/repository/RepositoryImporterTest.java 2008-09-10
18:05:54 UTC (rev 514)
+++
trunk/dna-repository/src/test/java/org/jboss/dna/repository/RepositoryImporterTest.java 2008-09-11
23:33:03 UTC (rev 515)
@@ -83,7 +83,7 @@
context.getNamespaceRegistry().register("nt",
"http://www.jcp.org/jcr/nt/1.0");
sourceName = "sourceA";
destinationPath =
context.getValueFactories().getPathFactory().create("/a/b");
- importer = new RepositoryImporter(sources, sourceName, context);
+ importer = new RepositoryImporter(sources, context);
connection = new MockRepositoryConnection();
stub(sources.createConnection(sourceName)).toReturn(connection);
}
@@ -91,10 +91,11 @@
@Test
public void shouldImportXmlContentAndGenerateTheCorrectCommands() throws Exception {
System.out.println(xmlContent);
- importer.importXml(xmlContent, destinationPath); // writes commands as
CompositeCommand to 'lastExecutedCommand'
+ importer.importXml(xmlContent).into(sourceName, destinationPath); // writes
commands as CompositeCommand to
+ // 'lastExecutedCommand'
assertThat(lastExecutedCommand, is(instanceOf(CompositeCommand.class)));
Iterator<GraphCommand> iter =
((CompositeCommand)lastExecutedCommand).iterator();
- assertCreateNode(iter, "/a/b/",
"jcr:primaryType={http://www.jboss.org/dna/xml/1.0}document");
+ // assertCreateNode(iter, "/a/b/",
"jcr:primaryType={http://www.jboss.org/dna/xml/1.0}document");
assertCreateNode(iter, "/a/b/dnaxml:comment[1]", "any
properties"); // jcr:primaryType and dnaxml:commentContent
assertCreateNode(iter, "/a/b/dna:system[1]",
"jcr:primaryType={http://www.jcp.org/jcr/nt/1.0}unstructured");
assertCreateNode(iter, "/a/b/dna:system[1]/dnaxml:comment[1]",
"any properties");
Modified:
trunk/dna-repository/src/test/java/org/jboss/dna/repository/RepositoryServiceTest.java
===================================================================
---
trunk/dna-repository/src/test/java/org/jboss/dna/repository/RepositoryServiceTest.java 2008-09-10
18:05:54 UTC (rev 514)
+++
trunk/dna-repository/src/test/java/org/jboss/dna/repository/RepositoryServiceTest.java 2008-09-11
23:33:03 UTC (rev 515)
@@ -45,6 +45,7 @@
import org.jboss.dna.spi.connector.RepositorySource;
import org.jboss.dna.spi.connector.SimpleRepository;
import org.jboss.dna.spi.connector.SimpleRepositorySource;
+import org.jboss.dna.spi.graph.Path;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -62,6 +63,7 @@
private SimpleRepositorySource configRepositorySource;
private RepositoryConnection configRepositoryConnection;
private ExecutionContext context;
+ private Path root;
@Mock
private RepositorySourceManager sources;
@@ -77,6 +79,7 @@
configRepositorySource.setName(configSourceName);
configRepositoryConnection = configRepositorySource.getConnection();
stub(sources.createConnection(configSourceName)).toReturn(configRepositoryConnection);
+ root = context.getValueFactories().getPathFactory().createRootPath();
service = new RepositoryService(sources, configSourceName, context, null);
}
@@ -150,7 +153,7 @@
sources.addSource(configRepositorySource);
assertThat(sources.getSources(),
hasItems((RepositorySource)configRepositorySource));
assertThat(sources.getSources().size(), is(1));
- service = new RepositoryService(sources, configSourceName, context, null);
+ service = new RepositoryService(sources, configSourceName, root, context, null);
// Set up the configuration repository to contain 3 sources ...
final String className = SimpleRepositorySource.class.getName();
Added:
trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/BasicExecutionContextFactory.java
===================================================================
---
trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/BasicExecutionContextFactory.java
(rev 0)
+++
trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/BasicExecutionContextFactory.java 2008-09-11
23:33:03 UTC (rev 515)
@@ -0,0 +1,166 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.spi.connector;
+
+import java.security.AccessControlContext;
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+import org.jboss.dna.spi.ExecutionContext;
+import org.jboss.dna.spi.ExecutionContextFactory;
+import org.jboss.dna.spi.graph.NamespaceRegistry;
+import org.jboss.dna.spi.graph.impl.BasicNamespaceRegistry;
+
+/**
+ * Basic implementation of a {@link ExecutionContextFactory} that returns {@link
BasicExecutionContext basic}
+ * {@link ExecutionContext}s.
+ *
+ * @author Randall Hauch
+ */
+public class BasicExecutionContextFactory implements ExecutionContextFactory {
+
+ private final NamespaceRegistry defaultNamespaces = new BasicNamespaceRegistry();
+
+ /**
+ * Create a new instance of this factory.
+ */
+ public BasicExecutionContextFactory() {
+ defaultNamespaces.register("jcr",
"http://www.jcp.org/jcr/1.0");
+ defaultNamespaces.register("mix",
"http://www.jcp.org/jcr/mix/1.0");
+ defaultNamespaces.register("nt",
"http://www.jcp.org/jcr/nt/1.0");
+ defaultNamespaces.register("dna",
"http://www.jboss.org/dna");
+ defaultNamespaces.register("dnadtd",
"http://www.jboss.org/dna/dtd/1.0");
+ defaultNamespaces.register("dnaxml",
"http://www.jboss.org/dna/xml/1.0");
+ }
+
+ /**
+ * Create a new instance of this factory.
+ *
+ * @param defaultNamespaceUri the URI of the namespace that should be used with names
that have no specified namespace prefix
+ * @throws IllegalArgumentException if the URI is null
+ */
+ public BasicExecutionContextFactory( String defaultNamespaceUri ) {
+ this();
+ defaultNamespaces.register("", defaultNamespaceUri);
+ }
+
+ /**
+ * @return defaultNamespaces
+ */
+ public NamespaceRegistry getDefaultNamespaces() {
+ return defaultNamespaces;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.spi.ExecutionContextFactory#create()
+ */
+ public ExecutionContext create() {
+ ExecutionContext context = new BasicExecutionContext();
+ initialize(context);
+ return context;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.spi.ExecutionContextFactory#create(java.security.AccessControlContext)
+ */
+ public ExecutionContext create( AccessControlContext accessControlContext ) {
+ ExecutionContext context = new BasicExecutionContext(accessControlContext);
+ initialize(context);
+ return context;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.spi.ExecutionContextFactory#create(javax.security.auth.login.LoginContext)
+ */
+ public ExecutionContext create( LoginContext loginContext ) {
+ ExecutionContext context = new BasicExecutionContext(loginContext);
+ initialize(context);
+ return context;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.spi.ExecutionContextFactory#create(java.lang.String)
+ */
+ public ExecutionContext create( String name ) throws LoginException {
+ LoginContext loginContext = new LoginContext(name);
+ ExecutionContext context = new BasicExecutionContext(loginContext);
+ initialize(context);
+ return context;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.spi.ExecutionContextFactory#create(java.lang.String,
javax.security.auth.Subject)
+ */
+ public ExecutionContext create( String name,
+ Subject subject ) throws LoginException {
+ LoginContext loginContext = new LoginContext(name, subject);
+ ExecutionContext context = new BasicExecutionContext(loginContext);
+ initialize(context);
+ return context;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.spi.ExecutionContextFactory#create(java.lang.String,
javax.security.auth.callback.CallbackHandler)
+ */
+ public ExecutionContext create( String name,
+ CallbackHandler callbackHandler ) throws
LoginException {
+ LoginContext loginContext = new LoginContext(name, callbackHandler);
+ ExecutionContext context = new BasicExecutionContext(loginContext);
+ initialize(context);
+ return context;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.spi.ExecutionContextFactory#create(java.lang.String,
javax.security.auth.Subject,
+ * javax.security.auth.callback.CallbackHandler)
+ */
+ public ExecutionContext create( String name,
+ Subject subject,
+ CallbackHandler callbackHandler ) throws
LoginException {
+ LoginContext loginContext = new LoginContext(name, subject, callbackHandler);
+ ExecutionContext context = new BasicExecutionContext(loginContext);
+ initialize(context);
+ return context;
+ }
+
+ protected synchronized void initialize( ExecutionContext context ) {
+ for (String uri : this.defaultNamespaces.getRegisteredNamespaceUris()) {
+ String prefix = this.defaultNamespaces.getPrefixForNamespaceUri(uri, false);
+ context.getNamespaceRegistry().register(prefix, uri);
+ }
+ }
+}
Property changes on:
trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/BasicExecutionContextFactory.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified:
trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositoryConnectionPool.java
===================================================================
---
trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositoryConnectionPool.java 2008-09-10
18:05:54 UTC (rev 514)
+++
trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositoryConnectionPool.java 2008-09-11
23:33:03 UTC (rev 515)
@@ -638,19 +638,22 @@
*/
public boolean awaitTermination( long timeout,
TimeUnit unit ) throws InterruptedException {
+ this.logger.trace("Awaiting termination");
long nanos = unit.toNanos(timeout);
final ReentrantLock mainLock = this.mainLock;
try {
mainLock.lock();
for (;;) {
- // this.logger.debug("---> Run state = {}; condition = {}",
runState, termination);
+ // this.logger.trace("---> Run state = {0}; condition = {1}, {2}
open", runState, termination, poolSize);
if (runState == TERMINATED) return true;
if (nanos <= 0) return false;
nanos = termination.awaitNanos(nanos);
- // this.logger.debug("---> Done waiting: run state = {};
condition = {}", runState, termination);
+ //this.logger.trace("---> Done waiting: run state = {0};
condition = {1}, {2} open",runState,termination,poolSize)
+ // ;
}
} finally {
mainLock.unlock();
+ this.logger.trace("Finished awaiting termination");
}
}
@@ -798,7 +801,7 @@
}
// Close the connection if we're supposed to (do it outside of the main
lock)...
if (wrapperToClose != null) {
- closeConnection(wrapper);
+ closeConnection(wrapperToClose);
}
}
@@ -853,7 +856,7 @@
RepositoryConnection original = wrapper.getOriginal();
assert original != null;
try {
- this.logger.debug("Closing repository connection to {0}",
getSourceName());
+ this.logger.debug("Closing repository connection to {0} ({1} open
connections remain)", getSourceName(), poolSize);
original.close();
} finally {
final ReentrantLock mainLock = this.mainLock;
@@ -862,7 +865,7 @@
// No matter what reduce the pool size count
--this.poolSize;
// And if shutting down and this was the last connection being used...
- if (this.runState == SHUTDOWN && this.poolSize <= 0) {
+ if ((runState == SHUTDOWN || runState == STOP) && this.poolSize
<= 0) {
// then signal anybody that has called
"awaitTermination(...)"
this.logger.trace("Signalling termination of repository
connection pool for {0}", getSourceName());
this.runState = TERMINATED;
@@ -890,7 +893,7 @@
}
int numClosed = extraConnections.size();
this.poolSize -= numClosed;
- this.logger.trace("Drained {0} unused connections", numClosed);
+ this.logger.trace("Drained {0} unused connections ({1} open connections
remain)", numClosed, poolSize);
return numClosed;
}
Modified: trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/BasicName.java
===================================================================
--- trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/BasicName.java 2008-09-10
18:05:54 UTC (rev 514)
+++ trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/BasicName.java 2008-09-11
23:33:03 UTC (rev 515)
@@ -31,125 +31,125 @@
/**
* A basic implementation of {@link Name}.
- *
+ *
* @author Randall Hauch
* @author John Verhaeg
*/
@Immutable
public class BasicName implements Name {
- /**
+ /**
*/
private static final long serialVersionUID = -1737537720336990144L;
private final String namespaceUri;
- private final String localName;
- private final int hc;
+ private final String localName;
+ private final int hc;
- public BasicName( String namespaceUri,
- String localName ) {
- ArgCheck.isNotEmpty(localName, "localName");
- this.namespaceUri = namespaceUri != null ? namespaceUri.trim() : "";
- this.localName = localName != null ? localName.trim() : "";
- this.hc = HashCode.compute(this.namespaceUri, this.localName);
- }
+ public BasicName( String namespaceUri,
+ String localName ) {
+ ArgCheck.isNotEmpty(localName, "localName");
+ this.namespaceUri = namespaceUri != null ? namespaceUri.trim() : "";
+ this.localName = localName != null ? localName.trim() : "";
+ this.hc = HashCode.compute(this.namespaceUri, this.localName);
+ }
- /**
- * {@inheritDoc}
- */
- public String getLocalName() {
- return this.localName;
- }
+ /**
+ * {@inheritDoc}
+ */
+ public String getLocalName() {
+ return this.localName;
+ }
- /**
- * {@inheritDoc}
- */
- public String getNamespaceUri() {
- return this.namespaceUri;
- }
+ /**
+ * {@inheritDoc}
+ */
+ public String getNamespaceUri() {
+ return this.namespaceUri;
+ }
- /**
- * {@inheritDoc}
- */
- public String getString() {
- return getString(Path.DEFAULT_ENCODER);
- }
+ /**
+ * {@inheritDoc}
+ */
+ public String getString() {
+ return getString(Path.DEFAULT_ENCODER);
+ }
- /**
- * {@inheritDoc}
- */
- public String getString( TextEncoder encoder ) {
- if (this.getNamespaceUri().length() == 0) {
- if (this.getLocalName().equals(Path.SELF)) return Path.SELF;
- if (this.getLocalName().equals(Path.PARENT)) return Path.PARENT;
- }
- if (encoder == null) encoder = Path.DEFAULT_ENCODER;
- return "{" + encoder.encode(this.namespaceUri) + "}" +
encoder.encode(this.localName);
- }
+ /**
+ * {@inheritDoc}
+ */
+ public String getString( TextEncoder encoder ) {
+ if (this.getNamespaceUri().length() == 0) {
+ if (this.getLocalName().equals(Path.SELF)) return Path.SELF;
+ if (this.getLocalName().equals(Path.PARENT)) return Path.PARENT;
+ }
+ if (encoder == null) encoder = Path.DEFAULT_ENCODER;
+ return "{" + encoder.encode(this.namespaceUri) + "}" +
encoder.encode(this.localName);
+ }
- /**
- * {@inheritDoc}
- */
- public String getString( NamespaceRegistry namespaceRegistry ) {
- ArgCheck.isNotNull(namespaceRegistry, "namespaceRegistry");
- String prefix = namespaceRegistry.getPrefixForNamespaceUri(this.namespaceUri, true);
- if (prefix != null) {
- return prefix + ":" + this.localName;
- }
- return this.localName;
- }
+ /**
+ * {@inheritDoc}
+ */
+ public String getString( NamespaceRegistry namespaceRegistry ) {
+ ArgCheck.isNotNull(namespaceRegistry, "namespaceRegistry");
+ String prefix = namespaceRegistry.getPrefixForNamespaceUri(this.namespaceUri,
true);
+ if (prefix != null && prefix.length() != 0) {
+ return prefix + ":" + this.localName;
+ }
+ return this.localName;
+ }
- /**
- * {@inheritDoc}
- */
- public String getString( NamespaceRegistry namespaceRegistry,
- TextEncoder encoder ) {
- ArgCheck.isNotNull(namespaceRegistry, "namespaceRegistry");
- String prefix = namespaceRegistry.getPrefixForNamespaceUri(this.namespaceUri, true);
- if (prefix != null && prefix.length() != 0) {
- return encoder.encode(prefix) + ":" + encoder.encode(this.localName);
- }
- return this.localName;
- }
+ /**
+ * {@inheritDoc}
+ */
+ public String getString( NamespaceRegistry namespaceRegistry,
+ TextEncoder encoder ) {
+ ArgCheck.isNotNull(namespaceRegistry, "namespaceRegistry");
+ String prefix = namespaceRegistry.getPrefixForNamespaceUri(this.namespaceUri,
true);
+ if (prefix != null && prefix.length() != 0) {
+ return encoder.encode(prefix) + ":" +
encoder.encode(this.localName);
+ }
+ return this.localName;
+ }
- /**
- * {@inheritDoc}
- */
- public int compareTo( Name that ) {
- if (that == this) return 0;
- int diff = this.getNamespaceUri().compareTo(that.getNamespaceUri());
- if (diff != 0) return diff;
- diff = this.getLocalName().compareTo(that.getLocalName());
- return diff;
- }
+ /**
+ * {@inheritDoc}
+ */
+ public int compareTo( Name that ) {
+ if (that == this) return 0;
+ int diff = this.getNamespaceUri().compareTo(that.getNamespaceUri());
+ if (diff != 0) return diff;
+ diff = this.getLocalName().compareTo(that.getLocalName());
+ return diff;
+ }
- /**
- * {@inheritDoc}
- */
- @Override
- public int hashCode() {
- return this.hc;
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ return this.hc;
+ }
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean equals( Object obj ) {
- if (obj == this) return true;
- if (obj instanceof Name) {
- Name that = (Name)obj;
- if (!this.getNamespaceUri().equals(that.getNamespaceUri())) return false;
- return this.getLocalName().equals(that.getLocalName());
- }
- return false;
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof Name) {
+ Name that = (Name)obj;
+ if (!this.getNamespaceUri().equals(that.getNamespaceUri())) return false;
+ return this.getLocalName().equals(that.getLocalName());
+ }
+ return false;
+ }
- /**
- * {@inheritDoc}
- */
- @Override
- public String toString() {
- return "{" + this.namespaceUri + "}" + this.localName;
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return "{" + this.namespaceUri + "}" + this.localName;
+ }
}
Modified:
trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/BasicNamespaceRegistry.java
===================================================================
---
trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/BasicNamespaceRegistry.java 2008-09-10
18:05:54 UTC (rev 514)
+++
trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/BasicNamespaceRegistry.java 2008-09-11
23:33:03 UTC (rev 515)
@@ -109,7 +109,8 @@
/**
* {@inheritDoc}
*/
- public String getPrefixForNamespaceUri( String namespaceUri, boolean
generateIfMissing ) {
+ public String getPrefixForNamespaceUri( String namespaceUri,
+ boolean generateIfMissing ) {
ArgCheck.isNotNull(namespaceUri, "namespaceUri");
String prefix = null;
Lock lock = this.registryLock.readLock();
@@ -169,7 +170,8 @@
/**
* {@inheritDoc}
*/
- public String register( String prefix, String namespaceUri ) {
+ public String register( String prefix,
+ String namespaceUri ) {
ArgCheck.isNotNull(namespaceUri, "namespaceUri");
String previousNamespaceForPrefix = null;
namespaceUri = namespaceUri.trim();
@@ -180,9 +182,12 @@
prefix = prefix.trim();
previousNamespaceForPrefix = this.namespacesByPrefix.put(prefix,
namespaceUri);
String previousPrefix = this.prefixesByNamespace.put(namespaceUri, prefix);
- if (previousPrefix != null) {
+ if (previousPrefix != null && !previousPrefix.equals(prefix)) {
this.namespacesByPrefix.remove(previousPrefix);
}
+ if (previousNamespaceForPrefix != null &&
!previousNamespaceForPrefix.equals(namespaceUri)) {
+ this.prefixesByNamespace.remove(previousNamespaceForPrefix);
+ }
} finally {
lock.unlock();
}
Modified: trunk/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/BasicNameTest.java
===================================================================
--- trunk/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/BasicNameTest.java 2008-09-10
18:05:54 UTC (rev 514)
+++ trunk/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/BasicNameTest.java 2008-09-11
23:33:03 UTC (rev 515)
@@ -155,4 +155,18 @@
assertThat(result, is("dna:some%3aname%3awith%3acolons"));
}
+ @Test
+ public void
shouldNotIncludeNamespacePrefixOrColonInResultFromGetStringWithNamespaceRegistry() {
+ validNamespaceUri = namespaceRegistry.getDefaultNamespaceUri();
+ name = new BasicName(validNamespaceUri, validLocalName);
+ String result = name.getString(namespaceRegistry, encoder);
+ assertThat(result, is(validLocalName));
+ result = name.getString(namespaceRegistry); // default encoder
+ assertThat(result, is(validLocalName));
+
+ validLocalName = "some:name:with:colons";
+ name = new BasicName(validNamespaceUri, validLocalName);
+ result = name.getString(namespaceRegistry, encoder);
+ assertThat(result, is("some:name:with:colons"));
+ }
}
Modified:
trunk/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/BasicNamespaceRegistryTest.java
===================================================================
---
trunk/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/BasicNamespaceRegistryTest.java 2008-09-10
18:05:54 UTC (rev 514)
+++
trunk/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/BasicNamespaceRegistryTest.java 2008-09-11
23:33:03 UTC (rev 515)
@@ -25,6 +25,7 @@
import static org.hamcrest.core.IsNull.notNullValue;
import static org.hamcrest.core.IsNull.nullValue;
import static org.junit.Assert.assertThat;
+import static org.junit.matchers.JUnitMatchers.hasItem;
import org.junit.Before;
import org.junit.Test;
@@ -122,6 +123,9 @@
namespaceRegistry.register(validPrefix1, validNamespaceUri1);
namespaceRegistry.register("", validNamespaceUri2);
assertThat(namespaceRegistry.getDefaultNamespaceUri(), is(validNamespaceUri2));
+ assertThat(namespaceRegistry.getNamespaceForPrefix(""),
is(validNamespaceUri2));
+ assertThat(namespaceRegistry.getRegisteredNamespaceUris(),
hasItem(validNamespaceUri2));
+ assertThat(namespaceRegistry.getPrefixForNamespaceUri(validNamespaceUri2, false),
is(""));
}
@Test
@@ -144,4 +148,36 @@
assertThat(namespaceRegistry.isRegisteredNamespaceUri(validNamespaceUri2),
is(true));
}
+ @Test
+ public void shouldBeAbleToCopyNamespacesToAnotherRegistry() {
+ namespaceRegistry.register(validPrefix1, validNamespaceUri1);
+ namespaceRegistry.register(validPrefix2, validNamespaceUri2);
+ namespaceRegistry.register("", validNamespaceUri3);
+ assertThat(namespaceRegistry.isRegisteredNamespaceUri(validNamespaceUri1),
is(true));
+ assertThat(namespaceRegistry.isRegisteredNamespaceUri(validNamespaceUri2),
is(true));
+ assertThat(namespaceRegistry.isRegisteredNamespaceUri(validNamespaceUri3),
is(true));
+ assertThat(namespaceRegistry.getPrefixForNamespaceUri(validNamespaceUri1, false),
is(validPrefix1));
+ assertThat(namespaceRegistry.getPrefixForNamespaceUri(validNamespaceUri2, false),
is(validPrefix2));
+ assertThat(namespaceRegistry.getPrefixForNamespaceUri(validNamespaceUri3, false),
is(""));
+ assertThat(namespaceRegistry.getNamespaceForPrefix(validPrefix1),
is(validNamespaceUri1));
+ assertThat(namespaceRegistry.getNamespaceForPrefix(validPrefix2),
is(validNamespaceUri2));
+ assertThat(namespaceRegistry.getNamespaceForPrefix(""),
is(validNamespaceUri3));
+
+ BasicNamespaceRegistry newRegistry = new BasicNamespaceRegistry();
+ for (String uri : this.namespaceRegistry.getRegisteredNamespaceUris()) {
+ String prefix = this.namespaceRegistry.getPrefixForNamespaceUri(uri, false);
+ newRegistry.register(prefix, uri);
+ }
+ assertThat(newRegistry.isRegisteredNamespaceUri(validNamespaceUri1), is(true));
+ assertThat(newRegistry.isRegisteredNamespaceUri(validNamespaceUri2), is(true));
+ assertThat(newRegistry.isRegisteredNamespaceUri(validNamespaceUri3), is(true));
+ assertThat(newRegistry.getPrefixForNamespaceUri(validNamespaceUri1, false),
is(validPrefix1));
+ assertThat(newRegistry.getPrefixForNamespaceUri(validNamespaceUri2, false),
is(validPrefix2));
+ assertThat(newRegistry.getPrefixForNamespaceUri(validNamespaceUri3, false),
is(""));
+ assertThat(newRegistry.getNamespaceForPrefix(validPrefix1),
is(validNamespaceUri1));
+ assertThat(newRegistry.getNamespaceForPrefix(validPrefix2),
is(validNamespaceUri2));
+ assertThat(newRegistry.getNamespaceForPrefix(""),
is(validNamespaceUri3));
+
+ }
+
}
Modified: trunk/docs/examples/gettingstarted/repositories/pom.xml
===================================================================
--- trunk/docs/examples/gettingstarted/repositories/pom.xml 2008-09-10 18:05:54 UTC (rev
514)
+++ trunk/docs/examples/gettingstarted/repositories/pom.xml 2008-09-11 23:33:03 UTC (rev
515)
@@ -50,6 +50,12 @@
<version>${dna-version}</version>
<scope>runtime</scope>
</dependency>
+ <dependency>
+ <groupId>org.jboss.dna</groupId>
+ <artifactId>dna-connector-federation</artifactId>
+ <version>${dna-version}</version>
+ <scope>runtime</scope>
+ </dependency>
<!--
Logging (require SLF4J API for compiling, but use Log4J and its SLF4J binding for
testing)
-->
@@ -80,6 +86,11 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
Modified: trunk/docs/examples/gettingstarted/repositories/src/main/assembly/basic.xml
===================================================================
--- trunk/docs/examples/gettingstarted/repositories/src/main/assembly/basic.xml 2008-09-10
18:05:54 UTC (rev 514)
+++ trunk/docs/examples/gettingstarted/repositories/src/main/assembly/basic.xml 2008-09-11
23:33:03 UTC (rev 515)
@@ -16,7 +16,7 @@
<directory>src/main/resources/</directory>
<outputDirectory/>
<includes>
- <include>*.*</include>
+ <include>*.xml</include>
</includes>
</fileSet>
</fileSets>
Added:
trunk/docs/examples/gettingstarted/repositories/src/main/java/org/jboss/example/dna/repository/ConsoleInput.java
===================================================================
---
trunk/docs/examples/gettingstarted/repositories/src/main/java/org/jboss/example/dna/repository/ConsoleInput.java
(rev 0)
+++
trunk/docs/examples/gettingstarted/repositories/src/main/java/org/jboss/example/dna/repository/ConsoleInput.java 2008-09-11
23:33:03 UTC (rev 515)
@@ -0,0 +1,243 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.example.dna.repository;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.jboss.dna.common.util.StringUtil;
+
+/**
+ * @author Randall Hauch
+ */
+public class ConsoleInput implements UserInterface {
+
+ protected static BufferedReader in = new BufferedReader(new
InputStreamReader(System.in));
+
+ private final RepositoryClient repositoryClient;
+ private final Map<Integer, String> selectionToSourceName = new
HashMap<Integer, String>();
+
+ public ConsoleInput( final RepositoryClient client,
+ final String[] args ) {
+ this.repositoryClient = client;
+ try {
+ System.out.println();
+ System.out.print("Starting repositories ... ");
+ client.startRepositories();
+ System.out.println("done.");
+ System.out.println();
+
+ System.out.println(getMenu());
+ Thread eventThread = new Thread(new Runnable() {
+
+ private boolean quit = false;
+
+ @SuppressWarnings( "synthetic-access" )
+ public void run() {
+ try {
+ while (!quit) {
+ System.out.print(">");
+ try {
+ String input = in.readLine();
+ if (input.length() != 1) {
+ System.out.println("Please enter a valid
option.");
+ continue;
+ }
+
+ char option = input.charAt(0);
+ switch (option) {
+ case '?':
+ case 'h':
+ System.out.println(getMenu());
+ break;
+ case 'q':
+ quit = true;
+ break;
+ default:
+ try {
+ int selection = Integer.parseInt(""
+ option);
+ String sourceName =
selectionToSourceName.get(selection);
+ navigate(sourceName);
+ } catch (NumberFormatException e) {
+ System.out.println("Invalid
option.");
+ break;
+ }
+ }
+ } catch (NumberFormatException e) {
+ System.out.println("Invalid integer " +
e.getMessage());
+ } catch (IllegalArgumentException e) {
+ System.out.println(e.getMessage());
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+ } finally {
+ try {
+ // Terminate ...
+ System.out.println();
+ System.out.print("done.\nShutting down repositories and
services ... ");
+ client.shutdown();
+ System.out.print("done.");
+ System.out.println();
+ System.out.println();
+ } catch (Exception err) {
+ System.out.println("Error shutting down sequencing
service and repository: "
+ + err.getLocalizedMessage());
+ err.printStackTrace(System.err);
+ }
+ }
+ }
+ });
+
+ eventThread.start();
+ } catch (Exception err) {
+ System.out.println("Error: " + err.getLocalizedMessage());
+ err.printStackTrace(System.err);
+ }
+ }
+
+ protected String getMenu() {
+ selectionToSourceName.clear();
+ StringBuilder buffer = new StringBuilder();
+ buffer.append("-----------------------------------\n");
+ buffer.append("Menu:\n");
+ buffer.append("\n");
+ buffer.append(" Select a repository to view:\n");
+ int selection = 1;
+ for (String sourceName : this.repositoryClient.getNamesOfRepositories()) {
+ selectionToSourceName.put(selection, sourceName);
+ buffer.append(" " + selection + ") " + sourceName +
"\n");
+ }
+ buffer.append(" or\n");
+ buffer.append(" ?) Show this menu\n");
+ buffer.append(" q) Quit");
+ return buffer.toString();
+ }
+
+ protected void navigate( String sourceName ) {
+ String currentPath = "/";
+ while (true) {
+
+ // Ask for the command ...
+ System.out.print("> ");
+ try {
+ String input = in.readLine().trim();
+ if (input.length() == 0) {
+ continue;
+ }
+
+ if ("?".equals(input) || "help".equals(input) ||
"h".equals(input)) {
+ System.out.println(" Enter a command:");
+ System.out.println(" pwd print the current
node's path");
+ System.out.println(" ls [path] to list the details of
the node at the specified absolute or relative path");
+ System.out.println(" (or the current path if
none is supplied)");
+ System.out.println(" cd path to change to the node at
the specified absolute or relative path");
+ System.out.println(" exit to exit this repository
and return to the main menu");
+ System.out.println(" and press return:");
+ } else if ("pwd".equals(input)) {
+ System.out.println(" " + currentPath);
+ } else if ("exit".equals(input)) {
+ return;
+ } else if (input.startsWith("ls")) {
+ input = input.substring("ls".length()).trim();
+ String path = currentPath;
+ if (input.length() != 0) path = input;
+ displayNode(sourceName, path);
+ } else if (input.startsWith("cd ")) {
+ input = input.substring("cd ".length()).trim();
+ if (input.length() == 0) continue;
+ // Check to see if the new path exists ...
+ if (!repositoryClient.getNodeInfo(sourceName, input, null, null)) {
+ System.out.println(" \"" + input + "\"
does not exist");
+ } else {
+ currentPath = input;
+ }
+ }
+ } catch (Throwable e) {
+ displayError(" processing your command", e);
+ }
+ }
+
+ }
+
+ protected void displayNode( String sourceName,
+ String path ) {
+ Map<String, Object[]> properties = new HashMap<String, Object[]>();
+ List<String> children = new ArrayList<String>();
+ try {
+ repositoryClient.getNodeInfo(sourceName, path, properties, children);
+ } catch (Throwable t) {
+ displayError(" displaying node \"" + path +
"\"", t);
+ }
+
+ System.out.println(" Path:" + path);
+ System.out.println(" Properties:");
+ int maxLength = 0;
+ for (String propertyName : properties.keySet()) {
+ maxLength = Math.max(maxLength, propertyName.length());
+ }
+ for (Map.Entry<String, Object[]> property : properties.entrySet()) {
+ String name = property.getKey();
+ name = StringUtil.justifyLeft(name, maxLength, ' ');
+ Object[] values = property.getValue();
+ String valueStr = StringUtil.readableString(values);
+ if (values.length == 1) StringUtil.readableString(values[0]);
+ System.out.println(" " + name + " = " + valueStr);
+ }
+ System.out.println(" Children:");
+ for (String childName : children) {
+ System.out.println(" " + childName);
+ }
+ System.out.println();
+ }
+
+ protected void displayError( String activity,
+ Throwable t ) {
+ System.err.println();
+ System.err.println("There has been an error" + activity);
+ System.err.println(" " + t.getMessage());
+ t.printStackTrace(System.err);
+ System.err.println();
+ System.err.println("Press any key to continue:");
+ try {
+ in.readLine();
+ } catch (IOException err) {
+ err.printStackTrace(System.err);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.example.dna.repository.UserInterface#getLocationOfRepositoryFiles()
+ */
+ public String getLocationOfRepositoryFiles() {
+ return new File("").getAbsolutePath();
+ }
+}
Property changes on:
trunk/docs/examples/gettingstarted/repositories/src/main/java/org/jboss/example/dna/repository/ConsoleInput.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified:
trunk/docs/examples/gettingstarted/repositories/src/main/java/org/jboss/example/dna/repository/RepositoryClient.java
===================================================================
---
trunk/docs/examples/gettingstarted/repositories/src/main/java/org/jboss/example/dna/repository/RepositoryClient.java 2008-09-10
18:05:54 UTC (rev 514)
+++
trunk/docs/examples/gettingstarted/repositories/src/main/java/org/jboss/example/dna/repository/RepositoryClient.java 2008-09-11
23:33:03 UTC (rev 515)
@@ -21,17 +21,284 @@
*/
package org.jboss.example.dna.repository;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import javax.jcr.Credentials;
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.PropertyIterator;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+import javax.security.auth.callback.PasswordCallback;
+import org.jboss.dna.common.component.ClassLoaderFactory;
+import org.jboss.dna.common.component.StandardClassLoaderFactory;
+import org.jboss.dna.connector.inmemory.InMemoryRepositorySource;
+import org.jboss.dna.jcr.JcrRepository;
+import org.jboss.dna.repository.RepositoryImporter;
+import org.jboss.dna.repository.RepositoryService;
+import org.jboss.dna.repository.RepositorySourceManager;
+import org.jboss.dna.spi.ExecutionContext;
+import org.jboss.dna.spi.ExecutionContextFactory;
+import org.jboss.dna.spi.connector.BasicExecutionContextFactory;
+import org.jboss.dna.spi.connector.RepositoryConnection;
+import org.jboss.dna.spi.graph.Path;
+import org.jboss.dna.spi.graph.PathFactory;
+import org.jboss.dna.spi.graph.PathNotFoundException;
+import org.jboss.dna.spi.graph.Property;
+import org.jboss.dna.spi.graph.commands.impl.BasicGetNodeCommand;
+
/**
- *
* @author Randall Hauch
*/
public class RepositoryClient {
+ public static final String INMEMORY_REPOSITORY_SOURCE_CLASSNAME =
"org.jboss.dna.connector.inmemory.InMemoryRepositorySource";
+ public static final String JAAS_LOGIN_CONTEXT_NAME =
"dna-repository-example";
+
/**
* @param args
*/
public static void main( String[] args ) {
+ RepositoryClient client = new RepositoryClient();
+ for (String arg : args) {
+ arg = arg.trim();
+ if (arg.equals("--api=jcr")) client.setApi(Api.JCR);
+ if (arg.equals("--api=dna")) client.setApi(Api.DNA);
+ if (arg.startsWith("--user=") && arg.length() > 7)
client.setUsername(arg.substring(7).trim());
+ }
+ client.setUserInterface(new ConsoleInput(client, args));
+ }
+ public enum Api {
+ JCR,
+ DNA;
}
+ private ClassLoaderFactory classLoaderFactory;
+ private RepositorySourceManager sources;
+ private ExecutionContextFactory contextFactory;
+ private RepositoryService repositoryService;
+ private Api api = Api.DNA;
+ private String username = null;
+ private char[] password = null;
+ private UserInterface userInterface;
+
+ /**
+ * @param userInterface Sets userInterface to the specified value.
+ */
+ public void setUserInterface( UserInterface userInterface ) {
+ this.userInterface = userInterface;
+ }
+
+ /**
+ * Set the API that this client should use to interact with the repositories.
+ *
+ * @param api The API that should be used
+ */
+ public void setApi( Api api ) {
+ this.api = api != null ? api : Api.DNA;
+ }
+
+ /**
+ * Set the username that this client should use.
+ *
+ * @param username the new username, or null if no username should be used.
+ */
+ public void setUsername( String username ) {
+ this.username = username;
+ this.password = null;
+ }
+
+ /**
+ * Clear any cached password.
+ */
+ public void clearPassword() {
+ password = null;
+ }
+
+ /**
+ * Method used internally to obtain the password, which is obtained from the user
(only once per process) if needed
+ *
+ * @return the user's password, or null if no username is known
+ */
+ private char[] getPassword() {
+ if (username == null) return null;
+ if (password == null) {
+ PasswordCallback callback = new PasswordCallback("Password:",
false);
+ password = callback.getPassword();
+ }
+ return password;
+ }
+
+ /**
+ * Start up the repositories. This method creates the necessary components and
services, and initializes the in-memory
+ * repositories.
+ *
+ * @throws IOException if there is a problem initializing the repositories from the
files.
+ */
+ public void startRepositories() throws IOException {
+ if (repositoryService != null) return; // already started
+
+ // Create the class loader factory, which for this example will simply use this
class' class loader...
+ classLoaderFactory = new StandardClassLoaderFactory();
+
+ // Create the factory for execution contexts.
+ contextFactory = new BasicExecutionContextFactory();
+
+ // Create the execution context that we'll use for the services. If we'd
want to use JAAS, we'd create the context
+ // by supply LoginContext, AccessControlContext, or even Subject with
CallbackHandlers. But no JAAS in this example.
+ ExecutionContext context = contextFactory.create();
+
+ // Create the manager for the RepositorySource instances ...
+ sources = new RepositorySourceManager();
+
+ // Load into the source manager the repository source for the configuration
repository ...
+ InMemoryRepositorySource configSource = new InMemoryRepositorySource();
+ configSource.setName("Configuration");
+ sources.addSource(configSource);
+
+ // For this example, we're using a couple of in-memory repositories
(including one for the configuration repository).
+ // Normally, these would exist already and would simply be accessed. But in this
example, we're going to
+ // populate these repositories here by importing from files. First do the
configuration repository ...
+ String location = this.userInterface.getLocationOfRepositoryFiles();
+ RepositoryImporter importer = new RepositoryImporter(sources, context);
+ importer.importXml(location +
"/configRepository.xml").into(configSource.getName());
+
+ // Now instantiate the Repository Service ...
+ repositoryService = new RepositoryService(sources, configSource.getName(),
context, classLoaderFactory);
+ repositoryService.getAdministrator().start();
+
+ // Now import the conten for two of the other in-memory repositories ...
+ importer.importXml(location + "/cars.xml").into("Cars");
+ importer.importXml(location +
"/aircraft.xml").into("Aircraft");
+ }
+
+ /**
+ * Get the names of the repositories.
+ *
+ * @return the repository names
+ */
+ public Collection<String> getNamesOfRepositories() {
+ return sources.getSourceNames();
+ }
+
+ /**
+ * Shut down the components and services and blocking until all resources have been
released.
+ *
+ * @throws InterruptedException if the thread was interrupted before completing the
shutdown.
+ */
+ public void shutdown() throws InterruptedException {
+ if (repositoryService == null) return;
+ try {
+ // Shut down the various services ...
+ repositoryService.getAdministrator().shutdown();
+
+ // Shut down the manager of the RepositorySource instances, waiting until all
connections are closed
+ sources.getAdministrator().shutdown();
+ sources.getAdministrator().awaitTermination(1, TimeUnit.SECONDS);
+ } finally {
+ repositoryService = null;
+ sources = null;
+ }
+ }
+
+ /**
+ * Get the information about a node, using the {@link #setApi(Api) API} method.
+ *
+ * @param sourceName the name of the repository source
+ * @param pathToNode the path to the node in the repository that is to be retrieved
+ * @param properties the map into which the property values will be placed; may be
null if the properties are not to be
+ * retrieved
+ * @param children the collection into which the child names should be placed; may be
null if the children are not to be
+ * retrieved
+ * @return true if the node was found, or false if it was not
+ * @throws Throwable
+ */
+ public boolean getNodeInfo( String sourceName,
+ String pathToNode,
+ Map<String, Object[]> properties,
+ List<String> children ) throws Throwable {
+ switch (api) {
+ case JCR: {
+ JcrRepository jcrRepository = new JcrRepository(contextFactory,
sources);
+ Session session = null;
+ if (username != null) {
+ Credentials credentials = new SimpleCredentials(username,
getPassword());
+ session = jcrRepository.login(credentials, sourceName);
+ } else {
+ session = jcrRepository.login(sourceName);
+ }
+ try {
+ // Get the node by path ...
+ Node root = session.getRootNode();
+ Node node = root.getNode(pathToNode);
+
+ // Now populate the properties and children ...
+ if (properties != null) {
+ for (PropertyIterator iter = node.getProperties();
iter.hasNext();) {
+ javax.jcr.Property property = iter.nextProperty();
+ properties.put(property.getName(), property.getValues());
+ }
+ }
+ if (children != null) {
+ for (NodeIterator iter = node.getNodes(); iter.hasNext();) {
+ javax.jcr.Node child = iter.nextNode();
+ children.add(child.getName());
+ }
+ }
+ } catch (javax.jcr.PathNotFoundException e) {
+ return false;
+ } finally {
+ if (session != null) session.logout();
+ }
+ break;
+ }
+ case DNA: {
+ ExecutionContext context = null;
+ if (username != null) {
+ context = contextFactory.create(JAAS_LOGIN_CONTEXT_NAME);
+ } else {
+ context = contextFactory.create();
+ }
+ PathFactory pathFactory = context.getValueFactories().getPathFactory();
+
+ // Get the node submitting a graph command to a repository connection.
+ // (Using commands is a little verbose, but we'll be introducing in
the next release
+ // an API that is much easier and concise.)
+ Path path = pathToNode != null ? pathFactory.create(pathToNode) :
pathFactory.createRootPath();
+ BasicGetNodeCommand command = new BasicGetNodeCommand(path);
+ RepositoryConnection connection = sources.createConnection(sourceName);
+ try {
+ connection.execute(context, command);
+ } finally {
+ if (connection != null) connection.close();
+ }
+
+ // Check whether there's been an error ...
+ if (command.hasError()) {
+ if (command.getError() instanceof PathNotFoundException) return
false;
+ throw command.getError();
+ }
+
+ // Now populate the properties and children ...
+ if (properties != null) {
+ for (Property property : command.getProperties()) {
+ String name =
property.getName().getString(context.getNamespaceRegistry());
+ properties.put(name, property.getValuesAsArray());
+ }
+ }
+ if (children != null) {
+ for (Path.Segment child : command.getChildren()) {
+ String name = child.getString(context.getNamespaceRegistry());
+ children.add(name);
+ }
+ }
+ break;
+ }
+ }
+ return true;
+ }
}
Added:
trunk/docs/examples/gettingstarted/repositories/src/main/java/org/jboss/example/dna/repository/UserInterface.java
===================================================================
---
trunk/docs/examples/gettingstarted/repositories/src/main/java/org/jboss/example/dna/repository/UserInterface.java
(rev 0)
+++
trunk/docs/examples/gettingstarted/repositories/src/main/java/org/jboss/example/dna/repository/UserInterface.java 2008-09-11
23:33:03 UTC (rev 515)
@@ -0,0 +1,31 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.example.dna.repository;
+
+/**
+ * @author Randall Hauch
+ */
+public interface UserInterface {
+
+ String getLocationOfRepositoryFiles();
+
+}
Property changes on:
trunk/docs/examples/gettingstarted/repositories/src/main/java/org/jboss/example/dna/repository/UserInterface.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/docs/examples/gettingstarted/repositories/src/main/resources/aircraft.xml
===================================================================
--- trunk/docs/examples/gettingstarted/repositories/src/main/resources/aircraft.xml
(rev 0)
+++
trunk/docs/examples/gettingstarted/repositories/src/main/resources/aircraft.xml 2008-09-11
23:33:03 UTC (rev 515)
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ JBoss, Home of Professional Open Source.
+ ~
+ ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ ~ indicated by the @author tags or express copyright attribution
+ ~ statements applied by the authors. All third-party contributions are
+ ~ distributed under license by Red Hat Middleware LLC.
+ ~
+ ~ This copyrighted material is made available to anyone wishing to use, modify,
+ ~ copy, or redistribute it subject to the terms and conditions of the GNU
+ ~ Lesser General Public License, as published by the Free Software Foundation.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ ~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ ~ for more details.
+ ~
+ ~ You should have received a copy of the GNU Lesser General Public License
+ ~ along with this distribution; if not, write to:
+ ~ Free Software Foundation, Inc.
+ ~ 51 Franklin Street, Fifth Floor
+ ~ Boston, MA 02110-1301 USA
+ -->
+<Aircraft
xmlns:jcr="http://www.jcp.org/jcr/1.0">
+ <Business>
+ <aircraft jcr:name="Gulfstream V" maker="Gulfstream"
model="G-V" introduced="1995" range="5800nm"
cruiseSpeed="488kt" crew="2" emptyWeight="46200lb"
url="http://en.wikipedia.org/wiki/Gulfstream_V"/>
+ <aircraft jcr:name="Learjet 45" maker="Learjet"
model="LJ45" introduced="1995" numberBuilt="264+"
crew="2" emptyWeight="13695lb" range="2120nm"
cruiseSpeed="457kt"
url="http://en.wikipedia.org/wiki/Learjet_45"/>
+ </Business>
+ <Commercial>
+ <aircraft jcr:name="Boeing 777" maker="Boeing"
model="777-200LR" introduced="1995" numberBuilt="731+"
maxRange="7500nm" emptyWeight="326000lb"
cruiseSpeed="560mph"
url="http://en.wikipedia.org/wiki/Boeing_777"/>
+ <aircraft jcr:name="Boeing 767" maker="Boeing"
model="767-200" introduced="1982" numberBuilt="966+"
maxRange="3950nm" emptyWeight="176650lb"
cruiseSpeed="530mph"
url="http://en.wikipedia.org/wiki/Boeing_767"/>
+ <aircraft jcr:name="Boeing 787" maker="Boeing"
model="787-3" introduced="2009" range="3050nm"
emptyWeight="223000lb" cruiseSpeed="561mph"
url="http://en.wikipedia.org/wiki/Boeing_787"/>
+ <aircraft jcr:name="Boeing 757" maker="Boeing"
model="757-200" introduced="1983" numberBuilt="1050"
range="3900nm" maxWeight="255000lb" cruiseSpeed="530mph"
url="http://en.wikipedia.org/wiki/Boeing_757"/>
+ <aircraft jcr:name="Airbus A380" maker="Airbus"
model="A380-800" introduced="2007" numberBuilt="18"
range="8200nm" maxWeight="1235000lb" cruiseSpeed="647mph"
url="http://en.wikipedia.org/wiki/Airbus_a380"/>
+ <aircraft jcr:name="Airbus A340" maker="Airbus"
model="A340-200" introduced="1993" numberBuilt="354"
range="8000nm" maxWeight="606300lb" cruiseSpeed="557mph"
url="http://en.wikipedia.org/wiki/Airbus_A-340"/>
+ <aircraft jcr:name="Airbus A310" maker="Airbus"
model="A310-200" introduced="1983" numberBuilt="255"
cruiseSpeed="850km/h" emptyWeight="176312lb" range="3670nm"
url="http://en.wikipedia.org/wiki/Airbus_A-310"/>
+ <aircraft jcr:name="Embraer " maker="Embraer"
model="ERJ170-200" introduced="2004" range="3334km"
cruiseSpeed="481kt" emptyWeight="21810kg"
url="http://en.wikipedia.org/wiki/EMBRAER_170"/>
+ </Commercial>
+ <Vintage>
+ <aircraft jcr:name="Fokker Trimotor" maker="Fokker"
model="F.VII" introduced="1925" cruiseSpeed="170km/h"
emptyWeight="3050kg" crew="2"
url="http://en.wikipedia.org/wiki/Fokker_trimotor"/>
+ <aircraft jcr:name="P-38 Lightning" maker="Lockheed"
model="P-38" designedBy="Kelly Johnson" introduced="1941"
numberBuilt="10037" rateOfClimb="4750ft/min" range="1300mi"
emptyWeight="12780lb" crew="1"
url="http://en.wikipedia.org/wiki/P-38_Lightning"/>
+ <aircraft jcr:name="A6M Zero" maker="Mitsubishi"
model="A6M" designedBy="Jiro Horikoshi" introduced="1940"
numberBuilt="11000" crew="1" emptyWeight="3704lb"
serviceCeiling="33000ft" maxSpeed="331mph" range="1929mi"
rateOfClimb="3100ft/min"
url="http://en.wikipedia.org/wiki/A6M_Zero"/>
+ <aircraft jcr:name="Bf 109" maker="Messerschmitt"
model="Bf 109" introduced="1937"
url="http://en.wikipedia.org/wiki/BF_109"/>
+ <aircraft jcr:name="Wright Flyer" maker="Wright Brothers"
introduced="1903" range="852ft" maxSpeed="30mph"
emptyWeight="605lb" crew="1"/>
+ </Vintage>
+ <Homebuilt>
+ <aircraft jcr:name="Long-EZ" maker="Rutan Aircraft
Factory" model="61" emptyWeight="760lb"
fuelCapacity="200L" maxSpeed="185kt" since="1976"
range="1200nm"
url="http://en.wikipedia.org/wiki/Rutan_Long-EZ"/>
+ <aircraft jcr:name="Cirrus VK-30" maker="Cirrus Design"
model="VK-30" emptyWeight="2400lb" maxLoad="1200lb"
maxSpeed="250mph" rateOfClimb="1500ft/min" range="1300mi"
url="http://en.wikipedia.org/wiki/Cirrus_VK-30"/>
+ <aircraft jcr:name="Van's RV-4" maker="Van's
Aircraft" model="RV-4" introduced="1980"
emptyWeight="905lb" maxLoad="500lb" maxSpeed="200mph"
rateOfClimb="2450ft/min" range="725mi"
url="http://en.wikipedia.org/wiki/Van%27s_Aircraft_RV-4"/>
+ </Homebuilt>
+</Aircraft>
\ No newline at end of file
Property changes on:
trunk/docs/examples/gettingstarted/repositories/src/main/resources/aircraft.xml
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/docs/examples/gettingstarted/repositories/src/main/resources/cars.xml
===================================================================
--- trunk/docs/examples/gettingstarted/repositories/src/main/resources/cars.xml
(rev 0)
+++ trunk/docs/examples/gettingstarted/repositories/src/main/resources/cars.xml 2008-09-11
23:33:03 UTC (rev 515)
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ JBoss, Home of Professional Open Source.
+ ~
+ ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ ~ indicated by the @author tags or express copyright attribution
+ ~ statements applied by the authors. All third-party contributions are
+ ~ distributed under license by Red Hat Middleware LLC.
+ ~
+ ~ This copyrighted material is made available to anyone wishing to use, modify,
+ ~ copy, or redistribute it subject to the terms and conditions of the GNU
+ ~ Lesser General Public License, as published by the Free Software Foundation.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ ~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ ~ for more details.
+ ~
+ ~ You should have received a copy of the GNU Lesser General Public License
+ ~ along with this distribution; if not, write to:
+ ~ Free Software Foundation, Inc.
+ ~ 51 Franklin Street, Fifth Floor
+ ~ Boston, MA 02110-1301 USA
+ -->
+<Cars
xmlns:jcr="http://www.jcp.org/jcr/1.0">
+ <Hybrid>
+ <car jcr:name="Toyota Prius" maker="Toyota"
model="Prius" year="2008" msrp="$21,500"
userRating="4.2" valueRating="5" mpgCity="48"
mpgHighway="45"/>
+ <car jcr:name="Toyota Highlander" maker="Toyota"
model="Highlander" year="2008" msrp="$34,200"
userRating="4" valueRating="5" mpgCity="27"
mpgHighway="25"/>
+ <car jcr:name="Nissan Altima" maker="Nissan"
model="Altima" year="2008" msrp="$18,260"
mpgCity="23" mpgHighway="32"/>
+ </Hybrid>
+ <Sports>
+ <car jcr:name="Aston Martin DB9" maker="Aston Martin"
model="DB9" year="2008" msrp="$171,600"
userRating="5" mpgCity="12" mpgHighway="19"
lengthInInches="185.5" wheelbaseInInches="108.0" engine="5,935 cc
5.9 liters V 12"/>
+ <car jcr:name="Infiniti G37" maker="Infiniti"
model="G37" year="2008" msrp="$34,900"
userRating="3.5" valueRating="4" mpgCity="18"
mpgHighway="24" />
+ </Sports>
+ <Luxury>
+ <car jcr:name="Cadillac DTS" maker="Cadillac"
model="DTS" year="2008" engine="3.6-liter V6"
userRating="0"/>
+ <car jcr:name="Bentley Continental" maker="Bentley"
model="Continental" year="2008" msrp="$170,990"
mpgCity="10" mpgHighway="17" />
+ <car jcr:name="Lexus IS350" maker="Lexus"
model="IS350" year="2008" msrp="$36,305"
mpgCity="18" mpgHighway="25" userRating="4"
valueRating="5" />
+ </Luxury>
+ <Utility>
+ <car jcr:name="Land Rover LR2" maker="Land Rover"
model="LR2" year="2008" msrp="$33,985"
userRating="4.5" valueRating="5" mpgCity="16"
mpgHighway="23" />
+ <car jcr:name="Land Rover LR3" maker="Land Rover"
model="LR3" year="2008" msrp="$48,525"
userRating="5" valueRating="2" mpgCity="12"
mpgHighway="17" />
+ <car jcr:name="Hummer H3" maker="Hummer"
model="H3" year="2008" msrp="$30,595"
userRating="3.5" valueRating="4" mpgCity="13"
mpgHighway="16" />
+ <car jcr:name="Ford F-150" maker="Ford"
model="F-150" year="2008" msrp="$23,910"
userRating="4" valueRating="1" mpgCity="14"
mpgHighway="20" />
+ </Utility>
+</Cars>
\ No newline at end of file
Property changes on:
trunk/docs/examples/gettingstarted/repositories/src/main/resources/cars.xml
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added:
trunk/docs/examples/gettingstarted/repositories/src/main/resources/configRepository.xml
===================================================================
---
trunk/docs/examples/gettingstarted/repositories/src/main/resources/configRepository.xml
(rev 0)
+++
trunk/docs/examples/gettingstarted/repositories/src/main/resources/configRepository.xml 2008-09-11
23:33:03 UTC (rev 515)
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ JBoss, Home of Professional Open Source.
+ ~
+ ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ ~ indicated by the @author tags or express copyright attribution
+ ~ statements applied by the authors. All third-party contributions are
+ ~ distributed under license by Red Hat Middleware LLC.
+ ~
+ ~ This copyrighted material is made available to anyone wishing to use, modify,
+ ~ copy, or redistribute it subject to the terms and conditions of the GNU
+ ~ Lesser General Public License, as published by the Free Software Foundation.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ ~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ ~ for more details.
+ ~
+ ~ You should have received a copy of the GNU Lesser General Public License
+ ~ along with this distribution; if not, write to:
+ ~ Free Software Foundation, Inc.
+ ~ 51 Franklin Street, Fifth Floor
+ ~ Boston, MA 02110-1301 USA
+ -->
+<dna:system
xmlns:dna="http://www.jboss.org/dna"
xmlns:jcr="http://www.jcp.org/jcr/1.0">
+ <!-- Define the sources from which content is made available -->
+ <dna:sources>
+ <sourceA name="Cars"
dna:classname="org.jboss.dna.connector.inmemory.InMemoryRepositorySource"
retryLimit="3" />
+ <sourceB name="Aircraft"
dna:classname="org.jboss.dna.connector.inmemory.InMemoryRepositorySource" />
+ <sourceC name="Vehicles"
dna:classname="org.jboss.dna.connector.federation.FederatedRepositorySource"
configurationSourceName="Configuration"
configurationSourcePath="/dna:system/dna:federatedRepositories/Vehicles" />
+ <sourceD name="Cache"
dna:classname="org.jboss.dna.connector.inmemory.InMemoryRepositorySource" />
+ </dna:sources>
+ <dna:federatedRepositories>
+ <Vehicles>
+ <!-- This section defines from where the content of the 'Vehicles'
federated repository is obtained -->
+ <dna:federation dna:timeToCache="100000">
+ <dna:cache>
+ <!-- Define how the content in the 'Cache' source is to
map to the federated cache -->
+ <Cache dna:projectionRules="/ => /" />
+ </dna:cache>
+ <dna:projections>
+ <!-- Define how the content in the difference sources maps to the
federated/unified repository.
+ This example puts the 'Cars' and 'Aircraft'
content underneath '/vehicles', but the
+ 'Configuration' content (which is defined by this file)
will appear under '/'. -->
+ <Cars dna:projectionRules="/vehicles => /" />
+ <Aircraft dna:projectionRules="/vehicles => /" />
+ <Configuration dna:projectionRules="/ => /" />
+ </dna:projections>
+ </dna:federation>
+ </Vehicles>
+ </dna:federatedRepositories>
+</dna:system>
\ No newline at end of file
Property changes on:
trunk/docs/examples/gettingstarted/repositories/src/main/resources/configRepository.xml
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified:
trunk/docs/examples/gettingstarted/repositories/src/main/resources/log4j.properties
===================================================================
---
trunk/docs/examples/gettingstarted/repositories/src/main/resources/log4j.properties 2008-09-10
18:05:54 UTC (rev 514)
+++
trunk/docs/examples/gettingstarted/repositories/src/main/resources/log4j.properties 2008-09-11
23:33:03 UTC (rev 515)
@@ -9,4 +9,9 @@
# Set up the default logging to be INFO level, then override specific units
log4j.logger.org.jboss.dna=INFO
+#log4j.logger.org.jboss.dna.repository.sequencers=TRACE
+#log4j.logger.org.jboss.dna.sequencer=DEBUG
+#log4j.logger.org.jboss.dna.connector=TRACE
+#log4j.logger.org.jboss.dna.spi.connector.RepositoryConnectionPool=TRACE
+#log4j.logger.org.jboss.dna.spi=DEBUG
Added:
trunk/docs/examples/gettingstarted/repositories/src/test/java/org/jboss/example/dna/repository/RepositoryClientTest.java
===================================================================
---
trunk/docs/examples/gettingstarted/repositories/src/test/java/org/jboss/example/dna/repository/RepositoryClientTest.java
(rev 0)
+++
trunk/docs/examples/gettingstarted/repositories/src/test/java/org/jboss/example/dna/repository/RepositoryClientTest.java 2008-09-11
23:33:03 UTC (rev 515)
@@ -0,0 +1,158 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.example.dna.repository;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.matchers.IsCollectionContaining.hasItems;
+import static org.mockito.Mockito.stub;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.jboss.dna.common.util.StringUtil;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.mockito.MockitoAnnotations;
+import org.mockito.MockitoAnnotations.Mock;
+
+/**
+ * @author Randall Hauch
+ */
+public class RepositoryClientTest {
+
+ private RepositoryClient client;
+ private Map<String, Object[]> properties;
+ private List<String> children;
+ @Mock
+ private UserInterface userInterface;
+
+ @Before
+ public void beforeEach() {
+ MockitoAnnotations.initMocks(this);
+ properties = new HashMap<String, Object[]>();
+ children = new ArrayList<String>();
+ client = new RepositoryClient();
+ client.setUserInterface(userInterface);
+ stub(userInterface.getLocationOfRepositoryFiles()).toReturn(new
File("src/main/resources").getAbsolutePath());
+ }
+
+ @After
+ public void afterEach() throws Exception {
+ client.shutdown();
+ }
+
+ protected void assertProperty( String propertyName,
+ Object... values ) {
+ Object[] actualValues = properties.get(propertyName);
+ assertThat(actualValues, is(values));
+ }
+
+ @Test
+ public void shouldStartupWithoutError() throws Exception {
+ client.startRepositories();
+ assertThat(client.getNamesOfRepositories(), hasItems("Aircraft",
"Cars", "Configuration", "Vehicles", "Cache"));
+ }
+
+ @Test
+ public void shouldStartupWithoutErrorMoreThanOnce() throws Exception {
+ client.startRepositories();
+ assertThat(client.getNamesOfRepositories(), hasItems("Aircraft",
"Cars", "Configuration", "Vehicles", "Cache"));
+ }
+
+ @Ignore
+ @Test
+ public void shouldHaveContentFromConfigurationRepository() throws Throwable {
+ client.startRepositories();
+ assertThat(client.getNodeInfo("Configuration", "/dna:system",
properties, children), is(true));
+ assertThat(children, hasItems("dna:sources",
"dna:federatedRepositories"));
+ assertThat(properties.containsKey("jcr:primaryType"), is(true));
+ assertThat(properties.containsKey("dna:uuid"), is(true));
+ assertThat(properties.size(), is(2));
+
+ properties.clear();
+ children.clear();
+ assertThat(client.getNodeInfo("Configuration",
"/dna:system/dna:sources", properties, children), is(true));
+ assertThat(children, hasItems("sourceA", "sourceB",
"sourceC", "sourceD"));
+ assertThat(properties.containsKey("jcr:primaryType"), is(true));
+ assertThat(properties.containsKey("dna:uuid"), is(true));
+ assertThat(properties.size(), is(2));
+
+ properties.clear();
+ children.clear();
+ assertThat(client.getNodeInfo("Configuration",
"/dna:system/dna:sources/sourceA", properties, children), is(true));
+ assertThat(children.size(), is(0));
+ System.out.println(StringUtil.readableString(properties));
+ assertThat(properties.containsKey("jcr:primaryType"), is(true));
+ assertThat(properties.containsKey("dna:uuid"), is(true));
+ assertProperty("dna:classname",
"org.jboss.dna.connector.inmemory.InMemoryRepositorySource");
+ assertProperty("name", "Cars");
+ assertProperty("retryLimit", "3");
+ assertThat(properties.size(), is(4));
+ }
+
+ @Test
+ public void shouldLoadCarsRepository() throws Throwable {
+ client.startRepositories();
+ assertThat(client.getNodeInfo("Cars", "/Cars", properties,
children), is(true));
+ assertThat(children, hasItems("Hybrid", "Sports",
"Luxury", "Utility"));
+ assertThat(properties.containsKey("jcr:primaryType"), is(true));
+ assertThat(properties.containsKey("dna:uuid"), is(true));
+ assertThat(properties.size(), is(2));
+
+ properties.clear();
+ children.clear();
+ assertThat(client.getNodeInfo("Cars", "/Cars/Hybrid",
properties, children), is(true));
+ assertThat(children, hasItems("Toyota Prius", "Toyota
Highlander", "Nissan Altima"));
+ assertThat(properties.containsKey("jcr:primaryType"), is(true));
+ assertThat(properties.containsKey("dna:uuid"), is(true));
+ assertThat(properties.size(), is(2));
+
+ properties.clear();
+ children.clear();
+ assertThat(client.getNodeInfo("Cars", "/Cars/Sports/Aston Martin
DB9", properties, children), is(true));
+ assertThat(children.size(), is(0));
+ assertThat(properties.containsKey("jcr:primaryType"), is(true));
+ assertThat(properties.containsKey("dna:uuid"), is(true));
+ assertProperty("maker", "Aston Martin");
+ assertProperty("maker", "Aston Martin");
+ assertProperty("model", "DB9");
+ assertProperty("year", "2008");
+ assertProperty("msrp", "$171,600");
+ assertProperty("userRating", "5");
+ assertProperty("mpgCity", "12");
+ assertProperty("mpgHighway", "19");
+ assertProperty("lengthInInches", "185.5");
+ assertProperty("wheelbaseInInches", "108.0");
+ assertProperty("engine", "5,935 cc 5.9 liters V 12");
+ assertThat(properties.size(), is(12));
+ }
+
+ @Test
+ public void shouldReturnNullForNonExistantNode() throws Throwable {
+ client.startRepositories();
+ assertThat(client.getNodeInfo("Cars", "/Cars/Sports/Non Existant
Car", properties, children), is(false));
+ }
+}
Property changes on:
trunk/docs/examples/gettingstarted/repositories/src/test/java/org/jboss/example/dna/repository/RepositoryClientTest.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified:
trunk/extensions/dna-connector-inmemory/src/main/java/org/jboss/dna/connector/inmemory/InMemoryConnectorI18n.java
===================================================================
---
trunk/extensions/dna-connector-inmemory/src/main/java/org/jboss/dna/connector/inmemory/InMemoryConnectorI18n.java 2008-09-10
18:05:54 UTC (rev 514)
+++
trunk/extensions/dna-connector-inmemory/src/main/java/org/jboss/dna/connector/inmemory/InMemoryConnectorI18n.java 2008-09-11
23:33:03 UTC (rev 515)
@@ -32,6 +32,7 @@
public static I18n connectorName;
public static I18n nodeDoesNotExist;
+ public static I18n errorSerializingCachePolicyInSource;
static {
try {
Modified:
trunk/extensions/dna-connector-inmemory/src/main/java/org/jboss/dna/connector/inmemory/InMemoryRepository.java
===================================================================
---
trunk/extensions/dna-connector-inmemory/src/main/java/org/jboss/dna/connector/inmemory/InMemoryRepository.java 2008-09-10
18:05:54 UTC (rev 514)
+++
trunk/extensions/dna-connector-inmemory/src/main/java/org/jboss/dna/connector/inmemory/InMemoryRepository.java 2008-09-11
23:33:03 UTC (rev 515)
@@ -44,6 +44,7 @@
import org.jboss.dna.spi.graph.commands.DeleteBranchCommand;
import org.jboss.dna.spi.graph.commands.GetChildrenCommand;
import org.jboss.dna.spi.graph.commands.GetPropertiesCommand;
+import org.jboss.dna.spi.graph.commands.GraphCommand;
import org.jboss.dna.spi.graph.commands.MoveBranchCommand;
import org.jboss.dna.spi.graph.commands.RecordBranchCommand;
import org.jboss.dna.spi.graph.commands.SetPropertiesCommand;
@@ -344,12 +345,15 @@
@Override
public void execute( CreateNodeCommand command ) {
Path path = command.getPath();
- Path parent = path.getParent();
- // Look up the parent node, which must exist ...
- Node parentNode = getNode(parent);
- if (parentNode == null) {
- Path lowestExisting = getLowestExistingPath(parent);
- throw new PathNotFoundException(path, lowestExisting,
InMemoryConnectorI18n.nodeDoesNotExist.text(parent));
+ Node parentNode = null;
+ if (!path.isRoot()) {
+ Path parent = path.getParent();
+ // Look up the parent node, which must exist ...
+ parentNode = getNode(parent);
+ if (parentNode == null) {
+ Path lowestExisting = getLowestExistingPath(parent);
+ throw new PathNotFoundException(path, lowestExisting,
InMemoryConnectorI18n.nodeDoesNotExist.text(parent));
+ }
}
UUID uuid = null;
for (Property property : command.getProperties()) {
@@ -376,6 +380,7 @@
@Override
public void execute( GetChildrenCommand command ) {
Node node = getTargetNode(command);
+ if (node == null) return;
// Get the names of the children ...
List<Node> children = node.getChildren();
for (Node child : children) {
@@ -387,6 +392,7 @@
@Override
public void execute( GetPropertiesCommand command ) {
Node node = getTargetNode(command);
+ if (node == null) return;
for (Property property : node.getProperties().values()) {
command.setProperty(property);
}
@@ -396,6 +402,7 @@
@Override
public void execute( SetPropertiesCommand command ) {
Node node = getTargetNode(command);
+ if (node == null) return;
// Now set (or remove) the properties to the supplied node ...
for (Property property : command.getProperties()) {
Name propName = property.getName();
@@ -412,12 +419,14 @@
@Override
public void execute( DeleteBranchCommand command ) {
Node node = getTargetNode(command);
+ if (node == null) return;
removeNode(getExecutionContext(), node);
}
@Override
public void execute( CopyNodeCommand command ) {
Node node = getTargetNode(command);
+ if (node == null) return;
// Look up the new parent, which must exist ...
Path newPath = command.getNewPath();
Node newParent = getNode(newPath.getParent());
@@ -427,6 +436,7 @@
@Override
public void execute( CopyBranchCommand command ) {
Node node = getTargetNode(command);
+ if (node == null) return;
// Look up the new parent, which must exist ...
Path newPath = command.getNewPath();
Node newParent = getNode(newPath.getParent());
@@ -436,6 +446,7 @@
@Override
public void execute( MoveBranchCommand command ) {
Node node = getTargetNode(command);
+ if (node == null) return;
// Look up the new parent, which must exist ...
Path newPath = command.getNewPath();
Node newParent = getNode(newPath.getParent());
@@ -445,6 +456,7 @@
@Override
public void execute( RecordBranchCommand command ) {
Node node = getTargetNode(command);
+ if (node == null) return;
recordNode(command, node);
}
@@ -456,15 +468,17 @@
}
}
- protected Node getTargetNode( ActsOnPath command ) {
+ protected <T extends ActsOnPath & GraphCommand> Node getTargetNode( T
command ) {
Path path = command.getPath();
// Look up the node with the supplied path ...
Node node = InMemoryRepository.this.getNode(path);
if (node == null) {
Path lowestExisting = getLowestExistingPath(path);
- throw new PathNotFoundException(path, lowestExisting,
InMemoryConnectorI18n.nodeDoesNotExist.text(path));
+ command.setError(new PathNotFoundException(path, lowestExisting,
+
InMemoryConnectorI18n.nodeDoesNotExist.text(path)));
+ return null;
}
- return null;
+ return node;
}
}
Modified:
trunk/extensions/dna-connector-inmemory/src/main/java/org/jboss/dna/connector/inmemory/InMemoryRepositoryConnection.java
===================================================================
---
trunk/extensions/dna-connector-inmemory/src/main/java/org/jboss/dna/connector/inmemory/InMemoryRepositoryConnection.java 2008-09-10
18:05:54 UTC (rev 514)
+++
trunk/extensions/dna-connector-inmemory/src/main/java/org/jboss/dna/connector/inmemory/InMemoryRepositoryConnection.java 2008-09-11
23:33:03 UTC (rev 515)
@@ -24,6 +24,8 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import javax.transaction.xa.XAResource;
+import org.jboss.dna.common.stats.Stopwatch;
+import org.jboss.dna.common.util.Logger;
import org.jboss.dna.spi.ExecutionContext;
import org.jboss.dna.spi.cache.CachePolicy;
import org.jboss.dna.spi.connector.RepositoryConnection;
@@ -112,6 +114,12 @@
*/
public void execute( ExecutionContext context,
GraphCommand... commands ) throws RepositorySourceException {
+ Logger logger = context.getLogger(getClass());
+ Stopwatch sw = null;
+ if (logger.isTraceEnabled()) {
+ sw = new Stopwatch();
+ sw.start();
+ }
// Do any commands update/write?
Lock lock = this.content.getLock().readLock();
for (GraphCommand command : commands) {
@@ -131,6 +139,11 @@
} finally {
lock.unlock();
}
+ if (logger.isTraceEnabled()) {
+ assert sw != null;
+ sw.stop();
+ logger.trace("InMemoryRepositoryConnection.execute(...) took " +
sw.getTotalDuration());
+ }
}
protected InMemoryRepository getContent() {
Modified:
trunk/extensions/dna-connector-inmemory/src/main/java/org/jboss/dna/connector/inmemory/InMemoryRepositorySource.java
===================================================================
---
trunk/extensions/dna-connector-inmemory/src/main/java/org/jboss/dna/connector/inmemory/InMemoryRepositorySource.java 2008-09-10
18:05:54 UTC (rev 514)
+++
trunk/extensions/dna-connector-inmemory/src/main/java/org/jboss/dna/connector/inmemory/InMemoryRepositorySource.java 2008-09-11
23:33:03 UTC (rev 515)
@@ -21,16 +21,18 @@
*/
package org.jboss.dna.connector.inmemory;
-import java.util.Collections;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Enumeration;
+import java.util.HashMap;
import java.util.Hashtable;
-import java.util.Set;
+import java.util.Map;
import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
+import javax.naming.BinaryRefAddr;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
@@ -39,6 +41,7 @@
import javax.naming.StringRefAddr;
import javax.naming.spi.ObjectFactory;
import net.jcip.annotations.GuardedBy;
+import org.jboss.dna.common.i18n.I18n;
import org.jboss.dna.common.util.ArgCheck;
import org.jboss.dna.spi.cache.CachePolicy;
import org.jboss.dna.spi.connector.RepositoryConnection;
@@ -61,40 +64,12 @@
*/
public static final int DEFAULT_RETRY_LIMIT = 0;
- private static final ConcurrentMap<String, InMemoryRepositorySource> sources =
new ConcurrentHashMap<String, InMemoryRepositorySource>();
- private static final ReadWriteLock sourcesLock = new ReentrantReadWriteLock();
+ protected static final String ROOT_NODE_UUID = "rootNodeUuid";
+ protected static final String SOURCE_NAME = "sourceName";
+ protected static final String DEFAULT_CACHE_POLICY = "defaultCachePolicy";
+ protected static final String JNDI_NAME = "jndiName";
+ protected static final String RETRY_LIMIT = "retryLimit";
- /**
- * Get the names of the in-memory repository sources that are currently registered
- *
- * @return the unmodifiable set of names
- */
- public static Set<String> getSourceNames() {
- Lock lock = sourcesLock.readLock();
- try {
- lock.lock();
- return Collections.unmodifiableSet(sources.keySet());
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Get the source with the supplied name.
- *
- * @param name the name
- * @return the source, or null if there is no source with the supplied name
- */
- public static InMemoryRepositorySource getSource( String name ) {
- Lock lock = sourcesLock.readLock();
- try {
- lock.lock();
- return sources.get(name);
- } finally {
- lock.unlock();
- }
- }
-
@GuardedBy( "sourcesLock" )
private String name;
@GuardedBy( "this" )
@@ -212,37 +187,14 @@
* {@inheritDoc}
*/
public String getName() {
- Lock lock = sourcesLock.readLock();
- try {
- lock.lock();
- return this.name;
- } finally {
- lock.unlock();
- }
+ return this.name;
}
/**
* @param name Sets name to the specified value.
- * @return true if the name was changed, or false if an existing instance already
exists with that name
*/
- public boolean setName( String name ) {
- Lock lock = sourcesLock.writeLock();
- try {
- lock.lock();
- // Determine if this name is allowed ...
- if (sources.containsKey(name)) return false;
-
- // Remove this object under its current name
- if (this.name != null) {
- sources.remove(this.name);
- }
- // Register this object under the new name
- this.name = name;
- sources.put(this.name, this);
- return true;
- } finally {
- lock.unlock();
- }
+ public void setName( String name ) {
+ this.name = name;
}
/**
@@ -260,11 +212,34 @@
/**
* {@inheritDoc}
*/
- public Reference getReference() {
+ public synchronized Reference getReference() {
String className = getClass().getName();
- String factoryClassName = className;
- return new Reference(className, new
StringRefAddr("DnaConnectorInMemoryRepositorySource", getName()),
factoryClassName,
- null);
+ String factoryClassName = this.getClass().getName();
+ Reference ref = new Reference(className, factoryClassName, null);
+
+ if (getName() != null) {
+ ref.add(new StringRefAddr(SOURCE_NAME, getName()));
+ }
+ if (getRootNodeUuid() != null) {
+ ref.add(new StringRefAddr(ROOT_NODE_UUID, getRootNodeUuid().toString()));
+ }
+ if (getJndiName() != null) {
+ ref.add(new StringRefAddr(JNDI_NAME, getJndiName()));
+ }
+ if (getDefaultCachePolicy() != null) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ CachePolicy policy = getDefaultCachePolicy();
+ try {
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ oos.writeObject(policy);
+ ref.add(new BinaryRefAddr(DEFAULT_CACHE_POLICY, baos.toByteArray()));
+ } catch (IOException e) {
+ I18n msg = InMemoryConnectorI18n.errorSerializingCachePolicyInSource;
+ throw new RepositorySourceException(getName(),
msg.text(policy.getClass().getName(), getName()), e);
+ }
+ }
+ ref.add(new StringRefAddr(RETRY_LIMIT, Integer.toString(getRetryLimit())));
+ return ref;
}
/**
@@ -273,13 +248,45 @@
public Object getObjectInstance( Object obj,
javax.naming.Name name,
Context nameCtx,
- Hashtable<?, ?> environment ) {
+ Hashtable<?, ?> environment ) throws Exception
{
if (obj instanceof Reference) {
+ Map<String, Object> values = new HashMap<String, Object>();
Reference ref = (Reference)obj;
- if (ref.getClassName().equals(getClass().getName())) {
- RefAddr addr =
ref.get("DnaConnectorInMemoryRepositorySource");
- return InMemoryRepositorySource.getSource((String)addr.getContent());
+ Enumeration<?> en = ref.getAll();
+ while (en.hasMoreElements()) {
+ RefAddr subref = (RefAddr)en.nextElement();
+ if (subref instanceof StringRefAddr) {
+ String key = subref.getType();
+ Object value = subref.getContent();
+ if (value != null) values.put(key, value.toString());
+ } else if (subref instanceof BinaryRefAddr) {
+ String key = subref.getType();
+ Object value = subref.getContent();
+ if (value instanceof byte[]) {
+ // Deserialize ...
+ ByteArrayInputStream bais = new
ByteArrayInputStream((byte[])value);
+ ObjectInputStream ois = new ObjectInputStream(bais);
+ value = ois.readObject();
+ values.put(key, value);
+ }
+ }
}
+ String sourceName = (String)values.get(SOURCE_NAME);
+ String rootNodeUuidString = (String)values.get(ROOT_NODE_UUID);
+ String jndiName = (String)values.get(JNDI_NAME);
+ Object defaultCachePolicy = values.get(DEFAULT_CACHE_POLICY);
+ String retryLimit = (String)values.get(RETRY_LIMIT);
+
+ // Create the source instance ...
+ InMemoryRepositorySource source = new InMemoryRepositorySource();
+ if (sourceName != null) source.setName(sourceName);
+ if (rootNodeUuidString != null)
source.setRootNodeUuid(UUID.fromString(rootNodeUuidString));
+ if (jndiName != null) source.setJndiName(jndiName);
+ if (defaultCachePolicy instanceof CachePolicy) {
+ source.setDefaultCachePolicy((CachePolicy)defaultCachePolicy);
+ }
+ if (retryLimit != null) source.setRetryLimit(Integer.parseInt(retryLimit));
+ return source;
}
return null;
}
Modified:
trunk/extensions/dna-connector-inmemory/src/main/resources/org/jboss/dna/connector/inmemory/InMemoryConnectorI18n.properties
===================================================================
---
trunk/extensions/dna-connector-inmemory/src/main/resources/org/jboss/dna/connector/inmemory/InMemoryConnectorI18n.properties 2008-09-10
18:05:54 UTC (rev 514)
+++
trunk/extensions/dna-connector-inmemory/src/main/resources/org/jboss/dna/connector/inmemory/InMemoryConnectorI18n.properties 2008-09-11
23:33:03 UTC (rev 515)
@@ -21,4 +21,5 @@
#
connectorName = In-Memory Connector
-nodeDoesNotExist = Could not find an existing node at {0}
\ No newline at end of file
+nodeDoesNotExist = Could not find an existing node at {0}
+errorSerializingCachePolicyInSource = Error serializing a {0} instance owned by the {1}
InMemoryRepositorySource
Added: trunk/extensions/dna-connector-inmemory/src/test/resources/log4j.properties
===================================================================
--- trunk/extensions/dna-connector-inmemory/src/test/resources/log4j.properties
(rev 0)
+++ trunk/extensions/dna-connector-inmemory/src/test/resources/log4j.properties 2008-09-11
23:33:03 UTC (rev 515)
@@ -0,0 +1,20 @@
+# Direct log messages to stdout
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %m%n
+
+# Root logger option
+log4j.rootLogger=INFO, stdout
+
+# Set up the default logging to be INFO level, then override specific units
+log4j.logger.org.jboss.dna=INFO
+#log4j.logger.org.jboss.dna.repository.sequencers=TRACE
+#log4j.logger.org.jboss.dna.sequencer=DEBUG
+#log4j.logger.org.jboss.dna.connector=TRACE
+#log4j.logger.org.jboss.dna.spi=DEBUG
+
+# Jackrabbit logging
+log4j.logger.org.apache.jackrabbit=WARN, stdout
+log4j.logger.org.apache.derby=INFO, stdout
+
Property changes on:
trunk/extensions/dna-connector-inmemory/src/test/resources/log4j.properties
___________________________________________________________________
Name: svn:mime-type
+ text/plain