[dna-commits] DNA SVN: r219 - in branches/federation: connectors and 16 other directories.

dna-commits at lists.jboss.org dna-commits at lists.jboss.org
Mon Jun 2 12:45:46 EDT 2008


Author: rhauch
Date: 2008-06-02 12:45:45 -0400 (Mon, 02 Jun 2008)
New Revision: 219

Added:
   branches/federation/connectors/
   branches/federation/connectors/dna-connector-jbosscache/
   branches/federation/connectors/dna-connector-jbosscache/.classpath
   branches/federation/connectors/dna-connector-jbosscache/.project
   branches/federation/connectors/dna-connector-jbosscache/pom.xml
   branches/federation/connectors/dna-connector-jbosscache/src/
   branches/federation/connectors/dna-connector-jbosscache/src/main/
   branches/federation/connectors/dna-connector-jbosscache/src/main/java/
   branches/federation/connectors/dna-connector-jbosscache/src/main/java/org/
   branches/federation/connectors/dna-connector-jbosscache/src/main/java/org/jboss/
   branches/federation/connectors/dna-connector-jbosscache/src/main/java/org/jboss/dna/
   branches/federation/connectors/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/
   branches/federation/connectors/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/
   branches/federation/connectors/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheConnection.java
   branches/federation/connectors/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheConnectorI18n.java
   branches/federation/connectors/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheSource.java
   branches/federation/connectors/dna-connector-jbosscache/src/main/resources/
   branches/federation/connectors/dna-connector-jbosscache/src/main/resources/org/
   branches/federation/connectors/dna-connector-jbosscache/src/main/resources/org/jboss/
   branches/federation/connectors/dna-connector-jbosscache/src/main/resources/org/jboss/dna/
   branches/federation/connectors/dna-connector-jbosscache/src/main/resources/org/jboss/dna/connector/
   branches/federation/connectors/dna-connector-jbosscache/src/main/resources/org/jboss/dna/connector/jbosscache/
   branches/federation/connectors/dna-connector-jbosscache/src/main/resources/org/jboss/dna/connector/jbosscache/JBossCacheConnectorI18n.properties
   branches/federation/connectors/dna-connector-jbosscache/src/test/
   branches/federation/connectors/dna-connector-jbosscache/src/test/java/
   branches/federation/connectors/dna-connector-jbosscache/src/test/resources/
Modified:
   branches/federation/pom.xml
Log:
Added JBoss Cache connector project


Property changes on: branches/federation/connectors/dna-connector-jbosscache
___________________________________________________________________
Name: svn:ignore
   + target


Added: branches/federation/connectors/dna-connector-jbosscache/.classpath
===================================================================
--- branches/federation/connectors/dna-connector-jbosscache/.classpath	                        (rev 0)
+++ branches/federation/connectors/dna-connector-jbosscache/.classpath	2008-06-02 16:45:45 UTC (rev 219)
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src/main/java"/>
+	<classpathentry kind="src" path="src/main/resources"/>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/resources"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>

Added: branches/federation/connectors/dna-connector-jbosscache/.project
===================================================================
--- branches/federation/connectors/dna-connector-jbosscache/.project	                        (rev 0)
+++ branches/federation/connectors/dna-connector-jbosscache/.project	2008-06-02 16:45:45 UTC (rev 219)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>dna-connector-jbosscache</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.maven.ide.eclipse.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.maven.ide.eclipse.maven2Nature</nature>
+	</natures>
+</projectDescription>

