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
+ */
+@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>