Author: rhauch
Date: 2009-01-15 21:37:49 -0500 (Thu, 15 Jan 2009)
New Revision: 710
Added:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryNode.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepository.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositoryConnection.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositorySource.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/package-info.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/inmemory/
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/inmemory/InMemoryConnectorReadingTest.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/inmemory/InMemoryConnectorWritingTest.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositoryTest.java
Removed:
trunk/extensions/dna-connector-inmemory/
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/GraphI18n.java
trunk/dna-graph/src/main/resources/org/jboss/dna/graph/GraphI18n.properties
trunk/docs/examples/gettingstarted/pom.xml
trunk/docs/examples/gettingstarted/repositories/pom.xml
trunk/docs/examples/gettingstarted/repositories/src/main/java/org/jboss/example/dna/repository/RepositoryClient.java
trunk/docs/examples/gettingstarted/repositories/src/main/resources/configRepository.xml
trunk/docs/examples/gettingstarted/repositories/src/test/java/org/jboss/example/dna/repository/RepositoryClientTest.java
trunk/docs/gettingstarted/src/main/docbook/en-US/content/understanding_dna.xml
trunk/docs/reference/src/main/docbook/en-US/content/introduction.xml
trunk/docs/reference/src/main/docbook/en-US/content/repositories.xml
trunk/docs/reference/src/main/docbook/en-US/custom.dtd
trunk/extensions/dna-connector-federation/src/test/resources/log4j.properties
trunk/pom.xml
Log:
DNA-272 Move the In-Memory connector into "dna-graph"
The In-Memory connector was moved from a separate extension project into the dna-graph
project. This change did cause the package names to differ slightly (the addition of the
'graph' intermediate package), and so this affected the repository example and the
documentation.
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/GraphI18n.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/GraphI18n.java 2009-01-15 21:15:57
UTC (rev 709)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/GraphI18n.java 2009-01-16 02:37:49
UTC (rev 710)
@@ -83,6 +83,12 @@
public static I18n errorImportingContent;
public static I18n unableToFindRepositorySourceWithName;
+ /* In-Memory Connector */
+ public static I18n inMemoryConnectorName;
+ public static I18n inMemoryNodeDoesNotExist;
+ public static I18n errorSerializingInMemoryCachePolicyInSource;
+ public static I18n inMemoryConnectorRequestsMustHavePathOrUuid;
+
static {
try {
I18n.initialize(GraphI18n.class);
Added:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryNode.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryNode.java
(rev 0)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryNode.java 2009-01-16
02:37:49 UTC (rev 710)
@@ -0,0 +1,171 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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.graph.connector.inmemory;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import net.jcip.annotations.NotThreadSafe;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.Path;
+import org.jboss.dna.graph.property.Property;
+import org.jboss.dna.graph.property.PropertyFactory;
+
+/**
+ * @author Randall Hauch
+ */
+@NotThreadSafe
+public class InMemoryNode {
+
+ private final UUID uuid;
+ private InMemoryNode parent;
+ private Path.Segment name;
+ private final Map<Name, Property> properties = new HashMap<Name,
Property>();
+ private final List<InMemoryNode> children = new
LinkedList<InMemoryNode>();
+
+ public InMemoryNode( UUID uuid ) {
+ assert uuid != null;
+ this.uuid = uuid;
+ }
+
+ /**
+ * @return uuid
+ */
+ public UUID getUuid() {
+ return uuid;
+ }
+
+ /**
+ * @return name
+ */
+ public Path.Segment getName() {
+ return name;
+ }
+
+ /**
+ * @param name Sets name to the specified value.
+ */
+ protected void setName( Path.Segment name ) {
+ this.name = name;
+ }
+
+ /**
+ * @return parent
+ */
+ public InMemoryNode getParent() {
+ return parent;
+ }
+
+ /**
+ * @param parent Sets parent to the specified value.
+ */
+ protected void setParent( InMemoryNode parent ) {
+ this.parent = parent;
+ }
+
+ /**
+ * @return children
+ */
+ protected List<InMemoryNode> getChildren() {
+ return children;
+ }
+
+ /**
+ * @return properties
+ */
+ protected Map<Name, Property> getProperties() {
+ return properties;
+ }
+
+ public InMemoryNode setProperty( Property property ) {
+ if (property != null) {
+ this.properties.put(property.getName(), property);
+ }
+ return this;
+ }
+
+ public InMemoryNode setProperty( ExecutionContext context,
+ String name,
+ Object... values ) {
+ PropertyFactory propertyFactory = context.getPropertyFactory();
+ Name propertyName = context.getValueFactories().getNameFactory().create(name);
+ return setProperty(propertyFactory.create(propertyName, values));
+ }
+
+ public Property getProperty( ExecutionContext context,
+ String name ) {
+ Name propertyName = context.getValueFactories().getNameFactory().create(name);
+ return getProperty(propertyName);
+ }
+
+ public Property getProperty( Name name ) {
+ return this.properties.get(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return uuid.hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof InMemoryNode) {
+ InMemoryNode that = (InMemoryNode)obj;
+ if (!this.getUuid().equals(that.getUuid())) return false;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ if (this.name == null) {
+ sb.append("");
+ } else {
+ sb.append(this.name);
+ }
+ sb.append(" (").append(uuid).append(")");
+ return sb.toString();
+ }
+}
Added:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepository.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepository.java
(rev 0)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepository.java 2009-01-16
02:37:49 UTC (rev 710)
@@ -0,0 +1,583 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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.graph.connector.inmemory;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import net.jcip.annotations.NotThreadSafe;
+import org.jboss.dna.common.i18n.I18n;
+import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.graph.DnaLexicon;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.GraphI18n;
+import org.jboss.dna.graph.Location;
+import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.Path;
+import org.jboss.dna.graph.property.PathFactory;
+import org.jboss.dna.graph.property.PathNotFoundException;
+import org.jboss.dna.graph.property.Property;
+import org.jboss.dna.graph.property.PropertyFactory;
+import org.jboss.dna.graph.property.PropertyType;
+import org.jboss.dna.graph.property.Reference;
+import org.jboss.dna.graph.property.UuidFactory;
+import org.jboss.dna.graph.property.ValueFactory;
+import org.jboss.dna.graph.property.Path.Segment;
+import org.jboss.dna.graph.property.basic.RootPath;
+import org.jboss.dna.graph.request.CopyBranchRequest;
+import org.jboss.dna.graph.request.CreateNodeRequest;
+import org.jboss.dna.graph.request.DeleteBranchRequest;
+import org.jboss.dna.graph.request.MoveBranchRequest;
+import org.jboss.dna.graph.request.ReadAllChildrenRequest;
+import org.jboss.dna.graph.request.ReadAllPropertiesRequest;
+import org.jboss.dna.graph.request.Request;
+import org.jboss.dna.graph.request.UpdatePropertiesRequest;
+import org.jboss.dna.graph.request.processor.RequestProcessor;
+
+/**
+ * @author Randall Hauch
+ */
+@NotThreadSafe
+public class InMemoryRepository {
+
+ protected final ReadWriteLock lock = new ReentrantReadWriteLock();
+ private final String name;
+ private final UUID rootNodeUuid;
+ private final Map<UUID, InMemoryNode> nodesByUuid = new HashMap<UUID,
InMemoryNode>();
+
+ public InMemoryRepository( String name,
+ UUID rootNodeUUID ) {
+ CheckArg.isNotNull(rootNodeUUID, "rootNodeUUID");
+ CheckArg.isNotEmpty(name, "name");
+ this.name = name;
+ this.rootNodeUuid = rootNodeUUID;
+ // Create the root node ...
+ InMemoryNode root = new InMemoryNode(rootNodeUUID);
+ nodesByUuid.put(root.getUuid(), root);
+ }
+
+ /**
+ * @return lock
+ */
+ public ReadWriteLock getLock() {
+ return lock;
+ }
+
+ /**
+ * @return name
+ */
+ public String getName() {
+ return name;
+ }
+
+ public InMemoryNode getRoot() {
+ return nodesByUuid.get(this.rootNodeUuid);
+ }
+
+ public InMemoryNode getNode( UUID uuid ) {
+ assert uuid != null;
+ return nodesByUuid.get(uuid);
+ }
+
+ protected Map<UUID, InMemoryNode> getNodesByUuid() {
+ return nodesByUuid;
+ }
+
+ public InMemoryNode getNode( ExecutionContext context,
+ String path ) {
+ assert context != null;
+ assert path != null;
+ return getNode(context.getValueFactories().getPathFactory().create(path));
+ }
+
+ /**
+ * Find a node with the given path.
+ *
+ * @param path the path to the node; may not be null
+ * @return the node with the path, or null if the node does not exist
+ */
+ public InMemoryNode getNode( Path path ) {
+ assert path != null;
+ InMemoryNode node = getRoot();
+ for (Path.Segment segment : path) {
+ InMemoryNode desiredChild = null;
+ for (InMemoryNode child : node.getChildren()) {
+ if (child == null) continue;
+ Path.Segment childName = child.getName();
+ if (childName == null) continue;
+ if (childName.equals(segment)) {
+ desiredChild = child;
+ break;
+ }
+ }
+ if (desiredChild != null) {
+ node = desiredChild;
+ } else {
+ return null;
+ }
+ }
+ return node;
+ }
+
+ /**
+ * Find the lowest existing node along the path.
+ *
+ * @param path the path to the node; may not be null
+ * @return the lowest existing node along the path, or the root node if no node
exists on the path
+ */
+ public Path getLowestExistingPath( Path path ) {
+ assert path != null;
+ InMemoryNode node = getRoot();
+ int segmentNumber = 0;
+ for (Path.Segment segment : path) {
+ InMemoryNode desiredChild = null;
+ for (InMemoryNode child : node.getChildren()) {
+ if (child == null) continue;
+ Path.Segment childName = child.getName();
+ if (childName == null) continue;
+ if (childName.equals(segment)) {
+ desiredChild = child;
+ break;
+ }
+ }
+ if (desiredChild != null) {
+ node = desiredChild;
+ } else {
+ return path.subpath(0, segmentNumber);
+ }
+ ++segmentNumber;
+ }
+ return RootPath.INSTANCE;
+ }
+
+ protected UUID generateUuid() {
+ return UUID.randomUUID();
+ }
+
+ public void removeNode( ExecutionContext context,
+ InMemoryNode node ) {
+ assert context != null;
+ assert node != null;
+ assert getRoot().equals(node) != true;
+ InMemoryNode parent = node.getParent();
+ assert parent != null;
+ parent.getChildren().remove(node);
+ correctSameNameSiblingIndexes(context, parent, node.getName().getName());
+ removeUuidReference(node);
+ }
+
+ protected void removeUuidReference( InMemoryNode node ) {
+ nodesByUuid.remove(node.getUuid());
+ for (InMemoryNode child : node.getChildren()) {
+ removeUuidReference(child);
+ }
+ }
+
+ /**
+ * Create a node at the supplied path. The parent of the new node must already
exist.
+ *
+ * @param context the environment; may not be null
+ * @param pathToNewNode the path to the new node; may not be null
+ * @return the new node (or root if the path specified the root)
+ */
+ public InMemoryNode createNode( ExecutionContext context,
+ String pathToNewNode ) {
+ assert context != null;
+ assert pathToNewNode != null;
+ Path path = context.getValueFactories().getPathFactory().create(pathToNewNode);
+ if (path.isRoot()) return getRoot();
+ Path parentPath = path.getParent();
+ InMemoryNode parentNode = getNode(parentPath);
+ Name name = path.getLastSegment().getName();
+ return createNode(context, parentNode, name, null);
+ }
+
+ /**
+ * Create a new node with the supplied name, as a child of the supplied parent.
+ *
+ * @param context the execution context
+ * @param parentNode the parent node; may not be null
+ * @param name the name; may not be null
+ * @param uuid the UUID of the node, or null if the UUID is to be generated
+ * @return the new node
+ */
+ public InMemoryNode createNode( ExecutionContext context,
+ InMemoryNode parentNode,
+ Name name,
+ UUID uuid ) {
+ assert context != null;
+ assert name != null;
+ if (parentNode == null) parentNode = getRoot();
+ if (uuid == null) uuid = generateUuid();
+ InMemoryNode node = new InMemoryNode(uuid);
+ nodesByUuid.put(node.getUuid(), node);
+ node.setParent(parentNode);
+ Path.Segment newName =
context.getValueFactories().getPathFactory().createSegment(name);
+ node.setName(newName);
+ parentNode.getChildren().add(node);
+ correctSameNameSiblingIndexes(context, parentNode, name);
+ return node;
+ }
+
+ protected void correctSameNameSiblingIndexes( ExecutionContext context,
+ InMemoryNode parentNode,
+ Name name ) {
+ if (parentNode == null) return;
+ // Look for the highest existing index ...
+ List<InMemoryNode> childrenWithSameNames = new
LinkedList<InMemoryNode>();
+ for (InMemoryNode child : parentNode.getChildren()) {
+ if (child.getName().getName().equals(name))
childrenWithSameNames.add(child);
+ }
+ if (childrenWithSameNames.size() == 0) return;
+ if (childrenWithSameNames.size() == 1) {
+ InMemoryNode childWithSameName = childrenWithSameNames.get(0);
+ Path.Segment newName =
context.getValueFactories().getPathFactory().createSegment(name, Path.NO_INDEX);
+ childWithSameName.setName(newName);
+ return;
+ }
+ int index = 1;
+ for (InMemoryNode childWithSameName : childrenWithSameNames) {
+ Path.Segment segment = childWithSameName.getName();
+ if (segment.getIndex() != index) {
+ Path.Segment newName =
context.getValueFactories().getPathFactory().createSegment(name, index);
+ childWithSameName.setName(newName);
+ }
+ ++index;
+ }
+ }
+
+ /**
+ * Move the supplied node to the new parent. This method automatically removes the
node from its existing parent, and also
+ * correctly adjusts the {@link Path.Segment#getIndex() index} to be correct in the
new parent.
+ *
+ * @param context
+ * @param node the node to be moved; may not be the {@link #getRoot() root}
+ * @param newParent the new parent; may not be the {@link #getRoot() root}
+ */
+ public void moveNode( ExecutionContext context,
+ InMemoryNode node,
+ InMemoryNode newParent ) {
+ assert context != null;
+ assert newParent != null;
+ assert node != null;
+ assert getRoot().equals(newParent) != true;
+ assert getRoot().equals(node) != true;
+ InMemoryNode oldParent = node.getParent();
+ if (oldParent != null) {
+ if (oldParent.equals(newParent)) return;
+ boolean removed = oldParent.getChildren().remove(node);
+ assert removed == true;
+ node.setParent(null);
+ correctSameNameSiblingIndexes(context, oldParent, node.getName().getName());
+ }
+ node.setParent(newParent);
+ newParent.getChildren().add(node);
+ correctSameNameSiblingIndexes(context, newParent, node.getName().getName());
+ }
+
+ /**
+ * This should copy the subgraph given by the original node and place the new copy
under the supplied new parent. Note that
+ * internal references between nodes within the original subgraph must be reflected
as internal nodes within the new subgraph.
+ *
+ * @param context
+ * @param original
+ * @param newParent
+ * @param recursive
+ * @param oldToNewUuids the map of UUIDs of nodes in the new subgraph keyed by the
UUIDs of nodes in the original; may not be
+ * null
+ * @return the new node, which is the top of the new subgraph
+ */
+ public InMemoryNode copyNode( ExecutionContext context,
+ InMemoryNode original,
+ InMemoryNode newParent,
+ boolean recursive,
+ Map<UUID, UUID> oldToNewUuids ) {
+ assert context != null;
+ assert original != null;
+ assert newParent != null;
+ assert oldToNewUuids != null;
+
+ // Get or create the new node ...
+ InMemoryNode copy = createNode(context, newParent, original.getName().getName(),
null);
+ oldToNewUuids.put(original.getUuid(), copy.getUuid());
+
+ // Copy the properties ...
+ copy.getProperties().clear();
+ copy.getProperties().putAll(original.getProperties());
+ if (recursive) {
+ // Loop over each child and call this method ...
+ for (InMemoryNode child : original.getChildren()) {
+ copyNode(context, child, copy, true, oldToNewUuids);
+ }
+ }
+
+ // Now, adjust any references in the new subgraph to objects in the original
subgraph
+ // (because they were internal references, and need to be internal to the new
subgraph)
+ PropertyFactory propertyFactory = context.getPropertyFactory();
+ UuidFactory uuidFactory = context.getValueFactories().getUuidFactory();
+ ValueFactory<Reference> referenceFactory =
context.getValueFactories().getReferenceFactory();
+ for (Map.Entry<UUID, UUID> oldToNew : oldToNewUuids.entrySet()) {
+ InMemoryNode oldNode = nodesByUuid.get(oldToNew.getKey());
+ InMemoryNode newNode = nodesByUuid.get(oldToNew.getValue());
+ assert oldNode != null;
+ assert newNode != null;
+ // Iterate over the properties of the new ...
+ for (Map.Entry<Name, Property> entry :
newNode.getProperties().entrySet()) {
+ Property property = entry.getValue();
+ // Now see if any of the property values are references ...
+ List<Object> newValues = new ArrayList<Object>();
+ boolean foundReference = false;
+ for (Iterator<?> iter = property.getValues(); iter.hasNext();) {
+ Object value = iter.next();
+ PropertyType type = PropertyType.discoverType(value);
+ if (type == PropertyType.REFERENCE) {
+ UUID oldReferencedUuid = uuidFactory.create(value);
+ UUID newReferencedUuid = oldToNewUuids.get(oldReferencedUuid);
+ if (newReferencedUuid != null) {
+ newValues.add(referenceFactory.create(newReferencedUuid));
+ foundReference = true;
+ }
+ } else {
+ newValues.add(value);
+ }
+ }
+ // If we found at least one reference, we have to build a new Property
object ...
+ if (foundReference) {
+ Property newProperty = propertyFactory.create(property.getName(),
newValues);
+ entry.setValue(newProperty);
+ }
+ }
+ }
+
+ return copy;
+ }
+
+ /**
+ * Get a request processor given the supplied environment and source name.
+ *
+ * @param context the environment in which the commands are to be executed
+ * @param sourceName the name of the repository source
+ * @return the request processor; never null
+ */
+ /*package*/RequestProcessor getRequestProcessor( ExecutionContext context,
+ String sourceName ) {
+ return new Processor(context, sourceName);
+ }
+
+ protected class Processor extends RequestProcessor {
+ private final PathFactory pathFactory;
+ private final PropertyFactory propertyFactory;
+
+ protected Processor( ExecutionContext context,
+ String sourceName ) {
+ super(sourceName, context);
+ pathFactory = context.getValueFactories().getPathFactory();
+ propertyFactory = context.getPropertyFactory();
+ }
+
+ @Override
+ public void process( ReadAllChildrenRequest request ) {
+ InMemoryNode node = getTargetNode(request, request.of());
+ if (node == null) return;
+ Location actualLocation = getActualLocation(request.of().getPath(), node);
+ Path path = actualLocation.getPath();
+ // Get the names of the children ...
+ List<InMemoryNode> children = node.getChildren();
+ for (InMemoryNode child : children) {
+ Segment childName = child.getName();
+ Path childPath = pathFactory.create(path, childName);
+ request.addChild(childPath, propertyFactory.create(DnaLexicon.UUID,
child.getUuid()));
+ }
+ request.setActualLocationOfNode(actualLocation);
+ setCacheableInfo(request);
+ }
+
+ @Override
+ public void process( ReadAllPropertiesRequest request ) {
+ InMemoryNode node = getTargetNode(request, request.at());
+ if (node == null) return;
+ // Get the properties of the node ...
+ Location actualLocation = getActualLocation(request.at().getPath(), node);
+ request.addProperty(propertyFactory.create(DnaLexicon.UUID,
node.getUuid()));
+ for (Property property : node.getProperties().values()) {
+ request.addProperty(property);
+ }
+ request.setActualLocationOfNode(actualLocation);
+ setCacheableInfo(request);
+ }
+
+ @Override
+ public void process( CopyBranchRequest request ) {
+ InMemoryNode node = getTargetNode(request, request.from());
+ if (node == null) return;
+ // Look up the new parent, which must exist ...
+ Path newParentPath = request.into().getPath();
+ InMemoryNode newParent = getNode(newParentPath);
+ InMemoryNode newNode = copyNode(getExecutionContext(), node, newParent, true,
new HashMap<UUID, UUID>());
+ Path newPath =
getExecutionContext().getValueFactories().getPathFactory().create(newParentPath,
newNode.getName());
+ Location oldLocation = getActualLocation(request.from().getPath(), node);
+ Location newLocation = new Location(newPath, newNode.getUuid());
+ request.setActualLocations(oldLocation, newLocation);
+ }
+
+ @Override
+ public void process( CreateNodeRequest request ) {
+ Path parent = request.under().getPath();
+ CheckArg.isNotNull(parent, "request.under().getPath()");
+ InMemoryNode node = null;
+ // Look up the parent node, which must exist ...
+ InMemoryNode parentNode = getNode(parent);
+ if (parentNode == null) {
+ Path lowestExisting = getLowestExistingPath(parent);
+ request.setError(new PathNotFoundException(request.under(),
lowestExisting,
+
GraphI18n.inMemoryNodeDoesNotExist.text(parent)));
+ }
+ UUID uuid = null;
+ for (Property property : request.properties()) {
+ if (property.getName().equals(DnaLexicon.UUID)) {
+ uuid =
getExecutionContext().getValueFactories().getUuidFactory().create(property.getValues().next());
+ break;
+ }
+ }
+ node = createNode(getExecutionContext(), parentNode, request.named(), uuid);
+ assert node != null;
+ Path path =
getExecutionContext().getValueFactories().getPathFactory().create(parent,
node.getName());
+ // Now add the properties to the supplied node ...
+ for (Property property : request.properties()) {
+ Name propName = property.getName();
+ if (property.size() == 0) {
+ node.getProperties().remove(propName);
+ continue;
+ }
+ if (!propName.equals(DnaLexicon.UUID)) {
+ node.getProperties().put(propName, property);
+ }
+ }
+ Location actualLocation = getActualLocation(path, node);
+ request.setActualLocationOfNode(actualLocation);
+ }
+
+ @Override
+ public void process( DeleteBranchRequest request ) {
+ InMemoryNode node = getTargetNode(request, request.at());
+ if (node == null) return;
+ removeNode(getExecutionContext(), node);
+ Location actualLocation = getActualLocation(request.at().getPath(), node);
+ request.setActualLocationOfNode(actualLocation);
+ }
+
+ @Override
+ public void process( MoveBranchRequest request ) {
+ InMemoryNode node = getTargetNode(request, request.from());
+ if (node == null) return;
+ // Look up the new parent, which must exist ...
+ Path newPath = request.into().getPath();
+ Path newParentPath = newPath.getParent();
+ InMemoryNode newParent = getNode(newParentPath);
+ node.setParent(newParent);
+ newPath =
getExecutionContext().getValueFactories().getPathFactory().create(newParentPath,
node.getName());
+ Location oldLocation = getActualLocation(request.from().getPath(), node);
+ Location newLocation = new Location(newPath, node.getUuid());
+ request.setActualLocations(oldLocation, newLocation);
+ }
+
+ @Override
+ public void process( UpdatePropertiesRequest request ) {
+ InMemoryNode node = getTargetNode(request, request.on());
+ if (node == null) return;
+ // Now set (or remove) the properties to the supplied node ...
+ for (Property property : request.properties()) {
+ Name propName = property.getName();
+ if (property.size() == 0) {
+ node.getProperties().remove(propName);
+ continue;
+ }
+ if (!propName.equals(DnaLexicon.UUID)) {
+ node.getProperties().put(propName, property);
+ }
+ }
+ Location actualLocation = getActualLocation(request.on().getPath(), node);
+ request.setActualLocationOfNode(actualLocation);
+ }
+
+ protected Location getActualLocation( Path path,
+ InMemoryNode node ) {
+ if (path == null) {
+ // Find the path on the node ...
+ LinkedList<Path.Segment> segments = new
LinkedList<Path.Segment>();
+ InMemoryNode n = node;
+ while (n != null) {
+ if (n.getParent() == null) break;
+ segments.addFirst(n.getName());
+ n = n.getParent();
+ }
+ path = pathFactory.createAbsolutePath(segments);
+ }
+ return new Location(path, node.getUuid());
+ }
+
+ protected InMemoryNode getTargetNode( Request request,
+ Location location ) {
+ // Check first for the UUID ...
+ InMemoryNode node = null;
+ UUID uuid = location.getUuid();
+ if (uuid != null) {
+ node = InMemoryRepository.this.getNode(uuid);
+ }
+ Path path = null;
+ if (node == null) {
+ // Look up the node with the supplied path ...
+ path = location.getPath();
+ if (path != null) {
+ node = InMemoryRepository.this.getNode(path);
+ }
+ }
+ if (node == null) {
+ if (path == null) {
+ if (uuid == null) {
+ // Missing both path and UUID ...
+ I18n msg =
GraphI18n.inMemoryConnectorRequestsMustHavePathOrUuid;
+ request.setError(new IllegalArgumentException(msg.text()));
+ return null;
+ }
+ // Missing path, and could not find by UUID ...
+ request.setError(new PathNotFoundException(location,
pathFactory.createRootPath(),
+
GraphI18n.inMemoryNodeDoesNotExist.text(path)));
+ return null;
+ }
+ // Could not find the node given the supplied path, so find the lowest
path that does exist ...
+ Path lowestExisting = getLowestExistingPath(path);
+ request.setError(new PathNotFoundException(location, lowestExisting,
+
GraphI18n.inMemoryNodeDoesNotExist.text(path)));
+ }
+ return node;
+ }
+ }
+}
Added:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositoryConnection.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositoryConnection.java
(rev 0)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositoryConnection.java 2009-01-16
02:37:49 UTC (rev 710)
@@ -0,0 +1,158 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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.graph.connector.inmemory;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+import javax.transaction.xa.XAResource;
+import org.jboss.dna.common.statistic.Stopwatch;
+import org.jboss.dna.common.util.Logger;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.cache.CachePolicy;
+import org.jboss.dna.graph.connector.RepositoryConnection;
+import org.jboss.dna.graph.connector.RepositorySourceException;
+import org.jboss.dna.graph.connector.RepositorySourceListener;
+import org.jboss.dna.graph.request.Request;
+import org.jboss.dna.graph.request.processor.RequestProcessor;
+
+/**
+ * @author Randall Hauch
+ */
+public class InMemoryRepositoryConnection implements RepositoryConnection {
+
+ protected static final RepositorySourceListener NO_OP_LISTENER = new
RepositorySourceListener() {
+
+ /**
+ * {@inheritDoc}
+ */
+ public void notify( String sourceName,
+ Object... events ) {
+ // do nothing
+ }
+ };
+
+ private final InMemoryRepositorySource source;
+ private final InMemoryRepository content;
+ private RepositorySourceListener listener = NO_OP_LISTENER;
+
+ InMemoryRepositoryConnection( InMemoryRepositorySource source,
+ InMemoryRepository content ) {
+ assert source != null;
+ assert content != null;
+ this.source = source;
+ this.content = content;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getSourceName() {
+ return source.getName();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public CachePolicy getDefaultCachePolicy() {
+ return source.getDefaultCachePolicy();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public XAResource getXAResource() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean ping( long time,
+ TimeUnit unit ) {
+ this.content.getRoot();
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setListener( RepositorySourceListener listener ) {
+ this.listener = listener != null ? listener : NO_OP_LISTENER;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void close() {
+ // do nothing
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.connector.RepositoryConnection#execute(org.jboss.dna.graph.ExecutionContext,
+ * org.jboss.dna.graph.request.Request)
+ */
+ public void execute( ExecutionContext context,
+ Request request ) throws RepositorySourceException {
+ Logger logger = context.getLogger(getClass());
+ Stopwatch sw = null;
+ if (logger.isTraceEnabled()) {
+ sw = new Stopwatch();
+ sw.start();
+ }
+ // Do any commands update/write?
+ RequestProcessor processor = this.content.getRequestProcessor(context,
this.getSourceName());
+
+ Lock lock = request.isReadOnly() ? content.getLock().readLock() :
content.getLock().writeLock();
+ lock.lock();
+ try {
+ // Obtain the lock and execute the commands ...
+ processor.process(request);
+ } finally {
+ try {
+ processor.close();
+ } finally {
+ lock.unlock();
+ }
+ }
+ if (logger.isTraceEnabled()) {
+ assert sw != null;
+ sw.stop();
+ logger.trace("InMemoryRepositoryConnection.execute(...) took " +
sw.getTotalDuration());
+ }
+ }
+
+ protected InMemoryRepository getContent() {
+ return content;
+ }
+
+ /**
+ * @return listener
+ */
+ protected RepositorySourceListener getListener() {
+ return this.listener;
+ }
+
+}
Added:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositorySource.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositorySource.java
(rev 0)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositorySource.java 2009-01-16
02:37:49 UTC (rev 710)
@@ -0,0 +1,325 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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.graph.connector.inmemory;
+
+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.Map;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicInteger;
+import javax.naming.BinaryRefAddr;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.naming.RefAddr;
+import javax.naming.Reference;
+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.CheckArg;
+import org.jboss.dna.graph.GraphI18n;
+import org.jboss.dna.graph.cache.CachePolicy;
+import org.jboss.dna.graph.connector.RepositoryConnection;
+import org.jboss.dna.graph.connector.RepositoryContext;
+import org.jboss.dna.graph.connector.RepositorySource;
+import org.jboss.dna.graph.connector.RepositorySourceCapabilities;
+import org.jboss.dna.graph.connector.RepositorySourceException;
+
+/**
+ * @author Randall Hauch
+ */
+public class InMemoryRepositorySource implements RepositorySource, ObjectFactory {
+
+ /**
+ * The initial version is 1
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * The default limit is {@value} for retrying {@link RepositoryConnection connection}
calls to the underlying source.
+ */
+ public static final int DEFAULT_RETRY_LIMIT = 0;
+
+ protected static final RepositorySourceCapabilities CAPABILITIES = new
RepositorySourceCapabilities(true, true);
+
+ 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";
+
+ @GuardedBy( "sourcesLock" )
+ private String name;
+ @GuardedBy( "this" )
+ private String jndiName;
+ private UUID rootNodeUuid = UUID.randomUUID();
+ private CachePolicy defaultCachePolicy;
+ private final AtomicInteger retryLimit = new AtomicInteger(DEFAULT_RETRY_LIMIT);
+ private transient InMemoryRepository repository;
+ private transient RepositoryContext repositoryContext;
+
+ /**
+ * Create a repository source instance.
+ */
+ public InMemoryRepositorySource() {
+ super();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.connector.RepositorySource#initialize(org.jboss.dna.graph.connector.RepositoryContext)
+ */
+ public void initialize( RepositoryContext context ) throws RepositorySourceException
{
+ this.repositoryContext = context;
+ }
+
+ /**
+ * @return repositoryContext
+ */
+ public RepositoryContext getRepositoryContext() {
+ return repositoryContext;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.connector.RepositorySource#getRetryLimit()
+ */
+ public int getRetryLimit() {
+ return retryLimit.get();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.connector.RepositorySource#setRetryLimit(int)
+ */
+ public void setRetryLimit( int limit ) {
+ retryLimit.set(limit < 0 ? 0 : limit);
+ }
+
+ /**
+ * Get the default cache policy for this source, or null if the global default cache
policy should be used
+ *
+ * @return the default cache policy, or null if this source has no explicit default
cache policy
+ */
+ public CachePolicy getDefaultCachePolicy() {
+ return defaultCachePolicy;
+ }
+
+ /**
+ * @param defaultCachePolicy Sets defaultCachePolicy to the specified value.
+ */
+ public void setDefaultCachePolicy( CachePolicy defaultCachePolicy ) {
+ this.defaultCachePolicy = defaultCachePolicy;
+ }
+
+ /**
+ * @return rootNodeUuid
+ */
+ public UUID getRootNodeUuid() {
+ return this.rootNodeUuid;
+ }
+
+ /**
+ * @param rootNodeUuid Sets rootNodeUuid to the specified value.
+ */
+ public void setRootNodeUuid( UUID rootNodeUuid ) {
+ this.rootNodeUuid = rootNodeUuid != null ? rootNodeUuid : UUID.randomUUID();
+ }
+
+ /**
+ * If you use this to set a JNDI name, this source will be bound to that name using
the default {@link InitialContext}. You
+ * can also do this manually if you have additional requirements.
+ *
+ * @param name the JNDI name
+ * @throws NamingException if there is a problem registering this object
+ * @see #getJndiName()
+ */
+ public void setJndiName( String name ) throws NamingException {
+ setJndiName(name, null);
+ }
+
+ /**
+ * Register this source in JNDI under the supplied name using the supplied context.
to set a JNDI name, this source will be
+ * bound to that name using the default {@link InitialContext}. You can also do this
manually if you have additional
+ * requirements.
+ *
+ * @param name the JNDI name, or null if this object is to no longer be registered
+ * @param context the JNDI context, or null if the {@link InitialContext} should be
used
+ * @throws NamingException if there is a problem registering this object
+ * @see #getJndiName()
+ */
+ public synchronized void setJndiName( String name,
+ Context context ) throws NamingException {
+ CheckArg.isNotNull(name, "name");
+ if (context == null) context = new InitialContext();
+
+ // First register in JNDI under the new name ...
+ if (name != null) {
+ context.bind(name, this);
+ }
+ // Second, unregister from JNDI if there is already a name ...
+ if (jndiName != null && !jndiName.equals(name)) {
+ context.unbind(jndiName);
+ }
+ // Record the new name ...
+ this.jndiName = name;
+ }
+
+ /**
+ * Gets the JNDI name this source is bound to. Only valid if you used setJNDIName to
bind it.
+ *
+ * @return the JNDI name, or null if it is not bound in JNDI
+ * @see #setJndiName(String)
+ */
+ public synchronized String getJndiName() {
+ return jndiName;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getName() {
+ return this.name;
+ }
+
+ /**
+ * @param name Sets name to the specified value.
+ */
+ public void setName( String name ) {
+ this.name = name;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.connector.RepositorySource#getConnection()
+ */
+ public RepositoryConnection getConnection() throws RepositorySourceException {
+ if (repository == null) {
+ repository = new InMemoryRepository(name, rootNodeUuid);
+ }
+ return new InMemoryRepositoryConnection(this, repository);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public synchronized Reference getReference() {
+ String className = getClass().getName();
+ 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 = GraphI18n.errorSerializingInMemoryCachePolicyInSource;
+ throw new RepositorySourceException(getName(),
msg.text(policy.getClass().getName(), getName()), e);
+ }
+ }
+ ref.add(new StringRefAddr(RETRY_LIMIT, Integer.toString(getRetryLimit())));
+ return ref;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object getObjectInstance( Object obj,
+ javax.naming.Name name,
+ Context nameCtx,
+ Hashtable<?, ?> environment ) throws Exception
{
+ if (obj instanceof Reference) {
+ Map<String, Object> values = new HashMap<String, Object>();
+ Reference ref = (Reference)obj;
+ 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;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.connector.RepositorySource#getCapabilities()
+ */
+ public RepositorySourceCapabilities getCapabilities() {
+ return CAPABILITIES;
+ }
+}
Added:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/package-info.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/package-info.java
(rev 0)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/package-info.java 2009-01-16
02:37:49 UTC (rev 710)
@@ -0,0 +1,31 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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.
+ */
+/**
+ * The In-Memory Connector represents a {@link
org.jboss.dna.graph.connector.RepositorySource connector} that maintains
+ * a graph in transient in-process memory. This connector is a good solution for a
readable and writable repository source
+ * that is very lightweight and of small to moderate sizes.
+ */
+
+package org.jboss.dna.graph.connector.inmemory;
+
Modified: trunk/dna-graph/src/main/resources/org/jboss/dna/graph/GraphI18n.properties
===================================================================
--- trunk/dna-graph/src/main/resources/org/jboss/dna/graph/GraphI18n.properties 2009-01-15
21:15:57 UTC (rev 709)
+++ trunk/dna-graph/src/main/resources/org/jboss/dna/graph/GraphI18n.properties 2009-01-16
02:37:49 UTC (rev 710)
@@ -70,3 +70,8 @@
errorImportingContent = Error importing {0} content from {1}
unableToFindRepositorySourceWithName = Unable to find a repository source named
"{0}"
+# In-memory connector
+inMemoryConnectorName = In-Memory Connector
+inMemoryNodeDoesNotExist = Could not find an existing node at {0}
+errorSerializingInMemoryCachePolicyInSource = Error serializing a {0} instance owned by
the {1} In-Memory repository source
+inMemoryConnectorRequestsMustHavePathOrUuid = In-Memory connector can only process
requests with a path and/or UUID
Added:
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/inmemory/InMemoryConnectorReadingTest.java
===================================================================
---
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/inmemory/InMemoryConnectorReadingTest.java
(rev 0)
+++
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/inmemory/InMemoryConnectorReadingTest.java 2009-01-16
02:37:49 UTC (rev 710)
@@ -0,0 +1,63 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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.graph.connector.inmemory;
+
+import org.jboss.dna.common.statistic.Stopwatch;
+import org.jboss.dna.graph.Graph;
+import org.jboss.dna.graph.connector.RepositorySource;
+import org.jboss.dna.graph.connector.test.ReadableConnectorTest;
+
+/**
+ * @author Randall Hauch
+ */
+public class InMemoryConnectorReadingTest extends ReadableConnectorTest {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.connector.test.AbstractConnectorTest#setUpSource()
+ */
+ @Override
+ protected RepositorySource setUpSource() {
+ InMemoryRepositorySource source = new InMemoryRepositorySource();
+ source.setName("Test Repository");
+ return source;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.connector.test.AbstractConnectorTest#initializeContent(org.jboss.dna.graph.Graph)
+ */
+ @Override
+ protected void initializeContent( Graph graph ) {
+ String initialPath = "";
+ int depth = 4;
+ int numChildrenPerNode = 4;
+ int numPropertiesPerNode = 7;
+ Stopwatch sw = new Stopwatch();
+ boolean batch = true;
+ createSubgraph(graph, initialPath, depth, numChildrenPerNode,
numPropertiesPerNode, batch, sw, System.out, null);
+ }
+}
Added:
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/inmemory/InMemoryConnectorWritingTest.java
===================================================================
---
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/inmemory/InMemoryConnectorWritingTest.java
(rev 0)
+++
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/inmemory/InMemoryConnectorWritingTest.java 2009-01-16
02:37:49 UTC (rev 710)
@@ -0,0 +1,56 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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.graph.connector.inmemory;
+
+import org.jboss.dna.graph.Graph;
+import org.jboss.dna.graph.connector.RepositorySource;
+import org.jboss.dna.graph.connector.test.WritableConnectorTest;
+
+/**
+ * @author Randall Hauch
+ */
+public class InMemoryConnectorWritingTest extends WritableConnectorTest {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.connector.test.AbstractConnectorTest#setUpSource()
+ */
+ @Override
+ protected RepositorySource setUpSource() {
+ InMemoryRepositorySource source = new InMemoryRepositorySource();
+ source.setName("Test Repository");
+ return source;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.connector.test.AbstractConnectorTest#initializeContent(org.jboss.dna.graph.Graph)
+ */
+ @Override
+ protected void initializeContent( Graph graph ) {
+ }
+
+}
Added:
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositoryTest.java
===================================================================
---
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositoryTest.java
(rev 0)
+++
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositoryTest.java 2009-01-16
02:37:49 UTC (rev 710)
@@ -0,0 +1,365 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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.graph.connector.inmemory;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNull.notNullValue;
+import static org.hamcrest.core.IsNull.nullValue;
+import static org.hamcrest.core.IsSame.sameInstance;
+import static org.junit.Assert.assertThat;
+import static org.junit.matchers.JUnitMatchers.hasItems;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.stub;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.UUID;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.NameFactory;
+import org.jboss.dna.graph.property.PathFactory;
+import org.jboss.dna.graph.property.Property;
+import org.jboss.dna.graph.property.PropertyFactory;
+import org.jboss.dna.graph.property.ValueFactories;
+import org.jboss.dna.graph.property.ValueFactory;
+import org.jboss.dna.graph.property.basic.BasicNamespaceRegistry;
+import org.jboss.dna.graph.property.basic.BasicPropertyFactory;
+import org.jboss.dna.graph.property.basic.StandardValueFactories;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.MockitoAnnotations;
+import org.mockito.MockitoAnnotations.Mock;
+
+/**
+ * @author Randall Hauch
+ */
+public class InMemoryRepositoryTest {
+
+ private InMemoryRepository repository;
+ private String name;
+ private UUID rootUuid;
+ private ValueFactories valueFactories;
+ private PathFactory pathFactory;
+ private NameFactory nameFactory;
+ private PropertyFactory propertyFactory;
+ @Mock
+ private ExecutionContext context;
+
+ @Before
+ public void beforeEach() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ valueFactories = new StandardValueFactories(new BasicNamespaceRegistry());
+ pathFactory = valueFactories.getPathFactory();
+ nameFactory = valueFactories.getNameFactory();
+ propertyFactory = new BasicPropertyFactory(valueFactories);
+ name = "Test repository";
+ rootUuid = UUID.randomUUID();
+ repository = new InMemoryRepository(name, rootUuid);
+ stub(context.getValueFactories()).toReturn(valueFactories);
+ stub(context.getPropertyFactory()).toReturn(propertyFactory);
+ }
+
+ @Test( expected = IllegalArgumentException.class )
+ public void shouldNotAllowNullNameInConstructor() {
+ new InMemoryRepository(null, rootUuid);
+ }
+
+ @Test( expected = IllegalArgumentException.class )
+ public void shouldNotAllowBlankNameInConstructor() {
+ new InMemoryRepository(" \t ", rootUuid);
+ }
+
+ @Test
+ public void shouldHaveLock() {
+ assertThat(repository.getLock(), is(notNullValue()));
+ }
+
+ @Test
+ public void shouldHaveRootNodeAfterInstantiating() {
+ assertThat(repository.getRoot(), is(notNullValue()));
+ }
+
+ @Test
+ public void shouldHaveNameAfterInstantiating() {
+ assertThat(repository.getName(), is(name));
+ }
+
+ @Test
+ public void shouldHaveRootNodeWithRootUuid() {
+ assertThat(repository.getRoot().getUuid(), is(rootUuid));
+ }
+
+ @Test
+ public void shouldGenerateUuids() {
+ Set<UUID> uuids = new HashSet<UUID>();
+ for (int i = 0; i != 100; ++i) {
+ assertThat(uuids.add(repository.generateUuid()), is(true));
+ }
+ }
+
+ @Test( expected = AssertionError.class )
+ public void shouldNotAllowRootToBeRemoved() {
+ repository.removeNode(context, repository.getRoot());
+ }
+
+ @Test( expected = AssertionError.class )
+ public void shouldNotAllowRootToBeMoved() {
+ InMemoryNode node = mock(InMemoryNode.class);
+ repository.moveNode(context, repository.getRoot(), node);
+ }
+
+ @Test( expected = AssertionError.class )
+ public void shouldNotAllowNodeToBeMovedUsingNullEnvironment() {
+ InMemoryNode node = mock(InMemoryNode.class);
+ InMemoryNode newParent = mock(InMemoryNode.class);
+ repository.moveNode(null, node, newParent);
+ }
+
+ @Test( expected = AssertionError.class )
+ public void shouldNotAllowNullNodeToBeMoved() {
+ InMemoryNode newParent = mock(InMemoryNode.class);
+ repository.moveNode(context, null, newParent);
+ }
+
+ @Test( expected = AssertionError.class )
+ public void shouldNotAllowNodeToBeRemovedUsingNullEnvironment() {
+ InMemoryNode node = mock(InMemoryNode.class);
+ repository.removeNode(null, node);
+ }
+
+ @Test( expected = AssertionError.class )
+ public void shouldNotAllowNullNodeToBeRemoved() {
+ repository.removeNode(context, null);
+ }
+
+ @Test
+ public void shouldCreateNodesByPath() {
+ Name name_a = nameFactory.create("a");
+ InMemoryNode node_a = repository.createNode(context, repository.getRoot(),
name_a, null);
+ assertThat(node_a, is(notNullValue()));
+ assertThat(node_a.getParent(), is(repository.getRoot()));
+ assertThat(node_a.getName().getName(), is(name_a));
+ assertThat(node_a.getName().hasIndex(), is(false));
+
+ Name name_b = nameFactory.create("b");
+ InMemoryNode node_b = repository.createNode(context, node_a, name_b, null);
+ assertThat(node_b, is(notNullValue()));
+ assertThat(node_b.getParent(), is(node_a));
+ assertThat(node_b.getName().getName(), is(name_b));
+ assertThat(node_b.getName().hasIndex(), is(false));
+
+ Name name_c = nameFactory.create("c");
+ InMemoryNode node_c = repository.createNode(context, node_b, name_c, null);
+ assertThat(node_c, is(notNullValue()));
+ assertThat(node_c.getParent(), is(node_b));
+ assertThat(node_c.getName().getName(), is(name_c));
+ assertThat(node_c.getName().hasIndex(), is(false));
+
+ assertThat(repository.getNodesByUuid().size(), is(4));
+ assertThat(repository.getNode(pathFactory.create("/")),
is(sameInstance(repository.getRoot())));
+ assertThat(repository.getNode(pathFactory.create("/a")),
is(sameInstance(node_a)));
+ assertThat(repository.getNode(pathFactory.create("/a/b")),
is(sameInstance(node_b)));
+ assertThat(repository.getNode(pathFactory.create("/a/b/c")),
is(sameInstance(node_c)));
+ }
+
+ @Test
+ public void shouldNotFindNodesThatDoNotExist() {
+ InMemoryNode node_a = repository.createNode(context, repository.getRoot(),
nameFactory.create("a"), null);
+ InMemoryNode node_b = repository.createNode(context, node_a,
nameFactory.create("b"), null);
+ /*Node node_c =*/repository.createNode(context, node_b,
nameFactory.create("c"), null);
+
+ assertThat(repository.getNodesByUuid().size(), is(4));
+ assertThat(repository.getNode(pathFactory.create("/a")), is(node_a));
+ assertThat(repository.getNode(pathFactory.create("/a/b")),
is(node_b));
+ assertThat(repository.getNode(pathFactory.create("/a[1]")),
is(node_a));
+ assertThat(repository.getNode(pathFactory.create("/a/b[1]")),
is(node_b));
+ assertThat(repository.getNode(pathFactory.create("/a[1]/b[1]")),
is(node_b));
+ assertThat(repository.getNode(pathFactory.create("/a[2]")),
is(nullValue()));
+ assertThat(repository.getNode(pathFactory.create("/b[2]")),
is(nullValue()));
+ assertThat(repository.getNode(pathFactory.create("/d")),
is(nullValue()));
+ }
+
+ @Test
+ public void shouldCorrectlyManageIndexesOfSiblingsWithSameNames() {
+ Name name_a1 = nameFactory.create("a");
+ InMemoryNode node_a1 = repository.createNode(context, repository.getRoot(),
name_a1, null);
+ assertThat(node_a1, is(notNullValue()));
+ assertThat(node_a1.getParent(), is(repository.getRoot()));
+ assertThat(node_a1.getName().getName(), is(name_a1));
+ assertThat(node_a1.getName().hasIndex(), is(false));
+
+ Name name_a2 = nameFactory.create("a");
+ InMemoryNode node_a2 = repository.createNode(context, repository.getRoot(),
name_a2, null);
+ assertThat(node_a2, is(notNullValue()));
+ assertThat(node_a2.getParent(), is(repository.getRoot()));
+ assertThat(node_a2.getName().getName(), is(name_a2));
+ assertThat(node_a2.getName().hasIndex(), is(true));
+ assertThat(node_a2.getName().getIndex(), is(2));
+
+ // node 1 should now have an index ...
+ assertThat(node_a1.getName().getIndex(), is(1));
+
+ // Add another node without the same name ...
+ Name name_b = nameFactory.create("b");
+ InMemoryNode node_b = repository.createNode(context, repository.getRoot(),
name_b, null);
+ assertThat(node_b, is(notNullValue()));
+ assertThat(node_b.getParent(), is(repository.getRoot()));
+ assertThat(node_b.getName().getName(), is(name_b));
+ assertThat(node_b.getName().hasIndex(), is(false));
+
+ // Add a third node with the same name ...
+ Name name_a3 = nameFactory.create("a");
+ InMemoryNode node_a3 = repository.createNode(context, repository.getRoot(),
name_a3, null);
+ assertThat(node_a3, is(notNullValue()));
+ assertThat(node_a3.getParent(), is(repository.getRoot()));
+ assertThat(node_a3.getName().getName(), is(name_a3));
+ assertThat(node_a3.getName().hasIndex(), is(true));
+ assertThat(node_a3.getName().getIndex(), is(3));
+
+ // Check the number of children ...
+ assertThat(repository.getRoot().getChildren().size(), is(4));
+ assertThat(repository.getRoot().getChildren(), hasItems(node_a1, node_a2, node_b,
node_a3));
+ assertThat(repository.getNodesByUuid().size(), is(5));
+ assertThat(repository.getNode(pathFactory.create("/a[1]")),
is(sameInstance(node_a1)));
+ assertThat(repository.getNode(pathFactory.create("/a[2]")),
is(sameInstance(node_a2)));
+ assertThat(repository.getNode(pathFactory.create("/a[3]")),
is(sameInstance(node_a3)));
+ assertThat(repository.getNode(pathFactory.create("/b")),
is(sameInstance(node_b)));
+
+ // Removing a node with the same name will reduce the index ...
+ repository.removeNode(context, node_a2);
+ assertThat(repository.getRoot().getChildren().size(), is(3));
+ assertThat(repository.getRoot().getChildren(), hasItems(node_a1, node_b,
node_a3));
+ assertThat(node_a1.getName().getIndex(), is(1));
+ assertThat(node_b.getName().hasIndex(), is(false));
+ assertThat(node_a3.getName().getIndex(), is(2));
+
+ // Removing a node with the same name will reduce the index ...
+ repository.removeNode(context, node_a1);
+ assertThat(repository.getRoot().getChildren().size(), is(2));
+ assertThat(repository.getRoot().getChildren(), hasItems(node_b, node_a3));
+ assertThat(node_b.getName().hasIndex(), is(false));
+ assertThat(node_a3.getName().hasIndex(), is(false));
+ assertThat(repository.getNodesByUuid().size(), is(3));
+ }
+
+ @Test
+ public void shouldMoveNodes() {
+ InMemoryNode root = repository.getRoot();
+ InMemoryNode node_a = repository.createNode(context, root,
nameFactory.create("a"), null);
+ InMemoryNode node_b = repository.createNode(context, node_a,
nameFactory.create("b"), null);
+ InMemoryNode node_c = repository.createNode(context, node_b,
nameFactory.create("c"), null);
+ InMemoryNode node_d = repository.createNode(context, root,
nameFactory.create("d"), null);
+ InMemoryNode node_e = repository.createNode(context, node_d,
nameFactory.create("e"), null);
+ InMemoryNode node_b2 = repository.createNode(context, node_d,
nameFactory.create("b"), null);
+
+ assertThat(repository.getNodesByUuid().size(), is(7));
+ assertThat(repository.getNode(pathFactory.create("/")),
is(sameInstance(repository.getRoot())));
+ assertThat(repository.getNode(pathFactory.create("/a")),
is(sameInstance(node_a)));
+ assertThat(repository.getNode(pathFactory.create("/a/b")),
is(sameInstance(node_b)));
+ assertThat(repository.getNode(pathFactory.create("/a/b/c")),
is(sameInstance(node_c)));
+ assertThat(repository.getNode(pathFactory.create("/d")),
is(sameInstance(node_d)));
+ assertThat(repository.getNode(pathFactory.create("/d/e")),
is(sameInstance(node_e)));
+ assertThat(repository.getNode(pathFactory.create("/d/b")),
is(sameInstance(node_b2)));
+
+ repository.moveNode(context, node_b, node_d);
+
+ assertThat(repository.getNode(pathFactory.create("/")),
is(sameInstance(repository.getRoot())));
+ assertThat(repository.getNode(pathFactory.create("/a")),
is(sameInstance(node_a)));
+ assertThat(repository.getNode(pathFactory.create("/d")),
is(sameInstance(node_d)));
+ assertThat(repository.getNode(pathFactory.create("/d/e")),
is(sameInstance(node_e)));
+ assertThat(repository.getNode(pathFactory.create("/d/b[1]")),
is(sameInstance(node_b2)));
+ assertThat(repository.getNode(pathFactory.create("/d/b[2]")),
is(sameInstance(node_b)));
+ assertThat(repository.getNode(pathFactory.create("/d/b[2]/c")),
is(sameInstance(node_c)));
+
+ repository.moveNode(context, node_b, node_e);
+
+ assertThat(repository.getNode(pathFactory.create("/")),
is(sameInstance(repository.getRoot())));
+ assertThat(repository.getNode(pathFactory.create("/a")),
is(sameInstance(node_a)));
+ assertThat(repository.getNode(pathFactory.create("/d")),
is(sameInstance(node_d)));
+ assertThat(repository.getNode(pathFactory.create("/d/e")),
is(sameInstance(node_e)));
+ assertThat(repository.getNode(pathFactory.create("/d/e/b")),
is(sameInstance(node_b)));
+ assertThat(repository.getNode(pathFactory.create("/d/e/b/c")),
is(sameInstance(node_c)));
+ assertThat(repository.getNode(pathFactory.create("/d/b")),
is(sameInstance(node_b2)));
+ }
+
+ @Test
+ public void shouldCopyNodes() {
+ InMemoryNode root = repository.getRoot();
+ InMemoryNode node_a = repository.createNode(context, root,
nameFactory.create("a"), null);
+ InMemoryNode node_b = repository.createNode(context, node_a,
nameFactory.create("b"), null);
+ InMemoryNode node_c = repository.createNode(context, node_b,
nameFactory.create("c"), null);
+ InMemoryNode node_d = repository.createNode(context, root,
nameFactory.create("d"), null);
+ InMemoryNode node_e = repository.createNode(context, node_d,
nameFactory.create("e"), null);
+ InMemoryNode node_b2 = repository.createNode(context, node_d,
nameFactory.create("b"), null);
+
+ ValueFactory<String> stringFactory = valueFactories.getStringFactory();
+ Name propertyName = nameFactory.create("something");
+ Property property = propertyFactory.create(propertyName,
stringFactory.create("Worth the wait"));
+ node_b.getProperties().put(propertyName, property);
+
+ assertThat(repository.getNodesByUuid().size(), is(7));
+ assertThat(repository.getNode(pathFactory.create("/")),
is(sameInstance(repository.getRoot())));
+ assertThat(repository.getNode(pathFactory.create("/a")),
is(sameInstance(node_a)));
+ assertThat(repository.getNode(pathFactory.create("/a/b")),
is(sameInstance(node_b)));
+ assertThat(repository.getNode(pathFactory.create("/a/b/c")),
is(sameInstance(node_c)));
+ assertThat(repository.getNode(pathFactory.create("/d")),
is(sameInstance(node_d)));
+ assertThat(repository.getNode(pathFactory.create("/d/e")),
is(sameInstance(node_e)));
+ assertThat(repository.getNode(pathFactory.create("/d/b")),
is(sameInstance(node_b2)));
+
+
assertThat(repository.getNode(pathFactory.create("/a/b")).getProperties().get(propertyName),
is(property));
+
+ repository.copyNode(context, node_b, node_d, true, new HashMap<UUID,
UUID>());
+
+ assertThat(repository.getNodesByUuid().size(), is(9));
+ assertThat(repository.getNode(pathFactory.create("/")),
is(sameInstance(repository.getRoot())));
+ assertThat(repository.getNode(pathFactory.create("/a")),
is(sameInstance(node_a)));
+ assertThat(repository.getNode(pathFactory.create("/a/b")),
is(sameInstance(node_b)));
+ assertThat(repository.getNode(pathFactory.create("/a/b/c")),
is(sameInstance(node_c)));
+ assertThat(repository.getNode(pathFactory.create("/d")),
is(sameInstance(node_d)));
+ assertThat(repository.getNode(pathFactory.create("/d/e")),
is(sameInstance(node_e)));
+ assertThat(repository.getNode(pathFactory.create("/d/b[1]")),
is(sameInstance(node_b2)));
+ assertThat(repository.getNode(pathFactory.create("/d/b[2]")),
is(notNullValue()));
+ assertThat(repository.getNode(pathFactory.create("/d/b[2]/c")),
is(notNullValue()));
+
+
assertThat(repository.getNode(pathFactory.create("/a/b")).getProperties().get(propertyName),
is(property));
+
assertThat(repository.getNode(pathFactory.create("/d/b[2]")).getProperties().get(propertyName),
is(property));
+ }
+
+ @Test
+ public void shouldCreateRepositoryStructure() {
+ repository.createNode(context, "/a").setProperty(context,
"name", "value").setProperty(context,
+
"desc",
+
"Some description");
+ repository.createNode(context, "/a/b").setProperty(context,
"name", "value2").setProperty(context,
+
"desc",
+
"Some description 2");
+ assertThat(repository.getNode(context, "/a").getProperty(context,
"name").getValuesAsArray(), is(new Object[] {"value"}));
+ assertThat(repository.getNode(context, "/a").getProperty(context,
"desc").getValuesAsArray(),
+ is(new Object[] {"Some description"}));
+ assertThat(repository.getNode(context, "/a/b").getProperty(context,
"name").getValuesAsArray(),
+ is(new Object[] {"value2"}));
+ assertThat(repository.getNode(context, "/a/b").getProperty(context,
"desc").getValuesAsArray(),
+ is(new Object[] {"Some description 2"}));
+ }
+}
Modified: trunk/docs/examples/gettingstarted/pom.xml
===================================================================
--- trunk/docs/examples/gettingstarted/pom.xml 2009-01-15 21:15:57 UTC (rev 709)
+++ trunk/docs/examples/gettingstarted/pom.xml 2009-01-16 02:37:49 UTC (rev 710)
@@ -52,11 +52,6 @@
</dependency>
<dependency>
<groupId>org.jboss.dna</groupId>
- <artifactId>dna-connector-inmemory</artifactId>
- <version>${pom.version}</version>
- </dependency>
- <dependency>
- <groupId>org.jboss.dna</groupId>
<artifactId>dna-connector-jbosscache</artifactId>
<version>${pom.version}</version>
</dependency>
Modified: trunk/docs/examples/gettingstarted/repositories/pom.xml
===================================================================
--- trunk/docs/examples/gettingstarted/repositories/pom.xml 2009-01-15 21:15:57 UTC (rev
709)
+++ trunk/docs/examples/gettingstarted/repositories/pom.xml 2009-01-16 02:37:49 UTC (rev
710)
@@ -36,12 +36,6 @@
</dependency>
<dependency>
<groupId>org.jboss.dna</groupId>
- <artifactId>dna-connector-inmemory</artifactId>
- <version>${pom.version}</version>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>org.jboss.dna</groupId>
<artifactId>dna-connector-jbosscache</artifactId>
<version>${pom.version}</version>
<scope>runtime</scope>
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 2009-01-15
21:15:57 UTC (rev 709)
+++
trunk/docs/examples/gettingstarted/repositories/src/main/java/org/jboss/example/dna/repository/RepositoryClient.java 2009-01-16
02:37:49 UTC (rev 710)
@@ -43,11 +43,11 @@
import net.jcip.annotations.Immutable;
import org.jboss.dna.common.text.NoOpEncoder;
import org.jboss.dna.common.util.CheckArg;
-import org.jboss.dna.connector.inmemory.InMemoryRepositorySource;
import org.jboss.dna.graph.ExecutionContext;
import org.jboss.dna.graph.ExecutionContextFactory;
import org.jboss.dna.graph.Graph;
import org.jboss.dna.graph.Location;
+import org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource;
import org.jboss.dna.graph.property.Path;
import org.jboss.dna.graph.property.PathFactory;
import org.jboss.dna.graph.property.PathNotFoundException;
Modified:
trunk/docs/examples/gettingstarted/repositories/src/main/resources/configRepository.xml
===================================================================
---
trunk/docs/examples/gettingstarted/repositories/src/main/resources/configRepository.xml 2009-01-15
21:15:57 UTC (rev 709)
+++
trunk/docs/examples/gettingstarted/repositories/src/main/resources/configRepository.xml 2009-01-16
02:37:49 UTC (rev 710)
@@ -27,15 +27,15 @@
<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>
- <dna:source jcr:name="SourceA" dna:name="Cars"
dna:classname="org.jboss.dna.connector.inmemory.InMemoryRepositorySource"
dna:retryLimit="3" />
- <dna:source jcr:name="SourceB" dna:name="Aircraft"
dna:classname="org.jboss.dna.connector.inmemory.InMemoryRepositorySource" />
+ <dna:source jcr:name="SourceA" dna:name="Cars"
dna:classname="org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource"
dna:retryLimit="3" />
+ <dna:source jcr:name="SourceB" dna:name="Aircraft"
dna:classname="org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource"
/>
<dna:source jcr:name="SourceC" dna:name="Vehicles"
dna:classname="org.jboss.dna.connector.federation.FederatedRepositorySource"
dna:repositoryName="Configuration Repository"
dna:configurationSourceName="Configuration"
dna:configurationSourcePath="/dna:system/dna:federatedRepositories/Vehicles"
dna:repositoryConnectionFactoryJndiName="/dna/connectionFactory"
dna:executionContextFactoryJndiName="/dna/contextFactory"/>
- <dna:source jcr:name="SourceD" dna:name="Cache"
dna:classname="org.jboss.dna.connector.inmemory.InMemoryRepositorySource" />
+ <dna:source jcr:name="SourceD" dna:name="Cache"
dna:classname="org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource"
/>
</dna:sources>
<dna:federatedRepositories>
<!-- This section defines from where the content of the 'Vehicles'
federated repository is obtained.
Modified:
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 2009-01-15
21:15:57 UTC (rev 709)
+++
trunk/docs/examples/gettingstarted/repositories/src/test/java/org/jboss/example/dna/repository/RepositoryClientTest.java 2009-01-16
02:37:49 UTC (rev 710)
@@ -125,7 +125,7 @@
assertThat(children.size(), is(0));
assertThat(properties.containsKey("jcr:primaryType"), is(true));
assertThat(properties.containsKey("dna:uuid"), is(true));
- assertProperty("dna:classname",
"org.jboss.dna.connector.inmemory.InMemoryRepositorySource");
+ assertProperty("dna:classname",
org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource.class.getName());
assertProperty("dna:name", "Cars");
assertProperty("dna:retryLimit", "3");
assertThat(properties.size(), is(5));
Modified: trunk/docs/gettingstarted/src/main/docbook/en-US/content/understanding_dna.xml
===================================================================
---
trunk/docs/gettingstarted/src/main/docbook/en-US/content/understanding_dna.xml 2009-01-15
21:15:57 UTC (rev 709)
+++
trunk/docs/gettingstarted/src/main/docbook/en-US/content/understanding_dna.xml 2009-01-16
02:37:49 UTC (rev 710)
@@ -360,12 +360,6 @@
<itemizedlist>
<listitem>
<para>
- <emphasis role="strong">In-Memory Connector</emphasis>
- - Creates a transient, in-memory repository.
- </para>
- </listitem>
- <listitem>
- <para>
<emphasis role="strong">JBoss Cache
Connector</emphasis>
- Uses a JBoss Cache instance as a repository. JBoss Cache is a powerful
cache capable of persisting the information
and being clustered for concurrent use by multiple processes.
Modified: trunk/docs/reference/src/main/docbook/en-US/content/introduction.xml
===================================================================
--- trunk/docs/reference/src/main/docbook/en-US/content/introduction.xml 2009-01-15
21:15:57 UTC (rev 709)
+++ trunk/docs/reference/src/main/docbook/en-US/content/introduction.xml 2009-01-16
02:37:49 UTC (rev 710)
@@ -331,13 +331,6 @@
</listitem>
<listitem>
<para>
- <emphasis
role="strong">dna-connector-inmemory</emphasis>
- is a simple DNA repository connector that manages content within memory. This
can be used as a simple cache or as a
- transient repository.
- </para>
- </listitem>
- <listitem>
- <para>
<emphasis
role="strong">dna-connector-jbosscache</emphasis>
is a DNA repository connector that manages content within a
<ulink
url="http://www.jboss.org/jbosscache/">JBoss
Cache</ulink>
Modified: trunk/docs/reference/src/main/docbook/en-US/content/repositories.xml
===================================================================
--- trunk/docs/reference/src/main/docbook/en-US/content/repositories.xml 2009-01-15
21:15:57 UTC (rev 709)
+++ trunk/docs/reference/src/main/docbook/en-US/content/repositories.xml 2009-01-16
02:37:49 UTC (rev 710)
@@ -587,9 +587,9 @@
and would like to help create it, please <link
linkend="preface">join the community</link>.
</para>
<para>In lieu of a Maven archetype, you may find it easier to start with a
small existing connector project.
- The <emphasis role="strong">dna-connector-inmemory</emphasis>
project is small, but it may be tough to separate
+ The <emphasis
role="strong">dna-connector-filesystem</emphasis> project is small, but
it may be tough to separate
the stuff that every connector needs from the extra code and data structures that
manage the content.
- See the subversion repository: <ulink
url="&Subversion;trunk/extensions/dna-connector-inmemory/">&Subversion;trunk/extensions/dna-connector-inmemory/</ulink>
+ See the subversion repository: <ulink
url="&Subversion;trunk/extensions/dna-connector-filesystem/">&Subversion;trunk/extensions/dna-connector-filesystem/</ulink>
</para>
</note>
<para>
Modified: trunk/docs/reference/src/main/docbook/en-US/custom.dtd
===================================================================
--- trunk/docs/reference/src/main/docbook/en-US/custom.dtd 2009-01-15 21:15:57 UTC (rev
709)
+++ trunk/docs/reference/src/main/docbook/en-US/custom.dtd 2009-01-16 02:37:49 UTC (rev
710)
@@ -75,6 +75,8 @@
<!ENTITY RepositoryConnectionFactory "<ulink
url='&API;graph/connector/RepositoryConnectionFactory.html'><interface>RepositoryConnectionFactory</interface></ulink>">
<!ENTITY RepositorySourceListener "<ulink
url='&API;graph/connector/RepositorySourceListener.html'><interface>RepositorySourceListener</interface></ulink>">
<!ENTITY RepositorySourceCapabilities "<ulink
url='&API;graph/connector/RepositorySourceCapabilities.html'><classname>RepositorySourceCapabilities</classname></ulink>">
+<!ENTITY InMemoryRepository "<ulink
url='&API;graph.connector/inmemory/InMemoryRepository.html'><classname>InMemoryRepository</classname></ulink>">
+<!ENTITY InMemoryRepositorySource "<ulink
url='&API;graph.connector/inmemory/InMemoryRepositorySource.html'><classname>InMemoryRepositorySource</classname></ulink>">
<!ENTITY CachePolicy "<ulink
url='&API;graph/cache/CachePolicy.html'><interface>CachePolicy</interface></ulink>">
<!ENTITY Request "<ulink
url='&API;graph/request/Requests.html'><classname>Request</classname></ulink>">
<!ENTITY CompositeRequest "<ulink
url='&API;graph/request/CompositeRequest.html'><classname>CompositeRequest</classname></ulink>">
@@ -110,8 +112,6 @@
<!-- Types in extensions/ -->
-<!ENTITY InMemoryRepository "<ulink
url='&API;connector/inmemory/InMemoryRepository.html'><classname>InMemoryRepository</classname></ulink>">
-<!ENTITY InMemoryRepositorySource "<ulink
url='&API;connector/inmemory/InMemoryRepositorySource.html'><classname>InMemoryRepositorySource</classname></ulink>">
<!ENTITY JBossCacheRepository "<ulink
url='&API;connector/jbosscache/JBossCacheRepository.html'><classname>JBossCacheRepository</classname></ulink>">
<!ENTITY JBossCacheSource "<ulink
url='&API;connector/jbosscache/JBossCacheSource.html'><classname>JBossCacheSource</classname></ulink>">
<!ENTITY FederatedRepositorySource "<ulink
url='&API;connector/federation/FederatedRepositorySource.html'><classname>FederatedRepositorySource</classname></ulink>">
Modified: trunk/extensions/dna-connector-federation/src/test/resources/log4j.properties
===================================================================
---
trunk/extensions/dna-connector-federation/src/test/resources/log4j.properties 2009-01-15
21:15:57 UTC (rev 709)
+++
trunk/extensions/dna-connector-federation/src/test/resources/log4j.properties 2009-01-16
02:37:49 UTC (rev 710)
@@ -9,7 +9,7 @@
# Set up the default logging to be INFO level, then override specific units
log4j.logger.org.jboss.dna=INFO
-log4j.logger.org.jboss.dna.connector.federation.executor=TRACE
+log4j.logger.org.jboss.dna.connector.federation.executor=INFO
# Jackrabbit logging
log4j.logger.org.apache.jackrabbit=WARN, stdout
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2009-01-15 21:15:57 UTC (rev 709)
+++ trunk/pom.xml 2009-01-16 02:37:49 UTC (rev 710)
@@ -126,7 +126,6 @@
<module>extensions/dna-sequencer-xml</module>
<module>extensions/dna-sequencer-zip</module>
<module>extensions/dna-connector-federation</module>
- <module>extensions/dna-connector-inmemory</module>
<module>extensions/dna-connector-jbosscache</module>
<module>extensions/dna-connector-svn</module>
<module>extensions/dna-connector-store-jpa</module>
@@ -401,11 +400,6 @@
</dependency>
<dependency>
<groupId>org.jboss.dna</groupId>
- <artifactId>dna-connector-inmemory</artifactId>
- <version>${pom.version}</version>
- </dependency>
- <dependency>
- <groupId>org.jboss.dna</groupId>
<artifactId>dna-mimetype-detector-aperture</artifactId>
<version>${pom.version}</version>
</dependency>