Added: branches/federation/connectors/dna-connector-jbosscache/pom.xml
===================================================================
--- branches/federation/connectors/dna-connector-jbosscache/pom.xml	                        (rev 0)
+++ branches/federation/connectors/dna-connector-jbosscache/pom.xml	2008-06-02 16:45:45 UTC (rev 219)
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.jboss.dna</groupId>
+    <artifactId>dna</artifactId>
+    <version>0.2-SNAPSHOT</version>
+    <relativePath>../..</relativePath>
+  </parent>
+  <!-- The groupId and version values are inherited from parent -->
+  <artifactId>dna-connector-jbosscache</artifactId>
+  <packaging>jar</packaging>
+  <name>JBoss DNA Connector to JBoss Cache</name>
+  <description>JBoss DNA Connector that accesses an in-process JBoss Cache instance.</description>
+  <url>http://labs.jboss.org/dna</url>
+  
+  <properties>
+    <dna-version>0.2-SNAPSHOT</dna-version>
+  </properties>
+  <!--
+  Define the dependencies.  Note that all version and scopes default to those 
+  defined in the dependencyManagement section of the parent pom.
+  -->
+  <dependencies>
+    <!-- 
+    Common
+    -->
+    <dependency>
+      <groupId>org.jboss.dna</groupId>
+      <artifactId>dna-common</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.jboss.dna</groupId>
+      <artifactId>dna-spi</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.jboss.dna</groupId>
+      <artifactId>dna-common</artifactId>
+      <version>${dna-version}</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.jboss.dna</groupId>
+      <artifactId>dna-spi</artifactId>
+      <version>${dna-version}</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <!-- 
+    JBoss Cache
+    -->
+    <dependency>
+      <groupId>org.jboss.cache</groupId>
+      <artifactId>jbosscache-core</artifactId>
+      <version>2.2.0.CR1</version>
+    </dependency>
+    <!-- 
+    Testing (note the scope)
+    -->
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-library</artifactId>
+    </dependency>
+    <!-- 
+    Logging (require SLF4J API for compiling, but use Log4J and its SLF4J binding for testing) 
+    -->
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-log4j12</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>log4j</groupId>
+      <artifactId>log4j</artifactId>
+    </dependency>
+    <!-- 
+    Java Concurrency in Practice annotations
+    -->
+  <dependency>
+    <groupId>net.jcip</groupId>
+    <artifactId>jcip-annotations</artifactId>
+  </dependency>
+  </dependencies>
+  <reporting>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-report-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </reporting>
+</project>
\ No newline at end of file

Added: branches/federation/connectors/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheConnection.java
===================================================================
--- branches/federation/connectors/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheConnection.java	                        (rev 0)
+++ branches/federation/connectors/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheConnection.java	2008-06-02 16:45:45 UTC (rev 219)
@@ -0,0 +1,323 @@
+/*
+ * 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.connector.jbosscache;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+import javax.transaction.xa.XAResource;
+import org.jboss.cache.Cache;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.Node;
+import org.jboss.dna.spi.graph.Name;
+import org.jboss.dna.spi.graph.Path;
+import org.jboss.dna.spi.graph.Property;
+import org.jboss.dna.spi.graph.Path.Segment;
+import org.jboss.dna.spi.graph.commands.ActsOnPath;
+import org.jboss.dna.spi.graph.commands.CopyBranchCommand;
+import org.jboss.dna.spi.graph.commands.CopyNodeCommand;
+import org.jboss.dna.spi.graph.commands.CreateNodeCommand;
+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.SetPropertiesCommand;
+import org.jboss.dna.spi.graph.connection.ExecutionEnvironment;
+import org.jboss.dna.spi.graph.connection.RepositoryConnection;
+import org.jboss.dna.spi.graph.connection.RepositorySourceException;
+import org.jboss.dna.spi.graph.connection.RepositorySourceListener;
+
+/**
+ * @author Randall Hauch
+ */
+public class JBossCacheConnection implements RepositoryConnection {
+
+    protected static final RepositorySourceListener NO_OP_LISTENER = new RepositorySourceListener() {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void notify( String sourceName, Object... events ) {
+            // do nothing
+        }
+    };
+
+    private boolean initializedUuidPropertyName = false;
+    private Name uuidPropertyName;
+    private final JBossCacheSource source;
+    private final Cache<Name, Object> cache;
+    private RepositorySourceListener listener = NO_OP_LISTENER;
+
+    /**
+     * 
+     */
+    /* package */JBossCacheConnection( JBossCacheSource source, Cache<Name, Object> cache ) {
+        assert source != null;
+        assert cache != null;
+        this.source = source;
+        this.cache = cache;
+    }
+
+    /**
+     * @return uuidPropertyName
+     */
+    public Name getUuidPropertyName() {
+        return this.uuidPropertyName;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getSourceName() {
+        return source.getName();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public XAResource getXAResource() {
+        return null;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean ping( long time, TimeUnit unit ) {
+        this.cache.getRoot();
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setListener( RepositorySourceListener listener ) {
+        this.listener = listener != null ? listener : NO_OP_LISTENER;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void close() {
+        // do nothing
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute( ExecutionEnvironment env, GraphCommand... commands ) throws RepositorySourceException {
+        // Set up the workspace ...
+
+        // Now execute the commands ...
+        for (GraphCommand command : commands) {
+            // This node reference is available for any command that extends ActsOnPath ...
+            Node<Name, Object> node = null;
+
+            // First, process the commands that create a new node ...
+            if (command instanceof CreateNodeCommand) {
+                CreateNodeCommand theCommand = (CreateNodeCommand)command;
+                Path path = theCommand.getPath();
+                Path parent = path.getAncestor();
+                Fqn<Segment> childFqn = getFullyQualifiedName(path.getLastSegment());
+                // Look up the parent node, which must exist ...
+                Node<Name, Object> parentNode = getNode(env, parent);
+                node = parentNode.addChild(childFqn);
+                // Add the UUID property (if required), which may be overwritten by a supplied property ...
+                Name uuidPropertyName = getUuidProperty(env);
+                if (uuidPropertyName != null) {
+                    node.put(uuidPropertyName, generateUuid());
+                }
+                // Now add the properties to the supplied node ...
+                for (Property property : theCommand.getProperties()) {
+                    if (property.size() == 0) continue;
+                    Name propName = property.getName();
+                    Object value = null;
+                    if (property.size() == 1) {
+                        value = property.iterator().next();
+                    } else {
+                        value = property.getValuesAsArray();
+                    }
+                    node.put(propName, value);
+                }
+                assert node != null;
+            }
+
+            // Otherwise, check whether the command is applies to a path; all the remaining commands
+            // that do so expect the node to exist ...
+            else if (command instanceof ActsOnPath) {
+                ActsOnPath theCommand = (ActsOnPath)command;
+                Path path = theCommand.getPath();
+                // Look up the node with the supplied path ...
+                node = getNode(env, path);
+                assert node != null;
+            }
+
+            if (command instanceof GetChildrenCommand) {
+                GetChildrenCommand theCommand = (GetChildrenCommand)command;
+                assert command instanceof ActsOnPath;
+                assert node != null;
+                // Get the names of the children ...
+                List<Segment> childSegments = new ArrayList<Segment>();
+                for (Node<Name, Object> child : node.getChildren()) {
+                    childSegments.add((Segment)child.getFqn().getLastElement());
+                }
+                theCommand.setChildren(childSegments);
+
+            }
+            if (command instanceof GetPropertiesCommand) {
+                GetPropertiesCommand theCommand = (GetPropertiesCommand)command;
+                assert command instanceof ActsOnPath;
+                assert node != null;
+                Map<Name, Object> dataMap = node.getData();
+                for (Map.Entry<Name, Object> data : dataMap.entrySet()) {
+                    Name propertyName = data.getKey();
+                    Object values = data.getValue();
+                    theCommand.setProperty(propertyName, values);
+                }
+            }
+            if (command instanceof SetPropertiesCommand) {
+                SetPropertiesCommand theCommand = (SetPropertiesCommand)command;
+                assert command instanceof ActsOnPath;
+                assert node != null;
+                // Now set (or remove) the properties to the supplied node ...
+                for (Property property : theCommand.getProperties()) {
+                    Name propName = property.getName();
+                    if (property.size() == 0) {
+                        node.remove(propName);
+                        continue;
+                    }
+                    Object value = null;
+                    if (property.size() == 1) {
+                        value = property.iterator().next();
+                    } else {
+                        value = property.getValuesAsArray();
+                    }
+                    node.put(propName, value);
+                }
+            }
+            if (command instanceof DeleteBranchCommand) {
+                assert command instanceof ActsOnPath;
+                assert node != null;
+                node.getParent().removeChild(node.getFqn().getLastElement());
+            }
+            if (command instanceof CopyNodeCommand) {
+                CopyNodeCommand theCommand = (CopyNodeCommand)command;
+                boolean recursive = command instanceof CopyBranchCommand;
+                // Look up the new parent, which must exist ...
+                Path newPath = theCommand.getNewPath();
+                Node<Name, Object> newParent = getNode(env, newPath.getAncestor());
+                copyNode(node, newParent, recursive, null);
+            }
+            if (command instanceof MoveBranchCommand) {
+                MoveBranchCommand theCommand = (MoveBranchCommand)command;
+                assert command instanceof ActsOnPath;
+                assert node != null;
+                boolean recursive = true;
+                Name uuidProperty = getUuidProperty(env);
+                // Look up the new parent, which must exist ...
+                Path newPath = theCommand.getNewPath();
+                Node<Name, Object> newParent = getNode(env, newPath.getAncestor());
+                copyNode(node, newParent, recursive, uuidProperty);
+                // Now delete the old node ...
+                Node<Name, Object> oldParent = node.getParent();
+                boolean removed = oldParent.removeChild(node.getFqn().getLastElement());
+                assert removed;
+            }
+        }
+    }
+
+    /**
+     * @return listener
+     */
+    protected RepositorySourceListener getListener() {
+        return this.listener;
+    }
+
+    /**
+     * Utility method to calculate (if required) and obtain the name that should be used to store the UUID values for each node.
+     * This method may be called without regard to synchronization, since it should return the same value if it happens to be
+     * called concurrently while not yet initialized.
+     * 
+     * @param env the environment
+     * @return the name, or null if the UUID should not be stored
+     */
+    protected Name getUuidProperty( ExecutionEnvironment env ) {
+        if (!initializedUuidPropertyName) {
+            this.uuidPropertyName = this.source.getUuidPropertyName(env.getValueFactories().getNameFactory());
+            initializedUuidPropertyName = true;
+        }
+        return this.uuidPropertyName;
+    }
+
+    protected Fqn<Path.Segment> getFullyQualifiedName( Path path ) {
+        return Fqn.fromList(path.getSegmentsList());
+    }
+
+    /**
+     * Get a relative fully-qualified name that consists only of the supplied segment.
+     * 
+     * @param pathSegment the segment from which the fully qualified name is to be created
+     * @return the relative fully-qualified name
+     */
+    protected Fqn<Path.Segment> getFullyQualifiedName( Path.Segment pathSegment ) {
+        return Fqn.fromElements(pathSegment);
+    }
+
+    protected Node<Name, Object> getNode( ExecutionEnvironment env, Path path ) {
+        // Look up the node with the supplied path ...
+        Fqn<Segment> fqn = getFullyQualifiedName(path);
+        Node<Name, Object> node = cache.getNode(fqn);
+        if (node == null) {
+            String nodePath = path.getString(env.getNamespaceRegistry());
+            throw new RepositorySourceException(getSourceName(), JBossCacheConnectorI18n.nodeDoesNotExist.text(nodePath));
+        }
+        return node;
+
+    }
+
+    protected UUID generateUuid() {
+        return UUID.randomUUID();
+    }
+
+    protected int copyNode( Node<Name, Object> original, Node<Name, Object> newParent, boolean recursive, Name uuidProperty ) {
+        // Get or create the new node ...
+        Segment name = (Segment)original.getFqn().getLastElement();
+        Node<Name, Object> copy = newParent.addChild(getFullyQualifiedName(name));
+        // Copy the properties ...
+        copy.clearData();
+        copy.putAll(original.getData());
+        if (uuidProperty != null) {
+            // Generate a new UUID for the new node ...
+            copy.put(uuidProperty, generateUuid());
+        }
+        int numNodesCopied = 1;
+        if (recursive) {
+            // Loop over each child and call this method ...
+            for (Node<Name, Object> child : original.getChildren()) {
+                numNodesCopied += copyNode(child, copy, true, uuidProperty);
+            }
+        }
+        return numNodesCopied;
+    }
+}

Added: branches/federation/connectors/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheConnectorI18n.java
===================================================================
--- branches/federation/connectors/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheConnectorI18n.java	                        (rev 0)
+++ branches/federation/connectors/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheConnectorI18n.java	2008-06-02 16:45:45 UTC (rev 219)
@@ -0,0 +1,55 @@
+/*
+ * 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.connector.jbosscache;
+
+import java.util.Locale;
+import java.util.Set;
+import org.jboss.dna.common.i18n.I18n;
+
+/**
+ * @author Randall Hauch
+ */
+public final class JBossCacheConnectorI18n {
+
+    public static I18n connectorName;
+    public static I18n nodeDoesNotExist;
+
+    static {
+        try {
+            I18n.initialize(JBossCacheConnectorI18n.class);
+        } catch (final Exception err) {
+            System.err.println(err);
+        }
+    }
+
+    public static Set<Locale> getLocalizationProblemLocales() {
+        return I18n.getLocalizationProblemLocales(JBossCacheConnectorI18n.class);
+    }
+
+    public static Set<String> getLocalizationProblems() {
+        return I18n.getLocalizationProblems(JBossCacheConnectorI18n.class);
+    }
+
+    public static Set<String> getLocalizationProblems( Locale locale ) {
+        return I18n.getLocalizationProblems(JBossCacheConnectorI18n.class, locale);
+    }
+}

Added: branches/federation/connectors/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheSource.java
===================================================================
--- branches/federation/connectors/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheSource.java	                        (rev 0)
+++ branches/federation/connectors/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheSource.java	2008-06-02 16:45:45 UTC (rev 219)
@@ -0,0 +1,316 @@
+/*
+ * 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.connector.jbosscache;
+
+import java.util.Collections;
+import java.util.Hashtable;
+import java.util.Set;
+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.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 net.jcip.annotations.ThreadSafe;
+import org.jboss.cache.Cache;
+import org.jboss.cache.CacheFactory;
+import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.dna.common.util.ArgCheck;
+import org.jboss.dna.spi.cache.CachePolicy;
+import org.jboss.dna.spi.graph.Name;
+import org.jboss.dna.spi.graph.NameFactory;
+import org.jboss.dna.spi.graph.connection.RepositoryConnection;
+import org.jboss.dna.spi.graph.connection.RepositorySource;
+import org.jboss.dna.spi.graph.connection.RepositorySourceException;
+
+/**
+ * @author Randall Hauch
+ */
+ at ThreadSafe
+public class JBossCacheSource implements RepositorySource, ObjectFactory {
+
+    public static final String DEFAULT_UUID_PROPERTY_NAMESPACE = "http://www.jboss.org/dna/connector/jbosscache";
+    public static final String DEFAULT_UUID_PROPERTY_NAME = "uuid";
+
+    private static final ConcurrentMap<String, JBossCacheSource> sources = new ConcurrentHashMap<String, JBossCacheSource>();
+    private static final ReadWriteLock sourcesLock = new ReentrantReadWriteLock();
+
+    /**
+     * 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 JBossCacheSource getSource( String name ) {
+        Lock lock = sourcesLock.readLock();
+        try {
+            lock.lock();
+            return sources.get(name);
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    @GuardedBy( "sourcesLock" )
+    private String name;
+    @GuardedBy( "this" )
+    private String jndiName;
+    private final AtomicInteger retryLimit = new AtomicInteger(0);
+    private UUID rootNodeUuid = UUID.randomUUID();
+    private CachePolicy defaultCachePolicy;
+    private String cacheConfigurationName;
+    private String uuidPropertyName = DEFAULT_UUID_PROPERTY_NAME;
+    private String uuidPropertyNamespaceUri = DEFAULT_UUID_PROPERTY_NAMESPACE;
+    private transient Cache<Name, Object> cache;
+
+    /**
+     * Create a repository source instance.
+     */
+    public JBossCacheSource() {
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    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();
+    }
+
+    /**
+     * @return uuidPropertyName
+     */
+    public String getUuidPropertyName() {
+        return this.uuidPropertyName;
+    }
+
+    /**
+     * @param uuidPropertyName Sets uuidPropertyName to the specified value.
+     */
+    public synchronized void setUuidPropertyName( String uuidPropertyName ) {
+        this.uuidPropertyName = uuidPropertyName != null ? uuidPropertyName.trim() : DEFAULT_UUID_PROPERTY_NAME;
+    }
+
+    /**
+     * @return uuidPropertyNamespaceUri
+     */
+    public String getUuidPropertyNamespaceUri() {
+        return this.uuidPropertyNamespaceUri;
+    }
+
+    /**
+     * @param uuidPropertyNamespaceUri Sets uuidPropertyNamespaceUri to the specified value.
+     */
+    public synchronized void setUuidPropertyNamespaceUri( String uuidPropertyNamespaceUri ) {
+        this.uuidPropertyNamespaceUri = uuidPropertyNamespaceUri != null ? uuidPropertyNamespaceUri.trim() : DEFAULT_UUID_PROPERTY_NAMESPACE;
+    }
+
+    /**
+     * 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 {
+        ArgCheck.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() {
+        Lock lock = sourcesLock.readLock();
+        try {
+            lock.lock();
+            return this.name;
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * @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();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public int getRetryLimit() {
+        return retryLimit.get();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setRetryLimit( int limit ) {
+        retryLimit.set(limit);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public synchronized RepositoryConnection getConnection() throws RepositorySourceException {
+        if (this.cache == null) {
+            CacheFactory<Name, Object> factory = new DefaultCacheFactory<Name, Object>();
+            cache = factory.createCache(cacheConfigurationName);
+        }
+        return new JBossCacheConnection(this, this.cache);
+    }
+
+    /**
+     * Utility method to obtain a consistent {@link Name} for the property that should store the UUID value on each node. This
+     * method is properly coded so that it is threadsafe.
+     * 
+     * @param factory the name factory; may not be null
+     * @return the property name, or null if UUIDs are not to be maintained
+     */
+    /* package */synchronized Name getUuidPropertyName( NameFactory factory ) {
+        if (this.uuidPropertyName.length() == 0 && this.uuidPropertyNamespaceUri.length() == 0) return null;
+        return factory.create(this.uuidPropertyNamespaceUri, this.uuidPropertyName);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Reference getReference() {
+        String className = getClass().getName();
+        String factoryClassName = className;
+        return new Reference(className, new StringRefAddr("DnaConnectorJBossCacheSource", getName()), factoryClassName, null);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object getObjectInstance( Object obj, javax.naming.Name name, Context nameCtx, Hashtable<?, ?> environment ) throws Exception {
+        if (obj instanceof Reference) {
+            Reference ref = (Reference)obj;
+            if (ref.getClassName().equals(getClass().getName())) {
+                RefAddr addr = ref.get("DnaConnectorJBossCacheSource");
+                return JBossCacheSource.getSource((String)addr.getContent());
+            }
+        }
+        return null;
+    }
+
+}

Added: branches/federation/connectors/dna-connector-jbosscache/src/main/resources/org/jboss/dna/connector/jbosscache/JBossCacheConnectorI18n.properties
===================================================================
--- branches/federation/connectors/dna-connector-jbosscache/src/main/resources/org/jboss/dna/connector/jbosscache/JBossCacheConnectorI18n.properties	                        (rev 0)
+++ branches/federation/connectors/dna-connector-jbosscache/src/main/resources/org/jboss/dna/connector/jbosscache/JBossCacheConnectorI18n.properties	2008-06-02 16:45:45 UTC (rev 219)
@@ -0,0 +1,24 @@
+#
+# 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.
+#
+
+connectorName = In-Memory Connector
+nodeDoesNotExist = Could not find an existing node at {0}
\ No newline at end of file

Modified: branches/federation/pom.xml
===================================================================
--- branches/federation/pom.xml	2008-06-02 16:34:47 UTC (rev 218)
+++ branches/federation/pom.xml	2008-06-02 16:45:45 UTC (rev 219)
@@ -61,7 +61,8 @@
 		<module>dna-maven-classloader</module>
 		<module>sequencers/dna-sequencer-images</module>
 		<module>sequencers/dna-sequencer-mp3</module>
-        <module>dna-integration-tests</module>
+		<module>connectors/dna-connector-jbosscache</module>
+    	<module>dna-integration-tests</module>
 	</modules>
 
 	<properties>




More information about the dna-commits mailing list