DNA SVN: r1067 - in trunk/dna-jcr/src: test/java/org/jboss/dna/jcr and 1 other directories.
by dna-commits@lists.jboss.org
Author: bcarothers
Date: 2009-06-27 22:14:25 -0400 (Sat, 27 Jun 2009)
New Revision: 1067
Modified:
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNamespaceRegistry.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNodeTypeManager.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrRepository.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSession.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/DnaTckTest.java
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrNamespaceRegistryTest.java
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrRepositoryTest.java
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/SessionCacheTest.java
trunk/dna-jcr/src/test/resources/security/tck_roles.properties
trunk/dna-jcr/src/test/resources/security/tck_users.properties
Log:
DNA-399 Need to Add Session.checkPermission Calls to Guard Read, Add Node, Set Property, and Remove Item Access
Applied patch that incorporates the feedback-to-date from the forum topic. An additional "admin" role is added and security checks for permanently registering and unregistering types and namespaces were added that check for this role. The admin role is a superset of the readwrite role, which is itself a superset of the readonly role. The pattern for mapping roles was changed to be <role name>[.<repository name>[.<workspace name>]] instead of <role name>[.<workspace name>]. Finally, JcrRepository.login was modified to not allow users to log into workspaces to which they do not have at least readonly access. JcrWorkspace.getAccessibleWorkspaceNames() was also modified to filter out workspace names to which the user does not have at least readonly access.
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNamespaceRegistry.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNamespaceRegistry.java 2009-06-28 00:33:32 UTC (rev 1066)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNamespaceRegistry.java 2009-06-28 02:14:25 UTC (rev 1067)
@@ -23,6 +23,7 @@
*/
package org.jboss.dna.jcr;
+import java.security.AccessControlException;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -39,6 +40,7 @@
import org.jboss.dna.graph.JcrMixLexicon;
import org.jboss.dna.graph.JcrNtLexicon;
import org.jboss.dna.graph.property.NamespaceRegistry;
+import org.jboss.dna.graph.property.Path;
import org.jboss.dna.graph.property.NamespaceRegistry.Namespace;
/**
@@ -108,17 +110,22 @@
private final Behavior behavior;
private final NamespaceRegistry registry;
private final NamespaceRegistry workspaceRegistry;
+ private final JcrSession session;
- JcrNamespaceRegistry( NamespaceRegistry workspaceRegistry ) {
- this(Behavior.WORKSPACE, null, workspaceRegistry);
+ JcrNamespaceRegistry( NamespaceRegistry workspaceRegistry,
+ JcrSession session ) {
+ this(Behavior.WORKSPACE, null, workspaceRegistry, session);
}
JcrNamespaceRegistry( Behavior behavior,
NamespaceRegistry localRegistry,
- NamespaceRegistry workspaceRegistry ) {
+ NamespaceRegistry workspaceRegistry,
+ JcrSession session ) {
this.behavior = behavior;
this.registry = localRegistry != null ? localRegistry : workspaceRegistry;
this.workspaceRegistry = workspaceRegistry;
+ this.session = session;
+
// Add the built-ins, ensuring we overwrite any badly-initialized values ...
for (Map.Entry<String, String> builtIn : STANDARD_BUILT_IN_NAMESPACES_BY_PREFIX.entrySet()) {
this.registry.register(builtIn.getKey(), builtIn.getValue());
@@ -126,6 +133,7 @@
assert this.behavior != null;
assert this.registry != null;
assert this.workspaceRegistry != null;
+ assert this.session != null;
}
/**
@@ -272,6 +280,12 @@
// JSR-170 & JSR-283 Workspace namespace registry ...
// --------------------------------------------------
+ try {
+ session.checkPermission((Path)null, JcrSession.DNA_REGISTER_NAMESPACE_PERMISSION);
+ } catch (AccessControlException ace) {
+ throw new AccessDeniedException(ace);
+ }
+
// Check the zero-length prefix and zero-length URI ...
if (DEFAULT_NAMESPACE_PREFIX.equals(prefix) || DEFAULT_NAMESPACE_URI.equals(uri)) {
throw new NamespaceException(JcrI18n.unableToChangeTheDefaultNamespace.text());
@@ -319,6 +333,16 @@
public synchronized void unregisterNamespace( String prefix )
throws NamespaceException, AccessDeniedException, RepositoryException {
CheckArg.isNotNull(prefix, "prefix");
+
+ // Don't need to check permissions for transient registration/unregistration
+ if (behavior.equals(Behavior.WORKSPACE)) {
+ try {
+ session.checkPermission((Path)null, JcrSession.DNA_REGISTER_NAMESPACE_PERMISSION);
+ } catch (AccessControlException ace) {
+ throw new AccessDeniedException(ace);
+ }
+ }
+
// Look to see whether the prefix is registered ...
String uri = registry.getNamespaceForPrefix(prefix);
// It is an error to unregister a namespace that is not registered ...
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNodeTypeManager.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNodeTypeManager.java 2009-06-28 00:33:32 UTC (rev 1066)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNodeTypeManager.java 2009-06-28 02:14:25 UTC (rev 1067)
@@ -23,9 +23,11 @@
*/
package org.jboss.dna.jcr;
+import java.security.AccessControlException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import javax.jcr.AccessDeniedException;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.UnsupportedRepositoryOperationException;
@@ -40,6 +42,7 @@
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.Path;
import org.jboss.dna.jcr.nodetype.InvalidNodeTypeDefinitionException;
import org.jboss.dna.jcr.nodetype.NodeDefinitionTemplate;
import org.jboss.dna.jcr.nodetype.NodeTypeDefinition;
@@ -58,15 +61,19 @@
@Immutable
class JcrNodeTypeManager implements NodeTypeManager {
- private final ExecutionContext context;
+ private final JcrSession session;
private final RepositoryNodeTypeManager repositoryTypeManager;
- JcrNodeTypeManager( ExecutionContext context,
+ JcrNodeTypeManager( JcrSession session,
RepositoryNodeTypeManager repositoryTypeManager ) {
- this.context = context;
+ this.session = session;
this.repositoryTypeManager = repositoryTypeManager;
}
+ private final ExecutionContext context() {
+ return session.getExecutionContext();
+ }
+
/**
* {@inheritDoc}
*
@@ -87,7 +94,7 @@
// Need to return a version of the node type with the current context
for (JcrNodeType type : rawTypes) {
- types.add(type.with(context));
+ types.add(type.with(context()));
}
return new JcrNodeTypeIterator(types);
@@ -99,10 +106,10 @@
* @see javax.jcr.nodetype.NodeTypeManager#getNodeType(java.lang.String)
*/
public JcrNodeType getNodeType( String nodeTypeName ) throws NoSuchNodeTypeException, RepositoryException {
- Name ntName = context.getValueFactories().getNameFactory().create(nodeTypeName);
+ Name ntName = context().getValueFactories().getNameFactory().create(nodeTypeName);
JcrNodeType type = repositoryTypeManager.getNodeType(ntName);
if (type != null) {
- type = type.with(context);
+ type = type.with(context());
return type;
}
throw new NoSuchNodeTypeException(JcrI18n.typeNotFound.text(nodeTypeName));
@@ -119,7 +126,7 @@
JcrNodeType nodeType = repositoryTypeManager.getNodeType(nodeTypeName);
if (nodeType != null) {
- nodeType = nodeType.with(context);
+ nodeType = nodeType.with(context());
}
return nodeType;
@@ -136,7 +143,7 @@
// Need to return a version of the node type with the current context
for (JcrNodeType type : rawTypes) {
- types.add(type.with(context));
+ types.add(type.with(context()));
}
return new JcrNodeTypeIterator(types);
@@ -383,12 +390,20 @@
* name that already exists
* @throws UnsupportedRepositoryOperationException if {@code allowUpdate} is true; DNA does not allow updating node types at
* this time.
+ * @throws AccessDeniedException if the current session does not have the {@link JcrSession#DNA_REGISTER_TYPE_PERMISSION
+ * register type permission}.
* @throws RepositoryException if another error occurs
*/
public NodeType registerNodeType( NodeTypeDefinition template,
boolean allowUpdate )
throws InvalidNodeTypeDefinitionException, NodeTypeExistsException, UnsupportedRepositoryOperationException,
- RepositoryException {
+ AccessDeniedException, RepositoryException {
+
+ try {
+ session.checkPermission((Path)null, JcrSession.DNA_REGISTER_TYPE_PERMISSION);
+ } catch (AccessControlException ace) {
+ throw new AccessDeniedException(ace);
+ }
return this.repositoryTypeManager.registerNodeType(template, allowUpdate);
}
@@ -407,12 +422,21 @@
* specifies a node type name that already exists
* @throws UnsupportedRepositoryOperationException if {@code allowUpdate} is true; DNA does not allow updating node types at
* this time.
+ * @throws AccessDeniedException if the current session does not have the {@link JcrSession#DNA_REGISTER_TYPE_PERMISSION
+ * register type permission}.
* @throws RepositoryException if another error occurs
*/
public NodeTypeIterator registerNodeTypes( Collection<NodeTypeDefinition> templates,
boolean allowUpdates )
throws InvalidNodeTypeDefinitionException, NodeTypeExistsException, UnsupportedRepositoryOperationException,
- RepositoryException {
+ AccessDeniedException, RepositoryException {
+
+ try {
+ session.checkPermission((Path)null, JcrSession.DNA_REGISTER_TYPE_PERMISSION);
+ } catch (AccessControlException ace) {
+ throw new AccessDeniedException(ace);
+ }
+
return new JcrNodeTypeIterator(this.repositoryTypeManager.registerNodeTypes(templates, allowUpdates));
}
@@ -433,8 +457,14 @@
*/
public void unregisterNodeType( Collection<String> nodeTypeNames )
throws NoSuchNodeTypeException, InvalidNodeTypeDefinitionException, RepositoryException {
- NameFactory nameFactory = this.context.getValueFactories().getNameFactory();
+ NameFactory nameFactory = context().getValueFactories().getNameFactory();
+ try {
+ session.checkPermission((Path)null, JcrSession.DNA_REGISTER_TYPE_PERMISSION);
+ } catch (AccessControlException ace) {
+ throw new AccessDeniedException(ace);
+ }
+
Collection<Name> names = new ArrayList<Name>(nodeTypeNames.size());
for (String name : nodeTypeNames) {
names.add(nameFactory.create(name));
@@ -451,7 +481,7 @@
* @throws RepositoryException if another error occurs
*/
public NodeTypeTemplate createNodeTypeTemplate() throws RepositoryException {
- return new JcrNodeTypeTemplate(this.context);
+ return new JcrNodeTypeTemplate(context());
}
/**
@@ -463,7 +493,7 @@
* @throws RepositoryException if another error occurs
*/
public NodeDefinitionTemplate createNodeDefinitionTemplate() throws RepositoryException {
- return new JcrNodeDefinitionTemplate(this.context);
+ return new JcrNodeDefinitionTemplate(context());
}
/**
@@ -475,6 +505,6 @@
* @throws RepositoryException if another error occurs
*/
public PropertyDefinitionTemplate createPropertyDefinitionTemplate() throws RepositoryException {
- return new JcrPropertyDefinitionTemplate(this.context);
+ return new JcrPropertyDefinitionTemplate(context());
}
}
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrRepository.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrRepository.java 2009-06-28 00:33:32 UTC (rev 1066)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrRepository.java 2009-06-28 02:14:25 UTC (rev 1067)
@@ -26,6 +26,7 @@
import java.io.IOException;
import java.lang.reflect.Method;
import java.security.AccessControlContext;
+import java.security.AccessControlException;
import java.security.AccessController;
import java.util.Collections;
import java.util.EnumMap;
@@ -428,6 +429,7 @@
// Per JCR 1.0 6.1.1, if the workspaceName is not recognized, a NoSuchWorkspaceException is thrown
throw new NoSuchWorkspaceException(JcrI18n.workspaceNameIsInvalid.text(sourceName, workspaceName));
}
+
graph.useWorkspace(workspaceName);
} catch (InvalidWorkspaceException e) {
throw new NoSuchWorkspaceException(JcrI18n.workspaceNameIsInvalid.text(sourceName, workspaceName), e);
@@ -440,7 +442,17 @@
// Create the workspace, which will create its own session ...
sessionAttributes = Collections.unmodifiableMap(sessionAttributes);
JcrWorkspace workspace = new JcrWorkspace(this, workspaceName, execContext, sessionAttributes);
- return workspace.getSession();
+
+ JcrSession session = (JcrSession) workspace.getSession();
+
+ // Need to make sure that the user has access to this session
+ try {
+ session.checkPermission(workspaceName, null, JcrSession.JCR_READ_PERMISSION);
+ }
+ catch (AccessControlException ace) {
+ throw new NoSuchWorkspaceException(JcrI18n.workspaceNameIsInvalid.text(sourceName, workspaceName));
+ }
+ return session;
}
/**
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSession.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSession.java 2009-06-28 00:33:32 UTC (rev 1066)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSession.java 2009-06-28 02:14:25 UTC (rev 1067)
@@ -83,7 +83,11 @@
public static final String DNA_READ_PERMISSION = "readonly";
public static final String DNA_WRITE_PERMISSION = "readwrite";
+ public static final String DNA_ADMIN_PERMISSION = "admin";
+ public static final String DNA_REGISTER_NAMESPACE_PERMISSION = "register_namespace";
+ public static final String DNA_REGISTER_TYPE_PERMISSION = "register_type";
+
public static final String JCR_ADD_NODE_PERMISSION = "add_node";
public static final String JCR_SET_PROPERTY_PERMISSION = "set_property";
public static final String JCR_REMOVE_PERMISSION = "remove";
@@ -145,7 +149,7 @@
NamespaceRegistry workspaceRegistry = workspaceContext.getNamespaceRegistry();
NamespaceRegistry local = new LocalNamespaceRegistry(workspaceRegistry);
this.executionContext = workspaceContext.with(local);
- this.sessionRegistry = new JcrNamespaceRegistry(Behavior.JSR170_SESSION, local, workspaceRegistry);
+ this.sessionRegistry = new JcrNamespaceRegistry(Behavior.JSR170_SESSION, local, workspaceRegistry, this);
this.rootPath = this.executionContext.getValueFactories().getPathFactory().createRootPath();
// Set up the graph to use for this session (which uses the session's namespace registry and context) ...
@@ -291,10 +295,16 @@
* Returns whether the authenticated user has the given role.
*
* @param roleName the name of the role to check
+ * @param workspaceName the workspace under which the user must have the role. This may be different from the current
+ * workspace.
* @return true if the user has the role and is logged in; false otherwise
*/
- final boolean hasRole( String roleName ) {
- return getExecutionContext().getSecurityContext().hasRole(roleName);
+ final boolean hasRole( String roleName,
+ String workspaceName ) {
+ SecurityContext context = getExecutionContext().getSecurityContext();
+
+ return context.hasRole(roleName) || context.hasRole(roleName + "." + this.repository.getName())
+ || context.hasRole(roleName + "." + this.repository.getName() + "." + workspaceName);
}
/**
@@ -342,17 +352,19 @@
CheckArg.isNotEmpty(actions, "actions");
- if ("read".equals(actions)) {
- // readonly access is sufficient
- if (hasRole(DNA_READ_PERMISSION) || hasRole(DNA_READ_PERMISSION + "." + workspaceName)) {
- return;
+ boolean hasPermission = true;
+ for (String action : actions.split(",")) {
+ if (JCR_READ_PERMISSION.equals(action)) {
+ hasPermission &= hasRole(DNA_READ_PERMISSION, workspaceName) || hasRole(DNA_WRITE_PERMISSION, workspaceName)
+ || hasRole(DNA_ADMIN_PERMISSION, workspaceName);
+ } else if (DNA_REGISTER_NAMESPACE_PERMISSION.equals(action) || DNA_REGISTER_TYPE_PERMISSION.equals(action)) {
+ hasPermission &= hasRole(DNA_ADMIN_PERMISSION, workspaceName);
+ } else {
+ hasPermission &= hasRole(DNA_ADMIN_PERMISSION, workspaceName) || hasRole(DNA_WRITE_PERMISSION, workspaceName);
}
}
- // need readwrite access
- if (hasRole(DNA_WRITE_PERMISSION) || hasRole(DNA_WRITE_PERMISSION + "." + workspaceName)) {
- return;
- }
+ if (hasPermission) return;
String pathAsString = path != null ? path.getString(this.namespaces()) : "<unknown>";
throw new AccessControlException(JcrI18n.permissionDenied.text(pathAsString, actions));
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java 2009-06-28 00:33:32 UTC (rev 1066)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java 2009-06-28 02:14:25 UTC (rev 1067)
@@ -170,9 +170,6 @@
uriProperty, namespaceType);
this.context = context.with(persistentRegistry);
- // Set up and initialize the persistent JCR namespace registry ...
- this.workspaceRegistry = new JcrNamespaceRegistry(persistentRegistry);
-
// Now create a graph with this new execution context ...
this.graph = Graph.create(this.repository.getRepositorySourceName(), this.repository.getConnectionFactory(), this.context);
this.graph.useWorkspace(workspaceName);
@@ -182,13 +179,17 @@
// This must be initialized after the session
RepositoryNodeTypeManager repoTypeManager = repository.getRepositoryTypeManager();
- this.nodeTypeManager = new JcrNodeTypeManager(session.getExecutionContext(), repoTypeManager);
+ this.nodeTypeManager = new JcrNodeTypeManager(session, repoTypeManager);
this.queryManager = new JcrQueryManager(this.session);
if (Boolean.valueOf(repository.getOptions().get(Option.PROJECT_NODE_TYPES))) {
Path parentOfTypeNodes = context.getValueFactories().getPathFactory().create(systemPath, JcrLexicon.NODE_TYPES);
repoTypeManager.projectOnto(this.graph, parentOfTypeNodes);
}
+
+ // Set up and initialize the persistent JCR namespace registry ...
+ this.workspaceRegistry = new JcrNamespaceRegistry(persistentRegistry, this.session);
+
}
final String getSourceName() {
@@ -231,8 +232,20 @@
*/
public String[] getAccessibleWorkspaceNames() throws RepositoryException {
try {
- Set<String> workspaces = graph.getWorkspaces();
- return workspaces.toArray(new String[workspaces.size()]);
+ Set<String> workspaceNamesFromGraph = graph.getWorkspaces();
+ Set<String> workspaceNames = new HashSet<String>(workspaceNamesFromGraph.size());
+
+ for(String workspaceName : workspaceNamesFromGraph) {
+ try {
+ session.checkPermission(workspaceName, null, JcrSession.JCR_READ_PERMISSION);
+ workspaceNames.add(workspaceName);
+ }
+ catch (AccessControlException ace) {
+ // Can happen if user doesn't have the privileges to read from the workspace
+ }
+ }
+
+ return workspaceNames.toArray(new String[workspaceNames.size()]);
} catch (RepositorySourceException e) {
throw new RepositoryException(JcrI18n.errorObtainingWorkspaceNames.text(getSourceName(), e.getMessage()), e);
}
Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/DnaTckTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/DnaTckTest.java 2009-06-28 00:33:32 UTC (rev 1066)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/DnaTckTest.java 2009-06-28 02:14:25 UTC (rev 1067)
@@ -2,8 +2,10 @@
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
+import java.util.Collections;
import javax.jcr.AccessDeniedException;
import javax.jcr.Credentials;
+import javax.jcr.NoSuchWorkspaceException;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.PathNotFoundException;
@@ -12,6 +14,7 @@
import javax.jcr.SimpleCredentials;
import javax.jcr.nodetype.ConstraintViolationException;
import org.apache.jackrabbit.test.AbstractJCRTest;
+import org.jboss.dna.jcr.nodetype.NodeTypeTemplate;
/**
* Additional DNA tests that check for JCR compliance.
@@ -68,6 +71,7 @@
private void testRemoveProperty( Session session ) throws Exception {
Session localAdmin = helper.getRepository().login(helper.getSuperuserCredentials(), session.getWorkspace().getName());
+
assertEquals(session.getWorkspace().getName(), superuser.getWorkspace().getName());
Node superRoot = localAdmin.getRootNode();
@@ -90,6 +94,21 @@
session.save();
}
+ private void testRegisterNamespace( Session session ) throws Exception {
+ String unusedPrefix = session.getUserID();
+ session.getWorkspace().getNamespaceRegistry().registerNamespace(unusedPrefix, unusedPrefix);
+ session.getWorkspace().getNamespaceRegistry().unregisterNamespace(unusedPrefix);
+ }
+
+ private void testRegisterType( Session session ) throws Exception {
+ JcrNodeTypeManager nodeTypes = (JcrNodeTypeManager)session.getWorkspace().getNodeTypeManager();
+ NodeTypeTemplate newType = nodeTypes.createNodeTypeTemplate();
+ String nodeTypeName = session.getUserID() + "Type";
+ newType.setName(nodeTypeName);
+ nodeTypes.registerNodeType(newType, false);
+ nodeTypes.unregisterNodeType(Collections.singleton(nodeTypeName));
+ }
+
private void testWrite( Session session ) throws Exception {
testAddNode(session);
testSetProperty(session);
@@ -97,6 +116,11 @@
testRemoveNode(session);
}
+ private void testAdmin( Session session ) throws Exception {
+ testRegisterNamespace(session);
+ testRegisterType(session);
+ }
+
/**
* Tests that read-only sessions can read nodes by loading all of the children of the root node
*
@@ -137,6 +161,25 @@
}
/**
+ * Tests that read-only sessions cannot register namespaces or types
+ *
+ * @throws Exception
+ */
+ public void testShouldNotAllowReadOnlySessionToAdmin() throws Exception {
+ session = helper.getReadOnlySession();
+ try {
+ testRegisterNamespace(session);
+ fail("Read-only sessions should not be able to register namespaces");
+ } catch (AccessDeniedException expected) {
+ }
+ try {
+ testRegisterType(session);
+ fail("Read-only sessions should not be able to register types");
+ } catch (AccessDeniedException expected) {
+ }
+ }
+
+ /**
* Tests that read-write sessions can read nodes by loading all of the children of the root node
*
* @throws Exception
@@ -157,6 +200,55 @@
}
/**
+ * Tests that read-write sessions cannot register namespaces or types
+ *
+ * @throws Exception
+ */
+ public void testShouldNotAllowReadWriteSessionToAdmin() throws Exception {
+ session = helper.getReadWriteSession();
+ try {
+ testRegisterNamespace(session);
+ fail("Read-write sessions should not be able to register namespaces");
+ } catch (AccessDeniedException expected) {
+ }
+ try {
+ testRegisterType(session);
+ fail("Read-write sessions should not be able to register types");
+ } catch (AccessDeniedException expected) {
+ }
+ }
+
+ /**
+ * Tests that admin sessions can read nodes by loading all of the children of the root node
+ *
+ * @throws Exception
+ */
+ public void testShouldAllowAdminSessionToRead() throws Exception {
+ session = helper.getSuperuserSession();
+ testRead(session);
+ }
+
+ /**
+ * Tests that admin sessions can add nodes, remove nodes, set nodes, and set properties.
+ *
+ * @throws Exception
+ */
+ public void testShouldAllowAdminSessionToWrite() throws Exception {
+ session = helper.getSuperuserSession();
+ testWrite(session);
+ }
+
+ /**
+ * Tests that admin sessions can register namespaces and types
+ *
+ * @throws Exception
+ */
+ public void testShouldAllowAdminSessionToAdmin() throws Exception {
+ session = helper.getSuperuserSession();
+ testAdmin(session);
+ }
+
+ /**
* User defaultuser is configured to have readwrite in "otherWorkspace" and readonly in the default workspace. This test makes
* sure both work.
*
@@ -181,6 +273,32 @@
session.logout();
}
+ /**
+ * Users should not be able to see workspaces to which they don't at least have read access.
+ * User 'noaccess' has no access to the default workspace.
+ * @throws Exception
+ */
+ public void testShouldNotSeeWorkspacesWithoutReadPermission() throws Exception {
+ Credentials creds = new SimpleCredentials("noaccess", "noaccess".toCharArray());
+
+ try {
+ session = helper.getRepository().login(creds);
+ fail("User 'noaccess' with no access to the default workspace should not be able to log into that workspace");
+ }
+ catch (NoSuchWorkspaceException le) {
+ // Expected
+ }
+
+ session = helper.getRepository().login(creds, "otherWorkspace");
+
+ String[] workspaceNames = session.getWorkspace().getAccessibleWorkspaceNames();
+
+ assertThat(workspaceNames.length, is(1));
+ assertThat(workspaceNames[0], is("otherWorkspace"));
+
+ session.logout();
+ }
+
public void testShouldCopyFromAnotherWorkspace() throws Exception {
session = helper.getSuperuserSession("otherWorkspace");
String nodetype1 = this.getProperty("nodetype");
Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrNamespaceRegistryTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrNamespaceRegistryTest.java 2009-06-28 00:33:32 UTC (rev 1066)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrNamespaceRegistryTest.java 2009-06-28 02:14:25 UTC (rev 1067)
@@ -31,6 +31,8 @@
import org.jboss.dna.graph.ExecutionContext;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.MockitoAnnotations;
+import org.mockito.MockitoAnnotations.Mock;
/**
* @author jverhaeg
@@ -39,11 +41,15 @@
private ExecutionContext executionContext;
private JcrNamespaceRegistry registry;
+ @Mock
+ private JcrSession session;
@Before
public void before() {
+ MockitoAnnotations.initMocks(this);
executionContext = new ExecutionContext();
- registry = new JcrNamespaceRegistry(executionContext.getNamespaceRegistry());
+ registry = new JcrNamespaceRegistry(executionContext.getNamespaceRegistry(), session);
+
}
protected void assertThatNamespaceIsRegistered( String prefix,
Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrRepositoryTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrRepositoryTest.java 2009-06-28 00:33:32 UTC (rev 1066)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrRepositoryTest.java 2009-06-28 02:14:25 UTC (rev 1067)
@@ -30,6 +30,7 @@
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.jcr.Credentials;
@@ -208,7 +209,10 @@
@Test
public void shouldAllowLoginWithProperCredentials() throws Exception {
repository.login(credentials);
- repository.login(new SecurityContextCredentials(new MockSecurityContext(null)));
+ repository.login(new SecurityContextCredentials(
+ new MockSecurityContext(
+ null,
+ Collections.singleton(JcrSession.DNA_ADMIN_PERMISSION))));
}
@Test
@@ -216,7 +220,11 @@
Session session = repository.login(credentials, null);
assertThat(session, notNullValue());
session.logout();
- session = repository.login(new SecurityContextCredentials(new MockSecurityContext(null)), (String)null);
+ session = repository.login(new SecurityContextCredentials(
+ new MockSecurityContext(
+ null,
+ Collections.singleton(JcrSession.DNA_ADMIN_PERMISSION))),
+ (String)null);
assertThat(session, notNullValue());
session.logout();
}
Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/SessionCacheTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/SessionCacheTest.java 2009-06-28 00:33:32 UTC (rev 1066)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/SessionCacheTest.java 2009-06-28 02:14:25 UTC (rev 1067)
@@ -114,7 +114,7 @@
throw new IllegalStateException("Could not access node type definition files", ioe);
}
- nodeTypes = new JcrNodeTypeManager(this.context, repoTypes);
+ nodeTypes = new JcrNodeTypeManager(this.session, repoTypes);
stub(session.nodeTypeManager()).toReturn(nodeTypes);
// Now set up the graph and session cache ...
Modified: trunk/dna-jcr/src/test/resources/security/tck_roles.properties
===================================================================
--- trunk/dna-jcr/src/test/resources/security/tck_roles.properties 2009-06-28 00:33:32 UTC (rev 1066)
+++ trunk/dna-jcr/src/test/resources/security/tck_roles.properties 2009-06-28 02:14:25 UTC (rev 1067)
@@ -1,6 +1,7 @@
#<userName>=[readonly[.<workspaceName>] | readwrite[.<workspaceName>]][, [readonly[.<workspaceName>] | readwrite[.<workspaceName>]]]*
-superuser=readwrite
+superuser=admin
readwrite=readwrite
readonly=readonly
# default workspace name is the empty string
-defaultonly=readwrite.,readonly.otherWorkspace
+defaultonly=readwrite.Store.,readonly.Store.otherWorkspace
+noaccess=readonly.Store.otherWorkspace
Modified: trunk/dna-jcr/src/test/resources/security/tck_users.properties
===================================================================
--- trunk/dna-jcr/src/test/resources/security/tck_users.properties 2009-06-28 00:33:32 UTC (rev 1066)
+++ trunk/dna-jcr/src/test/resources/security/tck_users.properties 2009-06-28 02:14:25 UTC (rev 1067)
@@ -3,3 +3,4 @@
readwrite=readwrite
readonly=readonly
defaultonly=defaultonly
+noaccess=noaccess
14 years, 10 months
DNA SVN: r1066 - in trunk: dna-graph/src/main/java/org/jboss/dna/graph/connector and 16 other directories.
by dna-commits@lists.jboss.org
Author: bcarothers
Date: 2009-06-27 20:33:32 -0400 (Sat, 27 Jun 2009)
New Revision: 1066
Added:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CloneBranchRequest.java
Removed:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/UuidConflictBehavior.java
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/Graph.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/GraphI18n.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/UuidAlreadyExistsException.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/ForkRequestProcessor.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/JoinMirrorRequestProcessor.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/JoinRequestProcessor.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/AbstractMapWorkspace.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepository.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRequestProcessor.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapWorkspace.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/BatchRequestBuilder.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CopyBranchRequest.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/RequestBuilder.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/processor/LoggingRequestProcessor.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/processor/RequestProcessor.java
trunk/dna-graph/src/main/resources/org/jboss/dna/graph/GraphI18n.properties
trunk/dna-graph/src/test/java/org/jboss/dna/graph/GraphTest.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/MockRepositoryRequestProcessor.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/test/WritableConnectorTest.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrNode.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrTckTest.java
trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatingRequestProcessor.java
trunk/extensions/dna-connector-filesystem/src/main/java/org/jboss/dna/connector/filesystem/FileSystemRequestProcessor.java
trunk/extensions/dna-connector-jdbc-metadata/src/main/java/org/jboss/dna/connector/jdbc/JdbcRequestProcesor.java
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicRequestProcessor.java
trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorWritingTest.java
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositoryRequestProcessor.java
Log:
DNA-370 JcrWorkspace.clone Is Not Implemented
I tried to make workspace.update work with the existing CopyBranchRequest, but it required some changes that would have made the semantics of to(...) and into(...) ambiguous and dependent on whether the UUID conflict behavior was ALWAYS_CREATE_NEW or not. Instead, I pulled the UUID behavior out of the CopyBranchRequest and added it into a new request - CloneBranchRequest. This provides clear semantics for copy (always creates new UUIDs, may be between workspaces or within a single workspace, may function at the property or node level) and clone (always preserves UUIDs, only works between workspaces, may remove nodes from target workspace, only works at the node level).
Committed the patch that adds the new request and all of the associated changes on the graph side (adding clone operation) and the connector (implementing clone behavior for writable connectors) and modifies the workspace.clone and node.update operations accordingly.
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/Graph.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/Graph.java 2009-06-27 02:54:06 UTC (rev 1065)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/Graph.java 2009-06-28 00:33:32 UTC (rev 1066)
@@ -78,7 +78,6 @@
import org.jboss.dna.graph.request.Request;
import org.jboss.dna.graph.request.RequestBuilder;
import org.jboss.dna.graph.request.UnsupportedRequestException;
-import org.jboss.dna.graph.request.UuidConflictBehavior;
import org.jboss.dna.graph.request.VerifyWorkspaceRequest;
import org.jboss.dna.graph.request.CloneWorkspaceRequest.CloneConflictBehavior;
import org.jboss.dna.graph.request.CreateWorkspaceRequest.CreateConflictBehavior;
@@ -525,7 +524,7 @@
* </p>
*
* @param firstIdProperty the first identification property of the node that is to be moved
- * @param additionalIdProperties the remaining idenficiation properties of the node that is to be moved
+ * @param additionalIdProperties the remaining identification properties of the node that is to be moved
* @return the object that can be used to specify addition nodes to be moved or the location of the node where the node is to
* be moved
*/
@@ -535,6 +534,174 @@
}
/**
+ * Begin the request to clone a node at the specified location into a parent node at a different location, which is specified
+ * via the <code>into(...)</code> method on the returned {@link Clone} object.
+ * <p>
+ * Like all other methods on the {@link Graph}, the clone request will be performed immediately when the {@link WithUuids UUID
+ * behavior} is specified.
+ * </p>
+ * <p>
+ * The clone operation differs from the copy operation in that it must replicate nodes from one workspace to another (the copy
+ * operations supports replicating nodes within a workspace as well as across workspaces) and that it preserves UUIDs (the
+ * copy operation always generates new UUIDs).
+ * </p>
+ *
+ * @param from the location of the node that is to be cloned.
+ * @return the object that can be used to specify the location of the node where the node is to be cloned
+ */
+ public Clone<Graph> clone( Location from ) {
+ return new CloneAction<Graph>(this, from) {
+ @Override
+ protected Graph submit( String fromWorkspaceName,
+ Location from,
+ String intoWorkspaceName,
+ Location into,
+ Name desiredName,
+ Segment desiredSegment,
+ boolean removeExisting ) {
+ requests.cloneBranch(from,
+ fromWorkspaceName,
+ into,
+ intoWorkspaceName,
+ desiredName,
+ desiredSegment,
+ removeExisting);
+ return and();
+ }
+ };
+ }
+
+ /**
+ * Begin the request to clone the specified node into a parent node at a different location, which is specified via the
+ * <code>into(...)</code> method on the returned {@link Clone} object.
+ * <p>
+ * Like all other methods on the {@link Graph}, the clone request will be performed immediately when the {@link WithUuids UUID
+ * behavior} is specified.
+ * </p>
+ * <p>
+ * The clone operation differs from the copy operation in that it must replicate nodes from one workspace to another (the copy
+ * operations supports replicating nodes within a workspace as well as across workspaces) and that it preserves UUIDs (the
+ * copy operation always generates new UUIDs).
+ * </p>
+ *
+ * @param from the node that is to be copied.
+ * @return the object that can be used to specify addition nodes to be copied or the location of the node where the node is to
+ * be copied
+ */
+ public Clone<Graph> clone( Node from ) {
+ return clone(from.getLocation());
+ }
+
+ /**
+ * Begin the request to clone a node located at the supplied path into a parent node at a different location, which is
+ * specified via the <code>into(...)</code> method on the returned {@link Clone} object.
+ * <p>
+ * Like all other methods on the {@link Graph}, the clone request will be performed immediately when the {@link WithUuids UUID
+ * behavior} is specified.
+ * </p>
+ * <p>
+ * The clone operation differs from the copy operation in that it must replicate nodes from one workspace to another (the copy
+ * operations supports replicating nodes within a workspace as well as across workspaces) and that it preserves UUIDs (the
+ * copy operation always generates new UUIDs).
+ * </p>
+ *
+ * @param fromPath the path to the node that is to be copied.
+ * @return the object that can be used to specify addition nodes to be copied or the location of the node where the node is to
+ * be copied
+ */
+ public Clone<Graph> clone( String fromPath ) {
+ return clone(Location.create(createPath(fromPath)));
+ }
+
+ /**
+ * Begin the request to clone a node located at the supplied path into a parent node at a different location, which is
+ * specified via the <code>into(...)</code> method on the returned {@link Clone} object.
+ * <p>
+ * Like all other methods on the {@link Graph}, the clone request will be performed immediately when the {@link WithUuids UUID
+ * behavior} is specified.
+ * </p>
+ * <p>
+ * The clone operation differs from the copy operation in that it must replicate nodes from one workspace to another (the copy
+ * operations supports replicating nodes within a workspace as well as across workspaces) and that it preserves UUIDs (the
+ * copy operation always generates new UUIDs).
+ * </p>
+ *
+ * @param from the path to the node that is to be copied.
+ * @return the object that can be used to specify addition nodes to be copied or the location of the node where the node is to
+ * be copied
+ */
+ public Clone<Graph> clone( Path from ) {
+ return clone(Location.create(from));
+ }
+
+ /**
+ * Begin the request to clone a node with the specified unique identifier into a parent node at a different location, which is
+ * specified via the <code>into(...)</code> method on the returned {@link Clone} object.
+ * <p>
+ * Like all other methods on the {@link Graph}, the clone request will be performed immediately when the {@link WithUuids UUID
+ * behavior} is specified.
+ * </p>
+ * <p>
+ * The clone operation differs from the copy operation in that it must replicate nodes from one workspace to another (the copy
+ * operations supports replicating nodes within a workspace as well as across workspaces) and that it preserves UUIDs (the
+ * copy operation always generates new UUIDs).
+ * </p>
+ *
+ * @param from the UUID of the node that is to be copied.
+ * @return the object that can be used to specify addition nodes to be copied or the location of the node where the node is to
+ * be copied
+ */
+ public Clone<Graph> clone( UUID from ) {
+ return clone(Location.create(from));
+ }
+
+ /**
+ * Begin the request to clone a node with the specified unique identification property into a parent node at a different
+ * location, which is specified via the <code>into(...)</code> method on the returned {@link Clone} object. The identification
+ * property should uniquely identify a single node.
+ * <p>
+ * Like all other methods on the {@link Graph}, the clone request will be performed immediately when the {@link WithUuids UUID
+ * behavior} is specified.
+ * </p>
+ * <p>
+ * The clone operation differs from the copy operation in that it must replicate nodes from one workspace to another (the copy
+ * operations supports replicating nodes within a workspace as well as across workspaces) and that it preserves UUIDs (the
+ * copy operation always generates new UUIDs).
+ * </p>
+ *
+ * @param idProperty the unique identification property of the node that is to be copied.
+ * @return the object that can be used to specify addition nodes to be copied or the location of the node where the node is to
+ * be copied
+ */
+ public Clone<Graph> clone( Property idProperty ) {
+ return clone(Location.create(idProperty));
+ }
+
+ /**
+ * Begin the request to clone a node with the specified identification properties into a parent node at a different location,
+ * which is specified via the <code>into(...)</code> method on the returned {@link Clone} object. The identification
+ * properties should uniquely identify a single node.
+ * <p>
+ * Like all other methods on the {@link Graph}, the clone request will be performed immediately when the {@link WithUuids UUID
+ * behavior} is specified.
+ * </p>
+ * <p>
+ * The clone operation differs from the copy operation in that it must replicate nodes from one workspace to another (the copy
+ * operations supports replicating nodes within a workspace as well as across workspaces) and that it preserves UUIDs (the
+ * copy operation always generates new UUIDs).
+ * </p>
+ *
+ * @param firstIdProperty the first identification property of the node that is to be copied
+ * @param additionalIdProperties the remaining identification properties of the node that is to be copied
+ * @return the object that can be used to specify addition nodes to be copied or the location of the node where the node is to
+ * be copied
+ */
+ public Clone<Graph> clone( Property firstIdProperty,
+ Property... additionalIdProperties ) {
+ return clone(Location.create(firstIdProperty, additionalIdProperties));
+ }
+
+ /**
* Begin the request to copy the specified node into a parent node at a different location, which is specified via the
* <code>into(...)</code> method on the returned {@link Copy} object.
* <p>
@@ -568,8 +735,7 @@
protected Graph submit( String fromWorkspaceName,
Locations from,
Location into,
- Name childName,
- UuidConflictBehavior uuidConflictBehavior ) {
+ Name childName ) {
String workspaceName = fromWorkspaceName != null ? fromWorkspaceName : getCurrentWorkspaceName();
do {
requests.copyBranch(from.getLocation(),
@@ -577,8 +743,7 @@
into,
getCurrentWorkspaceName(),
childName,
- NodeConflictBehavior.APPEND,
- uuidConflictBehavior);
+ NodeConflictBehavior.APPEND);
} while ((from = from.next()) != null);
return and();
}
@@ -660,7 +825,7 @@
* </p>
*
* @param firstIdProperty the first identification property of the node that is to be copied
- * @param additionalIdProperties the remaining idenficiation properties of the node that is to be copied
+ * @param additionalIdProperties the remaining identification properties of the node that is to be copied
* @return the object that can be used to specify addition nodes to be copied or the location of the node where the node is to
* be copied
*/
@@ -737,7 +902,7 @@
* a single node. This request is submitted to the repository immediately.
*
* @param firstIdProperty the first identification property of the node that is to be copied
- * @param additionalIdProperties the remaining idenficiation properties of the node that is to be copied
+ * @param additionalIdProperties the remaining identification properties of the node that is to be copied
* @return an object that may be used to start another request
*/
public Conjunction<Graph> delete( Property firstIdProperty,
@@ -2312,7 +2477,7 @@
* </p>
*
* @param firstIdProperty the first identification property of the node that is to be moved
- * @param additionalIdProperties the remaining idenficiation properties of the node that is to be moved
+ * @param additionalIdProperties the remaining identification properties of the node that is to be moved
* @return the object that can be used to specify addition nodes to be moved or the location of the node where the node is
* to be moved
*/
@@ -2330,7 +2495,7 @@
* called.
* </p>
*
- * @param idProperties the idenficiation properties of the node that is to be moved
+ * @param idProperties the identification properties of the node that is to be moved
* @return the object that can be used to specify addition nodes to be moved or the location of the node where the node is
* to be moved
*/
@@ -2339,6 +2504,158 @@
}
/**
+ * Begin the request to clone the specified node into a parent node at a different location, which is specified via the
+ * <code>into(...)</code> method on the returned {@link Clone} object.
+ * <p>
+ * Like all other methods on the {@link Batch}, the request will be performed when the {@link #execute()} method is
+ * called.
+ * </p>
+ *
+ * @param from the node that is to be copied.
+ * @return the object that can be used to specify addition nodes to be copied or the location of the node where the node
+ * is to be copied
+ */
+ public Clone<BatchConjunction> clone( Node from ) {
+ return clone(from.getLocation());
+ }
+
+ /**
+ * Begin the request to clone a node at the specified location into a parent node at a different location, which is
+ * specified via the <code>into(...)</code> method on the returned {@link Clone} object.
+ * <p>
+ * Like all other methods on the {@link Batch}, the request will be performed when the {@link #execute()} method is
+ * called.
+ * </p>
+ *
+ * @param from the location of the node that is to be copied.
+ * @return the object that can be used to specify addition nodes to be copied or the location of the node where the node
+ * is to be copied
+ */
+ public Clone<BatchConjunction> clone( Location from ) {
+ assertNotExecuted();
+ return new CloneAction<BatchConjunction>(this.nextRequests, from) {
+ @Override
+ protected BatchConjunction submit( String fromWorkspaceName,
+ Location from,
+ String intoWorkspaceName,
+ Location into,
+ Name desiredName,
+ Segment desiredSegment,
+ boolean removeExisting ) {
+ requests.cloneBranch(from,
+ fromWorkspaceName,
+ into,
+ intoWorkspaceName,
+ desiredName,
+ desiredSegment,
+ removeExisting);
+ return and();
+ }
+ };
+ }
+
+ /**
+ * Begin the request to clone a node located at the supplied path into a parent node at a different location, which is
+ * specified via the <code>into(...)</code> method on the returned {@link Clone} object.
+ * <p>
+ * Like all other methods on the {@link Batch}, the request will be performed when the {@link #execute()} method is
+ * called.
+ * </p>
+ *
+ * @param fromPath the path to the node that is to be copied.
+ * @return the object that can be used to specify addition nodes to be copied or the location of the node where the node
+ * is to be copied
+ */
+ public Clone<BatchConjunction> clone( String fromPath ) {
+ return clone(Location.create(createPath(fromPath)));
+ }
+
+ /**
+ * Begin the request to clone a node located at the supplied path into a parent node at a different location, which is
+ * specified via the <code>into(...)</code> method on the returned {@link Clone} object.
+ * <p>
+ * Like all other methods on the {@link Graph}, the clone request will be performed immediately when the
+ * <code>into(...)</code> method is called.
+ * </p>
+ *
+ * @param from the path to the node that is to be copied.
+ * @return the object that can be used to specify addition nodes to be copied or the location of the node where the node
+ * is to be copied
+ */
+ public Clone<BatchConjunction> clone( Path from ) {
+ return clone(Location.create(from));
+ }
+
+ /**
+ * Begin the request to clone a node with the specified unique identifier into a parent node at a different location,
+ * which is specified via the <code>into(...)</code> method on the returned {@link Clone} object.
+ * <p>
+ * Like all other methods on the {@link Batch}, the request will be performed when the {@link #execute()} method is
+ * called.
+ * </p>
+ *
+ * @param from the UUID of the node that is to be copied.
+ * @return the object that can be used to specify addition nodes to be copied or the location of the node where the node
+ * is to be copied
+ */
+ public Clone<BatchConjunction> clone( UUID from ) {
+ return clone(Location.create(from));
+ }
+
+ /**
+ * Begin the request to clone a node with the specified unique identification property into a parent node at a different
+ * location, which is specified via the <code>into(...)</code> method on the returned {@link Clone} object. The
+ * identification property should uniquely identify a single node.
+ * <p>
+ * Like all other methods on the {@link Batch}, the request will be performed when the {@link #execute()} method is
+ * called.
+ * </p>
+ *
+ * @param idProperty the unique identification property of the node that is to be copied.
+ * @return the object that can be used to specify addition nodes to be copied or the location of the node where the node
+ * is to be copied
+ */
+ public Clone<BatchConjunction> clone( Property idProperty ) {
+ return clone(Location.create(idProperty));
+ }
+
+ /**
+ * Begin the request to clone a node with the specified identification properties into a parent node at a different
+ * location, which is specified via the <code>into(...)</code> method on the returned {@link Clone} object. The
+ * identification properties should uniquely identify a single node.
+ * <p>
+ * Like all other methods on the {@link Batch}, the request will be performed when the {@link #execute()} method is
+ * called.
+ * </p>
+ *
+ * @param firstIdProperty the first identification property of the node that is to be copied
+ * @param additionalIdProperties the remaining identification properties of the node that is to be copied
+ * @return the object that can be used to specify addition nodes to be copied or the location of the node where the node
+ * is to be copied
+ */
+ public Clone<BatchConjunction> clone( Property firstIdProperty,
+ Property... additionalIdProperties ) {
+ return clone(Location.create(firstIdProperty, additionalIdProperties));
+ }
+
+ /**
+ * Begin the request to clone a node with the specified identification properties into a parent node at a different
+ * location, which is specified via the <code>into(...)</code> method on the returned {@link Clone} object. The
+ * identification properties should uniquely identify a single node.
+ * <p>
+ * Like all other methods on the {@link Batch}, the request will be performed when the {@link #execute()} method is
+ * called.
+ * </p>
+ *
+ * @param idProperties the identification properties of the node that is to be copied
+ * @return the object that can be used to specify addition nodes to be copied or the location of the node where the node
+ * is to be copied
+ */
+ public Clone<BatchConjunction> clone( Iterable<Property> idProperties ) {
+ return clone(Location.create(idProperties));
+ }
+
+ /**
* Begin the request to copy the specified node into a parent node at a different location, which is specified via the
* <code>into(...)</code> method on the returned {@link Copy} object.
* <p>
@@ -2373,17 +2690,10 @@
protected BatchConjunction submit( String fromWorkspaceName,
Locations from,
Location into,
- Name copyName,
- UuidConflictBehavior uuidConflictBehavior ) {
+ Name copyName ) {
String workspaceName = fromWorkspaceName != null ? fromWorkspaceName : getCurrentWorkspaceName();
do {
- requestQueue.copyBranch(from.getLocation(),
- workspaceName,
- into,
- workspaceName,
- copyName,
- null,
- uuidConflictBehavior);
+ requestQueue.copyBranch(from.getLocation(), workspaceName, into, workspaceName, copyName, null);
} while ((from = from.next()) != null);
return and();
}
@@ -2465,7 +2775,7 @@
* </p>
*
* @param firstIdProperty the first identification property of the node that is to be copied
- * @param additionalIdProperties the remaining idenficiation properties of the node that is to be copied
+ * @param additionalIdProperties the remaining identification properties of the node that is to be copied
* @return the object that can be used to specify addition nodes to be copied or the location of the node where the node
* is to be copied
*/
@@ -2586,7 +2896,7 @@
* </p>
*
* @param firstIdProperty the first identification property of the node that is to be copied
- * @param additionalIdProperties the remaining idenficiation properties of the node that is to be copied
+ * @param additionalIdProperties the remaining identification properties of the node that is to be copied
* @return an object that may be used to start another request
*/
public BatchConjunction delete( Property firstIdProperty,
@@ -3894,6 +4204,31 @@
}
/**
+ * A component that defines a new child name for a node.
+ *
+ * @param <Next> The interface that is to be returned when this request is completed
+ */
+ public interface AsChild<Next> {
+ /**
+ * Finish the request by specifying the exact segment for the new child node. If no segment already exists, this request
+ * should fail.
+ *
+ * @param newSegment the new name
+ * @return the interface for additional requests or actions
+ */
+ Next as( Path.Segment newSegment );
+
+ /**
+ * Finish the request by specifying the name of the new child node. This method indicates that the child should be added
+ * as a new node with the given name at the end of the parents children
+ *
+ * @param newName the new name
+ * @return the interface for additional requests or actions
+ */
+ Next as( Name newName );
+ }
+
+ /**
* A component that defines a new name for a node.
*
* @param <Next> The interface that is to be returned when this request is completed
@@ -4003,14 +4338,32 @@
* @param <Next> The interface that is to be returned when this request is completed
* @author Randall Hauch
*/
- public interface Copy<Next>
- extends WithUuids<FromWorkspace<CopyTarget<Next>>>, FromWorkspace<CopyTarget<Next>>, CopyTarget<Next>, And<Copy<Next>> {
+ public interface Copy<Next> extends FromWorkspace<CopyTarget<Next>>, CopyTarget<Next>, And<Copy<Next>> {
}
public interface CopyTarget<Next> extends To<Next>, Into<Next> {
}
/**
+ * The interface for defining a branch of nodes to be cloned and the location where the clone is to be placed. Cloning a
+ * branch differs from copying a branch in that:
+ * <ol>
+ * <li>Nodes can be copied within the same workspace or to another workspace; cloned nodes must be copied from one workspace
+ * into another.</li>
+ * <li>Copied nodes always get new UUIDs; cloned nodes always maintain their UUIDs and hence must define the behavior that
+ * occurs if a node with the same UUID already exists in the new workspace.</li>
+ * <li>Nodes can be copied to a specific name under a specific parent, but can only be added as a new child node at the end of
+ * the new parent's children; nodes can be cloned to an exact location among the parent's children, replacing the existing
+ * node at that location.</li>
+ * </ol>
+ *
+ * @param <Next>
+ */
+ public interface Clone<Next> extends FromWorkspace<AsChild<Into<WithUuids<Next>>>> {
+
+ }
+
+ /**
* The interface for specifying that a node should come from a workspace other than the current workspace.
*
* @param <Next> The interface that is to be returned when this request is completed
@@ -4025,10 +4378,8 @@
* @param <Next> The interface that is to be returned when this request is completed
*/
public interface WithUuids<Next> {
- Next withNewUuids();
+ Next failingIfAnyUuidsMatch();
- Next failingIfUuidsMatch();
-
Next replacingExistingNodesWithSameUuids();
}
@@ -5797,14 +6148,12 @@
protected abstract class CopyAction<T> extends AbstractAction<T> implements Copy<T> {
protected Locations from;
protected String fromWorkspaceName;
- protected UuidConflictBehavior uuidConflictBehavior;
/*package*/CopyAction( T afterConjunction,
Location from ) {
super(afterConjunction);
this.from = new Locations(from);
this.fromWorkspaceName = Graph.this.getCurrentWorkspaceName();
- this.uuidConflictBehavior = UuidConflictBehavior.ALWAYS_CREATE_NEW_UUID;
}
public Copy<T> and( Location from ) {
@@ -5850,31 +6199,13 @@
* @param from the locations that are being copied
* @param into the parent location
* @param nameForCopy the name that should be used for the copy, or null if the name should be the same as the original
- * @param uuidConflictBehavior the behavior to be used for resolving any UUID collisions that the copy request might
- * create
* @return this object, for method chaining
*/
protected abstract T submit( String fromWorkspaceName,
Locations from,
Location into,
- Name nameForCopy,
- UuidConflictBehavior uuidConflictBehavior );
+ Name nameForCopy );
- public FromWorkspace<CopyTarget<T>> failingIfUuidsMatch() {
- this.uuidConflictBehavior = UuidConflictBehavior.THROW_EXCEPTION;
- return this;
- }
-
- public FromWorkspace<CopyTarget<T>> withNewUuids() {
- this.uuidConflictBehavior = UuidConflictBehavior.ALWAYS_CREATE_NEW_UUID;
- return this;
- }
-
- public FromWorkspace<CopyTarget<T>> replacingExistingNodesWithSameUuids() {
- this.uuidConflictBehavior = UuidConflictBehavior.REPLACE_EXISTING_NODE;
- return this;
- }
-
public CopyTarget<T> fromWorkspace( String workspaceName ) {
this.fromWorkspaceName = workspaceName;
@@ -5882,32 +6213,28 @@
}
public T into( Location into ) {
- return submit(this.fromWorkspaceName, this.from, into, null, this.uuidConflictBehavior);
+ return submit(this.fromWorkspaceName, this.from, into, null);
}
public T into( Path into ) {
- return submit(this.fromWorkspaceName, this.from, Location.create(into), null, this.uuidConflictBehavior);
+ return submit(this.fromWorkspaceName, this.from, Location.create(into), null);
}
public T into( UUID into ) {
- return submit(this.fromWorkspaceName, this.from, Location.create(into), null, this.uuidConflictBehavior);
+ return submit(this.fromWorkspaceName, this.from, Location.create(into), null);
}
public T into( Property firstIdProperty,
Property... additionalIdProperties ) {
- return submit(this.fromWorkspaceName,
- this.from,
- Location.create(firstIdProperty, additionalIdProperties),
- null,
- this.uuidConflictBehavior);
+ return submit(this.fromWorkspaceName, this.from, Location.create(firstIdProperty, additionalIdProperties), null);
}
public T into( Property into ) {
- return submit(this.fromWorkspaceName, this.from, Location.create(into), null, this.uuidConflictBehavior);
+ return submit(this.fromWorkspaceName, this.from, Location.create(into), null);
}
public T into( String into ) {
- return submit(this.fromWorkspaceName, this.from, Location.create(createPath(into)), null, this.uuidConflictBehavior);
+ return submit(this.fromWorkspaceName, this.from, Location.create(createPath(into)), null);
}
public T to( Location desiredLocation ) {
@@ -5919,11 +6246,7 @@
throw new IllegalArgumentException(GraphI18n.unableToCopyToTheRoot.text(this.from, desiredLocation));
}
Path parent = desiredPath.getParent();
- return submit(this.fromWorkspaceName,
- this.from,
- Location.create(parent),
- desiredPath.getLastSegment().getName(),
- this.uuidConflictBehavior);
+ return submit(this.fromWorkspaceName, this.from, Location.create(parent), desiredPath.getLastSegment().getName());
}
public T to( Path desiredPath ) {
@@ -5931,11 +6254,7 @@
throw new IllegalArgumentException(GraphI18n.unableToCopyToTheRoot.text(this.from, desiredPath));
}
Path parent = desiredPath.getParent();
- return submit(this.fromWorkspaceName,
- this.from,
- Location.create(parent),
- desiredPath.getLastSegment().getName(),
- this.uuidConflictBehavior);
+ return submit(this.fromWorkspaceName, this.from, Location.create(parent), desiredPath.getLastSegment().getName());
}
public T to( String desiredPath ) {
@@ -5944,6 +6263,103 @@
}
@NotThreadSafe
+ public abstract class CloneAction<T> extends AbstractAction<T> implements Clone<T> {
+ private final Location from;
+
+ /*package*/CloneAction( T afterConjunction,
+ Location from ) {
+ super(afterConjunction);
+ this.from = from;
+ }
+
+ protected abstract T submit( String fromWorkspaceName,
+ Location from,
+ String intoWorkspaceName,
+ Location into,
+ Name desiredName,
+ Segment desiredSegment,
+ boolean removeExisting );
+
+ public AsChild<Into<WithUuids<T>>> fromWorkspace( final String workspaceName ) {
+ final CloneAction<T> source = this;
+ return new AsChild<Into<WithUuids<T>>>() {
+ public Into<WithUuids<T>> as( final Name name ) {
+ return new CloneTargetAction<T>(afterConjunction(), source) {
+ @Override
+ protected T submit( Location into,
+ boolean removeExisting ) {
+ String intoWorkspaceName = getCurrentWorkspaceName();
+ return source.submit(workspaceName, from, intoWorkspaceName, into, name, null, removeExisting);
+ }
+ };
+ }
+
+ public Into<WithUuids<T>> as( final Segment segment ) {
+ return new CloneTargetAction<T>(afterConjunction(), source) {
+ @Override
+ protected T submit( Location into,
+ boolean removeExisting ) {
+ String intoWorkspaceName = getCurrentWorkspaceName();
+ return source.submit(workspaceName, from, intoWorkspaceName, into, null, segment, removeExisting);
+ }
+ };
+ }
+
+ };
+ }
+ }
+
+ @NotThreadSafe
+ public abstract class CloneTargetAction<T> extends AbstractAction<T> implements Into<WithUuids<T>> {
+ protected final CloneAction<T> source;
+
+ /*package*/CloneTargetAction( T afterConjunction,
+ CloneAction<T> source ) {
+ super(afterConjunction);
+ this.source = source;
+ }
+
+ protected abstract T submit( Location into,
+ boolean removeExisting );
+
+ public WithUuids<T> into( final Location into ) {
+ return new WithUuids<T>() {
+ public T failingIfAnyUuidsMatch() {
+ submit(into, false);
+ return and();
+ }
+
+ public T replacingExistingNodesWithSameUuids() {
+ submit(into, true);
+ return and();
+
+ }
+ };
+ }
+
+ public WithUuids<T> into( Path into ) {
+ return into(Location.create(into));
+ }
+
+ public WithUuids<T> into( UUID into ) {
+ return into(Location.create(into));
+ }
+
+ public WithUuids<T> into( Property firstIdProperty,
+ Property... additionalIdProperties ) {
+ return into(Location.create(firstIdProperty, additionalIdProperties));
+ }
+
+ public WithUuids<T> into( Property into ) {
+ return into(Location.create(into));
+ }
+
+ public WithUuids<T> into( String into ) {
+ return into(Location.create(createPath(into)));
+ }
+ }
+
+ @NotThreadSafe
protected abstract class CreateAction<T> extends AbstractAction<T> implements Create<T> {
private final String workspaceName;
private final Location parent;
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-06-27 02:54:06 UTC (rev 1065)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/GraphI18n.java 2009-06-28 00:33:32 UTC (rev 1066)
@@ -77,6 +77,8 @@
public static I18n unableToCopyToTheRoot;
public static I18n actualLocationIsNotSameAsInputLocation;
public static I18n actualLocationIsNotChildOfInputLocation;
+ public static I18n actualLocationIsNotAtCorrectChildSegment;
+ public static I18n actualLocationDoesNotHaveCorrectChildName;
public static I18n actualLocationMustHavePath;
public static I18n actualNewLocationIsNotSameAsInputLocation;
public static I18n actualNewLocationMustHavePath;
@@ -117,6 +119,7 @@
public static I18n unableToDeletePlaceholder;
public static I18n copyLimitedToBeWithinSingleSource;
public static I18n moveLimitedToBeWithinSingleSource;
+ public static I18n cloneLimitedToBeWithinSingleSource;
static {
try {
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/UuidAlreadyExistsException.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/UuidAlreadyExistsException.java 2009-06-27 02:54:06 UTC (rev 1065)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/UuidAlreadyExistsException.java 2009-06-28 00:33:32 UTC (rev 1066)
@@ -25,13 +25,12 @@
import java.util.UUID;
import org.jboss.dna.graph.GraphI18n;
-import org.jboss.dna.graph.request.CopyBranchRequest;
-import org.jboss.dna.graph.request.UuidConflictBehavior;
+import org.jboss.dna.graph.request.CloneBranchRequest;
/**
* Exception that indicates that a copy request failed because one of the UUIDs in the source branch already exists in the target
- * workspace and the {@link CopyBranchRequest#uuidConflictBehavior() UUID conflict behavior} is set to
- * {@link UuidConflictBehavior#THROW_EXCEPTION}.
+ * workspace and the {@link CloneBranchRequest#removeExisting() UUID conflict behavior} is set to throw an exception instead of
+ * removing the existing nodes.
*/
public class UuidAlreadyExistsException extends RepositorySourceException {
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/ForkRequestProcessor.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/ForkRequestProcessor.java 2009-06-27 02:54:06 UTC (rev 1065)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/ForkRequestProcessor.java 2009-06-28 00:33:32 UTC (rev 1066)
@@ -54,6 +54,7 @@
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.request.CloneBranchRequest;
import org.jboss.dna.graph.request.CloneWorkspaceRequest;
import org.jboss.dna.graph.request.CompositeRequest;
import org.jboss.dna.graph.request.CopyBranchRequest;
@@ -1262,7 +1263,7 @@
// Create the pushed-down request ...
CopyBranchRequest pushDown = new CopyBranchRequest(fromProxy.location(), fromProxy.workspaceName(), intoProxy.location(),
intoProxy.workspaceName(), request.desiredName(),
- request.nodeConflictBehavior(), request.uuidConflictBehavior());
+ request.nodeConflictBehavior());
// Create the federated request ...
FederatedRequest federatedRequest = new FederatedRequest(request);
federatedRequest.add(pushDown, sameLocation, false, fromProxy.projection(), intoProxy.projection());
@@ -1274,6 +1275,65 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CloneBranchRequest)
+ */
+ @Override
+ public void process( CloneBranchRequest request ) {
+ // Figure out where the 'from' is projected ...
+ ProjectedNode projectedFromNode = project(request.from(), request.fromWorkspace(), request, false);
+ if (projectedFromNode == null) return;
+ ProjectedNode projectedIntoNode = project(request.into(), request.intoWorkspace(), request, true);
+ if (projectedIntoNode == null) return;
+
+ // Limitation: only able to project the copy if the 'from' and 'into' are in the same source & projection ...
+ while (projectedFromNode != null) {
+ if (projectedFromNode.isProxy()) {
+ ProxyNode fromProxy = projectedFromNode.asProxy();
+ // Look for a projectedIntoNode that has the same source/projection ...
+ while (projectedIntoNode != null) {
+ if (projectedIntoNode.isProxy()) {
+ // Both are proxies, so compare the projection ...
+ ProxyNode intoProxy = projectedIntoNode.asProxy();
+ if (fromProxy.projection().getSourceName().equals(intoProxy.projection().getSourceName())) break;
+ }
+ projectedIntoNode = projectedIntoNode.next();
+ }
+ if (projectedIntoNode != null) break;
+ }
+ projectedFromNode = projectedFromNode.next();
+ }
+ if (projectedFromNode == null || projectedIntoNode == null) {
+ // The copy is not done within a single source ...
+ String msg = GraphI18n.cloneLimitedToBeWithinSingleSource.text(readable(request.from()),
+ request.fromWorkspace(),
+ readable(request.into()),
+ request.intoWorkspace(),
+ getSourceName());
+ request.setError(new UnsupportedRequestException(msg));
+ return;
+ }
+
+ ProxyNode fromProxy = projectedFromNode.asProxy();
+ ProxyNode intoProxy = projectedIntoNode.asProxy();
+ assert fromProxy.projection().getSourceName().equals(intoProxy.projection().getSourceName());
+ boolean sameLocation = fromProxy.isSameLocationAsOriginal() && intoProxy.isSameLocationAsOriginal();
+
+ // Create the pushed-down request ...
+ CloneBranchRequest pushDown = new CloneBranchRequest(fromProxy.location(), fromProxy.workspaceName(),
+ intoProxy.location(), intoProxy.workspaceName(),
+ request.desiredName(), request.desiredSegment(),
+ request.removeExisting());
+ // Create the federated request ...
+ FederatedRequest federatedRequest = new FederatedRequest(request);
+ federatedRequest.add(pushDown, sameLocation, false, fromProxy.projection(), intoProxy.projection());
+
+ // Submit the requests for processing and then STOP ...
+ submit(federatedRequest);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.MoveBranchRequest)
*/
@Override
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/JoinMirrorRequestProcessor.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/JoinMirrorRequestProcessor.java 2009-06-27 02:54:06 UTC (rev 1065)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/JoinMirrorRequestProcessor.java 2009-06-28 00:33:32 UTC (rev 1066)
@@ -33,6 +33,7 @@
import org.jboss.dna.graph.property.Name;
import org.jboss.dna.graph.property.Property;
import org.jboss.dna.graph.request.CacheableRequest;
+import org.jboss.dna.graph.request.CloneBranchRequest;
import org.jboss.dna.graph.request.CloneWorkspaceRequest;
import org.jboss.dna.graph.request.CopyBranchRequest;
import org.jboss.dna.graph.request.CreateNodeRequest;
@@ -173,8 +174,7 @@
*/
@Override
public void process( ReadNextBlockOfChildrenRequest request ) {
- ReadNextBlockOfChildrenRequest source = (ReadNextBlockOfChildrenRequest)federatedRequest.getFirstProjectedRequest()
- .getRequest();
+ ReadNextBlockOfChildrenRequest source = (ReadNextBlockOfChildrenRequest)federatedRequest.getFirstProjectedRequest().getRequest();
if (checkErrorOrCancel(request, source)) return;
request.setActualLocationOfStartingAfterNode(source.getActualLocationOfStartingAfterNode());
for (Location childInSource : source.getChildren()) {
@@ -317,6 +317,18 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CloneBranchRequest)
+ */
+ @Override
+ public void process( CloneBranchRequest request ) {
+ CloneBranchRequest source = (CloneBranchRequest)federatedRequest.getFirstProjectedRequest().getRequest();
+ if (checkErrorOrCancel(request, source)) return;
+ request.setActualLocations(source.getActualLocationBefore(), source.getActualLocationAfter());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.DeleteBranchRequest)
*/
@Override
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/JoinRequestProcessor.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/JoinRequestProcessor.java 2009-06-27 02:54:06 UTC (rev 1065)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/JoinRequestProcessor.java 2009-06-28 00:33:32 UTC (rev 1066)
@@ -45,6 +45,7 @@
import org.jboss.dna.graph.property.PropertyFactory;
import org.jboss.dna.graph.property.ValueComparators;
import org.jboss.dna.graph.request.CacheableRequest;
+import org.jboss.dna.graph.request.CloneBranchRequest;
import org.jboss.dna.graph.request.CloneWorkspaceRequest;
import org.jboss.dna.graph.request.CopyBranchRequest;
import org.jboss.dna.graph.request.CreateNodeRequest;
@@ -902,6 +903,24 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CloneBranchRequest)
+ */
+ @Override
+ public void process( CloneBranchRequest request ) {
+ ProjectedRequest projected = federatedRequest.getFirstProjectedRequest();
+ assert !projected.hasNext();
+ CloneBranchRequest source = (CloneBranchRequest)projected.getRequest();
+ if (checkErrorOrCancel(request, source)) return;
+ Location locationBefore = source.getActualLocationBefore();
+ Location locationAfter = source.getActualLocationBefore();
+ locationBefore = projectToFederated(request.from(), projected.getProjection(), locationBefore, request);
+ locationAfter = projectToFederated(request.into(), projected.getSecondProjection(), locationAfter, request);
+ request.setActualLocations(locationBefore, locationAfter);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.MoveBranchRequest)
*/
@Override
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/AbstractMapWorkspace.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/AbstractMapWorkspace.java 2009-06-27 02:54:06 UTC (rev 1065)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/AbstractMapWorkspace.java 2009-06-28 00:33:32 UTC (rev 1066)
@@ -45,8 +45,8 @@
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.UuidConflictBehavior;
/**
* A default implementation of {@link MapWorkspace} that only requires the user to implement some simple, map-like operations.
@@ -415,8 +415,6 @@
* @param newParent the parent where the copy is to be placed; may not be null
* @param desiredName the desired name for the node; if null, the name will be obtained from the original node
* @param recursive true if the copy should be recursive
- * @param uuidConflictBehavior the behavior to use if a UUID in the branch rooted at {@code original} already exists in the
- * new workspace
* @return the new node, which is the top of the new subgraph
*/
public MapNode copyNode( ExecutionContext context,
@@ -424,48 +422,8 @@
MapWorkspace newWorkspace,
MapNode newParent,
Name desiredName,
- boolean recursive,
- UuidConflictBehavior uuidConflictBehavior ) throws UuidAlreadyExistsException {
- Map<UUID, UUID> copyMap = null;
- Set<UUID> uuidsInFromBranch = null;
-
- switch (uuidConflictBehavior) {
- case ALWAYS_CREATE_NEW_UUID:
-
- /*
- * The copyNode method uses the presence of a non-null map as an indicator that new UUIDs should be created
- * during the copy operation
- */
- copyMap = new HashMap<UUID, UUID>();
- break;
- case REPLACE_EXISTING_NODE:
- uuidsInFromBranch = getUuidsUnderNode(original);
-
- for (UUID uuid : uuidsInFromBranch) {
- MapNode existing;
- if (null != (existing = newWorkspace.getNode(uuid))) {
- newWorkspace.removeNode(context, existing);
- }
- }
- break;
- case THROW_EXCEPTION:
- uuidsInFromBranch = getUuidsUnderNode(original);
- PathFactory pathFactory = context.getValueFactories().getPathFactory();
- for (UUID uuid : uuidsInFromBranch) {
- MapNode existing;
- if (null != (existing = newWorkspace.getNode(uuid))) {
- NamespaceRegistry namespaces = context.getNamespaceRegistry();
- String path = newWorkspace.pathFor(pathFactory, existing).getString(namespaces);
- throw new UuidAlreadyExistsException(repository.getSourceName(), uuid, path, newWorkspace.getName());
- }
- }
- break;
-
- default:
- throw new IllegalStateException("Unexpected UUID conflict behavior: " + uuidConflictBehavior);
- }
-
- return copyNode(context, original, newWorkspace, newParent, desiredName, true, copyMap);
+ boolean recursive ) {
+ return copyNode(context, original, newWorkspace, newParent, desiredName, true, new HashMap<UUID, UUID>());
}
/**
@@ -483,12 +441,12 @@
* @return the new node, which is the top of the new subgraph
*/
protected MapNode copyNode( ExecutionContext context,
- MapNode original,
- MapWorkspace newWorkspace,
- MapNode newParent,
- Name desiredName,
- boolean recursive,
- Map<UUID, UUID> oldToNewUuids ) {
+ MapNode original,
+ MapWorkspace newWorkspace,
+ MapNode newParent,
+ Name desiredName,
+ boolean recursive,
+ Map<UUID, UUID> oldToNewUuids ) {
assert context != null;
assert original != null;
assert newParent != null;
@@ -557,8 +515,83 @@
}
/**
- * Returns all of the UUIDs in the branch rooted at {@code node}
+ * {@inheritDoc}
*
+ * @see MapWorkspace#cloneNode(ExecutionContext, MapNode, MapWorkspace, MapNode, Name, Segment, boolean)
+ */
+ public MapNode cloneNode( ExecutionContext context,
+ MapNode original,
+ MapWorkspace newWorkspace,
+ MapNode newParent,
+ Name desiredName,
+ Segment desiredSegment,
+ boolean removeExisting ) throws UuidAlreadyExistsException {
+ assert context != null;
+ assert original != null;
+ assert newWorkspace != null;
+ assert newParent != null;
+
+ Set<UUID> uuidsInFromBranch = getUuidsUnderNode(original);
+ MapNode existing;
+
+ // TODO: Need to handle removing/throwing root node
+ if (removeExisting) {
+
+ for (UUID uuid : uuidsInFromBranch) {
+ if (null != (existing = newWorkspace.getNode(uuid))) {
+ newWorkspace.removeNode(context, existing);
+ }
+ }
+ } else {
+ PathFactory pathFactory = context.getValueFactories().getPathFactory();
+ uuidsInFromBranch.add(original.getUuid());
+ for (UUID uuid : uuidsInFromBranch) {
+ if (null != (existing = newWorkspace.getNode(uuid))) {
+ NamespaceRegistry namespaces = context.getNamespaceRegistry();
+ String path = newWorkspace.pathFor(pathFactory, existing).getString(namespaces);
+ throw new UuidAlreadyExistsException(repository.getSourceName(), uuid, path, newWorkspace.getName());
+ }
+ }
+ }
+
+ if (desiredSegment != null) {
+ MapNode newRoot = null;
+ for (MapNode child : newParent.getChildren()) {
+ if (desiredSegment.equals(child.getName())) {
+ newRoot = child;
+ break;
+ }
+ }
+
+ assert newRoot != null;
+
+ newRoot.getProperties().clear();
+ for (MapNode child : newRoot.getChildren()) {
+ newWorkspace.removeNode(context, child);
+ }
+
+ for (Property property : original.getProperties().values()) {
+ newRoot.setProperty(property);
+ }
+
+ for (MapNode child : original.getChildren()) {
+ copyNode(context, child, newWorkspace, newRoot, null, true, (Map<UUID, UUID>)null);
+ }
+ return newRoot;
+ }
+
+ existing = newWorkspace.getNode(original.getUuid());
+
+ if (existing != null) {
+ newWorkspace.removeNode(context, existing);
+ }
+ return copyNode(context, original, newWorkspace, newParent, desiredName, true, (Map<UUID, UUID>)null);
+ }
+
+ /**
+ * Returns all of the UUIDs in the branch rooted at {@code node}. The UUID of {@code node} will not be included in the set of
+ * returned UUIDs.
+ *
* @param node the root of the branch
* @return all of the UUIDs in the branch rooted at {@code node}
*/
@@ -571,9 +604,8 @@
private void uuidsUnderNode( MapNode node,
Set<UUID> accumulator ) {
- accumulator.add(node.getUuid());
-
for (MapNode child : node.getChildren()) {
+ accumulator.add(child.getUuid());
uuidsUnderNode(child, accumulator);
}
}
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepository.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepository.java 2009-06-27 02:54:06 UTC (rev 1065)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepository.java 2009-06-28 00:33:32 UTC (rev 1066)
@@ -32,7 +32,6 @@
import net.jcip.annotations.GuardedBy;
import org.jboss.dna.common.util.CheckArg;
import org.jboss.dna.graph.ExecutionContext;
-import org.jboss.dna.graph.request.UuidConflictBehavior;
import org.jboss.dna.graph.request.CreateWorkspaceRequest.CreateConflictBehavior;
/**
@@ -249,7 +248,7 @@
// Loop over each child and call this method to copy the immediate children (and below).
// Note that this makes the copy have the same UUID as the original.
for (MapNode originalNode : origRoot.getChildren()) {
- original.copyNode(context, originalNode, workspace, root, originalNode.getName().getName(), true, UuidConflictBehavior.REPLACE_EXISTING_NODE);
+ original.cloneNode(context, originalNode, workspace, root, originalNode.getName().getName(), null, true);
}
}
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRequestProcessor.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRequestProcessor.java 2009-06-27 02:54:06 UTC (rev 1065)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRequestProcessor.java 2009-06-28 00:33:32 UTC (rev 1066)
@@ -44,6 +44,7 @@
import org.jboss.dna.graph.property.Property;
import org.jboss.dna.graph.property.PropertyFactory;
import org.jboss.dna.graph.property.Path.Segment;
+import org.jboss.dna.graph.request.CloneBranchRequest;
import org.jboss.dna.graph.request.CloneWorkspaceRequest;
import org.jboss.dna.graph.request.CopyBranchRequest;
import org.jboss.dna.graph.request.CreateNodeRequest;
@@ -62,7 +63,6 @@
/**
* The default implementation of the {@link RequestProcessor} for map repositories.
- *
*/
public class MapRequestProcessor extends RequestProcessor {
private final PathFactory pathFactory;
@@ -70,8 +70,8 @@
private final MapRepository repository;
public MapRequestProcessor( ExecutionContext context,
- MapRepository repository,
- RepositoryContext repositoryContext ) {
+ MapRepository repository,
+ RepositoryContext repositoryContext ) {
super(repository.getSourceName(), context, repositoryContext != null ? repositoryContext.getObserver() : null);
this.repository = repository;
pathFactory = context.getValueFactories().getPathFactory();
@@ -119,6 +119,36 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CloneBranchRequest)
+ */
+ @Override
+ public void process( CloneBranchRequest request ) {
+ MapWorkspace workspace = getWorkspace(request, request.fromWorkspace());
+ MapWorkspace newWorkspace = getWorkspace(request, request.intoWorkspace());
+ if (workspace == null || newWorkspace == null) return;
+ MapNode node = getTargetNode(workspace, request, request.from());
+ if (node == null) return;
+
+ // Look up the new parent, which must exist ...
+ Path newParentPath = request.into().getPath();
+ MapNode newParent = newWorkspace.getNode(newParentPath);
+ MapNode newNode = workspace.cloneNode(getExecutionContext(),
+ node,
+ newWorkspace,
+ newParent,
+ request.desiredName(),
+ request.desiredSegment(),
+ request.removeExisting());
+ Path newPath = getExecutionContext().getValueFactories().getPathFactory().create(newParentPath, newNode.getName());
+ Location oldLocation = getActualLocation(request.from().getPath(), node);
+ Location newLocation = Location.create(newPath, newNode.getUuid());
+ request.setActualLocations(oldLocation, newLocation);
+ recordChange(request);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CopyBranchRequest)
*/
@Override
@@ -133,13 +163,7 @@
Path newParentPath = request.into().getPath();
Name desiredName = request.desiredName();
MapNode newParent = newWorkspace.getNode(newParentPath);
- MapNode newNode = workspace.copyNode(getExecutionContext(),
- node,
- newWorkspace,
- newParent,
- desiredName,
- true,
- request.uuidConflictBehavior());
+ MapNode newNode = workspace.copyNode(getExecutionContext(), node, newWorkspace, newParent, desiredName, true);
Path newPath = getExecutionContext().getValueFactories().getPathFactory().create(newParentPath, newNode.getName());
Location oldLocation = getActualLocation(request.from().getPath(), node);
Location newLocation = Location.create(newPath, newNode.getUuid());
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapWorkspace.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapWorkspace.java 2009-06-27 02:54:06 UTC (rev 1065)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapWorkspace.java 2009-06-28 00:33:32 UTC (rev 1066)
@@ -29,7 +29,6 @@
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.request.UuidConflictBehavior;
/**
* The {@code MapWorkspace} defines the required methods for workspaces in a {@link MapRepository map repository}. By default, a
@@ -138,20 +137,44 @@
* @param newParent the parent where the copy is to be placed; may not be null
* @param desiredName the desired name for the node; if null, the name will be obtained from the original node
* @param recursive true if the copy should be recursive
- * @param uuidConflictBehavior the behavior to use to manage UUIDs from the source into the target
* @return the new node, which is the top of the new subgraph
- * @throws UuidAlreadyExistsException if {@code uuidConflictBehavior} is true and and a UUID in the source tree alread exists
- * in the new workspace
*/
MapNode copyNode( ExecutionContext context,
MapNode original,
MapWorkspace newWorkspace,
MapNode newParent,
Name desiredName,
- boolean recursive,
- UuidConflictBehavior uuidConflictBehavior ) throws UuidAlreadyExistsException;
+ boolean recursive );
/**
+ * This should clone the subgraph given by the original node and place the cloned 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 the context; may not be null
+ * @param original the node to be cloned; may not be null
+ * @param newWorkspace the workspace containing the new parent node; may not be null
+ * @param newParent the parent where the clone is to be placed; may not be null
+ * @param desiredName the desired name for the node; if null, the name will be calculated from {@code desiredSegment}; Exactly
+ * one of {@code desiredSegment} and {@code desiredName} must be non-null
+ * @param desiredSegment the exact segment at which the clone should be rooted; if null, the name will be inferred from
+ * {@code desiredName}; Exactly one of {@code desiredSegment} and {@code desiredName} must be non-null
+ * @param removeExisting true if existing nodes in the new workspace with the same UUIDs as nodes in the branch rooted at
+ * {@code original} should be removed; if false, a UuidAlreadyExistsException will be thrown if a UUID conflict is
+ * detected
+ * @return the new node, which is the top of the new subgraph
+ * @throws UuidAlreadyExistsException if {@code removeExisting} is true and and a UUID in the source tree already exists in
+ * the new workspace
+ */
+ MapNode cloneNode( ExecutionContext context,
+ MapNode original,
+ MapWorkspace newWorkspace,
+ MapNode newParent,
+ Name desiredName,
+ Path.Segment desiredSegment,
+ boolean removeExisting ) throws UuidAlreadyExistsException;
+
+ /**
* Find the lowest existing node along the path.
*
* @param path the path to the node; may not be null
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/BatchRequestBuilder.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/BatchRequestBuilder.java 2009-06-27 02:54:06 UTC (rev 1065)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/BatchRequestBuilder.java 2009-06-28 00:33:32 UTC (rev 1066)
@@ -572,8 +572,7 @@
String intoWorkspace,
Name nameForCopy ) {
return add(new CopyBranchRequest(from, fromWorkspace, into, intoWorkspace, nameForCopy,
- CopyBranchRequest.DEFAULT_NODE_CONFLICT_BEHAVIOR,
- UuidConflictBehavior.ALWAYS_CREATE_NEW_UUID));
+ CopyBranchRequest.DEFAULT_NODE_CONFLICT_BEHAVIOR));
}
/**
@@ -587,9 +586,6 @@
* used
* @param conflictBehavior the expected behavior if an equivalently-named child already exists at the <code>into</code>
* location, or null if the default node conflict behavior should be used
- * @param uuidConflictBehavior the expected behavior if a node with the same UUID as any of the nodes in the branch under the
- * {@code from} location in the {@code fromWorkspace} workspace already exists in the workspace, or null if the default
- * UUID conflict behavior should be used
* @return this builder for method chaining; never null
* @throws IllegalArgumentException if either of the locations or workspace names are null
*/
@@ -598,12 +594,9 @@
Location into,
String intoWorkspace,
Name nameForCopy,
- NodeConflictBehavior conflictBehavior,
- UuidConflictBehavior uuidConflictBehavior) {
+ NodeConflictBehavior conflictBehavior ) {
if (conflictBehavior == null) conflictBehavior = CopyBranchRequest.DEFAULT_NODE_CONFLICT_BEHAVIOR;
- if (uuidConflictBehavior == null) uuidConflictBehavior = CopyBranchRequest.DEFAULT_UUID_CONFLICT_BEHAVIOR;
- return add(new CopyBranchRequest(from, fromWorkspace, into, intoWorkspace, nameForCopy, conflictBehavior,
- uuidConflictBehavior));
+ return add(new CopyBranchRequest(from, fromWorkspace, into, intoWorkspace, nameForCopy, conflictBehavior));
}
/**
Added: trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CloneBranchRequest.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CloneBranchRequest.java (rev 0)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CloneBranchRequest.java 2009-06-28 00:33:32 UTC (rev 1066)
@@ -0,0 +1,313 @@
+package org.jboss.dna.graph.request;
+
+import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.common.util.HashCode;
+import org.jboss.dna.graph.GraphI18n;
+import org.jboss.dna.graph.Location;
+import org.jboss.dna.graph.connector.UuidAlreadyExistsException;
+import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.Path;
+
+/**
+ * Instruction that a branch be cloned from one workspace into another. Cloning a branch differs from cloning a branch in that:
+ * <ol>
+ * <li>Nodes can be cloned within the same workspace or to another workspace; cloned nodes must be cloned from one workspace into
+ * another.</li>
+ * <li>Copied nodes always get new UUIDs; cloned nodes always maintain their UUIDs and hence must define the behavior that occurs
+ * if a node with the same UUID already exists in the new workspace.</li>
+ * <li>Nodes can be cloned to a specific name under a specific parent, but can only be added as a new child node at the end of the
+ * new parent's children; nodes can be cloned to an exact location among the parent's children, replacing the existing node at
+ * that location.</li>
+ * </ol>
+ *
+ * @author Brian Carothers
+ */
+public class CloneBranchRequest extends ChangeRequest {
+
+ private static final long serialVersionUID = 1L;
+
+ private final String fromWorkspace;
+ private final String intoWorkspace;
+ private final Location from;
+ private final Location into;
+ private final Name desiredName;
+ private final Path.Segment desiredSegment;
+ private final boolean removeExisting;
+ private Location actualFromLocation;
+ private Location actualIntoLocation;
+
+ /**
+ * Create a request to clone a branch to another.
+ *
+ * @param from the location of the top node in the existing branch that is to be cloned
+ * @param fromWorkspace the name of the workspace where the <code>from</code> node exists
+ * @param into the location of the existing node into which the clone should be placed
+ * @param intoWorkspace the name of the workspace where the <code>into</code> node is to be cloned
+ * @param nameForClone the desired name for the node that results from the clone, or null if the name of the original should
+ * be used
+ * @param exactSegmentForClone the exact {@link Path.Segment segment} at which the cloned tree should be rooted.
+ * @param removeExisting whether any nodes in the intoWorkspace with the same UUIDs as a node in the source branch should be
+ * removed (if true) or a {@link UuidAlreadyExistsException} should be thrown.
+ * @throws IllegalArgumentException if any of the parameters are null except for {@code nameForClone} or {@code
+ * exactSegmentForClone}. Exactly one of {@code nameForClone} and {@code exactSegmentForClone} must be null.
+ */
+ public CloneBranchRequest( Location from,
+ String fromWorkspace,
+ Location into,
+ String intoWorkspace,
+ Name nameForClone,
+ Path.Segment exactSegmentForClone,
+ boolean removeExisting ) {
+ CheckArg.isNotNull(from, "from");
+ CheckArg.isNotNull(into, "into");
+ CheckArg.isNotNull(fromWorkspace, "fromWorkspace");
+ CheckArg.isNotNull(intoWorkspace, "intoWorkspace");
+ CheckArg.isNotSame(from, fromWorkspace, into, intoWorkspace);
+ assert nameForClone == null ? exactSegmentForClone != null : exactSegmentForClone == null;
+ this.from = from;
+ this.into = into;
+ this.fromWorkspace = fromWorkspace;
+ this.intoWorkspace = intoWorkspace;
+ this.desiredName = nameForClone;
+ this.desiredSegment = exactSegmentForClone;
+ this.removeExisting = removeExisting;
+ }
+
+ /**
+ * Get the location defining the top of the branch to be cloned
+ *
+ * @return the from location; never null
+ */
+ public Location from() {
+ return from;
+ }
+
+ /**
+ * Get the location defining the parent where the new clone is to be placed
+ *
+ * @return the to location; never null
+ */
+ public Location into() {
+ return into;
+ }
+
+ /**
+ * Get the name of the workspace containing the branch to be cloned.
+ *
+ * @return the name of the workspace containing the branch to be cloned; never null
+ */
+ public String fromWorkspace() {
+ return fromWorkspace;
+ }
+
+ /**
+ * Get the name of the workspace where the clone is to be placed
+ *
+ * @return the name of the workspace where the clone is to be placed; never null
+ */
+ public String intoWorkspace() {
+ return intoWorkspace;
+ }
+
+ /**
+ * Determine whether this clone operation is within the same workspace.
+ *
+ * @return true if this operation is to be performed within the same workspace, or false if the workspace of the
+ * {@link #from() original} is different than that of the {@link #into() clone}
+ */
+ public boolean isSameWorkspace() {
+ return false;
+ }
+
+ /**
+ * Get the name of the clone if it is to be different than that of the original.
+ *
+ * @return the desired name of the clone, or null if an {@link #desiredSegment() exact segment} is specified.
+ */
+ public Name desiredName() {
+ return desiredName;
+ }
+
+ /**
+ * Get the exact {@link Path.Segment segment} at which the clone should be rooted
+ *
+ * @return the desired segment of the clone, or null if the desired name should be used to generate a new child node for the
+ * {@code into} location
+ */
+ public Path.Segment desiredSegment() {
+ return desiredSegment;
+ }
+
+ /**
+ * Gets whether the clone should remove existing nodes in the {@link #intoWorkspace new workspace} with the same UUID as any
+ * of the nodes in the source branch or should throw an exception if such conflict is detected.
+ *
+ * @return whether the clone should remove existing nodes in the {@link #intoWorkspace new workspace} with the same UUID as
+ * any of the nodes in the source branch or should throw an exception if such conflict is detected; true indicates
+ * that the nodes should be removed and false indicates that an exception should be thrown
+ */
+ public boolean removeExisting() {
+ return removeExisting;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.request.Request#isReadOnly()
+ */
+ @Override
+ public boolean isReadOnly() {
+ return false;
+ }
+
+ /**
+ * Sets the actual and complete location of the node being renamed and its new location. This method must be called when
+ * processing the request, and the actual location must have a {@link Location#getPath() path}.
+ *
+ * @param fromLocation the actual location of the node being cloned
+ * @param intoLocation the actual location of the new clone of the node
+ * @throws IllegalArgumentException if the either location is null; if the old location does not represent the
+ * {@link Location#isSame(Location) same location} as the {@link #from() from location}; if the new location does not
+ * represent the {@link Location#isSame(Location) same location} as the {@link #into() into location}; if the either
+ * location does not have a path
+ * @throws IllegalStateException if the request is frozen
+ */
+ public void setActualLocations( Location fromLocation,
+ Location intoLocation ) {
+ checkNotFrozen();
+ if (!from.isSame(fromLocation)) { // not same if actual is null
+ throw new IllegalArgumentException(GraphI18n.actualLocationIsNotSameAsInputLocation.text(fromLocation, from));
+ }
+ CheckArg.isNotNull(intoLocation, "intoLocation");
+ assert fromLocation != null;
+ assert intoLocation != null;
+ if (!fromLocation.hasPath()) {
+ throw new IllegalArgumentException(GraphI18n.actualOldLocationMustHavePath.text(fromLocation));
+ }
+ if (!intoLocation.hasPath()) {
+ throw new IllegalArgumentException(GraphI18n.actualNewLocationMustHavePath.text(intoLocation));
+ }
+ // The 'into' should be the parent of the 'newLocation' ...
+ if (into.hasPath() && !intoLocation.getPath().getParent().equals(into.getPath())) {
+ throw new IllegalArgumentException(GraphI18n.actualLocationIsNotChildOfInputLocation.text(intoLocation, into));
+ }
+
+ if (desiredSegment != null && !desiredSegment.equals(intoLocation.getPath().getLastSegment())) {
+ throw new IllegalArgumentException(GraphI18n.actualLocationIsNotAtCorrectChildSegment.text(intoLocation,
+ desiredSegment));
+ }
+
+ if (desiredName != null && !desiredName.equals(intoLocation.getPath().getLastSegment().getName())) {
+ throw new IllegalArgumentException(
+ GraphI18n.actualLocationDoesNotHaveCorrectChildName.text(intoLocation, desiredName));
+ }
+
+ this.actualFromLocation = fromLocation;
+ this.actualIntoLocation = intoLocation;
+ }
+
+ /**
+ * Get the actual location of the node before being cloned.
+ *
+ * @return the actual location of the node before being moved, or null if the actual location was not set
+ */
+ public Location getActualLocationBefore() {
+ return actualFromLocation;
+ }
+
+ /**
+ * Get the actual location of the node after being cloned.
+ *
+ * @return the actual location of the node after being cloned, or null if the actual location was not set
+ */
+ public Location getActualLocationAfter() {
+ return actualIntoLocation;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.request.ChangeRequest#changes(java.lang.String, org.jboss.dna.graph.property.Path)
+ */
+ @Override
+ public boolean changes( String workspace,
+ Path path ) {
+ return into.hasPath() && into.getPath().isAtOrBelow(path);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.request.ChangeRequest#changedLocation()
+ */
+ @Override
+ public Location changedLocation() {
+ return into;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.request.ChangeRequest#changedWorkspace()
+ */
+ @Override
+ public String changedWorkspace() {
+ return intoWorkspace();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return HashCode.compute(from, fromWorkspace, into, intoWorkspace);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.request.Request#cancel()
+ */
+ @Override
+ public void cancel() {
+ super.cancel();
+ this.actualFromLocation = null;
+ this.actualIntoLocation = null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (this.getClass().isInstance(obj)) {
+ CloneBranchRequest that = (CloneBranchRequest)obj;
+ if (!this.from().equals(that.from())) return false;
+ if (!this.into().equals(that.into())) return false;
+ if (!this.fromWorkspace.equals(that.fromWorkspace)) return false;
+ if (!this.intoWorkspace.equals(that.intoWorkspace)) return false;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ if (desiredName != null) {
+ return "clone branch " + from() + " in the \"" + fromWorkspace + "\" workspace into " + into() + " with name "
+ + desiredName + " in the \"" + intoWorkspace + "\" workspace";
+ }
+ return "clone branch " + from() + " in the \"" + fromWorkspace + "\" workspace into " + into() + " in the \""
+ + intoWorkspace + "\" workspace as child " + desiredSegment();
+ }
+}
Property changes on: trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CloneBranchRequest.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CopyBranchRequest.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CopyBranchRequest.java 2009-06-27 02:54:06 UTC (rev 1065)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CopyBranchRequest.java 2009-06-28 00:33:32 UTC (rev 1066)
@@ -33,16 +33,18 @@
/**
* Instruction that a branch be copied from one location into another. This request can copy a branch in one workspace into
- * another workspace, or it can copy a branch in the same workspace.
+ * another workspace, or it can copy a branch in the same workspace. Copying a branch always results in the generation of new
+ * UUIDs for the copied nodes. {@link CloneBranchRequest Cloning a branch} provides functionality similar to copy, but with the
+ * ability to preserve UUIDs in the move.
*
* @author Randall Hauch
+ * @see CloneBranchRequest
*/
public class CopyBranchRequest extends ChangeRequest {
private static final long serialVersionUID = 1L;
public static final NodeConflictBehavior DEFAULT_NODE_CONFLICT_BEHAVIOR = NodeConflictBehavior.APPEND;
- public static final UuidConflictBehavior DEFAULT_UUID_CONFLICT_BEHAVIOR = UuidConflictBehavior.ALWAYS_CREATE_NEW_UUID;
private final Location from;
private final Location into;
@@ -50,7 +52,6 @@
private final String intoWorkspace;
private final Name desiredNameForCopy;
private final NodeConflictBehavior nodeConflictBehavior;
- private final UuidConflictBehavior uuidConflictBehavior;
private Location actualFromLocation;
private Location actualIntoLocation;
@@ -68,7 +69,7 @@
String fromWorkspace,
Location into,
String intoWorkspace ) {
- this(from, fromWorkspace, into, intoWorkspace, null, DEFAULT_NODE_CONFLICT_BEHAVIOR, DEFAULT_UUID_CONFLICT_BEHAVIOR);
+ this(from, fromWorkspace, into, intoWorkspace, null, DEFAULT_NODE_CONFLICT_BEHAVIOR);
}
/**
@@ -87,7 +88,7 @@
Location into,
String intoWorkspace,
Name nameForCopy ) {
- this(from, fromWorkspace, into, intoWorkspace, nameForCopy, DEFAULT_NODE_CONFLICT_BEHAVIOR, DEFAULT_UUID_CONFLICT_BEHAVIOR);
+ this(from, fromWorkspace, into, intoWorkspace, nameForCopy, DEFAULT_NODE_CONFLICT_BEHAVIOR);
}
/**
@@ -101,8 +102,6 @@
* used
* @param nodeConflictBehavior the expected behavior if an equivalently-named child already exists at the <code>into</code>
* location
- * @param uuidConflictBehavior the expected behavior if a node with the same UUID as any of the nodes in the branch under the
- * {@code from} location in the {@code fromWorkspace} workspace already exists in the workspace
* @throws IllegalArgumentException if any of the parameters are null
*/
public CopyBranchRequest( Location from,
@@ -110,21 +109,18 @@
Location into,
String intoWorkspace,
Name nameForCopy,
- NodeConflictBehavior nodeConflictBehavior,
- UuidConflictBehavior uuidConflictBehavior ) {
+ NodeConflictBehavior nodeConflictBehavior ) {
CheckArg.isNotNull(from, "from");
CheckArg.isNotNull(into, "into");
CheckArg.isNotNull(fromWorkspace, "fromWorkspace");
CheckArg.isNotNull(intoWorkspace, "intoWorkspace");
CheckArg.isNotNull(nodeConflictBehavior, "nodeConflictBehavior");
- CheckArg.isNotNull(uuidConflictBehavior, "uuidConflictBehavior");
this.from = from;
this.into = into;
this.fromWorkspace = fromWorkspace;
this.intoWorkspace = intoWorkspace;
this.desiredNameForCopy = nameForCopy;
this.nodeConflictBehavior = nodeConflictBehavior;
- this.uuidConflictBehavior = uuidConflictBehavior;
}
/**
@@ -203,15 +199,6 @@
}
/**
- * Get the expected behavior when one of the nodes in the branch has the same UUID as an existing node in the workspace.
- *
- * @return the behavior specification
- */
- public UuidConflictBehavior uuidConflictBehavior() {
- return uuidConflictBehavior;
- }
-
- /**
* Sets the actual and complete location of the node being renamed and its new location. This method must be called when
* processing the request, and the actual location must have a {@link Location#getPath() path}.
*
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/RequestBuilder.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/RequestBuilder.java 2009-06-27 02:54:06 UTC (rev 1065)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/RequestBuilder.java 2009-06-28 00:33:32 UTC (rev 1066)
@@ -28,6 +28,7 @@
import java.util.Map;
import org.jboss.dna.graph.Location;
import org.jboss.dna.graph.NodeConflictBehavior;
+import org.jboss.dna.graph.connector.UuidAlreadyExistsException;
import org.jboss.dna.graph.property.Name;
import org.jboss.dna.graph.property.Path;
import org.jboss.dna.graph.property.Property;
@@ -432,8 +433,6 @@
* used
* @param conflictBehavior the expected behavior if an equivalently-named child already exists at the <code>into</code>
* location, or null if the default conflict behavior should be used
- * @param uuidConflictBehavior the expected behavior if a node with the same UUID as any of the nodes in the branch under the
- * {@code from} location in the {@code fromWorkspace} workspace already exists in the workspace
* @return the request; never null
* @throws IllegalArgumentException if either of the locations or workspace names are null
*/
@@ -442,14 +441,39 @@
Location into,
String intoWorkspace,
Name nameForCopy,
- NodeConflictBehavior conflictBehavior,
- UuidConflictBehavior uuidConflictBehavior) {
+ NodeConflictBehavior conflictBehavior ) {
if (conflictBehavior == null) conflictBehavior = CopyBranchRequest.DEFAULT_NODE_CONFLICT_BEHAVIOR;
- return process(new CopyBranchRequest(from, fromWorkspace, into, intoWorkspace, nameForCopy, conflictBehavior,
- uuidConflictBehavior));
+ return process(new CopyBranchRequest(from, fromWorkspace, into, intoWorkspace, nameForCopy, conflictBehavior));
}
/**
+ * Add a request to clone a branch to another.
+ *
+ * @param from the location of the top node in the existing branch that is to be cloned
+ * @param fromWorkspace the name of the workspace where the <code>from</code> node exists
+ * @param into the location of the existing node into which the clone should be placed
+ * @param intoWorkspace the name of the workspace where the <code>into</code> node is to be cloned
+ * @param nameForClone the desired name for the node that results from the clone, or null if the name of the original should
+ * be used
+ * @param exactSegmentForClone the exact {@link Path.Segment segment} at which the cloned tree should be rooted.
+ * @param removeExisting whether any nodes in the intoWorkspace with the same UUIDs as a node in the source branch should be
+ * removed (if true) or a {@link UuidAlreadyExistsException} should be thrown.
+ * @return the request; never null
+ * @throws IllegalArgumentException if any of the parameters are null except for {@code nameForClone} or {@code
+ * exactSegmentForClone}. Exactly one of {@code nameForClone} and {@code exactSegmentForClone} must be null.
+ */
+ public CloneBranchRequest cloneBranch( Location from,
+ String fromWorkspace,
+ Location into,
+ String intoWorkspace,
+ Name nameForClone,
+ Path.Segment exactSegmentForClone,
+ boolean removeExisting ) {
+ return process(new CloneBranchRequest(from, fromWorkspace, into, intoWorkspace, nameForClone, exactSegmentForClone,
+ removeExisting));
+ }
+
+ /**
* Create a request to move a branch from one location into another.
*
* @param from the location of the top node in the existing branch that is to be moved
Deleted: trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/UuidConflictBehavior.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/UuidConflictBehavior.java 2009-06-27 02:54:06 UTC (rev 1065)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/UuidConflictBehavior.java 2009-06-28 00:33:32 UTC (rev 1066)
@@ -1,14 +0,0 @@
-package org.jboss.dna.graph.request;
-
-/**
- * An enumeration used by {@link CopyBranchRequest} for the choice of handling duplicate UUIDs, such as when a node is to be
- * copied to another location where a node already exists.
- *
- * @author Randall Hauch
- */
-public enum UuidConflictBehavior {
-
- ALWAYS_CREATE_NEW_UUID,
- REPLACE_EXISTING_NODE,
- THROW_EXCEPTION;
-}
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/processor/LoggingRequestProcessor.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/processor/LoggingRequestProcessor.java 2009-06-27 02:54:06 UTC (rev 1065)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/processor/LoggingRequestProcessor.java 2009-06-28 00:33:32 UTC (rev 1066)
@@ -26,6 +26,7 @@
import org.jboss.dna.common.util.CheckArg;
import org.jboss.dna.common.util.Logger;
import org.jboss.dna.graph.GraphI18n;
+import org.jboss.dna.graph.request.CloneBranchRequest;
import org.jboss.dna.graph.request.CloneWorkspaceRequest;
import org.jboss.dna.graph.request.CompositeRequest;
import org.jboss.dna.graph.request.CopyBranchRequest;
@@ -115,6 +116,18 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CloneBranchRequest)
+ */
+ @Override
+ public void process( CloneBranchRequest request ) {
+ logger.log(level, GraphI18n.executingRequest, request);
+ delegate.process(request);
+ logger.log(level, GraphI18n.executedRequest, request);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CloneWorkspaceRequest)
*/
@Override
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/processor/RequestProcessor.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/processor/RequestProcessor.java 2009-06-27 02:54:06 UTC (rev 1065)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/processor/RequestProcessor.java 2009-06-28 00:33:32 UTC (rev 1066)
@@ -44,6 +44,7 @@
import org.jboss.dna.graph.property.ReferentialIntegrityException;
import org.jboss.dna.graph.request.CacheableRequest;
import org.jboss.dna.graph.request.ChangeRequest;
+import org.jboss.dna.graph.request.CloneBranchRequest;
import org.jboss.dna.graph.request.CloneWorkspaceRequest;
import org.jboss.dna.graph.request.CompositeRequest;
import org.jboss.dna.graph.request.CopyBranchRequest;
@@ -253,6 +254,8 @@
process((GetWorkspacesRequest)request);
} else if (request instanceof CreateWorkspaceRequest) {
process((CreateWorkspaceRequest)request);
+ } else if (request instanceof CloneBranchRequest) {
+ process((CloneBranchRequest)request);
} else if (request instanceof CloneWorkspaceRequest) {
process((CloneWorkspaceRequest)request);
} else if (request instanceof DestroyWorkspaceRequest) {
@@ -358,6 +361,16 @@
public abstract void process( CreateWorkspaceRequest request );
/**
+ * Process a request to clone a branch into a new workspace.
+ * <p>
+ * This method does nothing if the request is null.
+ * </p>
+ *
+ * @param request the request
+ */
+ public abstract void process( CloneBranchRequest request );
+
+ /**
* Process a request to clone an existing workspace as a new workspace.
* <p>
* This method does nothing if the request is null.
@@ -786,7 +799,7 @@
public void close() {
// Publish any changes ...
if (observer != null && !this.changes.isEmpty()) {
- String userName = context.getSecurityContext() != null ? context.getSecurityContext().getUserName() : null;
+ String userName = context.getSecurityContext() != null ? context.getSecurityContext().getUserName() : null;
Changes changes = new Changes(userName, getSourceName(), getNowInUtc(), this.changes);
observer.notify(changes);
}
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-06-27 02:54:06 UTC (rev 1065)
+++ trunk/dna-graph/src/main/resources/org/jboss/dna/graph/GraphI18n.properties 2009-06-28 00:33:32 UTC (rev 1066)
@@ -64,6 +64,8 @@
unableToCopyToTheRoot = Unable to copy node "{0}" to "{1}" since the desired location is the root node
actualLocationIsNotSameAsInputLocation = The actual location of {0} is not the same as the current location of {1}
actualLocationIsNotChildOfInputLocation = The actual location of {0} is not a child of the specified location {1}
+actualLocationIsNotAtCorrectChildSegment = The last segment of the actual location of {0} does not have the requested child segment {1}
+actualLocationDoesNotHaveCorrectChildName = The last segment of the actual location of {0} does not have the requested child name {1}
actualLocationMustHavePath = The actual location of {0} must have a path
actualNewLocationIsNotSameAsInputLocation = The actual new location of {0} is not the same as the input location of {1}
actualNewLocationMustHavePath = The actual new location of {0} must have a path
@@ -99,8 +101,9 @@
federatedSourceDoesNotSupportCloningWorkspaces = {0} is a source that does not allow cloning workspaces
federatedSourceDoesNotSupportDestroyingWorkspaces = {0} is a source that does not allow destroying workspaces
unableToProjectSourceInformationIntoWorkspace = Unable to project source information at {0} in the "{1} federated repository source using projection {2}
-unableToCreateNodeUnderPlaceholder = Unable to create node "{0}" under {1} in the "{2}" workspace of the "{3}" federarted repository because the parent is a placeholder
-unableToUpdatePlaceholder = Unable to update node {0} in the "{1}" workspace of the "{2}" federarted repository because the node is a placeholder
-unableToDeletePlaceholder = Unable to delete node {0} in the "{1}" workspace of the "{2}" federarted repository because the node is a placeholder
-copyLimitedToBeWithinSingleSource = Unable to copy {0} in the "{1}" workspace of the "{3}" federarted repository into {2} in the "{3}" workspace: copy is only supported when the original and new locations are within the same source
-moveLimitedToBeWithinSingleSource = Unable to move {0} in the "{1}" workspace of the "{3}" federarted repository into {2} in the "{3}" workspace: move is only supported when the original and new locations are within the same source
+unableToCreateNodeUnderPlaceholder = Unable to create node "{0}" under {1} in the "{2}" workspace of the "{3}" federated repository because the parent is a placeholder
+unableToUpdatePlaceholder = Unable to update node {0} in the "{1}" workspace of the "{2}" federated repository because the node is a placeholder
+unableToDeletePlaceholder = Unable to delete node {0} in the "{1}" workspace of the "{2}" federated repository because the node is a placeholder
+copyLimitedToBeWithinSingleSource = Unable to copy {0} in the "{1}" workspace of the "{3}" federated repository into {2} in the "{3}" workspace: copy is only supported when the original and new locations are within the same source
+moveLimitedToBeWithinSingleSource = Unable to move {0} in the "{1}" workspace of the "{3}" federated repository into {2} in the "{3}" workspace: move is only supported when the original and new locations are within the same source
+cloneLimitedToBeWithinSingleSource = Unable to clone {0} in the "{1}" workspace of the "{3}" federated repository into {2} in the "{3}" workspace: clone is only supported when the original and new locations are within the same source
Modified: trunk/dna-graph/src/test/java/org/jboss/dna/graph/GraphTest.java
===================================================================
--- trunk/dna-graph/src/test/java/org/jboss/dna/graph/GraphTest.java 2009-06-27 02:54:06 UTC (rev 1065)
+++ trunk/dna-graph/src/test/java/org/jboss/dna/graph/GraphTest.java 2009-06-28 00:33:32 UTC (rev 1066)
@@ -54,6 +54,7 @@
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.request.CloneBranchRequest;
import org.jboss.dna.graph.request.CloneWorkspaceRequest;
import org.jboss.dna.graph.request.CompositeRequest;
import org.jboss.dna.graph.request.CopyBranchRequest;
@@ -72,7 +73,6 @@
import org.jboss.dna.graph.request.Request;
import org.jboss.dna.graph.request.SetPropertyRequest;
import org.jboss.dna.graph.request.UpdatePropertiesRequest;
-import org.jboss.dna.graph.request.UuidConflictBehavior;
import org.jboss.dna.graph.request.VerifyNodeExistsRequest;
import org.jboss.dna.graph.request.VerifyWorkspaceRequest;
import org.jboss.dna.graph.request.CloneWorkspaceRequest.CloneConflictBehavior;
@@ -191,22 +191,14 @@
protected void assertNextRequestIsCopy( String fromWorkspace,
Location from,
Location to ) {
- assertNextRequestIsCopy(fromWorkspace, from, to, UuidConflictBehavior.ALWAYS_CREATE_NEW_UUID);
- }
-
- protected void assertNextRequestIsCopy( String fromWorkspace,
- Location from,
- Location to,
- UuidConflictBehavior uuidConflictBehavior) {
Request request = executedRequests.poll();
assertThat(request, is(instanceOf(CopyBranchRequest.class)));
CopyBranchRequest copy = (CopyBranchRequest)request;
assertThat(copy.fromWorkspace(), is(fromWorkspace));
assertThat(copy.from(), is(from));
assertThat(copy.into(), is(to));
- assertThat(copy.uuidConflictBehavior(), is(uuidConflictBehavior));
}
-
+
protected void assertNextRequestIsDelete( Location at ) {
Request request = executedRequests.poll();
assertThat(request, is(instanceOf(DeleteBranchRequest.class)));
@@ -1112,6 +1104,23 @@
}
@Override
+ public void process( CloneBranchRequest request ) {
+ // Create a child under the new parent ...
+ if (request.into().hasPath()) {
+ Name childName = request.desiredName();
+ if (childName == null) childName = request.desiredSegment().getName();
+
+ Path childPath = context.getValueFactories().getPathFactory().create(request.into().getPath(), childName);
+ Location newChild = actualLocationOf(Location.create(childPath));
+ // Just update the actual location
+ request.setActualLocations(actualLocationOf(request.from()), newChild);
+ } else {
+ // Just update the actual location
+ request.setActualLocations(actualLocationOf(request.from()), actualLocationOf(request.into()));
+ }
+ }
+
+ @Override
public void process( CreateNodeRequest request ) {
// Just update the actual location ...
Location parent = actualLocationOf(request.under()); // just make sure it has a path ...
Modified: trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/MockRepositoryRequestProcessor.java
===================================================================
--- trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/MockRepositoryRequestProcessor.java 2009-06-27 02:54:06 UTC (rev 1065)
+++ trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/MockRepositoryRequestProcessor.java 2009-06-28 00:33:32 UTC (rev 1066)
@@ -25,6 +25,7 @@
import java.util.Queue;
import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.request.CloneBranchRequest;
import org.jboss.dna.graph.request.CloneWorkspaceRequest;
import org.jboss.dna.graph.request.CopyBranchRequest;
import org.jboss.dna.graph.request.CreateNodeRequest;
@@ -136,6 +137,16 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CloneBranchRequest)
+ */
+ @Override
+ public void process( CloneBranchRequest request ) {
+ recordChange(request);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CreateNodeRequest)
*/
@Override
Modified: trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/test/WritableConnectorTest.java
===================================================================
--- trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/test/WritableConnectorTest.java 2009-06-27 02:54:06 UTC (rev 1065)
+++ trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/test/WritableConnectorTest.java 2009-06-28 00:33:32 UTC (rev 1066)
@@ -27,6 +27,7 @@
import static org.hamcrest.core.IsInstanceOf.instanceOf;
import static org.hamcrest.core.IsNot.not;
import static org.hamcrest.core.IsNull.notNullValue;
+import static org.hamcrest.core.IsNull.nullValue;
import static org.jboss.dna.graph.IsNodeWithChildren.hasChild;
import static org.jboss.dna.graph.IsNodeWithChildren.hasChildren;
import static org.jboss.dna.graph.IsNodeWithChildren.isEmpty;
@@ -44,9 +45,9 @@
import org.jboss.dna.graph.connector.RepositorySource;
import org.jboss.dna.graph.connector.UuidAlreadyExistsException;
import org.jboss.dna.graph.property.PathNotFoundException;
+import org.jboss.dna.graph.property.PropertyFactory;
import org.jboss.dna.graph.property.Reference;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
/**
@@ -75,14 +76,6 @@
IoUtil.read(getClass().getClassLoader().getResourceAsStream("LoremIpsum3.txt"))};
}
- protected void tryCreatingAWorkspaceNamed( String workspaceName ) {
- try {
- graph.createWorkspace().named(workspaceName);
- } catch (Exception ex) {
- assumeNoException(ex);
- }
- }
-
/**
* These tests require that the source supports updates, since all of the tests do some form of updates.
*/
@@ -308,7 +301,6 @@
createSubgraph(graph, initialPath, depth, numChildrenPerNode, numPropertiesPerNode, batch, sw, System.out, description);
}
- @Ignore
@Test
public void shouldCreateTreeWith10ChildrenAnd2LevelsDeepUsingIndividualRequests() {
String initialPath = "";
@@ -320,7 +312,6 @@
createSubgraph(graph, initialPath, depth, numChildrenPerNode, numPropertiesPerNode, batch, sw, System.out, null);
}
- @Ignore
@Test
public void shouldCreateTreeWith10ChildrenAnd2LevelsDeepUsingOneBatch() {
String initialPath = "";
@@ -332,7 +323,6 @@
createSubgraph(graph, initialPath, depth, numChildrenPerNode, numPropertiesPerNode, batch, sw, System.out, null);
}
- @Ignore
@Test
public void shouldCreateTreeWith10ChildrenAnd3LevelsDeepUsingOneBatch() {
String initialPath = "";
@@ -839,7 +829,7 @@
graph.useWorkspace(defaultWorkspaceName);
graph.create("/newUuids");
- graph.copy("/node1").withNewUuids().fromWorkspace(workspaceName).to("/newUuids/node1");
+ graph.copy("/node1").fromWorkspace(workspaceName).to("/newUuids/node1");
/*
* Focus on testing node structure, since shouldCopyNodeWithChildren tests that properties get copied
@@ -858,7 +848,7 @@
}
@Test
- public void shouldCopyChildrenBetweenWorkspacesPreservingUuids() throws Exception {
+ public void shouldNotCloneChildrenIfUuidConflictAndFailureBehavior() throws Exception {
String defaultWorkspaceName = graph.getCurrentWorkspaceName();
String workspaceName = "copyChildrenSource";
@@ -873,31 +863,27 @@
boolean batch = true;
createSubgraph(graph, initialPath, depth, numChildrenPerNode, numPropertiesPerNode, batch, sw, System.out, null);
- Subgraph source = graph.getSubgraphOfDepth(3).at("/node1");
-
graph.useWorkspace(defaultWorkspaceName);
graph.create("/newUuids");
- graph.copy("/node1").replacingExistingNodesWithSameUuids().fromWorkspace(workspaceName).to("/newUuids/node1");
+ // Copy once to get the UUID into the default workspace
+ //graph.copy("/node1/node1/node1").failingIfUuidsMatch().fromWorkspace(workspaceName).to("/newUuids/node1");
+ graph.clone("/node1/node1/node1").fromWorkspace(workspaceName).as(name("node1")).into("/newUuids").failingIfAnyUuidsMatch();
- /*
- * Focus on testing node structure, since shouldCopyNodeWithChildren tests that properties get copied
- */
- Subgraph target = graph.getSubgraphOfDepth(3).at("/newUuids/node1");
- assertThat(target, is(notNullValue()));
- assertThat(target.getNode(".").getChildren(), hasChildren(segment("node1"), segment("node2"), segment("node3")));
- assertThat(uuidFor(target.getNode(".")), is(uuidFor(source.getNode("."))));
- assertThat(target.getNode("node1").getChildren(), hasChildren(segment("node1"), segment("node2"), segment("node3")));
- assertThat(uuidFor(target.getNode("node1")), is(uuidFor(source.getNode("node1"))));
- assertThat(target.getNode("node2").getChildren(), hasChildren(segment("node1"), segment("node2"), segment("node3")));
- assertThat(uuidFor(target.getNode("node2")), is(uuidFor(source.getNode("node2"))));
- assertThat(target.getNode("node3").getChildren(), hasChildren(segment("node1"), segment("node2"), segment("node3")));
- assertThat(uuidFor(target.getNode("node3")), is(uuidFor(source.getNode("node3"))));
+ try {
+ // Copy again to get the exception since the UUID is already in the default workspace
+ // graph.copy("/node1/node1").failingIfUuidsMatch().fromWorkspace(workspaceName).to("/newUuids/shouldNotWork");
+ graph.clone("/node1/node1/node1").fromWorkspace(workspaceName).as(name("shouldNotWork")).into("/newUuids").failingIfAnyUuidsMatch();
+ fail("Should not be able to copy a node into a workspace if another node with the "
+ + "same UUID already exists in the workspace and UUID behavior is failingIfUuidsMatch");
+ } catch (UuidAlreadyExistsException ex) {
+ // Expected
+ }
}
@Test
- public void shouldNotCopyChildrenBetweenWorkspacesIfUuidConflictAndFailureBehavior() throws Exception {
+ public void shouldCloneChildrenAndRemoveExistingNodesWithSameUuidIfSpecified() throws Exception {
String defaultWorkspaceName = graph.getCurrentWorkspaceName();
String workspaceName = "copyChildrenSource";
@@ -912,25 +898,56 @@
boolean batch = true;
createSubgraph(graph, initialPath, depth, numChildrenPerNode, numPropertiesPerNode, batch, sw, System.out, null);
+ Subgraph source = graph.getSubgraphOfDepth(3).at("/node1");
+
graph.useWorkspace(defaultWorkspaceName);
graph.create("/newUuids");
// Copy once to get the UUID into the default workspace
- graph.copy("/node1/node1/node1").failingIfUuidsMatch().fromWorkspace(workspaceName).to("/newUuids/node1");
+ // graph.copy("/node1").replacingExistingNodesWithSameUuids().fromWorkspace(workspaceName).to("/newUuids/node1");
+ graph.clone("/node1").fromWorkspace(workspaceName).as(name("node1")).into("/newUuids").replacingExistingNodesWithSameUuids();
+
+ // Make sure that the node wasn't moved by the clone
+ graph.useWorkspace(workspaceName);
+ graph.getNodeAt("/node1");
+ graph.useWorkspace(defaultWorkspaceName);
+
+ // Create a new child node that in the target workspace that has no corresponding node in the source workspace
+ graph.create("/newUuids/node1/shouldBeRemoved");
+
+ // Copy again to test the behavior now that the UUIDs are already in the default workspace
+ // This should remove /newUuids/node1/shouldBeRemoved
+ // graph.copy("/node1").replacingExistingNodesWithSameUuids().fromWorkspace(workspaceName).to("/newUuids/otherNode");
+ graph.clone("/node1").fromWorkspace(workspaceName).as(name("otherNode")).into("/newUuids").replacingExistingNodesWithSameUuids();
+ /*
+ * Focus on testing node structure, since shouldCopyNodeWithChildren tests that properties get copied
+ */
+ // /newUuids/node1 should have been removed when the new node was added with the same UUID
+ assertThat(graph.getNodeAt("/newUuids").getChildren(), hasChildren(segment("otherNode")));
+
try {
- // Copy again to get the exception since the UUID is already in the default workspace
- graph.copy("/node1/node1").failingIfUuidsMatch().fromWorkspace(workspaceName).to("/newUuids/shouldNotWork");
- fail("Should not be able to copy a node into a workspace if another node with the "
- + "same UUID already exists in the workspace and UUID behavior is failingIfUuidsMatch");
- } catch (UuidAlreadyExistsException ex) {
+ graph.getNodeAt("/newUuids/node1/shouldBeRemoved");
+ fail("/newUuids/node1/shouldBeRemoved should no longer exist after the copy-with-remove-conflicting-uuids operation");
+ }
+ catch (PathNotFoundException pnfe) {
// Expected
}
-
+
+ Subgraph target = graph.getSubgraphOfDepth(3).at("/newUuids/otherNode");
+ assertThat(target, is(notNullValue()));
+ assertThat(target.getNode(".").getChildren(), hasChildren(segment("node1"), segment("node2"), segment("node3")));
+ assertThat(uuidFor(target.getNode(".")), is(uuidFor(source.getNode("."))));
+ assertThat(target.getNode("node1").getChildren(), hasChildren(segment("node1"), segment("node2"), segment("node3")));
+ assertThat(uuidFor(target.getNode("node1")), is(uuidFor(source.getNode("node1"))));
+ assertThat(target.getNode("node2").getChildren(), hasChildren(segment("node1"), segment("node2"), segment("node3")));
+ assertThat(uuidFor(target.getNode("node2")), is(uuidFor(source.getNode("node2"))));
+ assertThat(target.getNode("node3").getChildren(), hasChildren(segment("node1"), segment("node2"), segment("node3")));
+ assertThat(uuidFor(target.getNode("node3")), is(uuidFor(source.getNode("node3"))));
}
@Test
- public void shouldCopyChildrenBetweenWorkspacesAndRemoveExistingNodesWithSameUuidIfSpecified() throws Exception {
+ public void shouldCloneNodeIntoExactLocationIfSpecified() throws Exception {
String defaultWorkspaceName = graph.getCurrentWorkspaceName();
String workspaceName = "copyChildrenSource";
@@ -949,32 +966,27 @@
graph.useWorkspace(defaultWorkspaceName);
- graph.create("/newUuids");
+ graph.create("/segmentTestUuids");
// Copy once to get the UUID into the default workspace
- graph.copy("/node1").replacingExistingNodesWithSameUuids().fromWorkspace(workspaceName).to("/newUuids/node1");
+ graph.clone("/node1").fromWorkspace(workspaceName).as(name("node1")).into("/segmentTestUuids").failingIfAnyUuidsMatch();
// Create a new child node that in the target workspace that has no corresponding node in the source workspace
- graph.create("/newUuids/node1/shouldBeRemoved");
-
+ PropertyFactory propFactory = context.getPropertyFactory();
+ graph.create("/segmentTestUuids/node1", propFactory.create(name("identifier"), "backup copy"));
+
// Copy again to test the behavior now that the UUIDs are already in the default workspace
// This should remove /newUuids/node1/shouldBeRemoved
- graph.copy("/node1").replacingExistingNodesWithSameUuids().fromWorkspace(workspaceName).to("/newUuids/otherNode");
+ graph.clone("/node1").fromWorkspace(workspaceName).as(segment("node1[1]")).into("/segmentTestUuids").replacingExistingNodesWithSameUuids();
/*
* Focus on testing node structure, since shouldCopyNodeWithChildren tests that properties get copied
*/
// /newUuids/node1 should have been removed when the new node was added with the same UUID
- assertThat(graph.getNodeAt("/newUuids").getChildren(), hasChildren(segment("otherNode")));
-
- try {
- graph.getNodeAt("/newUuids/node1/shouldBeRemoved");
- fail("/newUuids/node1/shouldBeRemoved should no longer exist after the copy-with-remove-conflicting-uuids operation");
- }
- catch (PathNotFoundException pnfe) {
- // Expected
- }
+ assertThat(graph.getNodeAt("/segmentTestUuids").getChildren(), hasChildren(segment("node1"), segment("node1[2]")));
+ assertThat(graph.getNodeAt("/segmentTestUuids/node1[1]").getProperty("identifier"), is(nullValue()));
+ assertThat(graph.getNodeAt("/segmentTestUuids/node1[2]").getProperty("identifier").getFirstValue().toString(), is("backup copy"));
- Subgraph target = graph.getSubgraphOfDepth(3).at("/newUuids/otherNode");
+ Subgraph target = graph.getSubgraphOfDepth(3).at("/segmentTestUuids/node1[1]");
assertThat(target, is(notNullValue()));
assertThat(target.getNode(".").getChildren(), hasChildren(segment("node1"), segment("node2"), segment("node3")));
assertThat(uuidFor(target.getNode(".")), is(uuidFor(source.getNode("."))));
@@ -985,7 +997,15 @@
assertThat(target.getNode("node3").getChildren(), hasChildren(segment("node1"), segment("node2"), segment("node3")));
assertThat(uuidFor(target.getNode("node3")), is(uuidFor(source.getNode("node3"))));
}
-
+
+ protected void tryCreatingAWorkspaceNamed( String workspaceName ) {
+ try {
+ graph.createWorkspace().named(workspaceName);
+ } catch (Exception ex) {
+ assumeNoException(ex);
+ }
+ }
+
private UUID uuidFor( Node node ) {
return (UUID)node.getProperty(DnaLexicon.UUID).getFirstValue();
}
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrNode.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrNode.java 2009-06-27 02:54:06 UTC (rev 1065)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrNode.java 2009-06-28 00:33:32 UTC (rev 1066)
@@ -717,8 +717,7 @@
JcrNodeDefinition match = this.cache.nodeTypes().findChildNodeDefinition(mixinCandidateType.getInternalName(),
Collections.<Name>emptyList(),
nodeName,
- childNode.getPrimaryNodeType()
- .getInternalName(),
+ childNode.getPrimaryNodeType().getInternalName(),
snsCount,
false);
@@ -1408,7 +1407,6 @@
*
* @see javax.jcr.Node#update(java.lang.String)
*/
- @SuppressWarnings( "unused" )
public final void update( String srcWorkspaceName ) throws NoSuchWorkspaceException, RepositoryException {
CheckArg.isNotNull(srcWorkspaceName, "workspace name");
@@ -1424,7 +1422,10 @@
return;
}
- if (true) throw new UnsupportedOperationException();
+ // Need to force remove in case this node is not referenceable
+ this.session().workspace().clone(srcWorkspaceName, correspondingPath, path(), true, true);
+
+ session().refresh(false);
}
/**
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java 2009-06-27 02:54:06 UTC (rev 1065)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java 2009-06-28 00:33:32 UTC (rev 1066)
@@ -304,6 +304,17 @@
throw new AccessDeniedException(ace);
}
+ clone(srcWorkspace, srcPath, destPath, removeExisting, false);
+ }
+
+ void clone( String srcWorkspace,
+ Path srcPath,
+ Path destPath,
+ boolean removeExisting,
+ boolean destPathIncludesSegment )
+ throws ConstraintViolationException, VersionException, AccessDeniedException, PathNotFoundException, ItemExistsException,
+ LockException, RepositoryException {
+
/*
* Make sure that the node has a definition at the new location
*/
@@ -332,6 +343,7 @@
primaryTypeProp = props.get(JcrLexicon.PRIMARY_TYPE);
uuidProp = props.get(DnaLexicon.UUID);
} catch (org.jboss.dna.graph.property.PathNotFoundException pnfe) {
+ String srcAbsPath = srcPath.getString(this.context.getNamespaceRegistry());
throw new PathNotFoundException(JcrI18n.itemNotFoundAtPath.text(srcAbsPath, srcWorkspace));
} finally {
graph.useWorkspace(this.name);
@@ -391,12 +403,19 @@
}
}
- // Perform the copy operation, but use the "to" form (not the "into", which takes the parent) ...
- graph.copy(srcPath).replacingExistingNodesWithSameUuids().fromWorkspace(srcWorkspace).to(destPath);
+ if (destPathIncludesSegment) {
+ graph.clone(srcPath).fromWorkspace(srcWorkspace).as(destPath.getLastSegment()).into(destPath.getParent()).replacingExistingNodesWithSameUuids();
+ } else {
+ graph.clone(srcPath).fromWorkspace(srcWorkspace).as(newNodeName).into(destPath.getParent()).replacingExistingNodesWithSameUuids();
+ }
} else {
try {
- // Perform the copy operation, but use the "to" form (not the "into", which takes the parent) ...
- graph.copy(srcPath).failingIfUuidsMatch().fromWorkspace(srcWorkspace).to(destPath);
+ if (destPathIncludesSegment) {
+ graph.clone(srcPath).fromWorkspace(srcWorkspace).as(destPath.getLastSegment()).into(destPath.getParent()).replacingExistingNodesWithSameUuids();
+ } else {
+ graph.clone(srcPath).fromWorkspace(srcWorkspace).as(newNodeName).into(destPath.getParent()).failingIfAnyUuidsMatch();
+ }
+
} catch (UuidAlreadyExistsException uaee) {
throw new ItemExistsException(uaee.getMessage());
}
Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrTckTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrTckTest.java 2009-06-27 02:54:06 UTC (rev 1065)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrTckTest.java 2009-06-28 00:33:32 UTC (rev 1066)
@@ -37,6 +37,7 @@
import org.apache.jackrabbit.test.api.NodeItemIsNewTest;
import org.apache.jackrabbit.test.api.NodeOrderableChildNodesTest;
import org.apache.jackrabbit.test.api.NodeRemoveMixinTest;
+import org.apache.jackrabbit.test.api.NodeTest;
import org.apache.jackrabbit.test.api.PropertyItemIsModifiedTest;
import org.apache.jackrabbit.test.api.PropertyItemIsNewTest;
import org.apache.jackrabbit.test.api.PropertyTest;
@@ -178,7 +179,7 @@
// addTestSuite(ReferencesTest.class);
addTestSuite(SessionTest.class);
// addTestSuite(SessionUUIDTest.class);
- // addTestSuite(NodeTest.class);
+ addTestSuite(NodeTest.class);
// addTestSuite(NodeUUIDTest.class);
addTestSuite(NodeOrderableChildNodesTest.class);
addTestSuite(PropertyTest.class);
Modified: trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatingRequestProcessor.java
===================================================================
--- trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatingRequestProcessor.java 2009-06-27 02:54:06 UTC (rev 1065)
+++ trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatingRequestProcessor.java 2009-06-28 00:33:32 UTC (rev 1066)
@@ -62,6 +62,7 @@
import org.jboss.dna.graph.property.Property;
import org.jboss.dna.graph.property.PropertyFactory;
import org.jboss.dna.graph.request.ChangeRequest;
+import org.jboss.dna.graph.request.CloneBranchRequest;
import org.jboss.dna.graph.request.CloneWorkspaceRequest;
import org.jboss.dna.graph.request.CompositeRequest;
import org.jboss.dna.graph.request.CopyBranchRequest;
@@ -324,8 +325,8 @@
}
// Delete in the cache ...
- DeleteBranchRequest cacheRequest = new DeleteBranchRequest(request.at(), workspace.getCacheProjection()
- .getWorkspaceName());
+ DeleteBranchRequest cacheRequest = new DeleteBranchRequest(request.at(),
+ workspace.getCacheProjection().getWorkspaceName());
executeInCache(cacheRequest, workspace);
}
@@ -367,8 +368,7 @@
Location intoLocation = Location.create(intoProjection.pathInSource);
String workspaceName = fromProjection.projection.getWorkspaceName();
CopyBranchRequest sourceRequest = new CopyBranchRequest(fromLocation, workspaceName, intoLocation, workspaceName,
- request.desiredName(), request.nodeConflictBehavior(),
- request.uuidConflictBehavior());
+ request.desiredName(), request.nodeConflictBehavior());
execute(sourceRequest, fromProjection.projection);
// Copy/transform the results ...
@@ -380,14 +380,70 @@
}
// Delete from the cache the parent of the new location ...
- DeleteBranchRequest cacheRequest = new DeleteBranchRequest(request.into(), fromWorkspace.getCacheProjection()
- .getWorkspaceName());
+ DeleteBranchRequest cacheRequest = new DeleteBranchRequest(request.into(),
+ fromWorkspace.getCacheProjection().getWorkspaceName());
executeInCache(cacheRequest, fromWorkspace);
}
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CloneBranchRequest)
+ */
+ @Override
+ public void process( CloneBranchRequest request ) {
+ FederatedWorkspace fromWorkspace = getWorkspace(request, request.fromWorkspace());
+ if (fromWorkspace == null) return;
+ FederatedWorkspace intoWorkspace = getWorkspace(request, request.intoWorkspace());
+ if (intoWorkspace == null) return;
+ if (!fromWorkspace.equals(intoWorkspace)) {
+ // Otherwise there wasn't a single projection with a single path ...
+ String msg = FederationI18n.unableToPerformOperationSpanningWorkspaces.text(fromWorkspace.getName(),
+ intoWorkspace.getName());
+ request.setError(new UnsupportedRequestException(msg));
+ }
+
+ // Can push this down if and only if the entire request is within a single federated source ...
+ SingleProjection fromProjection = asSingleProjection(fromWorkspace, request.from(), request);
+ if (fromProjection == null) return;
+ SingleProjection intoProjection = asSingleProjection(intoWorkspace, request.into(), request);
+ if (intoProjection == null) return;
+ if (!intoProjection.projection.equals(fromProjection.projection)) {
+ // Otherwise there wasn't a single projection with a single path ...
+ String msg = FederationI18n.unableToPerformOperationUnlessLocationsAreFromSingleProjection.text(request.from(),
+ request.into(),
+ fromWorkspace.getName(),
+ fromProjection.projection.getRules(),
+ intoProjection.projection.getRules());
+ request.setError(new UnsupportedRequestException(msg));
+ }
+
+ // Push down the request ...
+ Location fromLocation = Location.create(fromProjection.pathInSource);
+ Location intoLocation = Location.create(intoProjection.pathInSource);
+ String workspaceName = fromProjection.projection.getWorkspaceName();
+ CloneBranchRequest sourceRequest = new CloneBranchRequest(fromLocation, workspaceName, intoLocation, workspaceName,
+ request.desiredName(), request.desiredSegment(),
+ request.removeExisting());
+ execute(sourceRequest, fromProjection.projection);
+
+ // Copy/transform the results ...
+ if (sourceRequest.hasError()) {
+ request.setError(sourceRequest.getError());
+ } else {
+ request.setActualLocations(fromProjection.convertToRepository(sourceRequest.getActualLocationBefore()),
+ intoProjection.convertToRepository(sourceRequest.getActualLocationAfter()));
+ }
+
+ // Delete from the cache the parent of the new location ...
+ DeleteBranchRequest cacheRequest = new DeleteBranchRequest(request.into(),
+ fromWorkspace.getCacheProjection().getWorkspaceName());
+ executeInCache(cacheRequest, fromWorkspace);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.MoveBranchRequest)
*/
@Override
@@ -411,14 +467,13 @@
}
SingleProjection beforeProjection = request.before() != null ? asSingleProjection(workspace, request.before(), request) : null;
-
// Push down the request ...
Location fromLocation = Location.create(fromProjection.pathInSource);
Location intoLocation = Location.create(intoProjection.pathInSource);
Location beforeLocation = beforeProjection != null ? Location.create(beforeProjection.pathInSource) : null;
String workspaceName = fromProjection.projection.getWorkspaceName();
- MoveBranchRequest sourceRequest = new MoveBranchRequest(fromLocation, intoLocation, beforeLocation, workspaceName, request.desiredName(),
- request.conflictBehavior());
+ MoveBranchRequest sourceRequest = new MoveBranchRequest(fromLocation, intoLocation, beforeLocation, workspaceName,
+ request.desiredName(), request.conflictBehavior());
execute(sourceRequest, fromProjection.projection);
// Copy/transform the results ...
@@ -429,8 +484,8 @@
intoProjection.convertToRepository(sourceRequest.getActualLocationAfter()));
}
// Delete from the cache ...
- DeleteBranchRequest cacheRequest = new DeleteBranchRequest(request.from(), workspace.getCacheProjection()
- .getWorkspaceName());
+ DeleteBranchRequest cacheRequest = new DeleteBranchRequest(request.from(),
+ workspace.getCacheProjection().getWorkspaceName());
executeInCache(cacheRequest, workspace);
// Mark the new parent node as being expired ...
cacheRequest = new DeleteBranchRequest(request.into(), workspace.getCacheProjection().getWorkspaceName());
@@ -465,8 +520,8 @@
}
// Update the cache ...
- UpdatePropertiesRequest cacheRequest = new UpdatePropertiesRequest(request.on(), workspace.getCacheProjection()
- .getWorkspaceName(),
+ UpdatePropertiesRequest cacheRequest = new UpdatePropertiesRequest(request.on(),
+ workspace.getCacheProjection().getWorkspaceName(),
request.properties());
executeInCache(cacheRequest, workspace);
}
@@ -1151,9 +1206,9 @@
readable(registry, create.properties()));
} else if (request instanceof UpdatePropertiesRequest) {
UpdatePropertiesRequest update = (UpdatePropertiesRequest)request;
- logger.trace(" updating {0} with properties {1}", update.on().getString(registry), readable(registry,
- update.properties()
- .values()));
+ logger.trace(" updating {0} with properties {1}",
+ update.on().getString(registry),
+ readable(registry, update.properties().values()));
} else {
logger.trace(" " + request.toString());
}
@@ -1172,9 +1227,9 @@
readable(registry, create.properties()));
} else if (request instanceof UpdatePropertiesRequest) {
UpdatePropertiesRequest update = (UpdatePropertiesRequest)request;
- logger.trace(" updating {0} with properties {1}", update.on().getString(registry), readable(registry,
- update.properties()
- .values()));
+ logger.trace(" updating {0} with properties {1}",
+ update.on().getString(registry),
+ readable(registry, update.properties().values()));
} else {
logger.trace(" " + request.toString());
}
Modified: trunk/extensions/dna-connector-filesystem/src/main/java/org/jboss/dna/connector/filesystem/FileSystemRequestProcessor.java
===================================================================
--- trunk/extensions/dna-connector-filesystem/src/main/java/org/jboss/dna/connector/filesystem/FileSystemRequestProcessor.java 2009-06-27 02:54:06 UTC (rev 1065)
+++ trunk/extensions/dna-connector-filesystem/src/main/java/org/jboss/dna/connector/filesystem/FileSystemRequestProcessor.java 2009-06-28 00:33:32 UTC (rev 1066)
@@ -47,6 +47,7 @@
import org.jboss.dna.graph.property.PathFactory;
import org.jboss.dna.graph.property.PathNotFoundException;
import org.jboss.dna.graph.property.PropertyFactory;
+import org.jboss.dna.graph.request.CloneBranchRequest;
import org.jboss.dna.graph.request.CloneWorkspaceRequest;
import org.jboss.dna.graph.request.CopyBranchRequest;
import org.jboss.dna.graph.request.CreateNodeRequest;
@@ -283,6 +284,16 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CloneBranchRequest)
+ */
+ @Override
+ public void process( CloneBranchRequest request ) {
+ updatesAllowed(request);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.DeleteBranchRequest)
*/
@Override
Modified: trunk/extensions/dna-connector-jdbc-metadata/src/main/java/org/jboss/dna/connector/jdbc/JdbcRequestProcesor.java
===================================================================
--- trunk/extensions/dna-connector-jdbc-metadata/src/main/java/org/jboss/dna/connector/jdbc/JdbcRequestProcesor.java 2009-06-27 02:54:06 UTC (rev 1065)
+++ trunk/extensions/dna-connector-jdbc-metadata/src/main/java/org/jboss/dna/connector/jdbc/JdbcRequestProcesor.java 2009-06-28 00:33:32 UTC (rev 1066)
@@ -28,6 +28,7 @@
import org.jboss.dna.common.util.Logger;
import org.jboss.dna.graph.ExecutionContext;
import org.jboss.dna.graph.property.DateTime;
+import org.jboss.dna.graph.request.CloneBranchRequest;
import org.jboss.dna.graph.request.CloneWorkspaceRequest;
import org.jboss.dna.graph.request.CopyBranchRequest;
import org.jboss.dna.graph.request.CreateNodeRequest;
@@ -100,6 +101,15 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CloneBranchRequest)
+ */
+ @Override
+ public void process( CloneBranchRequest request ) {
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CreateNodeRequest)
*/
@Override
Modified: trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicRequestProcessor.java
===================================================================
--- trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicRequestProcessor.java 2009-06-27 02:54:06 UTC (rev 1065)
+++ trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicRequestProcessor.java 2009-06-28 00:33:32 UTC (rev 1066)
@@ -82,6 +82,7 @@
import org.jboss.dna.graph.property.ValueFactories;
import org.jboss.dna.graph.property.ValueFactory;
import org.jboss.dna.graph.property.ValueFormatException;
+import org.jboss.dna.graph.request.CloneBranchRequest;
import org.jboss.dna.graph.request.CloneWorkspaceRequest;
import org.jboss.dna.graph.request.CopyBranchRequest;
import org.jboss.dna.graph.request.CreateNodeRequest;
@@ -102,7 +103,6 @@
import org.jboss.dna.graph.request.ReadPropertyRequest;
import org.jboss.dna.graph.request.Request;
import org.jboss.dna.graph.request.UpdatePropertiesRequest;
-import org.jboss.dna.graph.request.UuidConflictBehavior;
import org.jboss.dna.graph.request.VerifyWorkspaceRequest;
import org.jboss.dna.graph.request.processor.RequestProcessor;
@@ -132,6 +132,12 @@
protected final boolean enforceReferentialIntegrity;
private final Set<Long> workspaceIdsWithChangedReferences = new HashSet<Long>();
+ private enum UuidConflictBehavior {
+ ALWAYS_CREATE_NEW_UUID,
+ REPLACE_EXISTING_NODE,
+ THROW_EXCEPTION
+ }
+
/**
* @param sourceName
* @param context
@@ -1215,7 +1221,7 @@
intoWorkspace,
original,
actualNewParent,
- request.uuidConflictBehavior(),
+ UuidConflictBehavior.ALWAYS_CREATE_NEW_UUID,
desiredName,
originalToNewUuid,
addedLocations,
@@ -1236,7 +1242,7 @@
intoWorkspace,
original,
actualNewParent,
- request.uuidConflictBehavior(),
+ UuidConflictBehavior.ALWAYS_CREATE_NEW_UUID,
desiredName,
originalToNewUuid,
addedLocations,
@@ -1336,8 +1342,202 @@
entities.persist(copy);
}
entities.flush();
+ } finally {
+ // Close and release the temporary data used for this operation ...
+ query.close();
+ }
- if (request.uuidConflictBehavior() == UuidConflictBehavior.REPLACE_EXISTING_NODE) {
+ } catch (Throwable e) { // Includes PathNotFoundException
+ request.setError(e);
+ return;
+ }
+ request.setActualLocations(actualFromLocation, actualToLocation);
+ recordChange(request);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CloneBranchRequest)
+ */
+ @Override
+ public void process( CloneBranchRequest request ) {
+ logger.trace(request.toString());
+ Location actualFromLocation = null;
+ Location actualToLocation = null;
+ try {
+ // Find the workspaces ...
+ WorkspaceEntity fromWorkspace = getExistingWorkspace(request.fromWorkspace(), request);
+ if (fromWorkspace == null) return;
+ WorkspaceEntity intoWorkspace = getExistingWorkspace(request.intoWorkspace(), request);
+ if (intoWorkspace == null) return;
+ Long fromWorkspaceId = fromWorkspace.getId();
+ Long intoWorkspaceId = intoWorkspace.getId();
+ assert fromWorkspaceId != null;
+ assert intoWorkspaceId != null;
+
+ Location fromLocation = request.from();
+ ActualLocation actualFrom = getActualLocation(fromWorkspace, fromLocation);
+ actualFromLocation = actualFrom.location;
+ Path fromPath = actualFromLocation.getPath();
+
+ Location newParentLocation = request.into();
+ ActualLocation actualNewParent = getActualLocation(intoWorkspace, newParentLocation);
+ assert actualNewParent != null;
+
+ // Create a map that we'll use to record the new UUID for each of the original nodes ...
+ Map<String, String> originalToNewUuid = new HashMap<String, String>();
+
+ // Compute the subgraph, including the top node in the subgraph ...
+ SubgraphQuery query = SubgraphQuery.create(getExecutionContext(),
+ entities,
+ fromWorkspaceId,
+ actualFromLocation.getUuid(),
+ fromPath,
+ 0);
+
+ UuidConflictBehavior conflictBehavior = request.removeExisting() ? UuidConflictBehavior.REPLACE_EXISTING_NODE : UuidConflictBehavior.THROW_EXCEPTION;
+ try {
+ // Walk through the original nodes, creating new ChildEntity object (i.e., copy) for each original ...
+ List<ChildEntity> originalNodes = query.getNodes(true, true);
+ Iterator<ChildEntity> originalIter = originalNodes.iterator();
+ Map<String, ChildEntity> addedLocations = new HashMap<String, ChildEntity>();
+ Map<String, Location> deletedLocations = new HashMap<String, Location>();
+
+ // Start with the original (top-level) node first, since we need to add it to the list of children ...
+ if (originalIter.hasNext()) {
+ ChildEntity original = originalIter.next();
+
+ Name desiredName = request.desiredName();
+ if (desiredName == null) desiredName = fromPath.getLastSegment().getName();
+ actualToLocation = this.copyNode(entities,
+ fromWorkspace,
+ intoWorkspace,
+ original,
+ actualNewParent,
+ conflictBehavior,
+ desiredName,
+ originalToNewUuid,
+ addedLocations,
+ deletedLocations).location;
+ }
+
+ // Now create copies of all children in the subgraph.
+ while (originalIter.hasNext()) {
+ ChildEntity original = originalIter.next();
+ String newParentUuidOfCopy = originalToNewUuid.get(original.getParentUuidString());
+ assert newParentUuidOfCopy != null;
+
+ actualNewParent = getActualLocation(intoWorkspace, Location.create(UUID.fromString(newParentUuidOfCopy)));
+
+ Name desiredName = nameFactory.create(original.getChildNamespace().getUri(), original.getChildName());
+ this.copyNode(entities,
+ fromWorkspace,
+ intoWorkspace,
+ original,
+ actualNewParent,
+ conflictBehavior,
+ desiredName,
+ originalToNewUuid,
+ addedLocations,
+ deletedLocations);
+ }
+ entities.flush();
+
+ Set<String> newNodesWithReferenceProperties = new HashSet<String>();
+ // Now create copies of all the intra-subgraph references, replacing the UUIDs on both ends ...
+ for (ReferenceEntity reference : query.getInternalReferences()) {
+ String newFromUuid = originalToNewUuid.get(reference.getId().getFromUuidString());
+ assert newFromUuid != null;
+ String newToUuid = originalToNewUuid.get(reference.getId().getToUuidString());
+ assert newToUuid != null;
+ ReferenceEntity copy = new ReferenceEntity(new ReferenceId(intoWorkspaceId, newFromUuid, newToUuid));
+ entities.persist(copy);
+ newNodesWithReferenceProperties.add(newFromUuid);
+ }
+
+ // Now create copies of all the references owned by the subgraph but pointing to non-subgraph nodes,
+ // so we only replaced the 'from' UUID ...
+ for (ReferenceEntity reference : query.getOutwardReferences()) {
+ String oldToUuid = reference.getId().getToUuidString();
+ String newFromUuid = originalToNewUuid.get(reference.getId().getFromUuidString());
+ assert newFromUuid != null;
+
+ ActualLocation refTargetLocation = getActualLocation(intoWorkspace,
+ Location.create(UUID.fromString(oldToUuid)));
+ if (refTargetLocation == null) {
+ // Some of the references that remain will be invalid, since they point to nodes that
+ // have just been deleted. Build up the information necessary to produce a useful exception ...
+ ValueFactory<Reference> refFactory = getExecutionContext().getValueFactories().getReferenceFactory();
+ Map<Location, List<Reference>> invalidRefs = new HashMap<Location, List<Reference>>();
+ UUID fromUuid = UUID.fromString(reference.getId().getFromUuidString());
+ ActualLocation actualRefFromLocation = getActualLocation(intoWorkspace, Location.create(fromUuid));
+ Location refFromLocation = actualRefFromLocation.location;
+ List<Reference> refs = invalidRefs.get(fromLocation);
+ if (refs == null) {
+ refs = new ArrayList<Reference>();
+ invalidRefs.put(refFromLocation, refs);
+ }
+ UUID toUuid = UUID.fromString(oldToUuid);
+ refs.add(refFactory.create(toUuid));
+
+ String msg = JpaConnectorI18n.invalidReferences.text(reference.getId().getFromUuidString());
+ throw new ReferentialIntegrityException(invalidRefs, msg);
+ }
+
+ ReferenceEntity copy = new ReferenceEntity(new ReferenceId(intoWorkspaceId, newFromUuid, oldToUuid));
+ entities.persist(copy);
+ newNodesWithReferenceProperties.add(newFromUuid);
+ }
+
+ Set<PropertiesEntity> addedProps = new HashSet<PropertiesEntity>();
+ // Now process the properties, creating a copy (note references are not changed) ...
+ for (PropertiesEntity original : query.getProperties(true, true)) {
+ // Find the UUID of the copy ...
+ String copyUuid = originalToNewUuid.get(original.getId().getUuidString());
+ assert copyUuid != null;
+
+ // Create the copy ...
+ boolean compressed = original.isCompressed();
+ byte[] originalData = original.getData();
+ NodeId propertiesId = new NodeId(intoWorkspaceId, copyUuid);
+ PropertiesEntity copy = entities.find(PropertiesEntity.class, propertiesId);
+
+ if (copy == null) {
+ copy = new PropertiesEntity(propertiesId);
+ }
+ copy.setCompressed(compressed);
+ if (newNodesWithReferenceProperties.contains(copyUuid)) {
+
+ // This node has internal or outward references that must be adjusted ...
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ OutputStream os = compressed ? new GZIPOutputStream(baos) : baos;
+ ObjectOutputStream oos = new ObjectOutputStream(os);
+ ByteArrayInputStream bais = new ByteArrayInputStream(originalData);
+ InputStream is = compressed ? new GZIPInputStream(bais) : bais;
+ ObjectInputStream ois = new ObjectInputStream(is);
+ try {
+ serializer.adjustReferenceProperties(ois, oos, originalToNewUuid);
+ } finally {
+ try {
+ ois.close();
+ } finally {
+ oos.close();
+ }
+ }
+ copy.setData(baos.toByteArray());
+ } else {
+ // No references to adjust, so just copy the original data ...
+ copy.setData(originalData);
+ }
+ copy.setPropertyCount(original.getPropertyCount());
+ copy.setReferentialIntegrityEnforced(original.isReferentialIntegrityEnforced());
+ addedProps.add(copy);
+ entities.persist(copy);
+ }
+ entities.flush();
+
+ if (request.removeExisting()) {
/*
* We may have deleted some old copies of nodes and replaced them with new copies.
* Now we need to clean up any nodes that were descendants of the old copies of the
Modified: trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorWritingTest.java
===================================================================
--- trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorWritingTest.java 2009-06-27 02:54:06 UTC (rev 1065)
+++ trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorWritingTest.java 2009-06-28 00:33:32 UTC (rev 1066)
@@ -92,7 +92,8 @@
graph.create("/newUuids");
// Copy once to get the UUID into the default workspace
- graph.copy("/node1").replacingExistingNodesWithSameUuids().fromWorkspace(workspaceName).to("/newUuids/node1");
+ //graph.copy("/node1").replacingExistingNodesWithSameUuids().fromWorkspace(workspaceName).to("/newUuids/node1");
+ graph.clone("/node1").fromWorkspace(workspaceName).as(name("node1")).into("/newUuids").replacingExistingNodesWithSameUuids();
// Create a new child node that in the target workspace that has no corresponding node in the source workspace
graph.create("/newUuids/node1/shouldBeRemoved");
@@ -104,6 +105,7 @@
// Copy again to test the behavior now that the UUIDs are already in the default workspace
// This should fail because /newUuids/node1/shouldBeRemoved must be removed by the copy, but can't be removed
// because there is a reference to it.
- graph.copy("/node1").replacingExistingNodesWithSameUuids().fromWorkspace(workspaceName).to("/newUuids/otherNode");
+ //graph.copy("/node1").replacingExistingNodesWithSameUuids().fromWorkspace(workspaceName).to("/newUuids/otherNode");
+ graph.clone("/node1").fromWorkspace(workspaceName).as(name("otherNode")).into("/newUuids").replacingExistingNodesWithSameUuids();
}
}
Modified: trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositoryRequestProcessor.java
===================================================================
--- trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositoryRequestProcessor.java 2009-06-27 02:54:06 UTC (rev 1065)
+++ trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositoryRequestProcessor.java 2009-06-28 00:33:32 UTC (rev 1066)
@@ -50,6 +50,7 @@
import org.jboss.dna.graph.property.Property;
import org.jboss.dna.graph.property.PropertyFactory;
import org.jboss.dna.graph.property.ValueFactory;
+import org.jboss.dna.graph.request.CloneBranchRequest;
import org.jboss.dna.graph.request.CloneWorkspaceRequest;
import org.jboss.dna.graph.request.CopyBranchRequest;
import org.jboss.dna.graph.request.CreateNodeRequest;
@@ -346,6 +347,16 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CloneBranchRequest)
+ */
+ @Override
+ public void process( CloneBranchRequest request ) {
+ updatesAllowed(request);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.DeleteBranchRequest)
*/
@Override
14 years, 10 months
DNA SVN: r1065 - in trunk: dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory and 4 other directories.
by dna-commits@lists.jboss.org
Author: bcarothers
Date: 2009-06-26 22:54:06 -0400 (Fri, 26 Jun 2009)
New Revision: 1065
Added:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/AbstractMapWorkspace.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapNode.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepository.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepositoryConnection.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepositorySource.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRequestProcessor.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapWorkspace.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/package-info.java
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheRepository.java
Removed:
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/InMemoryRepositoryConnection.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRequestProcessor.java
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheConnection.java
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheLexicon.java
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheRequestProcessor.java
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheWorkspaces.java
trunk/extensions/dna-connector-jbosscache/src/test/java/org/jboss/dna/connector/jbosscache/JBossCacheRequestProcessorTest.java
Modified:
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/InMemoryRepositorySource.java
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/InMemoryRepositoryWorkspaceTest.java
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheSource.java
Log:
DNA-470 Provide Base Set of Connector Classes for All Map-Based Connectors
Applied patch that creates a new MapRepository class (and associated classes) based on the original InMemoryRepository implementation and refactors the In-Memory connector and JBoss Cache connector to utilize the new MapRepository.
Deleted: 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 2009-06-24 22:14:12 UTC (rev 1064)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryNode.java 2009-06-27 02:54:06 UTC (rev 1065)
@@ -1,173 +0,0 @@
-/*
- * 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.HashSet;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.Set;
-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 LinkedList<InMemoryNode> children = new LinkedList<InMemoryNode>();
- final Set<Name> existingNames = new HashSet<Name>();
-
- 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
- */
- LinkedList<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();
- }
-}
Modified: 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 2009-06-24 22:14:12 UTC (rev 1064)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepository.java 2009-06-27 02:54:06 UTC (rev 1065)
@@ -23,420 +23,80 @@
*/
package org.jboss.dna.graph.connector.inmemory;
-import java.util.ArrayList;
import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
import java.util.Map;
-import java.util.Set;
import java.util.UUID;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
import net.jcip.annotations.GuardedBy;
import net.jcip.annotations.NotThreadSafe;
-import org.jboss.dna.common.util.CheckArg;
import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.connector.map.AbstractMapWorkspace;
+import org.jboss.dna.graph.connector.map.MapNode;
+import org.jboss.dna.graph.connector.map.MapRepository;
+import org.jboss.dna.graph.connector.map.MapWorkspace;
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.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.basic.RootPath;
-import org.jboss.dna.graph.request.CreateWorkspaceRequest.CreateConflictBehavior;
/**
* @author Randall Hauch
*/
@NotThreadSafe
-public class InMemoryRepository {
+public class InMemoryRepository extends MapRepository {
- protected final ReadWriteLock lock = new ReentrantReadWriteLock();
- protected final UUID rootNodeUuid;
- private final String sourceName;
- private final String defaultWorkspaceName;
- private final Map<String, Workspace> workspaces = new HashMap<String, Workspace>();
-
public InMemoryRepository( String sourceName,
UUID rootNodeUuid ) {
- this(sourceName, rootNodeUuid, null);
+ super(sourceName, rootNodeUuid, null);
+ initialize();
}
public InMemoryRepository( String sourceName,
UUID rootNodeUuid,
String defaultWorkspaceName ) {
- CheckArg.isNotEmpty(sourceName, "sourceName");
- CheckArg.isNotNull(rootNodeUuid, "rootNodeUUID");
- this.rootNodeUuid = rootNodeUuid;
- this.sourceName = sourceName;
- this.defaultWorkspaceName = defaultWorkspaceName != null ? defaultWorkspaceName : "";
- // Create the default workspace ...
- workspaces.put(this.defaultWorkspaceName, new Workspace(this.defaultWorkspaceName));
+ super(sourceName, rootNodeUuid, defaultWorkspaceName);
+ initialize();
}
- /**
- * @return sourceName
- */
- public String getSourceName() {
- return sourceName;
- }
-
- /**
- * @return lock
- */
- public ReadWriteLock getLock() {
- return lock;
- }
-
@GuardedBy( "getLock()" )
- public Set<String> getWorkspaceNames() {
- return workspaces.keySet();
+ protected MapWorkspace createWorkspace( ExecutionContext context,
+ String name ) {
+ return new Workspace(this, name);
}
- @GuardedBy( "getLock()" )
- public Workspace getWorkspace( ExecutionContext context,
- String name ) {
- if (name == null) name = defaultWorkspaceName;
- return workspaces.get(name);
- }
+ protected class Workspace extends AbstractMapWorkspace {
+ private final Map<UUID, MapNode> nodesByUuid = new HashMap<UUID, MapNode>();
- @GuardedBy( "getLock()" )
- public Workspace createWorkspace( ExecutionContext context,
- String name,
- CreateConflictBehavior behavior ) {
- String newName = name;
- boolean conflictingName = workspaces.containsKey(newName);
- if (conflictingName) {
- switch (behavior) {
- case DO_NOT_CREATE:
- return null;
- case CREATE_WITH_ADJUSTED_NAME:
- int counter = 0;
- do {
- newName = name + (++counter);
- } while (workspaces.containsKey(newName));
- break;
- }
- }
- assert workspaces.containsKey(newName) == false;
- Workspace workspace = new Workspace(newName);
- workspaces.put(newName, workspace);
- return workspace;
- }
+ public Workspace( MapRepository repository,
+ String name ) {
+ super(repository, name);
- @GuardedBy( "getLock()" )
- public Workspace createWorkspace( ExecutionContext context,
- String name,
- CreateConflictBehavior existingWorkspaceBehavior,
- String nameOfWorkspaceToClone ) {
- Workspace workspace = createWorkspace(context, name, existingWorkspaceBehavior);
- if (workspace == null) {
- // Unable to create because of a duplicate name ...
- return null;
+ initialize();
}
- Workspace original = getWorkspace(context, nameOfWorkspaceToClone);
- if (original != null) {
- // Copy the properties of the root node ...
- InMemoryNode root = workspace.getRoot();
- InMemoryNode origRoot = original.getRoot();
- root.getProperties().clear();
- root.getProperties().putAll(origRoot.getProperties());
- // Loop over each child and call this method to copy the immediate children (and below).
- // Note that this makes the copy have the same UUID as the original.
- for (InMemoryNode originalNode : origRoot.getChildren()) {
- original.copyNode(context, originalNode, workspace, root, originalNode.getName().getName(), true, null);
- }
- }
- return workspace;
- }
-
- @GuardedBy( "getLock()" )
- public boolean destroyWorkspace( String name ) {
- return workspaces.remove(name) != null;
- }
-
- protected class Workspace {
- private final Map<UUID, InMemoryNode> nodesByUuid = new HashMap<UUID, InMemoryNode>();
- private final String name;
-
- protected Workspace( String name ) {
- assert name != null;
- this.name = name;
- // Create the root node ...
- InMemoryNode root = new InMemoryNode(rootNodeUuid);
- nodesByUuid.put(root.getUuid(), root);
- }
-
- /**
- * @return name
- */
- public String getName() {
- return name;
- }
-
- public InMemoryNode getRoot() {
- return nodesByUuid.get(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;
- }
-
- /**
- * Returns the absolute path to the given node
- *
- * @param pathFactory the path factory to use to create the path from the list of names of all of the nodes on the path
- * from the root node to the given node
- * @param node the node for which the path should be returned
- * @return the absolute path to the given node
- */
- Path pathFor( PathFactory pathFactory,
- InMemoryNode node ) {
+ protected void addNodeToMap( MapNode node ) {
assert node != null;
- assert pathFactory != null;
-
- LinkedList<Path.Segment> segments = new LinkedList<Path.Segment>();
- InMemoryNode root = getRoot();
-
- do {
- segments.addFirst(node.getName());
- node = node.getParent();
- } while (!node.equals(root));
-
- return pathFactory.createAbsolutePath(segments);
+ assert nodesByUuid != null;
+ nodesByUuid.put(node.getUuid(), 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 MapNode removeNodeFromMap( UUID nodeUuid ) {
+ assert nodeUuid != null;
+ return nodesByUuid.remove(nodeUuid);
}
- public void removeNode( ExecutionContext context,
- InMemoryNode node ) {
- assert context != null;
- assert node != null;
- if (getRoot().equals(node)) {
- nodesByUuid.clear();
- // Create the root node ...
- InMemoryNode root = new InMemoryNode(rootNodeUuid);
- nodesByUuid.put(root.getUuid(), root);
- return;
- }
- InMemoryNode parent = node.getParent();
- assert parent != null;
- parent.getChildren().remove(node);
- correctSameNameSiblingIndexes(context, parent, node.getName().getName());
- removeUuidReference(node);
+ protected void removeAllNodesFromMap() {
+ nodesByUuid.clear();
}
- protected void removeUuidReference( InMemoryNode node ) {
- nodesByUuid.remove(node.getUuid());
- for (InMemoryNode child : node.getChildren()) {
- removeUuidReference(child);
- }
+ public MapNode getNode( UUID nodeUuid ) {
+ assert nodeUuid != null;
+ return nodesByUuid.get(nodeUuid);
}
/**
- * 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 = UUID.randomUUID();
- InMemoryNode node = new InMemoryNode(uuid);
- nodesByUuid.put(node.getUuid(), node);
- node.setParent(parentNode);
- // Find the last node with this same name ...
- int nextIndex = 1;
- if (parentNode.existingNames.contains(name)) {
- ListIterator<InMemoryNode> iter = parentNode.getChildren().listIterator(parentNode.getChildren().size());
- while (iter.hasPrevious()) {
- InMemoryNode prev = iter.previous();
- if (prev.getName().getName().equals(name)) {
- nextIndex = prev.getName().getIndex() + 1;
- break;
- }
- }
- }
- Path.Segment newName = context.getValueFactories().getPathFactory().createSegment(name, nextIndex);
- node.setName(newName);
- parentNode.getChildren().add(node);
- parentNode.existingNames.add(name);
- return node;
- }
-
- /**
- * 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 Workspace#getRoot() root}
- * @param desiredNewName the new name for the node, if it is to be changed; may be null
- * @param newWorkspace the workspace containing the new parent node
- * @param newParent the new parent; may not be the {@link Workspace#getRoot() root}
- * @param beforeNode the node before which this new node should be placed
- */
- public void moveNode( ExecutionContext context,
- InMemoryNode node,
- Name desiredNewName,
- Workspace newWorkspace,
- InMemoryNode newParent,
- InMemoryNode beforeNode ) {
- assert context != null;
- assert newParent != null;
- assert node != null;
- // Why was this restriction here? -- BRC
- // assert newWorkspace.getRoot().equals(newParent) != true;
- assert this.getRoot().equals(node) != true;
- InMemoryNode oldParent = node.getParent();
- Name oldName = node.getName().getName();
- if (oldParent != null) {
- boolean removed = oldParent.getChildren().remove(node);
- assert removed == true;
- node.setParent(null);
- correctSameNameSiblingIndexes(context, oldParent, oldName);
- }
- node.setParent(newParent);
- Name newName = oldName;
- if (desiredNewName != null) {
- newName = desiredNewName;
- node.setName(context.getValueFactories().getPathFactory().createSegment(desiredNewName, 1));
- }
-
- if (beforeNode == null) {
- newParent.getChildren().add(node);
- } else {
- int index = newParent.getChildren().indexOf(beforeNode);
- newParent.getChildren().add(index, node);
- }
- correctSameNameSiblingIndexes(context, newParent, newName);
-
- // If the node was moved to a new workspace...
- if (!this.equals(newWorkspace)) {
- // We need to remove the node from this workspace's map of nodes ...
- this.moveNodeToWorkspace(node, newWorkspace);
- }
- }
-
- protected void moveNodeToWorkspace( InMemoryNode node,
- Workspace newWorkspace ) {
- assert this.nodesByUuid.containsKey(node.getUuid());
- assert !newWorkspace.nodesByUuid.containsKey(node.getUuid());
-
- this.nodesByUuid.remove(node.getUuid());
- newWorkspace.nodesByUuid.put(node.getUuid(), node);
- for (InMemoryNode child : node.getChildren()) {
- moveNodeToWorkspace(child, newWorkspace);
- }
- }
-
- /**
* 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.
+ * <p>
+ * This method is trivially overridden for testing purposes.
+ * </p>
*
* @param context the context; may not be null
* @param original the node to be copied; may not be null
@@ -448,152 +108,24 @@
* null if the UUIDs are to be maintained
* @return the new node, which is the top of the new subgraph
*/
- public InMemoryNode copyNode( ExecutionContext context,
- InMemoryNode original,
- Workspace newWorkspace,
- InMemoryNode newParent,
- Name desiredName,
- boolean recursive,
- Map<UUID, UUID> oldToNewUuids ) {
- assert context != null;
- assert original != null;
- assert newParent != null;
- assert newWorkspace != null;
- boolean reuseUuids = oldToNewUuids == null;
-
- // Get or create the new node ...
- Name childName = desiredName != null ? desiredName : original.getName().getName();
- UUID uuidForCopy = reuseUuids ? original.getUuid() : UUID.randomUUID();
- InMemoryNode copy = newWorkspace.createNode(context, newParent, childName, uuidForCopy);
- if (!reuseUuids) {
- assert oldToNewUuids != 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, newWorkspace, copy, null, true, oldToNewUuids);
- }
- }
-
- if (!reuseUuids) {
- assert oldToNewUuids != null;
- // 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 = this.getNode(oldToNew.getKey());
- InMemoryNode newNode = newWorkspace.getNode(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;
- }
-
- public Set<UUID> getUuidsUnderNode( InMemoryNode node ) {
- Set<UUID> uuids = new HashSet<UUID>();
- uuidsUnderNode(node, uuids);
-
- return uuids;
- }
-
- private void uuidsUnderNode( InMemoryNode node,
- Set<UUID> accumulator ) {
- accumulator.add(node.getUuid());
-
- for (InMemoryNode child : node.getChildren()) {
- uuidsUnderNode(child, accumulator);
- }
- }
-
- 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.DEFAULT_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;
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
@Override
- public boolean equals( Object obj ) {
- if (obj == this) return true;
- if (obj instanceof Workspace) {
- Workspace that = (Workspace)obj;
- // Assume the workspaces are in the same repository ...
- if (!this.name.equals(that.name)) return false;
- return true;
- }
- return false;
+ protected MapNode copyNode( ExecutionContext context,
+ MapNode original,
+ MapWorkspace newWorkspace,
+ MapNode newParent,
+ Name desiredName,
+ boolean recursive,
+ Map<UUID, UUID> oldToNewUuids ) {
+ return super.copyNode(context, original, newWorkspace, newParent, desiredName, recursive, oldToNewUuids);
}
/**
- * {@inheritDoc}
+ * Method added to support testing
*
- * @see java.lang.Object#toString()
+ * @return the number of nodes in the backing map
*/
- @Override
- public String toString() {
- return InMemoryRepository.this.getSourceName() + "/" + this.getName();
+ final int size() {
+ return nodesByUuid.size();
}
-
}
-
}
Deleted: 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 2009-06-24 22:14:12 UTC (rev 1064)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositoryConnection.java 2009-06-27 02:54:06 UTC (rev 1065)
@@ -1,135 +0,0 @@
-/*
- * 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.request.Request;
-import org.jboss.dna.graph.request.processor.RequestProcessor;
-
-/**
- * @author Randall Hauch
- */
-public class InMemoryRepositoryConnection implements RepositoryConnection {
-
- private final InMemoryRepositorySource source;
- private final InMemoryRepository repository;
-
- InMemoryRepositoryConnection( InMemoryRepositorySource source,
- InMemoryRepository repository ) {
- assert source != null;
- assert repository != null;
- this.source = source;
- this.repository = repository;
- }
-
- /**
- * {@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 ) {
- return true;
- }
-
- /**
- * {@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 = new InMemoryRequestProcessor(context, this.repository, this.source.getRepositoryContext());
-
- Lock lock = request.isReadOnly() ? repository.getLock().readLock() : repository.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());
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return "Connection to the \"" + getSourceName() + "\" in-memory repository";
- }
-}
Modified: 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 2009-06-24 22:14:12 UTC (rev 1064)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositorySource.java 2009-06-27 02:54:06 UTC (rev 1065)
@@ -52,6 +52,8 @@
import org.jboss.dna.graph.connector.RepositorySource;
import org.jboss.dna.graph.connector.RepositorySourceCapabilities;
import org.jboss.dna.graph.connector.RepositorySourceException;
+import org.jboss.dna.graph.connector.map.MapRepositoryConnection;
+import org.jboss.dna.graph.connector.map.MapRepositorySource;
/**
* A {@link RepositorySource} for an in-memory repository. Each {@link InMemoryRepositorySource} instance contains its own
@@ -59,7 +61,7 @@
*
* @author Randall Hauch
*/
-public class InMemoryRepositorySource implements RepositorySource, ObjectFactory {
+public class InMemoryRepositorySource implements MapRepositorySource, ObjectFactory {
/**
* The initial version is 1
@@ -258,7 +260,7 @@
if (repository == null) {
repository = new InMemoryRepository(name, rootNodeUuid, defaultWorkspaceName);
}
- return new InMemoryRepositoryConnection(this, repository);
+ return new MapRepositoryConnection(this, repository);
}
/**
Deleted: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRequestProcessor.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRequestProcessor.java 2009-06-24 22:14:12 UTC (rev 1064)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRequestProcessor.java 2009-06-27 02:54:06 UTC (rev 1065)
@@ -1,498 +0,0 @@
-/*
- * 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.
- *
- * 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.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-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.JcrLexicon;
-import org.jboss.dna.graph.Location;
-import org.jboss.dna.graph.connector.RepositoryContext;
-import org.jboss.dna.graph.connector.UuidAlreadyExistsException;
-import org.jboss.dna.graph.property.Name;
-import org.jboss.dna.graph.property.NamespaceRegistry;
-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.Path.Segment;
-import org.jboss.dna.graph.request.CloneWorkspaceRequest;
-import org.jboss.dna.graph.request.CopyBranchRequest;
-import org.jboss.dna.graph.request.CreateNodeRequest;
-import org.jboss.dna.graph.request.CreateWorkspaceRequest;
-import org.jboss.dna.graph.request.DeleteBranchRequest;
-import org.jboss.dna.graph.request.DestroyWorkspaceRequest;
-import org.jboss.dna.graph.request.GetWorkspacesRequest;
-import org.jboss.dna.graph.request.InvalidWorkspaceException;
-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.VerifyWorkspaceRequest;
-import org.jboss.dna.graph.request.processor.RequestProcessor;
-
-/**
- * A {@link RequestProcessor} implementation that operates on an {@link InMemoryRepository} and its
- * {@link InMemoryRepository.Workspace workspaces}.
- */
-public class InMemoryRequestProcessor extends RequestProcessor {
- private final PathFactory pathFactory;
- private final PropertyFactory propertyFactory;
- private final InMemoryRepository repository;
-
- protected InMemoryRequestProcessor( ExecutionContext context,
- InMemoryRepository repository,
- RepositoryContext repositoryContext ) {
- super(repository.getSourceName(), context, repositoryContext != null ? repositoryContext.getObserver() : null);
- this.repository = repository;
- pathFactory = context.getValueFactories().getPathFactory();
- propertyFactory = context.getPropertyFactory();
- }
-
- @Override
- public void process( ReadAllChildrenRequest request ) {
- InMemoryRepository.Workspace workspace = getWorkspace(request, request.inWorkspace());
- InMemoryNode node = getTargetNode(workspace, 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 ) {
- InMemoryRepository.Workspace workspace = getWorkspace(request, request.inWorkspace());
- InMemoryNode node = getTargetNode(workspace, 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 ) {
- InMemoryRepository.Workspace workspace = getWorkspace(request, request.fromWorkspace());
- InMemoryRepository.Workspace newWorkspace = getWorkspace(request, request.intoWorkspace());
- if (workspace == null || newWorkspace == null) return;
- InMemoryNode node = getTargetNode(workspace, request, request.from());
- if (node == null) return;
-
- Map<UUID, UUID> copyMap = null;
- Set<UUID> uuidsInFromBranch = null;
-
- switch (request.uuidConflictBehavior()) {
- case ALWAYS_CREATE_NEW_UUID:
-
- /*
- * The copyNode method uses the presence of a non-null map as an indicator that new UUIDs should be created
- * during the copy operation
- */
- copyMap = new HashMap<UUID, UUID>();
- break;
- case REPLACE_EXISTING_NODE:
- uuidsInFromBranch = workspace.getUuidsUnderNode(node);
-
- for (UUID uuid : uuidsInFromBranch) {
- InMemoryNode existing;
- if (null != (existing = newWorkspace.getNode(uuid))) {
- newWorkspace.removeNode(this.getExecutionContext(), existing);
- }
- }
- break;
- case THROW_EXCEPTION:
- uuidsInFromBranch = workspace.getUuidsUnderNode(node);
-
- for (UUID uuid : uuidsInFromBranch) {
- InMemoryNode existing;
- if (null != (existing = newWorkspace.getNode(uuid))) {
- NamespaceRegistry namespaces = this.getExecutionContext().getNamespaceRegistry();
- String path = newWorkspace.pathFor(pathFactory, existing).getString(namespaces);
- request.setError(new UuidAlreadyExistsException(this.getSourceName(), uuid, path, newWorkspace.getName()));
- return;
- }
- }
- break;
-
- default:
- throw new IllegalStateException("Unexpected UUID conflict behavior: " + request.uuidConflictBehavior());
- }
-
- // Look up the new parent, which must exist ...
- Path newParentPath = request.into().getPath();
- Name desiredName = request.desiredName();
- InMemoryNode newParent = newWorkspace.getNode(newParentPath);
- InMemoryNode newNode = workspace.copyNode(getExecutionContext(),
- node,
- newWorkspace,
- newParent,
- desiredName,
- true,
- copyMap);
- Path newPath = getExecutionContext().getValueFactories().getPathFactory().create(newParentPath, newNode.getName());
- Location oldLocation = getActualLocation(request.from().getPath(), node);
- Location newLocation = Location.create(newPath, newNode.getUuid());
- request.setActualLocations(oldLocation, newLocation);
- recordChange(request);
- }
-
- @Override
- public void process( CreateNodeRequest request ) {
- InMemoryRepository.Workspace workspace = getWorkspace(request, request.inWorkspace());
- if (workspace == null) return;
- Path parent = request.under().getPath();
- CheckArg.isNotNull(parent, "request.under().getPath()");
- InMemoryNode node = null;
- // Look up the parent node, which must exist ...
- // System.err.println(request.toString());
- InMemoryNode parentNode = workspace.getNode(parent);
- if (parentNode == null) {
- Path lowestExisting = workspace.getLowestExistingPath(parent);
- request.setError(new PathNotFoundException(request.under(), lowestExisting,
- GraphI18n.inMemoryNodeDoesNotExist.text(parent)));
- return;
- }
- UUID uuid = null;
- for (Property property : request.properties()) {
- if (property.getName().equals(DnaLexicon.UUID) || property.getName().equals(JcrLexicon.UUID)) {
- uuid = getExecutionContext().getValueFactories().getUuidFactory().create(property.getValues().next());
- break;
- }
- }
- switch (request.conflictBehavior()) {
- case APPEND:
- case DO_NOT_REPLACE:
- node = workspace.createNode(getExecutionContext(), parentNode, request.named(), uuid);
- break;
- case REPLACE:
- // See if the node already exists (this doesn't record an error on the request) ...
- node = getTargetNode(workspace, null, Location.create(pathFactory.create(parent, request.named()), uuid));
- if (node != null) {
- workspace.removeNode(getExecutionContext(), node);
- }
- node = workspace.createNode(getExecutionContext(), parentNode, request.named(), uuid);
- break;
- case UPDATE:
- // See if the node already exists (this doesn't record an error on the request) ...
- node = getTargetNode(workspace, null, Location.create(pathFactory.create(parent, request.named()), uuid));
- if (node == null) {
- node = workspace.createNode(getExecutionContext(), parentNode, request.named(), uuid);
- } // otherwise, we found it and we're setting any properties below
- break;
- }
- 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);
- recordChange(request);
- }
-
- @Override
- public void process( DeleteBranchRequest request ) {
- InMemoryRepository.Workspace workspace = getWorkspace(request, request.inWorkspace());
- if (workspace == null) return;
- InMemoryNode node = getTargetNode(workspace, request, request.at());
- if (node == null) return;
- workspace.removeNode(getExecutionContext(), node);
- Location actualLocation = getActualLocation(request.at().getPath(), node);
- request.setActualLocationOfNode(actualLocation);
- recordChange(request);
- }
-
- @Override
- public void process( MoveBranchRequest request ) {
- InMemoryRepository.Workspace workspace = getWorkspace(request, request.inWorkspace());
- if (workspace == null) return;
-
- InMemoryNode beforeNode = request.before() != null ? getTargetNode(workspace, request, request.before()) : null;
- InMemoryNode node = getTargetNode(workspace, request, request.from());
- if (node == null) return;
- // Look up the new parent, which must exist ...
- Path newParentPath;
-
- if (request.into() != null) {
- newParentPath = request.into().getPath();
- } else {
- // into or before cannot both be null
- assert beforeNode != null;
-
- // Build the path from the before node to the root.
- LinkedList<Path.Segment> segments = new LinkedList<Path.Segment>();
- InMemoryNode current = beforeNode.getParent();
- while (current != workspace.getRoot()) {
- segments.addFirst(current.getName());
- current = current.getParent();
- }
- newParentPath = getExecutionContext().getValueFactories().getPathFactory().createAbsolutePath(segments);
- }
-
- InMemoryNode newParent = workspace.getNode(newParentPath);
- workspace.moveNode(getExecutionContext(), node, request.desiredName(), workspace, newParent, beforeNode);
- assert node.getParent() == newParent;
- Path newPath = getExecutionContext().getValueFactories().getPathFactory().create(newParentPath, node.getName());
- Location oldLocation = getActualLocation(request.from().getPath(), node);
- Location newLocation = Location.create(newPath, node.getUuid());
- request.setActualLocations(oldLocation, newLocation);
- recordChange(request);
- }
-
- @Override
- public void process( UpdatePropertiesRequest request ) {
- InMemoryRepository.Workspace workspace = getWorkspace(request, request.inWorkspace());
- InMemoryNode node = getTargetNode(workspace, request, request.on());
- if (node == null) return;
- // Now set (or remove) the properties to the supplied node ...
- for (Map.Entry<Name, Property> propertyEntry : request.properties().entrySet()) {
- Property property = propertyEntry.getValue();
- if (property == null) {
- node.getProperties().remove(propertyEntry.getKey());
- continue;
- }
- Name propName = property.getName();
- if (!propName.equals(DnaLexicon.UUID)) {
- node.getProperties().put(propName, property);
- }
- }
- Location actualLocation = getActualLocation(request.on().getPath(), node);
- request.setActualLocationOfNode(actualLocation);
- recordChange(request);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CreateWorkspaceRequest)
- */
- @Override
- public void process( CreateWorkspaceRequest request ) {
- InMemoryRepository.Workspace workspace = repository.createWorkspace(getExecutionContext(),
- request.desiredNameOfNewWorkspace(),
- request.conflictBehavior());
- if (workspace == null) {
- String msg = GraphI18n.workspaceAlreadyExistsInRepository.text(request.desiredNameOfNewWorkspace(),
- repository.getSourceName());
- request.setError(new InvalidWorkspaceException(msg));
- } else {
- InMemoryNode root = workspace.getRoot();
- request.setActualRootLocation(Location.create(pathFactory.createRootPath(), root.getUuid()));
- request.setActualWorkspaceName(workspace.getName());
- recordChange(request);
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.DestroyWorkspaceRequest)
- */
- @Override
- public void process( DestroyWorkspaceRequest request ) {
- InMemoryRepository.Workspace workspace = repository.getWorkspace(getExecutionContext(), request.workspaceName());
- if (workspace != null) {
- InMemoryNode root = workspace.getRoot();
- request.setActualRootLocation(Location.create(pathFactory.createRootPath(), root.getUuid()));
- recordChange(request);
- } else {
- String msg = GraphI18n.workspaceDoesNotExistInRepository.text(request.workspaceName(), repository.getSourceName());
- request.setError(new InvalidWorkspaceException(msg));
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.GetWorkspacesRequest)
- */
- @Override
- public void process( GetWorkspacesRequest request ) {
- Set<String> names = repository.getWorkspaceNames();
- request.setAvailableWorkspaceNames(new HashSet<String>(names));
- setCacheableInfo(request);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.VerifyWorkspaceRequest)
- */
- @Override
- public void process( VerifyWorkspaceRequest request ) {
- InMemoryRepository.Workspace original = getWorkspace(request, request.workspaceName());
- if (original != null) {
- Path path = getExecutionContext().getValueFactories().getPathFactory().createRootPath();
- request.setActualRootLocation(Location.create(path, original.getRoot().getUuid()));
- request.setActualWorkspaceName(original.getName());
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CloneWorkspaceRequest)
- */
- @Override
- public void process( CloneWorkspaceRequest request ) {
- // Find the original workspace that we're cloning ...
- final ExecutionContext context = getExecutionContext();
- String targetWorkspaceName = request.desiredNameOfTargetWorkspace();
- String nameOfWorkspaceToBeCloned = request.nameOfWorkspaceToBeCloned();
- InMemoryRepository.Workspace original = repository.getWorkspace(context, nameOfWorkspaceToBeCloned);
- InMemoryRepository.Workspace target = repository.getWorkspace(context, targetWorkspaceName);
- if (original == null) {
- switch (request.cloneConflictBehavior()) {
- case DO_NOT_CLONE:
- String msg = GraphI18n.workspaceDoesNotExistInRepository.text(nameOfWorkspaceToBeCloned,
- repository.getSourceName());
- request.setError(new InvalidWorkspaceException(msg));
- return;
- case SKIP_CLONE:
- target = repository.createWorkspace(context, targetWorkspaceName, request.targetConflictBehavior());
- if (target == null) {
- msg = GraphI18n.workspaceAlreadyExistsInRepository.text(targetWorkspaceName, repository.getSourceName());
- request.setError(new InvalidWorkspaceException(msg));
- } else {
- InMemoryNode root = target.getRoot();
- request.setActualRootLocation(Location.create(pathFactory.createRootPath(), root.getUuid()));
- request.setActualWorkspaceName(target.getName());
- }
- return;
- }
- }
- assert original != null;
- target = repository.createWorkspace(context,
- targetWorkspaceName,
- request.targetConflictBehavior(),
- nameOfWorkspaceToBeCloned);
- if (target == null) {
- // Since the original was there, the only reason the target wasn't created was because the workspace already existed
- // ...
- String msg = GraphI18n.workspaceAlreadyExistsInRepository.text(targetWorkspaceName, repository.getSourceName());
- request.setError(new InvalidWorkspaceException(msg));
- } else {
- InMemoryNode root = target.getRoot();
- request.setActualRootLocation(Location.create(pathFactory.createRootPath(), root.getUuid()));
- request.setActualWorkspaceName(target.getName());
- recordChange(request);
- }
- }
-
- 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 Location.create(path, node.getUuid());
- }
-
- protected InMemoryRepository.Workspace getWorkspace( Request request,
- String workspaceName ) {
- // Get the workspace for this request ...
- InMemoryRepository.Workspace workspace = repository.getWorkspace(getExecutionContext(), workspaceName);
- if (workspace == null) {
- String msg = GraphI18n.workspaceDoesNotExistInRepository.text(workspaceName, repository.getSourceName());
- request.setError(new InvalidWorkspaceException(msg));
- }
- return workspace;
- }
-
- protected InMemoryNode getTargetNode( InMemoryRepository.Workspace workspace,
- Request request,
- Location location ) {
- if (workspace == null) return null;
- // Check first for the UUID ...
- InMemoryNode node = null;
- UUID uuid = location.getUuid();
- if (uuid != null) {
- node = workspace.getNode(uuid);
- }
- Path path = null;
- if (node == null) {
- // Look up the node with the supplied path ...
- path = location.getPath();
- if (path != null) {
- node = workspace.getNode(path);
- }
- }
- if (node == null && request != 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 = workspace.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/map/AbstractMapWorkspace.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/AbstractMapWorkspace.java (rev 0)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/AbstractMapWorkspace.java 2009-06-27 02:54:06 UTC (rev 1065)
@@ -0,0 +1,642 @@
+/*
+ * 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.map;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.connector.UuidAlreadyExistsException;
+import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.NamespaceRegistry;
+import org.jboss.dna.graph.property.Path;
+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.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.basic.RootPath;
+import org.jboss.dna.graph.request.UuidConflictBehavior;
+
+/**
+ * A default implementation of {@link MapWorkspace} that only requires the user to implement some simple, map-like operations.
+ */
+public abstract class AbstractMapWorkspace implements MapWorkspace {
+
+ private final MapRepository repository;
+ private final String name;
+
+ protected AbstractMapWorkspace( MapRepository repository,
+ String name ) {
+ assert repository != null;
+ assert name != null;
+
+ this.repository = repository;
+ this.name = name;
+ }
+
+ protected void initialize() {
+
+ // Create the root node ...
+ MapNode root = createMapNode(repository.getRootNodeUuid());
+ assert root != null;
+ addNodeToMap(root);
+
+ }
+
+ /**
+ * Adds the given node to the backing map, replacing any node already in the backing map with the same UUID.
+ *
+ * @param node the node to add to the map; may not be null
+ */
+ protected abstract void addNodeToMap( MapNode node );
+
+ /**
+ * Removes the node with the given UUID from the backing map, returning the node if it exists
+ *
+ * @param nodeUuid the UUID of the node to replace; may not be null
+ * @return if a node with that UUID exists in the backing map (prior to removal), that node is returned; otherwise null
+ */
+ protected abstract MapNode removeNodeFromMap( UUID nodeUuid );
+
+ /**
+ * Removes all of the nodes from the backing map
+ */
+ protected abstract void removeAllNodesFromMap();
+
+ /**
+ * Gets the node with the given UUID from the backing map, if one exists
+ *
+ * @param nodeUuid the UUID of the node to be retrieved; may not be null
+ * @return the node that exists in the backing map with the given UUID
+ */
+ public abstract MapNode getNode( UUID nodeUuid );
+
+ /**
+ * Creates an empty {@link MapNode node} with the given UUID.
+ * <p>
+ * This method does not add the new map node to the map. That must be done with a separate call to
+ * {@link #addNodeToMap(MapNode)}.
+ * </p>
+ *
+ * @param uuid the UUID that identifies the new node; may not be null
+ * @return the new node with the given UUID
+ */
+ protected MapNode createMapNode( UUID uuid ) {
+ assert uuid != null;
+ return new MapNode(uuid);
+ }
+
+ /**
+ * @return name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see MapWorkspace#getRoot()
+ */
+ public MapNode getRoot() {
+ return getNode(repository.getRootNodeUuid());
+ }
+
+ /**
+ * Find a node with the given path.
+ *
+ * @param context the execution context to use to convert {@code path} to a {@link Path}; may not be null
+ * @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 MapNode 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 MapNode getNode( Path path ) {
+ assert path != null;
+ MapNode node = getRoot();
+ for (Path.Segment segment : path) {
+ MapNode desiredChild = null;
+ for (MapNode 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;
+ }
+
+ /**
+ * Returns the absolute path to the given node
+ *
+ * @param pathFactory the path factory to use to create the path from the list of names of all of the nodes on the path from
+ * the root node to the given node
+ * @param node the node for which the path should be returned
+ * @return the absolute path to the given node
+ */
+ public Path pathFor( PathFactory pathFactory,
+ MapNode node ) {
+ assert node != null;
+ assert pathFactory != null;
+
+ LinkedList<Path.Segment> segments = new LinkedList<Path.Segment>();
+ MapNode root = getRoot();
+
+ do {
+ segments.addFirst(node.getName());
+ node = node.getParent();
+ } while (!node.equals(root));
+
+ return pathFactory.createAbsolutePath(segments);
+ }
+
+ /**
+ * 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;
+ MapNode node = getRoot();
+ int segmentNumber = 0;
+ for (Path.Segment segment : path) {
+ MapNode desiredChild = null;
+ for (MapNode 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;
+ }
+
+ /**
+ * Removes the given node and its children, correcting the SNS and child indices for its parent.
+ *
+ * @param context the current execution context
+ * @param node the node to be removed
+ */
+ public void removeNode( ExecutionContext context,
+ MapNode node ) {
+ assert context != null;
+ assert node != null;
+ if (getRoot().equals(node)) {
+ removeAllNodesFromMap();
+ // Recreate the root node ...
+ addNodeToMap(createMapNode(repository.getRootNodeUuid()));
+ return;
+ }
+ MapNode parent = node.getParent();
+ assert parent != null;
+ parent.getChildren().remove(node);
+ correctSameNameSiblingIndexes(context, parent, node.getName().getName());
+ removeUuidReference(node);
+ }
+
+ /**
+ * Recursively removes the given node and its children from the backing map
+ *
+ * @param node the root of the branch to be removed
+ */
+ protected void removeUuidReference( MapNode node ) {
+ assert node != null;
+ removeNodeFromMap(node.getUuid());
+
+ for (MapNode 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 MapNode 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();
+ MapNode 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 MapNode createNode( ExecutionContext context,
+ MapNode parentNode,
+ Name name,
+ UUID uuid ) {
+ assert context != null;
+ assert name != null;
+ if (parentNode == null) parentNode = getRoot();
+ if (uuid == null) uuid = UUID.randomUUID();
+
+ MapNode node = createMapNode(uuid);
+ addNodeToMap(node);
+
+ node.setParent(parentNode);
+ // Find the last node with this same name ...
+ int nextIndex = 1;
+ if (parentNode.existingNames.contains(name)) {
+ ListIterator<MapNode> iter = parentNode.getChildren().listIterator(parentNode.getChildren().size());
+ while (iter.hasPrevious()) {
+ MapNode prev = iter.previous();
+ if (prev.getName().getName().equals(name)) {
+ nextIndex = prev.getName().getIndex() + 1;
+ break;
+ }
+ }
+ }
+ Path.Segment newName = context.getValueFactories().getPathFactory().createSegment(name, nextIndex);
+ node.setName(newName);
+ parentNode.getChildren().add(node);
+ parentNode.existingNames.add(name);
+ return node;
+ }
+
+ /**
+ * 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 AbstractMapWorkspace#getRoot() root}
+ * @param desiredNewName the new name for the node, if it is to be changed; may be null
+ * @param newWorkspace the workspace containing the new parent node
+ * @param newParent the new parent; may not be the {@link AbstractMapWorkspace#getRoot() root}
+ * @param beforeNode the node before which this new node should be placed
+ */
+ public void moveNode( ExecutionContext context,
+ MapNode node,
+ Name desiredNewName,
+ MapWorkspace newWorkspace,
+ MapNode newParent,
+ MapNode beforeNode ) {
+ assert context != null;
+ assert newParent != null;
+ assert node != null;
+ assert newWorkspace instanceof AbstractMapWorkspace;
+
+ AbstractMapWorkspace newAbstractMapWorkspace = (AbstractMapWorkspace)newWorkspace;
+
+ // Why was this restriction here? -- BRC
+ // assert newAbstractMapWorkspace.getRoot().equals(newParent) != true;
+ assert this.getRoot().equals(node) != true;
+ MapNode oldParent = node.getParent();
+ Name oldName = node.getName().getName();
+ if (oldParent != null) {
+ boolean removed = oldParent.getChildren().remove(node);
+ assert removed == true;
+ node.setParent(null);
+ correctSameNameSiblingIndexes(context, oldParent, oldName);
+ }
+ node.setParent(newParent);
+ Name newName = oldName;
+ if (desiredNewName != null) {
+ newName = desiredNewName;
+ node.setName(context.getValueFactories().getPathFactory().createSegment(desiredNewName, 1));
+ }
+
+ if (beforeNode == null) {
+ newParent.getChildren().add(node);
+ } else {
+ int index = newParent.getChildren().indexOf(beforeNode);
+ newParent.getChildren().add(index, node);
+ }
+ correctSameNameSiblingIndexes(context, newParent, newName);
+
+ // If the node was moved to a new workspace...
+ if (!this.equals(newAbstractMapWorkspace)) {
+ // We need to remove the node from this workspace's map of nodes ...
+ this.moveNodeToWorkspace(node, newAbstractMapWorkspace);
+ }
+ }
+
+ /**
+ * Moves the branch rooted at the given node to the new workspace, removing it from this workspace. If a node with any of the
+ * UUIDs in the branch already exists in the new workspace, it will be replaced by the node from the branch.
+ *
+ * @param node the root node of the branch to be moved
+ * @param newWorkspace the workspace to which the branch should be moved
+ */
+ protected void moveNodeToWorkspace( MapNode node,
+ AbstractMapWorkspace newWorkspace ) {
+ assert getNode(node.getUuid()) != null;
+ assert newWorkspace.getNode(node.getUuid()) == null;
+
+ removeNodeFromMap(node.getUuid());
+ newWorkspace.addNodeToMap(node);
+
+ for (MapNode child : node.getChildren()) {
+ moveNodeToWorkspace(child, newWorkspace);
+ }
+ }
+
+ /**
+ * 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 the context; may not be null
+ * @param original the node to be copied; may not be null
+ * @param newWorkspace the workspace containing the new parent node; may not be null
+ * @param newParent the parent where the copy is to be placed; may not be null
+ * @param desiredName the desired name for the node; if null, the name will be obtained from the original node
+ * @param recursive true if the copy should be recursive
+ * @param uuidConflictBehavior the behavior to use if a UUID in the branch rooted at {@code original} already exists in the
+ * new workspace
+ * @return the new node, which is the top of the new subgraph
+ */
+ public MapNode copyNode( ExecutionContext context,
+ MapNode original,
+ MapWorkspace newWorkspace,
+ MapNode newParent,
+ Name desiredName,
+ boolean recursive,
+ UuidConflictBehavior uuidConflictBehavior ) throws UuidAlreadyExistsException {
+ Map<UUID, UUID> copyMap = null;
+ Set<UUID> uuidsInFromBranch = null;
+
+ switch (uuidConflictBehavior) {
+ case ALWAYS_CREATE_NEW_UUID:
+
+ /*
+ * The copyNode method uses the presence of a non-null map as an indicator that new UUIDs should be created
+ * during the copy operation
+ */
+ copyMap = new HashMap<UUID, UUID>();
+ break;
+ case REPLACE_EXISTING_NODE:
+ uuidsInFromBranch = getUuidsUnderNode(original);
+
+ for (UUID uuid : uuidsInFromBranch) {
+ MapNode existing;
+ if (null != (existing = newWorkspace.getNode(uuid))) {
+ newWorkspace.removeNode(context, existing);
+ }
+ }
+ break;
+ case THROW_EXCEPTION:
+ uuidsInFromBranch = getUuidsUnderNode(original);
+ PathFactory pathFactory = context.getValueFactories().getPathFactory();
+ for (UUID uuid : uuidsInFromBranch) {
+ MapNode existing;
+ if (null != (existing = newWorkspace.getNode(uuid))) {
+ NamespaceRegistry namespaces = context.getNamespaceRegistry();
+ String path = newWorkspace.pathFor(pathFactory, existing).getString(namespaces);
+ throw new UuidAlreadyExistsException(repository.getSourceName(), uuid, path, newWorkspace.getName());
+ }
+ }
+ break;
+
+ default:
+ throw new IllegalStateException("Unexpected UUID conflict behavior: " + uuidConflictBehavior);
+ }
+
+ return copyNode(context, original, newWorkspace, newParent, desiredName, true, copyMap);
+ }
+
+ /**
+ * 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 the context; may not be null
+ * @param original the node to be copied; may not be null
+ * @param newWorkspace the workspace containing the new parent node; may not be null
+ * @param newParent the parent where the copy is to be placed; may not be null
+ * @param desiredName the desired name for the node; if null, the name will be obtained from the original node
+ * @param recursive true if the copy should be recursive
+ * @param oldToNewUuids the map of UUIDs of nodes in the new subgraph keyed by the UUIDs of nodes in the original; may be null
+ * if the UUIDs are to be maintained
+ * @return the new node, which is the top of the new subgraph
+ */
+ protected MapNode copyNode( ExecutionContext context,
+ MapNode original,
+ MapWorkspace newWorkspace,
+ MapNode newParent,
+ Name desiredName,
+ boolean recursive,
+ Map<UUID, UUID> oldToNewUuids ) {
+ assert context != null;
+ assert original != null;
+ assert newParent != null;
+ assert newWorkspace != null;
+ boolean reuseUuids = oldToNewUuids == null;
+
+ // Get or create the new node ...
+ Name childName = desiredName != null ? desiredName : original.getName().getName();
+ UUID uuidForCopy = reuseUuids ? original.getUuid() : UUID.randomUUID();
+ MapNode copy = newWorkspace.createNode(context, newParent, childName, uuidForCopy);
+ if (!reuseUuids) {
+ 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 (MapNode child : original.getChildren()) {
+ copyNode(context, child, newWorkspace, copy, null, true, oldToNewUuids);
+ }
+ }
+
+ if (!reuseUuids) {
+ // 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()) {
+ MapNode oldNode = this.getNode(oldToNew.getKey());
+ MapNode newNode = newWorkspace.getNode(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;
+ }
+
+ /**
+ * Returns all of the UUIDs in the branch rooted at {@code node}
+ *
+ * @param node the root of the branch
+ * @return all of the UUIDs in the branch rooted at {@code node}
+ */
+ public Set<UUID> getUuidsUnderNode( MapNode node ) {
+ Set<UUID> uuids = new HashSet<UUID>();
+ uuidsUnderNode(node, uuids);
+
+ return uuids;
+ }
+
+ private void uuidsUnderNode( MapNode node,
+ Set<UUID> accumulator ) {
+ accumulator.add(node.getUuid());
+
+ for (MapNode child : node.getChildren()) {
+ uuidsUnderNode(child, accumulator);
+ }
+ }
+
+ /**
+ * Corrects the SNS indices for all children of the node with the given name
+ *
+ * @param context the execution context
+ * @param parentNode the parent node
+ * @param name the name of the child nodes for which the SNS indices should be recalculated
+ */
+ protected void correctSameNameSiblingIndexes( ExecutionContext context,
+ MapNode parentNode,
+ Name name ) {
+ if (parentNode == null) return;
+ // Look for the highest existing index ...
+ List<MapNode> childrenWithSameNames = new LinkedList<MapNode>();
+ for (MapNode child : parentNode.getChildren()) {
+ if (child.getName().getName().equals(name)) childrenWithSameNames.add(child);
+ }
+ if (childrenWithSameNames.size() == 0) return;
+ if (childrenWithSameNames.size() == 1) {
+ MapNode childWithSameName = childrenWithSameNames.get(0);
+ Path.Segment newName = context.getValueFactories().getPathFactory().createSegment(name, Path.DEFAULT_INDEX);
+ childWithSameName.setName(newName);
+ return;
+ }
+ int index = 1;
+ for (MapNode childWithSameName : childrenWithSameNames) {
+ Path.Segment segment = childWithSameName.getName();
+ if (segment.getIndex() != index) {
+ Path.Segment newName = context.getValueFactories().getPathFactory().createSegment(name, index);
+ childWithSameName.setName(newName);
+ }
+ ++index;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof AbstractMapWorkspace) {
+ AbstractMapWorkspace that = (AbstractMapWorkspace)obj;
+ // Assume the workspaces are in the same repository ...
+ if (!this.name.equals(that.name)) return false;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return repository.getSourceName() + "/" + this.getName();
+ }
+
+}
Property changes on: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/AbstractMapWorkspace.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapNode.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapNode.java (rev 0)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapNode.java 2009-06-27 02:54:06 UTC (rev 1065)
@@ -0,0 +1,202 @@
+/*
+ * 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.map;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Map;
+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.Path;
+import org.jboss.dna.graph.property.Property;
+import org.jboss.dna.graph.property.PropertyFactory;
+
+public class MapNode {
+
+ private final UUID uuid;
+ private MapNode parent;
+ private Path.Segment name;
+ private final Map<Name, Property> properties = new HashMap<Name, Property>();
+ private final LinkedList<MapNode> children = new LinkedList<MapNode>();
+ final Set<Name> existingNames = new HashSet<Name>();
+
+ public MapNode( UUID uuid ) {
+ assert uuid != null;
+ this.uuid = uuid;
+ }
+
+ /* (non-Javadoc)
+ * @see org.jboss.dna.graph.connector.map.MapNode#getUuid()
+ */
+ public UUID getUuid() {
+ return uuid;
+ }
+
+ /* (non-Javadoc)
+ * @see org.jboss.dna.graph.connector.map.MapNode#getName()
+ */
+ public Path.Segment getName() {
+ return name;
+ }
+
+ /**
+ * @param name Sets name to the specified value.
+ */
+ public void setName( Path.Segment name ) {
+ this.name = name;
+ }
+
+ public Set<Name> getUniqueChildNames() {
+ return existingNames;
+ }
+
+ /* (non-Javadoc)
+ * @see org.jboss.dna.graph.connector.map.MapNode#getParent()
+ */
+ public MapNode getParent() {
+ return parent;
+ }
+
+ /**
+ * @param parent Sets parent to the specified value.
+ */
+ public void setParent( MapNode parent ) {
+ this.parent = parent;
+ }
+
+ /**
+ * @return children
+ */
+ public LinkedList<MapNode> getChildren() {
+ return children;
+ }
+
+ /**
+ * @return properties
+ */
+ protected Map<Name, Property> getProperties() {
+ return properties;
+ }
+
+ /**
+ * Sets the property with the given name, overwriting any previous property for the given name
+ *
+ * @param property the property to set
+ * @return this map node
+ */
+ public MapNode setProperty( Property property ) {
+ if (property != null) {
+ this.properties.put(property.getName(), property);
+ }
+ return this;
+ }
+
+ /**
+ * Sets the property with the given name, overwriting any previous property for the given name
+ *
+ * @param context the current execution context, used to get a {@link NameFactory name factory} and {@link PropertyFactory
+ * property factory}.
+ * @param name the name of the property
+ * @param values the values for the property
+ * @return this map node
+ */
+ public MapNode setProperty( ExecutionContext context,
+ String name,
+ Object... values ) {
+ PropertyFactory propertyFactory = context.getPropertyFactory();
+ Name propertyName = context.getValueFactories().getNameFactory().create(name);
+ return setProperty(propertyFactory.create(propertyName, values));
+ }
+
+ /**
+ * Returns the named property
+ *
+ * @param context the current execution context, used to get a {@link NameFactory name factory}
+ * @param name the name of the property to return
+ * @return the property for the given name
+ */
+ public Property getProperty( ExecutionContext context,
+ String name ) {
+ Name propertyName = context.getValueFactories().getNameFactory().create(name);
+ return getProperty(propertyName);
+ }
+
+ /**
+ * Returns the named property
+ *
+ * @param name the name of the property to return
+ * @return the property for the given name
+ */
+ 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 MapNode) {
+ MapNode that = (MapNode)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();
+ }
+
+}
Property changes on: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapNode.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepository.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepository.java (rev 0)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepository.java 2009-06-27 02:54:06 UTC (rev 1065)
@@ -0,0 +1,271 @@
+/*
+ * 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.map;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import net.jcip.annotations.GuardedBy;
+import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.request.UuidConflictBehavior;
+import org.jboss.dna.graph.request.CreateWorkspaceRequest.CreateConflictBehavior;
+
+/**
+ * A default implementation of a map-based repository.
+ * <p>
+ * {@code MapRepository} provides means for creating, retrieving, and destroying {@link MapWorkspace map-based workspaces},
+ * including providing the locking primitives required for safe control of the workspaces.
+ * </p>
+ */
+public abstract class MapRepository {
+
+ protected final ReadWriteLock lock = new ReentrantReadWriteLock();
+ protected final UUID rootNodeUuid;
+ private final String sourceName;
+ private final String defaultWorkspaceName;
+ private final Map<String, MapWorkspace> workspaces = new HashMap<String, MapWorkspace>();
+
+ /**
+ * Creates a {@code MapRepository} with the given repository source name, root node UUID, and a default workspace named
+ * {@code ""} (the empty string).
+ *
+ * @param sourceName the name of the repository source for use in error and informational messages; may not be null or empty
+ * @param rootNodeUuid the UUID that will be used as the root node UUID for each workspace in the repository; may not be null
+ * or empty
+ */
+ public MapRepository( String sourceName,
+ UUID rootNodeUuid ) {
+ this(sourceName, rootNodeUuid, null);
+ }
+
+ /**
+ * Creates a {@code MapRepository} with the given repository source name, root node UUID, and a default workspace with the
+ * given name.
+ *
+ * @param sourceName the name of the repository source for use in error and informational messages; may not be null or empty
+ * @param rootNodeUuid the UUID that will be used as the root node UUID for each workspace in the repository; may not be null
+ * or empty
+ * @param defaultWorkspaceName the name of the default, auto-created workspace
+ */
+ public MapRepository( String sourceName,
+ UUID rootNodeUuid,
+ String defaultWorkspaceName ) {
+ CheckArg.isNotEmpty(sourceName, "sourceName");
+ CheckArg.isNotNull(rootNodeUuid, "rootNodeUUID");
+ this.rootNodeUuid = rootNodeUuid;
+ this.sourceName = sourceName;
+ this.defaultWorkspaceName = defaultWorkspaceName != null ? defaultWorkspaceName : "";
+ }
+
+ /**
+ * Initializes the repository by creating the default workspace.
+ * <p>
+ * Due to the ordering restrictions on constructor chaining, this method cannot be called until the repository is fully
+ * initialized. <b>This method MUST be called at the end of the constructor by any class that implements {@code MapRepository}
+ * .</b>
+ */
+ protected void initialize() {
+ // Create the default workspace ...
+ workspaces.put(this.defaultWorkspaceName, createWorkspace(null,
+ this.defaultWorkspaceName,
+ CreateConflictBehavior.DO_NOT_CREATE));
+
+ }
+
+ /**
+ * Returns the UUID used by the root nodes in each workspace.
+ * <p>
+ * Note that the root nodes themselves are distinct objects in each workspace and a change to the root node of one workspace
+ * does not imply a change to the root nodes of any other workspaces. However, the JCR specification mandates that all
+ * referenceable root nodes in a repository use a common UUID (in support of node correspondence); therefore this must be
+ * supported by DNA.
+ *
+ * @return the root node UUID
+ */
+ public final UUID getRootNodeUuid() {
+ return rootNodeUuid;
+ }
+
+ /**
+ * Returns the logical name (as opposed to the class name) of the repository source that defined this instance of the
+ * repository for use in error, informational, and other contextual messages.
+ *
+ * @return sourceName the logical name for the repository source name
+ */
+ public String getSourceName() {
+ return sourceName;
+ }
+
+ /**
+ * Returns the lock that must be used to ensure consistent access to the repository
+ *
+ * @return lock the lock that must be used to ensure consistent access to the repository
+ */
+ public ReadWriteLock getLock() {
+ return lock;
+ }
+
+ /**
+ * Returns a list of the names of the currently created workspaces
+ *
+ * @return a list of the names of the currently created workspaces
+ */
+ @GuardedBy( "getLock()" )
+ public Set<String> getWorkspaceNames() {
+ return workspaces.keySet();
+ }
+
+ /**
+ * Returns the workspace with the given name
+ *
+ * @param name the name of the workspace to return
+ * @return the workspace with the given name; may be null if no workspace with the given name exists
+ */
+ @GuardedBy( "getLock()" )
+ public MapWorkspace getWorkspace( String name ) {
+ if (name == null) name = defaultWorkspaceName;
+ return workspaces.get(name);
+ }
+
+ /**
+ * Creates a new workspace with the given name containing only a root node.
+ * <p>
+ * <b>This method does NOT automatically add the newly created workspace to the {@link #workspaces workspace map} or check to
+ * see if a workspace already exists in this repository with the same name.</b>
+ * </p>
+ *
+ * @param context the context in which the workspace is to be created
+ * @param name the name of the workspace
+ * @return the newly created workspace; may not be null
+ */
+ @GuardedBy( "getLock()" )
+ protected abstract MapWorkspace createWorkspace( ExecutionContext context,
+ String name );
+
+ /**
+ * Attempts to create a workspace with the given name with name-collision behavior determined by the behavior parameter.
+ * <p>
+ * This method will first check to see if a workspace already exists with the given name. If no such workspace exists, the
+ * method will create a new workspace with the given name, add it to the {@code #workspaces workspaces map}, and return it. If
+ * a workspace with the requested name already exists and the {@code behavior} is {@link CreateConflictBehavior#DO_NOT_CREATE}
+ * , this method will return {@code null} without modifying the state of the repository. If a workspace with the requested
+ * name already exists and the {@code behavior} is {@link CreateConflictBehavior#CREATE_WITH_ADJUSTED_NAME}, this method will
+ * generate a unique new name for the workspace, create a new workspace with the given name, added it to the {@code
+ * #workspaces workspaces map}, and return it.
+ *
+ * @param context the context in which the workspace is to be created; may not be null
+ * @param name the requested name of the workspace. The name of the workspace that is returned from this method may not be the
+ * same as the requested name; may not be null
+ * @param behavior the behavior to use in case a workspace with the requested name already exists in the repository
+ * @return the newly created workspace or {@code null} if a workspace with the requested name already exists in the repository
+ * and {@code behavior == CreateConflictBehavior#DO_NOT_CREATE}.
+ */
+ @GuardedBy( "getLock()" )
+ public MapWorkspace createWorkspace( ExecutionContext context,
+ String name,
+ CreateConflictBehavior behavior ) {
+ String newName = name;
+ boolean conflictingName = workspaces.containsKey(newName);
+ if (conflictingName) {
+ switch (behavior) {
+ case DO_NOT_CREATE:
+ return null;
+ case CREATE_WITH_ADJUSTED_NAME:
+ int counter = 0;
+ do {
+ newName = name + (++counter);
+ } while (workspaces.containsKey(newName));
+ break;
+ }
+ }
+ assert workspaces.containsKey(newName) == false;
+
+ MapWorkspace workspace = createWorkspace(context, name);
+ workspaces.put(name, workspace);
+ return workspace;
+ }
+
+ /**
+ * Attempts to create a workspace with the requested name as in the
+ * {@link #createWorkspace(ExecutionContext, String, CreateConflictBehavior)} method and then clones the content from the
+ * given source workspace into the new workspace if the creation was successful.
+ * <p>
+ * If no workspace with the name {@code nameOfWorkspaceToClone} exists, the method will return an empty workspace.
+ * </p>
+ *
+ * @param context the context in which the workspace is to be created; may not be null
+ * @param name the requested name of the workspace. The name of the workspace that is returned from this method may not be the
+ * same as the requested name; may not be null
+ * @param existingWorkspaceBehavior the behavior to use in case a workspace with the requested name already exists in the
+ * repository
+ * @param nameOfWorkspaceToClone the name of the workspace from which the content should be cloned; may not be null
+ * @return the newly created workspace with an exact copy of the contents from the workspace named {@code
+ * nameOfWorkspaceToClone} or {@code null} if a workspace with the requested name already exists in the repository and
+ * {@code behavior == CreateConflictBehavior#DO_NOT_CREATE}.
+ */
+ @GuardedBy( "getLock()" )
+ public MapWorkspace createWorkspace( ExecutionContext context,
+ String name,
+ CreateConflictBehavior existingWorkspaceBehavior,
+ String nameOfWorkspaceToClone ) {
+ MapWorkspace workspace = createWorkspace(context, name, existingWorkspaceBehavior);
+ if (workspace == null) {
+ // Unable to create because of a duplicate name ...
+ return null;
+ }
+ MapWorkspace original = getWorkspace(nameOfWorkspaceToClone);
+ if (original != null) {
+ // Copy the properties of the root node ...
+ MapNode root = workspace.getRoot();
+ MapNode origRoot = original.getRoot();
+ root.getProperties().clear();
+ root.getProperties().putAll(origRoot.getProperties());
+
+ // Loop over each child and call this method to copy the immediate children (and below).
+ // Note that this makes the copy have the same UUID as the original.
+ for (MapNode originalNode : origRoot.getChildren()) {
+ original.copyNode(context, originalNode, workspace, root, originalNode.getName().getName(), true, UuidConflictBehavior.REPLACE_EXISTING_NODE);
+ }
+ }
+
+ workspaces.put(name, workspace);
+ return workspace;
+ }
+
+ /**
+ * Removes the named workspace from the {@code #workspaces workspaces map}.
+ *
+ * @param name the name of the workspace to remove
+ * @return {@code true} if a workspace with that name previously existed in the map
+ */
+ @GuardedBy( "getLock()" )
+ public boolean destroyWorkspace( String name ) {
+ return workspaces.remove(name) != null;
+ }
+
+}
Property changes on: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepository.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepositoryConnection.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepositoryConnection.java (rev 0)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepositoryConnection.java 2009-06-27 02:54:06 UTC (rev 1065)
@@ -0,0 +1,132 @@
+/*
+ * 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.map;
+
+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.request.Request;
+import org.jboss.dna.graph.request.processor.RequestProcessor;
+
+public class MapRepositoryConnection implements RepositoryConnection {
+ private final MapRepositorySource source;
+ private final MapRepository repository;
+
+ public MapRepositoryConnection( MapRepositorySource source,
+ MapRepository repository ) {
+ assert source != null;
+ assert repository != null;
+ this.source = source;
+ this.repository = repository;
+ }
+
+ /**
+ * {@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 ) {
+ return true;
+ }
+
+ /**
+ * {@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 = new MapRequestProcessor(context, this.repository, this.source.getRepositoryContext());
+
+ Lock lock = request.isReadOnly() ? repository.getLock().readLock() : repository.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("MapRepositoryConnection.execute(...) took " + sw.getTotalDuration());
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "Connection to the \"" + getSourceName() + "\" " + repository.getClass().getSimpleName();
+ }
+
+}
Property changes on: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepositoryConnection.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepositorySource.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepositorySource.java (rev 0)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepositorySource.java 2009-06-27 02:54:06 UTC (rev 1065)
@@ -0,0 +1,48 @@
+/*
+ * 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.map;
+
+import org.jboss.dna.graph.cache.CachePolicy;
+import org.jboss.dna.graph.connector.RepositoryContext;
+import org.jboss.dna.graph.connector.RepositorySource;
+
+/**
+ * An extension of the {@link RepositorySource} class that provides a {@link CachePolicy cache policy} and a
+ * {@link RepositoryContext repository context}.
+ */
+public interface MapRepositorySource extends RepositorySource {
+
+ /**
+ * Returns the {@link CachePolicy cache policy} for the repository source
+ * @return the {@link CachePolicy cache policy} for the repository source
+ */
+ CachePolicy getDefaultCachePolicy();
+
+ /**
+ * Returns the {@link RepositoryContext repository context} for the repository source
+ * @return the {@link RepositoryContext repository context} for the repository source
+ */
+ RepositoryContext getRepositoryContext();
+
+}
Property changes on: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepositorySource.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRequestProcessor.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRequestProcessor.java (rev 0)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRequestProcessor.java 2009-06-27 02:54:06 UTC (rev 1065)
@@ -0,0 +1,485 @@
+/*
+ * 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.map;
+
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+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.JcrLexicon;
+import org.jboss.dna.graph.Location;
+import org.jboss.dna.graph.connector.RepositoryContext;
+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.Path.Segment;
+import org.jboss.dna.graph.request.CloneWorkspaceRequest;
+import org.jboss.dna.graph.request.CopyBranchRequest;
+import org.jboss.dna.graph.request.CreateNodeRequest;
+import org.jboss.dna.graph.request.CreateWorkspaceRequest;
+import org.jboss.dna.graph.request.DeleteBranchRequest;
+import org.jboss.dna.graph.request.DestroyWorkspaceRequest;
+import org.jboss.dna.graph.request.GetWorkspacesRequest;
+import org.jboss.dna.graph.request.InvalidWorkspaceException;
+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.VerifyWorkspaceRequest;
+import org.jboss.dna.graph.request.processor.RequestProcessor;
+
+/**
+ * The default implementation of the {@link RequestProcessor} for map repositories.
+ *
+ */
+public class MapRequestProcessor extends RequestProcessor {
+ private final PathFactory pathFactory;
+ private final PropertyFactory propertyFactory;
+ private final MapRepository repository;
+
+ public MapRequestProcessor( ExecutionContext context,
+ MapRepository repository,
+ RepositoryContext repositoryContext ) {
+ super(repository.getSourceName(), context, repositoryContext != null ? repositoryContext.getObserver() : null);
+ this.repository = repository;
+ pathFactory = context.getValueFactories().getPathFactory();
+ propertyFactory = context.getPropertyFactory();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.ReadAllChildrenRequest)
+ */
+ @Override
+ public void process( ReadAllChildrenRequest request ) {
+ MapWorkspace workspace = getWorkspace(request, request.inWorkspace());
+ MapNode node = getTargetNode(workspace, 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<MapNode> children = node.getChildren();
+ for (MapNode 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 ) {
+ MapWorkspace workspace = getWorkspace(request, request.inWorkspace());
+ MapNode node = getTargetNode(workspace, 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);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CopyBranchRequest)
+ */
+ @Override
+ public void process( CopyBranchRequest request ) {
+ MapWorkspace workspace = getWorkspace(request, request.fromWorkspace());
+ MapWorkspace newWorkspace = getWorkspace(request, request.intoWorkspace());
+ if (workspace == null || newWorkspace == null) return;
+ MapNode node = getTargetNode(workspace, request, request.from());
+ if (node == null) return;
+
+ // Look up the new parent, which must exist ...
+ Path newParentPath = request.into().getPath();
+ Name desiredName = request.desiredName();
+ MapNode newParent = newWorkspace.getNode(newParentPath);
+ MapNode newNode = workspace.copyNode(getExecutionContext(),
+ node,
+ newWorkspace,
+ newParent,
+ desiredName,
+ true,
+ request.uuidConflictBehavior());
+ Path newPath = getExecutionContext().getValueFactories().getPathFactory().create(newParentPath, newNode.getName());
+ Location oldLocation = getActualLocation(request.from().getPath(), node);
+ Location newLocation = Location.create(newPath, newNode.getUuid());
+ request.setActualLocations(oldLocation, newLocation);
+ recordChange(request);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CreateNodeRequest)
+ */
+ @Override
+ public void process( CreateNodeRequest request ) {
+ MapWorkspace workspace = getWorkspace(request, request.inWorkspace());
+ if (workspace == null) return;
+ Path parent = request.under().getPath();
+ CheckArg.isNotNull(parent, "request.under().getPath()");
+ MapNode node = null;
+ // Look up the parent node, which must exist ...
+
+ MapNode parentNode = workspace.getNode(parent);
+ if (parentNode == null) {
+ Path lowestExisting = workspace.getLowestExistingPath(parent);
+ request.setError(new PathNotFoundException(request.under(), lowestExisting,
+ GraphI18n.inMemoryNodeDoesNotExist.text(parent)));
+ return;
+ }
+ UUID uuid = null;
+ for (Property property : request.properties()) {
+ if (property.getName().equals(DnaLexicon.UUID) || property.getName().equals(JcrLexicon.UUID)) {
+ uuid = getExecutionContext().getValueFactories().getUuidFactory().create(property.getValues().next());
+ break;
+ }
+ }
+ switch (request.conflictBehavior()) {
+ case APPEND:
+ case DO_NOT_REPLACE:
+ node = workspace.createNode(getExecutionContext(), parentNode, request.named(), uuid);
+ break;
+ case REPLACE:
+ // See if the node already exists (this doesn't record an error on the request) ...
+ node = getTargetNode(workspace, null, Location.create(pathFactory.create(parent, request.named()), uuid));
+ if (node != null) {
+ workspace.removeNode(getExecutionContext(), node);
+ }
+ node = workspace.createNode(getExecutionContext(), parentNode, request.named(), uuid);
+ break;
+ case UPDATE:
+ // See if the node already exists (this doesn't record an error on the request) ...
+ node = getTargetNode(workspace, null, Location.create(pathFactory.create(parent, request.named()), uuid));
+ if (node == null) {
+ node = workspace.createNode(getExecutionContext(), parentNode, request.named(), uuid);
+ } // otherwise, we found it and we're setting any properties below
+ break;
+ }
+ 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);
+ recordChange(request);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.DeleteBranchRequest)
+ */
+ @Override
+ public void process( DeleteBranchRequest request ) {
+ MapWorkspace workspace = getWorkspace(request, request.inWorkspace());
+ if (workspace == null) return;
+ MapNode node = getTargetNode(workspace, request, request.at());
+ if (node == null) return;
+ workspace.removeNode(getExecutionContext(), node);
+ Location actualLocation = getActualLocation(request.at().getPath(), node);
+ request.setActualLocationOfNode(actualLocation);
+ recordChange(request);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.MoveBranchRequest)
+ */
+ @Override
+ public void process( MoveBranchRequest request ) {
+ MapWorkspace workspace = getWorkspace(request, request.inWorkspace());
+ if (workspace == null) return;
+
+ MapNode beforeNode = request.before() != null ? getTargetNode(workspace, request, request.before()) : null;
+ MapNode node = getTargetNode(workspace, request, request.from());
+ if (node == null) return;
+ // Look up the new parent, which must exist ...
+ Path newParentPath;
+
+ if (request.into() != null) {
+ newParentPath = request.into().getPath();
+ } else {
+ // into or before cannot both be null
+ assert beforeNode != null;
+
+ // Build the path from the before node to the root.
+ LinkedList<Path.Segment> segments = new LinkedList<Path.Segment>();
+ MapNode current = beforeNode.getParent();
+ while (current != workspace.getRoot()) {
+ segments.addFirst(current.getName());
+ current = current.getParent();
+ }
+ newParentPath = getExecutionContext().getValueFactories().getPathFactory().createAbsolutePath(segments);
+ }
+
+ MapNode newParent = workspace.getNode(newParentPath);
+ workspace.moveNode(getExecutionContext(), node, request.desiredName(), workspace, newParent, beforeNode);
+ assert node.getParent() == newParent;
+ Path newPath = getExecutionContext().getValueFactories().getPathFactory().create(newParentPath, node.getName());
+ Location oldLocation = getActualLocation(request.from().getPath(), node);
+ Location newLocation = Location.create(newPath, node.getUuid());
+ request.setActualLocations(oldLocation, newLocation);
+ recordChange(request);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.UpdatePropertiesRequest)
+ */
+ @Override
+ public void process( UpdatePropertiesRequest request ) {
+ MapWorkspace workspace = getWorkspace(request, request.inWorkspace());
+ MapNode node = getTargetNode(workspace, request, request.on());
+ if (node == null) return;
+ // Now set (or remove) the properties to the supplied node ...
+ for (Map.Entry<Name, Property> propertyEntry : request.properties().entrySet()) {
+ Property property = propertyEntry.getValue();
+ if (property == null) {
+ node.getProperties().remove(propertyEntry.getKey());
+ continue;
+ }
+ Name propName = property.getName();
+ if (!propName.equals(DnaLexicon.UUID)) {
+ node.getProperties().put(propName, property);
+ }
+ }
+ Location actualLocation = getActualLocation(request.on().getPath(), node);
+ request.setActualLocationOfNode(actualLocation);
+ recordChange(request);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CreateWorkspaceRequest)
+ */
+ @Override
+ public void process( CreateWorkspaceRequest request ) {
+ MapWorkspace workspace = repository.createWorkspace(getExecutionContext(),
+ request.desiredNameOfNewWorkspace(),
+ request.conflictBehavior());
+ if (workspace == null) {
+ String msg = GraphI18n.workspaceAlreadyExistsInRepository.text(request.desiredNameOfNewWorkspace(),
+ repository.getSourceName());
+ request.setError(new InvalidWorkspaceException(msg));
+ } else {
+ MapNode root = workspace.getRoot();
+ request.setActualRootLocation(Location.create(pathFactory.createRootPath(), root.getUuid()));
+ request.setActualWorkspaceName(workspace.getName());
+ recordChange(request);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.DestroyWorkspaceRequest)
+ */
+ @Override
+ public void process( DestroyWorkspaceRequest request ) {
+ MapWorkspace workspace = repository.getWorkspace(request.workspaceName());
+ if (workspace != null) {
+ MapNode root = workspace.getRoot();
+ request.setActualRootLocation(Location.create(pathFactory.createRootPath(), root.getUuid()));
+ recordChange(request);
+ } else {
+ String msg = GraphI18n.workspaceDoesNotExistInRepository.text(request.workspaceName(), repository.getSourceName());
+ request.setError(new InvalidWorkspaceException(msg));
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.GetWorkspacesRequest)
+ */
+ @Override
+ public void process( GetWorkspacesRequest request ) {
+ Set<String> names = repository.getWorkspaceNames();
+ request.setAvailableWorkspaceNames(new HashSet<String>(names));
+ setCacheableInfo(request);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.VerifyWorkspaceRequest)
+ */
+ @Override
+ public void process( VerifyWorkspaceRequest request ) {
+ MapWorkspace original = getWorkspace(request, request.workspaceName());
+ if (original != null) {
+ Path path = getExecutionContext().getValueFactories().getPathFactory().createRootPath();
+ request.setActualRootLocation(Location.create(path, original.getRoot().getUuid()));
+ request.setActualWorkspaceName(original.getName());
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CloneWorkspaceRequest)
+ */
+ @Override
+ public void process( CloneWorkspaceRequest request ) {
+ // Find the original workspace that we're cloning ...
+ final ExecutionContext context = getExecutionContext();
+ String targetWorkspaceName = request.desiredNameOfTargetWorkspace();
+ String nameOfWorkspaceToBeCloned = request.nameOfWorkspaceToBeCloned();
+ MapWorkspace original = repository.getWorkspace(nameOfWorkspaceToBeCloned);
+ MapWorkspace target = repository.getWorkspace(targetWorkspaceName);
+ if (original == null) {
+ switch (request.cloneConflictBehavior()) {
+ case DO_NOT_CLONE:
+ String msg = GraphI18n.workspaceDoesNotExistInRepository.text(nameOfWorkspaceToBeCloned,
+ repository.getSourceName());
+ request.setError(new InvalidWorkspaceException(msg));
+ return;
+ case SKIP_CLONE:
+ target = repository.createWorkspace(context, targetWorkspaceName, request.targetConflictBehavior());
+ if (target == null) {
+ msg = GraphI18n.workspaceAlreadyExistsInRepository.text(targetWorkspaceName, repository.getSourceName());
+ request.setError(new InvalidWorkspaceException(msg));
+ } else {
+ MapNode root = target.getRoot();
+ request.setActualRootLocation(Location.create(pathFactory.createRootPath(), root.getUuid()));
+ request.setActualWorkspaceName(target.getName());
+ }
+ return;
+ }
+ }
+ assert original != null;
+ target = repository.createWorkspace(context,
+ targetWorkspaceName,
+ request.targetConflictBehavior(),
+ nameOfWorkspaceToBeCloned);
+ if (target == null) {
+ // Since the original was there, the only reason the target wasn't created was because the workspace already existed
+ // ...
+ String msg = GraphI18n.workspaceAlreadyExistsInRepository.text(targetWorkspaceName, repository.getSourceName());
+ request.setError(new InvalidWorkspaceException(msg));
+ } else {
+ MapNode root = target.getRoot();
+ request.setActualRootLocation(Location.create(pathFactory.createRootPath(), root.getUuid()));
+ request.setActualWorkspaceName(target.getName());
+ recordChange(request);
+ }
+ }
+
+ protected Location getActualLocation( Path path,
+ MapNode node ) {
+ if (path == null) {
+ // Find the path on the node ...
+ LinkedList<Path.Segment> segments = new LinkedList<Path.Segment>();
+ MapNode n = node;
+ while (n != null) {
+ if (n.getParent() == null) break;
+ segments.addFirst(n.getName());
+ n = n.getParent();
+ }
+ path = pathFactory.createAbsolutePath(segments);
+ }
+ return Location.create(path, node.getUuid());
+ }
+
+ protected MapWorkspace getWorkspace( Request request,
+ String workspaceName ) {
+ // Get the workspace for this request ...
+ MapWorkspace workspace = repository.getWorkspace(workspaceName);
+ if (workspace == null) {
+ String msg = GraphI18n.workspaceDoesNotExistInRepository.text(workspaceName, repository.getSourceName());
+ request.setError(new InvalidWorkspaceException(msg));
+ }
+ return workspace;
+ }
+
+ protected MapNode getTargetNode( MapWorkspace workspace,
+ Request request,
+ Location location ) {
+ if (workspace == null) return null;
+ // Check first for the UUID ...
+ MapNode node = null;
+ UUID uuid = location.getUuid();
+ if (uuid != null) {
+ node = workspace.getNode(uuid);
+ }
+ Path path = null;
+ if (node == null) {
+ // Look up the node with the supplied path ...
+ path = location.getPath();
+ if (path != null) {
+ node = workspace.getNode(path);
+ }
+ }
+ if (node == null && request != 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 = workspace.getLowestExistingPath(path);
+ request.setError(new PathNotFoundException(location, lowestExisting, GraphI18n.inMemoryNodeDoesNotExist.text(path)));
+ }
+ return node;
+ }
+}
Property changes on: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRequestProcessor.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapWorkspace.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapWorkspace.java (rev 0)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapWorkspace.java 2009-06-27 02:54:06 UTC (rev 1065)
@@ -0,0 +1,172 @@
+/*
+ * 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.map;
+
+import java.util.UUID;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.connector.UuidAlreadyExistsException;
+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.request.UuidConflictBehavior;
+
+/**
+ * The {@code MapWorkspace} defines the required methods for workspaces in a {@link MapRepository map repository}. By default, a
+ * map repository supports multiple workspaces, each equating logically to a map of UUIDs to {@link MapNode map nodes}.
+ * <p>
+ * As each map node (except the root-node for the workspace) has a non-null parent and a set of children, the {@link MapNode map
+ * nodes} naturally construct a tree within the workspace.
+ * </p>
+ */
+public interface MapWorkspace {
+
+ /**
+ * Returns the name of the workspace. There can only be one workspace with a given name per repository.
+ *
+ * @return the name of the workspace
+ */
+ String getName();
+
+ /**
+ * Returns the root node in the workspace. This returns a {@link MapNode map node} where {@code node.getParent() == null} and
+ * {@code node.getUuid() == repository.getRootNodeUuid()}.
+ *
+ * @return the root node in the workspace
+ */
+ MapNode getRoot();
+
+ /**
+ * Returns the node with the given UUID, if one exists or {@code null} if no {@MapNode node} with the given UUID
+ * exists in the workspace.
+ * <p>
+ * That is, {@code node == null || node.getUuid().equals(uuid)} for the returned node.
+ * </p>
+ *
+ * @param uuid the UUID of the node to be retrieved; may not be null
+ * @return the node with the given UUID, if one exists or {@code null} if no {@MapNode node} with the given UUID
+ * exists in the workspace.
+ */
+ MapNode getNode( UUID uuid );
+
+ /**
+ * Returns the node at the given path, if one exists of {@code null} if no {@MapNode node} exists at the given path.
+ *
+ * @param path the path of the node to retrieve; may not be null
+ * @return the node at the given path, if one exists of {@code null} if no {@MapNode node} exists at the given path.
+ */
+ MapNode getNode( Path path );
+
+ /**
+ * Removes the given node. This method will return silently if the given node does not exist in this workspace.
+ *
+ * @param context the current execution context; may not be null
+ * @param node the node to be removed; may not be null
+ */
+ void removeNode( ExecutionContext context,
+ MapNode node );
+
+ /**
+ * 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)
+ */
+ MapNode createNode( ExecutionContext context,
+ String pathToNewNode );
+
+ /**
+ * 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
+ */
+ MapNode createNode( ExecutionContext context,
+ MapNode parentNode,
+ Name name,
+ UUID uuid );
+
+ /**
+ * 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 MapWorkspace#getRoot() root}
+ * @param desiredNewName the new name for the node, if it is to be changed; may be null
+ * @param newWorkspace the workspace containing the new parent node
+ * @param newParent the new parent; may not be the {@link MapWorkspace#getRoot() root}
+ * @param beforeNode the node before which this new node should be placed
+ */
+ void moveNode( ExecutionContext context,
+ MapNode node,
+ Name desiredNewName,
+ MapWorkspace newWorkspace,
+ MapNode newParent,
+ MapNode beforeNode );
+
+ /**
+ * 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 the context; may not be null
+ * @param original the node to be copied; may not be null
+ * @param newWorkspace the workspace containing the new parent node; may not be null
+ * @param newParent the parent where the copy is to be placed; may not be null
+ * @param desiredName the desired name for the node; if null, the name will be obtained from the original node
+ * @param recursive true if the copy should be recursive
+ * @param uuidConflictBehavior the behavior to use to manage UUIDs from the source into the target
+ * @return the new node, which is the top of the new subgraph
+ * @throws UuidAlreadyExistsException if {@code uuidConflictBehavior} is true and and a UUID in the source tree alread exists
+ * in the new workspace
+ */
+ MapNode copyNode( ExecutionContext context,
+ MapNode original,
+ MapWorkspace newWorkspace,
+ MapNode newParent,
+ Name desiredName,
+ boolean recursive,
+ UuidConflictBehavior uuidConflictBehavior ) throws UuidAlreadyExistsException;
+
+ /**
+ * 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
+ */
+ Path getLowestExistingPath( Path path );
+
+ /**
+ * Returns the path for the given node with this workspace if one exists, or a {@code null} if no node exists at the given
+ * path.
+ *
+ * @param pathFactory the path factory to use to construct the path; may not be null
+ * @param node the node for which the path should be retrieved; may not be null
+ * @return the path for the given node with this workspace if one exists or null if the node does not exist in this workspace
+ */
+ Path pathFor( PathFactory pathFactory,
+ MapNode node );
+}
Property changes on: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapWorkspace.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/package-info.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/package-info.java (rev 0)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/package-info.java 2009-06-27 02:54:06 UTC (rev 1065)
@@ -0,0 +1,72 @@
+/*
+ * 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 {@link MapRepository} class and its supporting classes provide a default implementation of the connector
+ * classes for connectors that support the transient or persistent mapping of a UUID to a {@link MapNode standard
+ * representation of a node}.
+ * To implement a connector based on this framework, one must create an implementation of {@link MapRepositorySource the repository source},
+ * an implementation of {@link MapRepository the repository itself}, and an implementation of {@link MapWorkspace the workspace}.
+ * <p>
+ * The {@link MapRepositorySource repository source implementation} contains properties for the repository configuration and caching policies. A key
+ * method in the {@code MapRepositorySource} implementation if the {@link org.jboss.dna.graph.connector.RepositorySource#getConnection()} method,
+ * which should generally be implemented using the {@link MapRepositoryConnection default connection implementation}.
+ * <pre>
+ * if (repository == null) {
+ * repository = new InMemoryRepository(name, rootNodeUuid, defaultWorkspaceName);
+ * }
+ * return new MapRepositoryConnection(this, repository);
+ * </pre>
+ * </p>
+ * <p>
+ * The {@link MapRepository repository implementation} is only required to provide an implementation of the {@link MapRepository#createWorkspace(org.jboss.dna.graph.ExecutionContext, String)}
+ * method that returns the appropriate {@link MapWorkspace workspace} implementation for the connector. However, all constructors for the repository must
+ * call {@link MapRepository#initialize()} after the constructor has completed its initialization, as demonstrated below:
+ * <pre>
+ * public InMemoryRepository( String sourceName,
+ * UUID rootNodeUuid,
+ * String defaultWorkspaceName ) {
+ * initialize();
+ * }
+ * </pre>
+ * </p>
+ * <p>
+ * Finally, the {@link MapWorkspace workspace implementation} must be created. Implementors should consider extending the {@link AbstractMapWorkspace} class, which provides reasonable default implementations (assuming that the backing map provides O(1) lookups - a sine qua non for maps) for almost
+ * this class imposes a requirement that its {@link AbstractMapWorkspace#initialize()} method also be called at the end of each constructor, like so:
+ * <pre>
+ * public Workspace( MapRepository repository,
+ * String name ) {
+ * super(repository, name);
+ *
+ * initialize();
+ * }
+ * </pre>
+ * </p>
+ *
+ * @see org.jboss.dna.graph.connector.inmemory.InMemoryRepository
+ * @see org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource
+ * @see org.jboss.dna.graph.connector.inmemory.InMemoryRepository#Workspace
+ */
+
+package org.jboss.dna.graph.connector.map;
+
Property changes on: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/package-info.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: 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 2009-06-24 22:14:12 UTC (rev 1064)
+++ trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositoryTest.java 2009-06-27 02:54:06 UTC (rev 1065)
@@ -31,7 +31,8 @@
import static org.junit.matchers.JUnitMatchers.hasItems;
import java.util.UUID;
import org.jboss.dna.graph.ExecutionContext;
-import org.jboss.dna.graph.connector.inmemory.InMemoryRepository.Workspace;
+import org.jboss.dna.graph.connector.map.MapNode;
+import org.jboss.dna.graph.connector.map.MapWorkspace;
import org.jboss.dna.graph.property.Name;
import org.jboss.dna.graph.property.NameFactory;
import org.jboss.dna.graph.property.PathFactory;
@@ -99,7 +100,7 @@
String workspaceName = "New Workspace";
assertThat(repository.createWorkspace(context, workspaceName, CreateConflictBehavior.DO_NOT_CREATE), is(notNullValue()));
assertThat(repository.getWorkspaceNames(), hasItems(workspaceName));
- Workspace secondWorkspace = repository.createWorkspace(context,
+ MapWorkspace secondWorkspace = repository.createWorkspace(context,
workspaceName,
CreateConflictBehavior.CREATE_WITH_ADJUSTED_NAME);
assertThat(secondWorkspace, is(notNullValue()));
@@ -124,25 +125,25 @@
@Test
public void shouldCloneWorkspaceAndCopyContentsIfWorkspaceWithSpecifiedNameExists() {
String workspaceName = "Original Workspace";
- Workspace workspace = repository.createWorkspace(context, workspaceName, CreateConflictBehavior.DO_NOT_CREATE);
+ MapWorkspace workspace = repository.createWorkspace(context, workspaceName, CreateConflictBehavior.DO_NOT_CREATE);
assertThat(workspace, is(notNullValue()));
assertThat(repository.getWorkspaceNames(), hasItems(workspaceName));
// Populate the workspace with a few nodes ...
- InMemoryNode root = workspace.getRoot();
- InMemoryNode node_a = workspace.createNode(context, root, nameFactory.create("a"), null);
- InMemoryNode node_b = workspace.createNode(context, node_a, nameFactory.create("b"), null);
- InMemoryNode node_c = workspace.createNode(context, node_b, nameFactory.create("c"), null);
- InMemoryNode node_d = workspace.createNode(context, root, nameFactory.create("d"), null);
- InMemoryNode node_e = workspace.createNode(context, node_d, nameFactory.create("e"), null);
- InMemoryNode node_b2 = workspace.createNode(context, node_d, nameFactory.create("b"), null);
+ MapNode root = workspace.getRoot();
+ MapNode node_a = workspace.createNode(context, root, nameFactory.create("a"), null);
+ MapNode node_b = workspace.createNode(context, node_a, nameFactory.create("b"), null);
+ MapNode node_c = workspace.createNode(context, node_b, nameFactory.create("c"), null);
+ MapNode node_d = workspace.createNode(context, root, nameFactory.create("d"), null);
+ MapNode node_e = workspace.createNode(context, node_d, nameFactory.create("e"), null);
+ MapNode node_b2 = workspace.createNode(context, node_d, nameFactory.create("b"), null);
ValueFactory<String> stringFactory = context.getValueFactories().getStringFactory();
Name propertyName = nameFactory.create("something");
Property property = propertyFactory.create(propertyName, stringFactory.create("Worth the wait"));
- node_b.getProperties().put(propertyName, property);
+ node_b.setProperty(property);
- assertThat(workspace.getNodesByUuid().size(), is(7));
+ assertThat(((InMemoryRepository.Workspace) workspace).size(), is(7));
assertThat(workspace.getNode(pathFactory.create("/")), is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")), is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/a/b")), is(sameInstance(node_b)));
@@ -150,11 +151,11 @@
assertThat(workspace.getNode(pathFactory.create("/d")), is(sameInstance(node_d)));
assertThat(workspace.getNode(pathFactory.create("/d/e")), is(sameInstance(node_e)));
assertThat(workspace.getNode(pathFactory.create("/d/b")), is(sameInstance(node_b2)));
- assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperties().get(propertyName), is(property));
+ assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperty(propertyName), is(property));
// Now clone the workspace ...
String newWorkspaceName = "New Workspace";
- Workspace new_workspace = repository.createWorkspace(context,
+ MapWorkspace new_workspace = repository.createWorkspace(context,
newWorkspaceName,
CreateConflictBehavior.DO_NOT_CREATE,
workspaceName);
@@ -162,7 +163,7 @@
assertThat(repository.getWorkspaceNames(), hasItems(workspaceName, newWorkspaceName));
// Now check that the original workspace still has its content ...
- assertThat(workspace.getNodesByUuid().size(), is(7));
+ assertThat(((InMemoryRepository.Workspace) workspace).size(), is(7));
assertThat(workspace.getNode(pathFactory.create("/")), is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")), is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/a/b")), is(sameInstance(node_b)));
@@ -170,10 +171,10 @@
assertThat(workspace.getNode(pathFactory.create("/d")), is(sameInstance(node_d)));
assertThat(workspace.getNode(pathFactory.create("/d/e")), is(sameInstance(node_e)));
assertThat(workspace.getNode(pathFactory.create("/d/b")), is(sameInstance(node_b2)));
- assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperties().get(propertyName), is(property));
+ assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperty(propertyName), is(property));
// Now check that the new workspace has its content ...
- assertThat(new_workspace.getNodesByUuid().size(), is(7));
+ assertThat(((InMemoryRepository.Workspace) new_workspace).size(), is(7));
// Since we cloned workspaces, the UUIDs should be the same in each workspace ...
assertThat(workspace.getNode(pathFactory.create("/")).getUuid(),
@@ -195,25 +196,25 @@
@Test
public void shouldCloneWorkspaceButShouldNotCopyContentsIfWorkspaceWithSpecifiedNameDoesNotExist() {
String workspaceName = "Original Workspace";
- Workspace workspace = repository.createWorkspace(context, workspaceName, CreateConflictBehavior.DO_NOT_CREATE);
+ MapWorkspace workspace = repository.createWorkspace(context, workspaceName, CreateConflictBehavior.DO_NOT_CREATE);
assertThat(workspace, is(notNullValue()));
assertThat(repository.getWorkspaceNames(), hasItems(workspaceName));
// Populate the workspace with a few nodes ...
- InMemoryNode root = workspace.getRoot();
- InMemoryNode node_a = workspace.createNode(context, root, nameFactory.create("a"), null);
- InMemoryNode node_b = workspace.createNode(context, node_a, nameFactory.create("b"), null);
- InMemoryNode node_c = workspace.createNode(context, node_b, nameFactory.create("c"), null);
- InMemoryNode node_d = workspace.createNode(context, root, nameFactory.create("d"), null);
- InMemoryNode node_e = workspace.createNode(context, node_d, nameFactory.create("e"), null);
- InMemoryNode node_b2 = workspace.createNode(context, node_d, nameFactory.create("b"), null);
+ MapNode root = workspace.getRoot();
+ MapNode node_a = workspace.createNode(context, root, nameFactory.create("a"), null);
+ MapNode node_b = workspace.createNode(context, node_a, nameFactory.create("b"), null);
+ MapNode node_c = workspace.createNode(context, node_b, nameFactory.create("c"), null);
+ MapNode node_d = workspace.createNode(context, root, nameFactory.create("d"), null);
+ MapNode node_e = workspace.createNode(context, node_d, nameFactory.create("e"), null);
+ MapNode node_b2 = workspace.createNode(context, node_d, nameFactory.create("b"), null);
ValueFactory<String> stringFactory = context.getValueFactories().getStringFactory();
Name propertyName = nameFactory.create("something");
Property property = propertyFactory.create(propertyName, stringFactory.create("Worth the wait"));
- node_b.getProperties().put(propertyName, property);
+ node_b.setProperty(property);
- assertThat(workspace.getNodesByUuid().size(), is(7));
+ assertThat(((InMemoryRepository.Workspace) workspace).size(), is(7));
assertThat(workspace.getNode(pathFactory.create("/")), is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")), is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/a/b")), is(sameInstance(node_b)));
@@ -221,11 +222,11 @@
assertThat(workspace.getNode(pathFactory.create("/d")), is(sameInstance(node_d)));
assertThat(workspace.getNode(pathFactory.create("/d/e")), is(sameInstance(node_e)));
assertThat(workspace.getNode(pathFactory.create("/d/b")), is(sameInstance(node_b2)));
- assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperties().get(propertyName), is(property));
+ assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperty(propertyName), is(property));
// Now clone the workspace ...
String newWorkspaceName = "New Workspace";
- Workspace new_workspace = repository.createWorkspace(context,
+ MapWorkspace new_workspace = repository.createWorkspace(context,
newWorkspaceName,
CreateConflictBehavior.DO_NOT_CREATE,
"non-existant workspace");
Modified: trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositoryWorkspaceTest.java
===================================================================
--- trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositoryWorkspaceTest.java 2009-06-24 22:14:12 UTC (rev 1064)
+++ trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositoryWorkspaceTest.java 2009-06-27 02:54:06 UTC (rev 1065)
@@ -34,7 +34,7 @@
import java.util.Map;
import java.util.UUID;
import org.jboss.dna.graph.ExecutionContext;
-import org.jboss.dna.graph.connector.inmemory.InMemoryRepository.Workspace;
+import org.jboss.dna.graph.connector.map.MapNode;
import org.jboss.dna.graph.property.Name;
import org.jboss.dna.graph.property.NameFactory;
import org.jboss.dna.graph.property.PathFactory;
@@ -75,7 +75,7 @@
rootUuid = UUID.randomUUID();
repository = new InMemoryRepository(repositoryName, rootUuid);
workspaceName = "My Workspace";
- workspace = repository.createWorkspace(context, workspaceName, CreateConflictBehavior.DO_NOT_CREATE);
+ workspace = (InMemoryRepository.Workspace) repository.createWorkspace(context, workspaceName, CreateConflictBehavior.DO_NOT_CREATE);
}
@Test
@@ -97,33 +97,33 @@
public void shouldAllowRootToBeRemoved() {
workspace.removeNode(context, workspace.getRoot());
assertThat(workspace.getRoot().getChildren().size(), is(0));
- assertThat(workspace.getRoot().getProperties().size(), is(0));
+ // assertThat(workspace.getRoot().getProperties().size(), is(0));
}
@Test
public void shouldCreateNodesByPath() {
Name name_a = nameFactory.create("a");
- InMemoryNode node_a = workspace.createNode(context, workspace.getRoot(), name_a, null);
+ MapNode node_a = workspace.createNode(context, workspace.getRoot(), name_a, null);
assertThat(node_a, is(notNullValue()));
assertThat(node_a.getParent(), is(workspace.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 = workspace.createNode(context, node_a, name_b, null);
+ MapNode node_b = workspace.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 = workspace.createNode(context, node_b, name_c, null);
+ MapNode node_c = workspace.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(workspace.getNodesByUuid().size(), is(4));
+ assertThat(workspace.size(), is(4));
assertThat(workspace.getNode(pathFactory.create("/")), is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")), is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/a/b")), is(sameInstance(node_b)));
@@ -132,11 +132,11 @@
@Test
public void shouldNotFindNodesThatDoNotExist() {
- InMemoryNode node_a = workspace.createNode(context, workspace.getRoot(), nameFactory.create("a"), null);
- InMemoryNode node_b = workspace.createNode(context, node_a, nameFactory.create("b"), null);
+ MapNode node_a = workspace.createNode(context, workspace.getRoot(), nameFactory.create("a"), null);
+ MapNode node_b = workspace.createNode(context, node_a, nameFactory.create("b"), null);
/*Node node_c =*/workspace.createNode(context, node_b, nameFactory.create("c"), null);
- assertThat(workspace.getNodesByUuid().size(), is(4));
+ assertThat(workspace.size(), is(4));
assertThat(workspace.getNode(pathFactory.create("/a")), is(node_a));
assertThat(workspace.getNode(pathFactory.create("/a/b")), is(node_b));
assertThat(workspace.getNode(pathFactory.create("/a[1]")), is(node_a));
@@ -150,50 +150,50 @@
@Test
public void shouldCorrectlyManageIndexesOfSiblingsWithSameNames() {
Name name_a1 = nameFactory.create("a");
- InMemoryNode node_a1 = workspace.createNode(context, workspace.getRoot(), name_a1, null);
+ MapNode node_a1 = workspace.createNode(context, workspace.getRoot(), name_a1, null);
assertThat(node_a1, is(notNullValue()));
assertThat(node_a1.getParent(), is(workspace.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 = workspace.createNode(context, workspace.getRoot(), name_a2, null);
+ MapNode node_a2 = workspace.createNode(context, workspace.getRoot(), name_a2, null);
assertThat(node_a2, is(notNullValue()));
assertThat(node_a2.getParent(), is(workspace.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 ...
+ // node 1 should now have an index ..
assertThat(node_a1.getName().getIndex(), is(1));
- // Add another node without the same name ...
+ // Add another node without the same name ..
Name name_b = nameFactory.create("b");
- InMemoryNode node_b = workspace.createNode(context, workspace.getRoot(), name_b, null);
+ MapNode node_b = workspace.createNode(context, workspace.getRoot(), name_b, null);
assertThat(node_b, is(notNullValue()));
assertThat(node_b.getParent(), is(workspace.getRoot()));
assertThat(node_b.getName().getName(), is(name_b));
assertThat(node_b.getName().hasIndex(), is(false));
- // Add a third node with the same name ...
+ // Add a third node with the same name ..
Name name_a3 = nameFactory.create("a");
- InMemoryNode node_a3 = workspace.createNode(context, workspace.getRoot(), name_a3, null);
+ MapNode node_a3 = workspace.createNode(context, workspace.getRoot(), name_a3, null);
assertThat(node_a3, is(notNullValue()));
assertThat(node_a3.getParent(), is(workspace.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 ...
+ // Check the number of children ..
assertThat(workspace.getRoot().getChildren().size(), is(4));
assertThat(workspace.getRoot().getChildren(), hasItems(node_a1, node_a2, node_b, node_a3));
- assertThat(workspace.getNodesByUuid().size(), is(5));
+ assertThat(workspace.size(), is(5));
assertThat(workspace.getNode(pathFactory.create("/a[1]")), is(sameInstance(node_a1)));
assertThat(workspace.getNode(pathFactory.create("/a[2]")), is(sameInstance(node_a2)));
assertThat(workspace.getNode(pathFactory.create("/a[3]")), is(sameInstance(node_a3)));
assertThat(workspace.getNode(pathFactory.create("/b")), is(sameInstance(node_b)));
- // Removing a node with the same name will reduce the index ...
+ // Removing a node with the same name will reduce the index ..
workspace.removeNode(context, node_a2);
assertThat(workspace.getRoot().getChildren().size(), is(3));
assertThat(workspace.getRoot().getChildren(), hasItems(node_a1, node_b, node_a3));
@@ -201,26 +201,26 @@
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 ...
+ // Removing a node with the same name will reduce the index ..
workspace.removeNode(context, node_a1);
assertThat(workspace.getRoot().getChildren().size(), is(2));
assertThat(workspace.getRoot().getChildren(), hasItems(node_b, node_a3));
assertThat(node_b.getName().hasIndex(), is(false));
assertThat(node_a3.getName().hasIndex(), is(false));
- assertThat(workspace.getNodesByUuid().size(), is(3));
+ assertThat(workspace.size(), is(3));
}
@Test
public void shouldMoveNodesWithinSameWorkspace() {
- InMemoryNode root = workspace.getRoot();
- InMemoryNode node_a = workspace.createNode(context, root, nameFactory.create("a"), null);
- InMemoryNode node_b = workspace.createNode(context, node_a, nameFactory.create("b"), null);
- InMemoryNode node_c = workspace.createNode(context, node_b, nameFactory.create("c"), null);
- InMemoryNode node_d = workspace.createNode(context, root, nameFactory.create("d"), null);
- InMemoryNode node_e = workspace.createNode(context, node_d, nameFactory.create("e"), null);
- InMemoryNode node_b2 = workspace.createNode(context, node_d, nameFactory.create("b"), null);
+ MapNode root = workspace.getRoot();
+ MapNode node_a = workspace.createNode(context, root, nameFactory.create("a"), null);
+ MapNode node_b = workspace.createNode(context, node_a, nameFactory.create("b"), null);
+ MapNode node_c = workspace.createNode(context, node_b, nameFactory.create("c"), null);
+ MapNode node_d = workspace.createNode(context, root, nameFactory.create("d"), null);
+ MapNode node_e = workspace.createNode(context, node_d, nameFactory.create("e"), null);
+ MapNode node_b2 = workspace.createNode(context, node_d, nameFactory.create("b"), null);
- assertThat(workspace.getNodesByUuid().size(), is(7));
+ assertThat(workspace.size(), is(7));
assertThat(workspace.getNode(pathFactory.create("/")), is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")), is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/a/b")), is(sameInstance(node_b)));
@@ -252,18 +252,18 @@
@Test
public void shouldMoveNodeBeforeAnother() {
- InMemoryNode root = workspace.getRoot();
- InMemoryNode node_a = workspace.createNode(context, root, nameFactory.create("a"), null);
- InMemoryNode node_b = workspace.createNode(context, node_a, nameFactory.create("b"), null);
- InMemoryNode node_c = workspace.createNode(context, node_b, nameFactory.create("c"), null);
- InMemoryNode node_d = workspace.createNode(context, root, nameFactory.create("d"), null);
- InMemoryNode node_e = workspace.createNode(context, node_d, nameFactory.create("e"), null);
- InMemoryNode node_b2 = workspace.createNode(context, node_d, nameFactory.create("b"), null);
+ MapNode root = workspace.getRoot();
+ MapNode node_a = workspace.createNode(context, root, nameFactory.create("a"), null);
+ MapNode node_b = workspace.createNode(context, node_a, nameFactory.create("b"), null);
+ MapNode node_c = workspace.createNode(context, node_b, nameFactory.create("c"), null);
+ MapNode node_d = workspace.createNode(context, root, nameFactory.create("d"), null);
+ MapNode node_e = workspace.createNode(context, node_d, nameFactory.create("e"), null);
+ MapNode node_b2 = workspace.createNode(context, node_d, nameFactory.create("b"), null);
Name propName = nameFactory.create("prop");
node_b.setProperty(propertyFactory.create(propName, "node_b"));
node_b2.setProperty(propertyFactory.create(propName, "node_b2"));
- assertThat(workspace.getNodesByUuid().size(), is(7));
+ assertThat(workspace.size(), is(7));
assertThat(workspace.getNode(pathFactory.create("/")), is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")), is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/a/b")), is(sameInstance(node_b)));
@@ -303,16 +303,16 @@
@Test
public void shouldMoveNodesFromOneWorkspaceToAnother() {
- // Populate the workspace with some content ...
- InMemoryNode root = workspace.getRoot();
- InMemoryNode node_a = workspace.createNode(context, root, nameFactory.create("a"), null);
- InMemoryNode node_b = workspace.createNode(context, node_a, nameFactory.create("b"), null);
- InMemoryNode node_c = workspace.createNode(context, node_b, nameFactory.create("c"), null);
- InMemoryNode node_d = workspace.createNode(context, root, nameFactory.create("d"), null);
- InMemoryNode node_e = workspace.createNode(context, node_d, nameFactory.create("e"), null);
- InMemoryNode node_b2 = workspace.createNode(context, node_d, nameFactory.create("b"), null);
+ // Populate the workspace with some content ..
+ MapNode root = workspace.getRoot();
+ MapNode node_a = workspace.createNode(context, root, nameFactory.create("a"), null);
+ MapNode node_b = workspace.createNode(context, node_a, nameFactory.create("b"), null);
+ MapNode node_c = workspace.createNode(context, node_b, nameFactory.create("c"), null);
+ MapNode node_d = workspace.createNode(context, root, nameFactory.create("d"), null);
+ MapNode node_e = workspace.createNode(context, node_d, nameFactory.create("e"), null);
+ MapNode node_b2 = workspace.createNode(context, node_d, nameFactory.create("b"), null);
- assertThat(workspace.getNodesByUuid().size(), is(7));
+ assertThat(workspace.size(), is(7));
assertThat(workspace.getNode(pathFactory.create("/")), is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")), is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/a/b")), is(sameInstance(node_b)));
@@ -321,19 +321,19 @@
assertThat(workspace.getNode(pathFactory.create("/d/e")), is(sameInstance(node_e)));
assertThat(workspace.getNode(pathFactory.create("/d/b")), is(sameInstance(node_b2)));
- // Create the second workspace and populate it with some content ...
- Workspace new_workspace = repository.createWorkspace(context, "Second Workspace", CreateConflictBehavior.DO_NOT_CREATE);
+ // Create the second workspace and populate it with some content ..
+ InMemoryRepository.Workspace new_workspace = (InMemoryRepository.Workspace) repository.createWorkspace(context, "Second Workspace", CreateConflictBehavior.DO_NOT_CREATE);
assertThat(new_workspace, is(notNullValue()));
- InMemoryNode new_root = new_workspace.getRoot();
- InMemoryNode new_node_a = new_workspace.createNode(context, new_root, nameFactory.create("a"), null);
- InMemoryNode new_node_b = new_workspace.createNode(context, new_node_a, nameFactory.create("b"), null);
- InMemoryNode new_node_c = new_workspace.createNode(context, new_node_b, nameFactory.create("c"), null);
- InMemoryNode new_node_d = new_workspace.createNode(context, new_root, nameFactory.create("d"), null);
- InMemoryNode new_node_e = new_workspace.createNode(context, new_node_d, nameFactory.create("e"), null);
- InMemoryNode new_node_b2 = new_workspace.createNode(context, new_node_d, nameFactory.create("b"), null);
+ MapNode new_root = new_workspace.getRoot();
+ MapNode new_node_a = new_workspace.createNode(context, new_root, nameFactory.create("a"), null);
+ MapNode new_node_b = new_workspace.createNode(context, new_node_a, nameFactory.create("b"), null);
+ MapNode new_node_c = new_workspace.createNode(context, new_node_b, nameFactory.create("c"), null);
+ MapNode new_node_d = new_workspace.createNode(context, new_root, nameFactory.create("d"), null);
+ MapNode new_node_e = new_workspace.createNode(context, new_node_d, nameFactory.create("e"), null);
+ MapNode new_node_b2 = new_workspace.createNode(context, new_node_d, nameFactory.create("b"), null);
- assertThat(new_workspace.getNodesByUuid().size(), is(7));
+ assertThat(new_workspace.size(), is(7));
assertThat(new_workspace.getNode(pathFactory.create("/")), is(sameInstance(new_root)));
assertThat(new_workspace.getNode(pathFactory.create("/a")), is(sameInstance(new_node_a)));
assertThat(new_workspace.getNode(pathFactory.create("/a/b")), is(sameInstance(new_node_b)));
@@ -345,14 +345,14 @@
// Move 'workspace::/a/b' into 'newWorkspace::/d'
workspace.moveNode(context, node_b, null, new_workspace, new_node_d, null);
- assertThat(workspace.getNodesByUuid().size(), is(5));
+ assertThat(workspace.size(), is(5));
assertThat(workspace.getNode(pathFactory.create("/")), is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")), is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/d")), is(sameInstance(node_d)));
assertThat(workspace.getNode(pathFactory.create("/d/e")), is(sameInstance(node_e)));
assertThat(workspace.getNode(pathFactory.create("/d/b")), is(sameInstance(node_b2)));
- assertThat(new_workspace.getNodesByUuid().size(), is(9));
+ assertThat(new_workspace.size(), is(9));
assertThat(new_workspace.getNode(pathFactory.create("/")), is(sameInstance(new_root)));
assertThat(new_workspace.getNode(pathFactory.create("/a")), is(sameInstance(new_node_a)));
assertThat(new_workspace.getNode(pathFactory.create("/d")), is(sameInstance(new_node_d)));
@@ -364,20 +364,20 @@
@Test
public void shouldCopyNodesWithinSameWorkspace() {
- InMemoryNode root = workspace.getRoot();
- InMemoryNode node_a = workspace.createNode(context, root, nameFactory.create("a"), null);
- InMemoryNode node_b = workspace.createNode(context, node_a, nameFactory.create("b"), null);
- InMemoryNode node_c = workspace.createNode(context, node_b, nameFactory.create("c"), null);
- InMemoryNode node_d = workspace.createNode(context, root, nameFactory.create("d"), null);
- InMemoryNode node_e = workspace.createNode(context, node_d, nameFactory.create("e"), null);
- InMemoryNode node_b2 = workspace.createNode(context, node_d, nameFactory.create("b"), null);
+ MapNode root = workspace.getRoot();
+ MapNode node_a = workspace.createNode(context, root, nameFactory.create("a"), null);
+ MapNode node_b = workspace.createNode(context, node_a, nameFactory.create("b"), null);
+ MapNode node_c = workspace.createNode(context, node_b, nameFactory.create("c"), null);
+ MapNode node_d = workspace.createNode(context, root, nameFactory.create("d"), null);
+ MapNode node_e = workspace.createNode(context, node_d, nameFactory.create("e"), null);
+ MapNode node_b2 = workspace.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);
+ node_b.setProperty(property);
- assertThat(workspace.getNodesByUuid().size(), is(7));
+ assertThat(workspace.size(), is(7));
assertThat(workspace.getNode(pathFactory.create("/")), is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")), is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/a/b")), is(sameInstance(node_b)));
@@ -386,11 +386,11 @@
assertThat(workspace.getNode(pathFactory.create("/d/e")), is(sameInstance(node_e)));
assertThat(workspace.getNode(pathFactory.create("/d/b")), is(sameInstance(node_b2)));
- assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperties().get(propertyName), is(property));
+ assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperty(propertyName), is(property));
workspace.copyNode(context, node_b, workspace, node_d, null, true, new HashMap<UUID, UUID>());
- assertThat(workspace.getNodesByUuid().size(), is(9));
+ assertThat(workspace.size(), is(9));
assertThat(workspace.getNode(pathFactory.create("/")), is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")), is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/a/b")), is(sameInstance(node_b)));
@@ -401,27 +401,27 @@
assertThat(workspace.getNode(pathFactory.create("/d/b[2]")), is(notNullValue()));
assertThat(workspace.getNode(pathFactory.create("/d/b[2]/c")), is(notNullValue()));
- assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperties().get(propertyName), is(property));
- assertThat(workspace.getNode(pathFactory.create("/d/b[2]")).getProperties().get(propertyName), is(property));
+ assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperty(propertyName), is(property));
+ assertThat(workspace.getNode(pathFactory.create("/d/b[2]")).getProperty(propertyName), is(property));
}
@Test
public void shouldCopyNodesFromOneWorkspaceToAnotherAndKeepSameUuids() {
- // Populate the workspace with some content ...
- InMemoryNode root = workspace.getRoot();
- InMemoryNode node_a = workspace.createNode(context, root, nameFactory.create("a"), null);
- InMemoryNode node_b = workspace.createNode(context, node_a, nameFactory.create("b"), null);
- InMemoryNode node_c = workspace.createNode(context, node_b, nameFactory.create("c"), null);
- InMemoryNode node_d = workspace.createNode(context, root, nameFactory.create("d"), null);
- InMemoryNode node_e = workspace.createNode(context, node_d, nameFactory.create("e"), null);
- InMemoryNode node_b2 = workspace.createNode(context, node_d, nameFactory.create("b"), null);
+ // Populate the workspace with some content ..
+ MapNode root = workspace.getRoot();
+ MapNode node_a = workspace.createNode(context, root, nameFactory.create("a"), null);
+ MapNode node_b = workspace.createNode(context, node_a, nameFactory.create("b"), null);
+ MapNode node_c = workspace.createNode(context, node_b, nameFactory.create("c"), null);
+ MapNode node_d = workspace.createNode(context, root, nameFactory.create("d"), null);
+ MapNode node_e = workspace.createNode(context, node_d, nameFactory.create("e"), null);
+ MapNode node_b2 = workspace.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);
+ node_b.setProperty(property);
- assertThat(workspace.getNodesByUuid().size(), is(7));
+ assertThat(workspace.size(), is(7));
assertThat(workspace.getNode(pathFactory.create("/")), is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")), is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/a/b")), is(sameInstance(node_b)));
@@ -430,21 +430,21 @@
assertThat(workspace.getNode(pathFactory.create("/d/e")), is(sameInstance(node_e)));
assertThat(workspace.getNode(pathFactory.create("/d/b")), is(sameInstance(node_b2)));
- assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperties().get(propertyName), is(property));
+ assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperty(propertyName), is(property));
- // Create the second workspace and populate it with some content ...
- Workspace new_workspace = repository.createWorkspace(context, "Second Workspace", CreateConflictBehavior.DO_NOT_CREATE);
+ // Create the second workspace and populate it with some content ..
+ InMemoryRepository.Workspace new_workspace = (InMemoryRepository.Workspace) repository.createWorkspace(context, "Second Workspace", CreateConflictBehavior.DO_NOT_CREATE);
assertThat(new_workspace, is(notNullValue()));
- InMemoryNode new_root = new_workspace.getRoot();
- InMemoryNode new_node_a = new_workspace.createNode(context, new_root, nameFactory.create("a"), null);
- InMemoryNode new_node_b = new_workspace.createNode(context, new_node_a, nameFactory.create("b"), null);
- InMemoryNode new_node_c = new_workspace.createNode(context, new_node_b, nameFactory.create("c"), null);
- InMemoryNode new_node_d = new_workspace.createNode(context, new_root, nameFactory.create("d"), null);
- InMemoryNode new_node_e = new_workspace.createNode(context, new_node_d, nameFactory.create("e"), null);
- InMemoryNode new_node_b2 = new_workspace.createNode(context, new_node_d, nameFactory.create("b"), null);
+ MapNode new_root = new_workspace.getRoot();
+ MapNode new_node_a = new_workspace.createNode(context, new_root, nameFactory.create("a"), null);
+ MapNode new_node_b = new_workspace.createNode(context, new_node_a, nameFactory.create("b"), null);
+ MapNode new_node_c = new_workspace.createNode(context, new_node_b, nameFactory.create("c"), null);
+ MapNode new_node_d = new_workspace.createNode(context, new_root, nameFactory.create("d"), null);
+ MapNode new_node_e = new_workspace.createNode(context, new_node_d, nameFactory.create("e"), null);
+ MapNode new_node_b2 = new_workspace.createNode(context, new_node_d, nameFactory.create("b"), null);
- assertThat(new_workspace.getNodesByUuid().size(), is(7));
+ assertThat(new_workspace.size(), is(7));
assertThat(new_workspace.getNode(pathFactory.create("/")), is(sameInstance(new_root)));
assertThat(new_workspace.getNode(pathFactory.create("/a")), is(sameInstance(new_node_a)));
assertThat(new_workspace.getNode(pathFactory.create("/a/b")), is(sameInstance(new_node_b)));
@@ -454,9 +454,9 @@
assertThat(new_workspace.getNode(pathFactory.create("/d/b")), is(sameInstance(new_node_b2)));
// Copy 'workspace::/a/b' into 'newWorkspace::/d'
- workspace.copyNode(context, node_b, new_workspace, new_node_d, null, true, null);
+ workspace.copyNode(context, node_b, new_workspace, new_node_d, null, true, (Map<UUID, UUID>) null);
- assertThat(workspace.getNodesByUuid().size(), is(7));
+ assertThat(workspace.size(), is(7));
assertThat(workspace.getNode(pathFactory.create("/")), is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")), is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/a/b")), is(sameInstance(node_b)));
@@ -464,9 +464,9 @@
assertThat(workspace.getNode(pathFactory.create("/d")), is(sameInstance(node_d)));
assertThat(workspace.getNode(pathFactory.create("/d/e")), is(sameInstance(node_e)));
assertThat(workspace.getNode(pathFactory.create("/d/b")), is(sameInstance(node_b2)));
- assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperties().get(propertyName), is(property));
+ assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperty(propertyName), is(property));
- assertThat(new_workspace.getNodesByUuid().size(), is(9));
+ assertThat(new_workspace.size(), is(9));
assertThat(new_workspace.getNode(pathFactory.create("/")), is(sameInstance(new_root)));
assertThat(new_workspace.getNode(pathFactory.create("/a")), is(sameInstance(new_node_a)));
assertThat(new_workspace.getNode(pathFactory.create("/a/b")), is(sameInstance(new_node_b)));
@@ -477,11 +477,11 @@
assertThat(new_workspace.getNode(pathFactory.create("/d/b[2]")), is(notNullValue()));
assertThat(new_workspace.getNode(pathFactory.create("/d/b[2]/c")), is(notNullValue()));
- assertThat(new_workspace.getNode(pathFactory.create("/d/b[2]")).getProperties().get(propertyName), is(property));
+ assertThat(new_workspace.getNode(pathFactory.create("/d/b[2]")).getProperty(propertyName), is(property));
- // The new copy should have the same UUIDs as in the original, since we specified no UUID map ...
- InMemoryNode new_copy_b = new_workspace.getNode(pathFactory.create("/d/b[2]"));
- InMemoryNode new_copy_c = new_workspace.getNode(pathFactory.create("/d/b[2]/c"));
+ // The new copy should have the same UUIDs as in the original, since we specified no UUID map ..
+ MapNode new_copy_b = new_workspace.getNode(pathFactory.create("/d/b[2]"));
+ MapNode new_copy_c = new_workspace.getNode(pathFactory.create("/d/b[2]/c"));
assertThat(new_copy_b, is(notNullValue()));
assertThat(new_copy_c, is(notNullValue()));
assertThat(new_copy_b.getUuid(), is(node_b.getUuid()));
@@ -490,21 +490,21 @@
@Test
public void shouldCopyNodesFromOneWorkspaceToAnotherAndGenerateNewUuids() {
- // Populate the workspace with some content ...
- InMemoryNode root = workspace.getRoot();
- InMemoryNode node_a = workspace.createNode(context, root, nameFactory.create("a"), null);
- InMemoryNode node_b = workspace.createNode(context, node_a, nameFactory.create("b"), null);
- InMemoryNode node_c = workspace.createNode(context, node_b, nameFactory.create("c"), null);
- InMemoryNode node_d = workspace.createNode(context, root, nameFactory.create("d"), null);
- InMemoryNode node_e = workspace.createNode(context, node_d, nameFactory.create("e"), null);
- InMemoryNode node_b2 = workspace.createNode(context, node_d, nameFactory.create("b"), null);
+ // Populate the workspace with some content ..
+ MapNode root = workspace.getRoot();
+ MapNode node_a = workspace.createNode(context, root, nameFactory.create("a"), null);
+ MapNode node_b = workspace.createNode(context, node_a, nameFactory.create("b"), null);
+ MapNode node_c = workspace.createNode(context, node_b, nameFactory.create("c"), null);
+ MapNode node_d = workspace.createNode(context, root, nameFactory.create("d"), null);
+ MapNode node_e = workspace.createNode(context, node_d, nameFactory.create("e"), null);
+ MapNode node_b2 = workspace.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);
+ node_b.setProperty(property);
- assertThat(workspace.getNodesByUuid().size(), is(7));
+ assertThat(workspace.size(), is(7));
assertThat(workspace.getNode(pathFactory.create("/")), is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")), is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/a/b")), is(sameInstance(node_b)));
@@ -513,21 +513,21 @@
assertThat(workspace.getNode(pathFactory.create("/d/e")), is(sameInstance(node_e)));
assertThat(workspace.getNode(pathFactory.create("/d/b")), is(sameInstance(node_b2)));
- assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperties().get(propertyName), is(property));
+ assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperty(propertyName), is(property));
- // Create the second workspace and populate it with some content ...
- Workspace new_workspace = repository.createWorkspace(context, "Second Workspace", CreateConflictBehavior.DO_NOT_CREATE);
+ // Create the second workspace and populate it with some content ..
+ InMemoryRepository.Workspace new_workspace = (InMemoryRepository.Workspace) repository.createWorkspace(context, "Second Workspace", CreateConflictBehavior.DO_NOT_CREATE);
assertThat(new_workspace, is(notNullValue()));
- InMemoryNode new_root = new_workspace.getRoot();
- InMemoryNode new_node_a = new_workspace.createNode(context, new_root, nameFactory.create("a"), null);
- InMemoryNode new_node_b = new_workspace.createNode(context, new_node_a, nameFactory.create("b"), null);
- InMemoryNode new_node_c = new_workspace.createNode(context, new_node_b, nameFactory.create("c"), null);
- InMemoryNode new_node_d = new_workspace.createNode(context, new_root, nameFactory.create("d"), null);
- InMemoryNode new_node_e = new_workspace.createNode(context, new_node_d, nameFactory.create("e"), null);
- InMemoryNode new_node_b2 = new_workspace.createNode(context, new_node_d, nameFactory.create("b"), null);
+ MapNode new_root = new_workspace.getRoot();
+ MapNode new_node_a = new_workspace.createNode(context, new_root, nameFactory.create("a"), null);
+ MapNode new_node_b = new_workspace.createNode(context, new_node_a, nameFactory.create("b"), null);
+ MapNode new_node_c = new_workspace.createNode(context, new_node_b, nameFactory.create("c"), null);
+ MapNode new_node_d = new_workspace.createNode(context, new_root, nameFactory.create("d"), null);
+ MapNode new_node_e = new_workspace.createNode(context, new_node_d, nameFactory.create("e"), null);
+ MapNode new_node_b2 = new_workspace.createNode(context, new_node_d, nameFactory.create("b"), null);
- assertThat(new_workspace.getNodesByUuid().size(), is(7));
+ assertThat(new_workspace.size(), is(7));
assertThat(new_workspace.getNode(pathFactory.create("/")), is(sameInstance(new_root)));
assertThat(new_workspace.getNode(pathFactory.create("/a")), is(sameInstance(new_node_a)));
assertThat(new_workspace.getNode(pathFactory.create("/a/b")), is(sameInstance(new_node_b)));
@@ -540,7 +540,7 @@
Map<UUID, UUID> oldToNewUuids = new HashMap<UUID, UUID>();
workspace.copyNode(context, node_b, new_workspace, new_node_d, null, true, oldToNewUuids);
- assertThat(workspace.getNodesByUuid().size(), is(7));
+ assertThat(workspace.size(), is(7));
assertThat(workspace.getNode(pathFactory.create("/")), is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")), is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/a/b")), is(sameInstance(node_b)));
@@ -549,9 +549,9 @@
assertThat(workspace.getNode(pathFactory.create("/d/e")), is(sameInstance(node_e)));
assertThat(workspace.getNode(pathFactory.create("/d/b")), is(sameInstance(node_b2)));
- assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperties().get(propertyName), is(property));
+ assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperty(propertyName), is(property));
- assertThat(new_workspace.getNodesByUuid().size(), is(9));
+ assertThat(new_workspace.size(), is(9));
assertThat(new_workspace.getNode(pathFactory.create("/")), is(sameInstance(new_root)));
assertThat(new_workspace.getNode(pathFactory.create("/a")), is(sameInstance(new_node_a)));
assertThat(new_workspace.getNode(pathFactory.create("/a/b")), is(sameInstance(new_node_b)));
@@ -562,11 +562,11 @@
assertThat(new_workspace.getNode(pathFactory.create("/d/b[2]")), is(notNullValue()));
assertThat(new_workspace.getNode(pathFactory.create("/d/b[2]/c")), is(notNullValue()));
- assertThat(new_workspace.getNode(pathFactory.create("/d/b[2]")).getProperties().get(propertyName), is(property));
+ assertThat(new_workspace.getNode(pathFactory.create("/d/b[2]")).getProperty(propertyName), is(property));
- // The new copy should have different UUIDs than in the original, since we did specify a UUID map ...
- InMemoryNode new_copy_b = new_workspace.getNode(pathFactory.create("/d/b[2]"));
- InMemoryNode new_copy_c = new_workspace.getNode(pathFactory.create("/d/b[2]/c"));
+ // The new copy should have different UUIDs than in the original, since we did specify a UUID map ..
+ MapNode new_copy_b = new_workspace.getNode(pathFactory.create("/d/b[2]"));
+ MapNode new_copy_c = new_workspace.getNode(pathFactory.create("/d/b[2]/c"));
assertThat(new_copy_b, is(notNullValue()));
assertThat(new_copy_c, is(notNullValue()));
assertThat(new_copy_b.getUuid(), is(not(node_b.getUuid())));
@@ -577,20 +577,20 @@
@Test
public void shouldCopyNodesWhenDesiredNameIsSpecified() {
- InMemoryNode root = workspace.getRoot();
- InMemoryNode node_a = workspace.createNode(context, root, nameFactory.create("a"), null);
- InMemoryNode node_b = workspace.createNode(context, node_a, nameFactory.create("b"), null);
- InMemoryNode node_c = workspace.createNode(context, node_b, nameFactory.create("c"), null);
- InMemoryNode node_d = workspace.createNode(context, root, nameFactory.create("d"), null);
- InMemoryNode node_e = workspace.createNode(context, node_d, nameFactory.create("e"), null);
- InMemoryNode node_b2 = workspace.createNode(context, node_d, nameFactory.create("b"), null);
+ MapNode root = workspace.getRoot();
+ MapNode node_a = workspace.createNode(context, root, nameFactory.create("a"), null);
+ MapNode node_b = workspace.createNode(context, node_a, nameFactory.create("b"), null);
+ MapNode node_c = workspace.createNode(context, node_b, nameFactory.create("c"), null);
+ MapNode node_d = workspace.createNode(context, root, nameFactory.create("d"), null);
+ MapNode node_e = workspace.createNode(context, node_d, nameFactory.create("e"), null);
+ MapNode node_b2 = workspace.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);
+ node_b.setProperty(property);
- assertThat(workspace.getNodesByUuid().size(), is(7));
+ assertThat(workspace.size(), is(7));
assertThat(workspace.getNode(pathFactory.create("/")), is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")), is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/a/b")), is(sameInstance(node_b)));
@@ -599,11 +599,11 @@
assertThat(workspace.getNode(pathFactory.create("/d/e")), is(sameInstance(node_e)));
assertThat(workspace.getNode(pathFactory.create("/d/b")), is(sameInstance(node_b2)));
- assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperties().get(propertyName), is(property));
+ assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperty(propertyName), is(property));
workspace.copyNode(context, node_b, workspace, node_d, nameFactory.create("x"), true, new HashMap<UUID, UUID>());
- assertThat(workspace.getNodesByUuid().size(), is(9));
+ assertThat(workspace.size(), is(9));
assertThat(workspace.getNode(pathFactory.create("/")), is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")), is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/a/b")), is(sameInstance(node_b)));
@@ -614,8 +614,8 @@
assertThat(workspace.getNode(pathFactory.create("/d/x")), is(notNullValue()));
assertThat(workspace.getNode(pathFactory.create("/d/x/c")), is(notNullValue()));
- assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperties().get(propertyName), is(property));
- assertThat(workspace.getNode(pathFactory.create("/d/x")).getProperties().get(propertyName), is(property));
+ assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperty(propertyName), is(property));
+ assertThat(workspace.getNode(pathFactory.create("/d/x")).getProperty(propertyName), is(property));
}
@Test
Deleted: trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheConnection.java
===================================================================
--- trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheConnection.java 2009-06-24 22:14:12 UTC (rev 1064)
+++ trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheConnection.java 2009-06-27 02:54:06 UTC (rev 1065)
@@ -1,108 +0,0 @@
-/*
- * 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.connector.jbosscache;
-
-import java.util.concurrent.TimeUnit;
-import javax.transaction.xa.XAResource;
-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.observe.Observer;
-import org.jboss.dna.graph.request.Request;
-import org.jboss.dna.graph.request.processor.RequestProcessor;
-
-/**
- * The repository connection to a JBoss Cache instance.
- *
- * @author Randall Hauch
- */
-public class JBossCacheConnection implements RepositoryConnection {
-
- private final JBossCacheSource source;
- private final JBossCacheWorkspaces workspaces;
-
- JBossCacheConnection( JBossCacheSource source,
- JBossCacheWorkspaces workspaces ) {
- assert source != null;
- assert workspaces != null;
- this.source = source;
- this.workspaces = workspaces;
- }
-
- /**
- * {@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 ) {
- return true;
- }
-
- /**
- * {@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( final ExecutionContext context,
- final Request request ) throws RepositorySourceException {
- Observer observer = source.getObserver();
- RequestProcessor processor = new JBossCacheRequestProcessor(getSourceName(), context, observer, workspaces,
- source.getNameOfDefaultWorkspace(),
- source.isCreatingWorkspacesAllowed());
- try {
- processor.process(request);
- } finally {
- processor.close();
- }
- }
-}
Deleted: trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheLexicon.java
===================================================================
--- trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheLexicon.java 2009-06-24 22:14:12 UTC (rev 1064)
+++ trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheLexicon.java 2009-06-27 02:54:06 UTC (rev 1065)
@@ -1,45 +0,0 @@
-/*
- * 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.connector.jbosscache;
-
-import org.jboss.dna.graph.property.Name;
-import org.jboss.dna.graph.property.basic.BasicName;
-
-/**
- * The namespace and property names used within a {@link JBossCacheSource} to store internal information.
- *
- * @author Randall Hauch
- */
-public class JBossCacheLexicon {
-
- public static class Namespace {
- public static final String URI = "http://www.jboss.org/dna/connector/jbosscache";
- public static final String PREFIX = "dnajbcc";
- }
-
- public static final Name CHILD_PATH_SEGMENT_LIST = new BasicName(Namespace.URI, "orderedChildNames");
- public static final Name UUIDS = new BasicName(Namespace.URI, "uuids");
- public static final Name FQN = new BasicName(Namespace.URI, "fqn");
-
-}
Added: trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheRepository.java
===================================================================
--- trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheRepository.java (rev 0)
+++ trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheRepository.java 2009-06-27 02:54:06 UTC (rev 1065)
@@ -0,0 +1,79 @@
+package org.jboss.dna.connector.jbosscache;
+
+import java.util.UUID;
+import org.jboss.cache.Cache;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.Node;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.connector.map.AbstractMapWorkspace;
+import org.jboss.dna.graph.connector.map.MapNode;
+import org.jboss.dna.graph.connector.map.MapRepository;
+import org.jboss.dna.graph.connector.map.MapWorkspace;
+
+public class JBossCacheRepository extends MapRepository {
+
+ private final Cache<UUID, MapNode> cache;
+
+ public JBossCacheRepository( String sourceName,
+ UUID rootNodeUuid,
+ Cache<UUID, MapNode> cache ) {
+ super(sourceName, rootNodeUuid, null);
+ assert cache != null;
+ this.cache = cache;
+ initialize();
+ }
+
+ public JBossCacheRepository( String sourceName,
+ UUID rootNodeUuid,
+ String defaultWorkspaceName,
+ Cache<UUID, MapNode> cache ) {
+ super(sourceName, rootNodeUuid, defaultWorkspaceName);
+
+ assert cache != null;
+ this.cache = cache;
+
+ initialize();
+ }
+
+ @Override
+ protected MapWorkspace createWorkspace( ExecutionContext context,
+ String name ) {
+ assert name != null;
+ assert cache != null;
+ Node<UUID, MapNode> newWorkspaceNode = cache.getRoot().addChild(Fqn.fromElements(name));
+ return new Workspace(this, name, newWorkspaceNode);
+ }
+
+ protected class Workspace extends AbstractMapWorkspace {
+ private final Node<UUID, MapNode> workspaceNode;
+
+ public Workspace( MapRepository repository,
+ String name,
+ Node<UUID, MapNode> workspaceNode ) {
+ super(repository, name);
+
+ this.workspaceNode = workspaceNode;
+ initialize();
+ }
+
+ protected void addNodeToMap( MapNode node ) {
+ assert node != null;
+ workspaceNode.put(node.getUuid(), node);
+ }
+
+ protected MapNode removeNodeFromMap( UUID nodeUuid ) {
+ assert nodeUuid != null;
+ return workspaceNode.remove(nodeUuid);
+ }
+
+ protected void removeAllNodesFromMap() {
+ workspaceNode.clearData();
+ }
+
+ public MapNode getNode( UUID nodeUuid ) {
+ assert nodeUuid != null;
+ return workspaceNode.get(nodeUuid);
+ }
+ }
+
+}
Property changes on: trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheRepository.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Deleted: trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheRequestProcessor.java
===================================================================
--- trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheRequestProcessor.java 2009-06-24 22:14:12 UTC (rev 1064)
+++ trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheRequestProcessor.java 2009-06-27 02:54:06 UTC (rev 1065)
@@ -1,1032 +0,0 @@
-/*
- * 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.
- *
- * 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.connector.jbosscache;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.atomic.AtomicInteger;
-import org.jboss.cache.Cache;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.Node;
-import org.jboss.dna.common.util.Logger;
-import org.jboss.dna.graph.DnaLexicon;
-import org.jboss.dna.graph.ExecutionContext;
-import org.jboss.dna.graph.Location;
-import org.jboss.dna.graph.connector.RepositorySourceException;
-import org.jboss.dna.graph.connector.UuidAlreadyExistsException;
-import org.jboss.dna.graph.observe.Observer;
-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.UuidFactory;
-import org.jboss.dna.graph.request.CloneWorkspaceRequest;
-import org.jboss.dna.graph.request.CopyBranchRequest;
-import org.jboss.dna.graph.request.CreateNodeRequest;
-import org.jboss.dna.graph.request.CreateWorkspaceRequest;
-import org.jboss.dna.graph.request.DeleteBranchRequest;
-import org.jboss.dna.graph.request.DestroyWorkspaceRequest;
-import org.jboss.dna.graph.request.GetWorkspacesRequest;
-import org.jboss.dna.graph.request.InvalidRequestException;
-import org.jboss.dna.graph.request.InvalidWorkspaceException;
-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.UuidConflictBehavior;
-import org.jboss.dna.graph.request.VerifyWorkspaceRequest;
-import org.jboss.dna.graph.request.processor.RequestProcessor;
-
-/**
- * A {@link RequestProcessor} implementation that operates upon a {@link Cache JBoss Cache} instance for each workspace in the
- * {@link JBossCacheSource source}.
- * <p>
- * This processor only uses {@link Location} objects with {@link Location#getPath() paths}. Even though every node in the cache is
- * automatically assigned a UUID (and all operations properly handle UUIDs), these UUIDs are not included in the {@link Location}
- * objects because the processor is unable to search the cache to find nodes by UUID.
- * </p>
- */
-public class JBossCacheRequestProcessor extends RequestProcessor {
-
- private final JBossCacheWorkspaces workspaces;
- private final boolean creatingWorkspacesAllowed;
- private final String defaultWorkspaceName;
- private final PathFactory pathFactory;
- private final PropertyFactory propertyFactory;
- private final UuidFactory uuidFactory;
- private Path.Segment dnaUuidsSegment;
-
- /**
- * @param sourceName the name of the source in which this processor is operating
- * @param context the execution context in which this processor operates
- * @param observer the observer to which events should be published; may be null if the events are not be published
- * @param workspaces the manager for the workspaces
- * @param defaultWorkspaceName the name of the default workspace; never null
- * @param creatingWorkspacesAllowed true if clients can create new workspaces, or false otherwise
- */
- JBossCacheRequestProcessor( String sourceName,
- ExecutionContext context,
- Observer observer,
- JBossCacheWorkspaces workspaces,
- String defaultWorkspaceName,
- boolean creatingWorkspacesAllowed ) {
- super(sourceName, context, observer);
- assert workspaces != null;
- assert defaultWorkspaceName != null;
- this.workspaces = workspaces;
- this.creatingWorkspacesAllowed = creatingWorkspacesAllowed;
- this.defaultWorkspaceName = defaultWorkspaceName;
- this.pathFactory = context.getValueFactories().getPathFactory();
- this.propertyFactory = context.getPropertyFactory();
- this.uuidFactory = context.getValueFactories().getUuidFactory();
- this.dnaUuidsSegment = pathFactory.createSegment(JBossCacheLexicon.UUIDS);
- }
-
- @Override
- public void process( ReadAllChildrenRequest request ) {
- // Look up the cache and the node ...
- Cache<Name, Object> cache = getCache(request, request.inWorkspace());
- if (cache == null) return;
- Path nodePath = request.of().getPath();
- Node<Name, Object> node = getNode(request, cache, nodePath);
- if (node == null) return;
-
- // Get the names of the children, using the child list ...
- Path.Segment[] childList = (Path.Segment[])node.get(JBossCacheLexicon.CHILD_PATH_SEGMENT_LIST);
- if (childList != null) {
- for (Path.Segment child : childList) {
- request.addChild(Location.create(pathFactory.create(nodePath, child)));
- }
- }
- request.setActualLocationOfNode(Location.create(nodePath));
- setCacheableInfo(request);
- }
-
- @Override
- public void process( ReadAllPropertiesRequest request ) {
- // Look up the cache and the node ...
- Cache<Name, Object> cache = getCache(request, request.inWorkspace());
- if (cache == null) return;
- Path nodePath = request.at().getPath();
- Node<Name, Object> node = getNode(request, cache, nodePath);
- if (node == null) return;
-
- // Get the properties on the node ...
- Map<Name, Object> dataMap = node.getData();
- for (Map.Entry<Name, Object> data : dataMap.entrySet()) {
- Name propertyName = data.getKey();
- // Don't allow the child list property to be accessed
- if (propertyName.equals(JBossCacheLexicon.CHILD_PATH_SEGMENT_LIST)) continue;
- Object values = data.getValue();
- Property property = propertyFactory.create(propertyName, values);
- request.addProperty(property);
- }
- request.setActualLocationOfNode(Location.create(nodePath));
- setCacheableInfo(request);
- }
-
- @Override
- @SuppressWarnings( "unchecked" )
- public void process( CreateNodeRequest request ) {
- // Look up the cache and the node ...
- Cache<Name, Object> cache = getCache(request, request.inWorkspace());
- if (cache == null) return;
- Path parent = request.under().getPath();
- Node<Name, Object> parentNode = getNode(request, cache, parent);
- if (parentNode == null) return;
-
- // Update the children to account for same-name siblings.
- // This not only updates the FQN of the child nodes, but it also sets the property that stores the
- // the array of Path.Segment for the children (since the cache doesn't maintain order).
- Path.Segment newSegment = updateChildList(cache, parentNode, request.named(), null, getExecutionContext(), true);
- Node<Name, Object> node = parentNode.addChild(Fqn.fromElements(newSegment));
- assert checkChildren(parentNode);
-
- // Add the UUID property (if required), which may be overwritten by a supplied property ...
- UUID uuid = uuidFactory.create();
- node.put(DnaLexicon.UUID, uuid);
- // Now add the properties to the supplied node ...
- for (Property property : request.properties()) {
- 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);
- }
-
- mapUuid(cache, uuid, node.getFqn());
- Path nodePath = pathFactory.create(parent, newSegment);
- request.setActualLocationOfNode(Location.create(nodePath));
- recordChange(request);
- }
-
- @Override
- public void process( UpdatePropertiesRequest request ) {
- // Look up the cache and the node ...
- Cache<Name, Object> cache = getCache(request, request.inWorkspace());
- if (cache == null) return;
- Path nodePath = request.on().getPath();
- Node<Name, Object> node = getNode(request, cache, nodePath);
- if (node == null) return;
-
- // Now set (or remove) the properties to the supplied node ...
- for (Map.Entry<Name, Property> entry : request.properties().entrySet()) {
- Name propName = entry.getKey();
- // Don't allow the child list property to be removed or changed
- if (propName.equals(JBossCacheLexicon.CHILD_PATH_SEGMENT_LIST)) continue;
-
- Property property = entry.getValue();
- if (property == null) {
- node.remove(propName);
- continue;
- }
- Object value = null;
- if (property.isSingle()) {
- value = property.iterator().next();
- } else {
- value = property.getValuesAsArray();
- }
- node.put(propName, value);
- }
- request.setActualLocationOfNode(Location.create(nodePath));
- recordChange(request);
- }
-
- @Override
- public void process( CopyBranchRequest request ) {
- // Look up the caches ...
- Cache<Name, Object> fromCache = getCache(request, request.fromWorkspace());
- if (fromCache == null) return;
- Cache<Name, Object> intoCache = getCache(request, request.intoWorkspace());
- if (intoCache == null) return;
-
- // Look up the current node and the new parent (both of which must exist) ...
- Path nodePath = request.from().getPath();
- Node<Name, Object> node = getNode(request, fromCache, nodePath);
- if (node == null) return;
- Path newParentPath = request.into().getPath();
- Node<Name, Object> newParent = getNode(request, intoCache, newParentPath);
- if (newParent == null) return;
-
- if (UuidConflictBehavior.THROW_EXCEPTION.equals(request.uuidConflictBehavior())) {
- // Build a list of all the UUIDs in the source branch
- Set<UUID> uuidsFromSource = new HashSet<UUID>();
- LinkedList<Node<Name, Object>> nodesToVisit = new LinkedList<Node<Name, Object>>();
- nodesToVisit.add(node);
-
- while (!nodesToVisit.isEmpty()) {
- Node<Name, Object> nodeToCheck = nodesToVisit.removeFirst();
- UUID uuid = uuidFactory.create(nodeToCheck.get(DnaLexicon.UUID));
- if (uuid != null) uuidsFromSource.add(uuid);
-
- nodesToVisit.addAll(nodeToCheck.getChildren());
- }
-
- // If any of the UUIDS currently exist in this workspace, throw an exception
- for (UUID uuid : uuidsFromSource) {
- Fqn<Path.Segment> path;
- if (null != (path = getFullyQualifiedName(intoCache, uuid))) {
- String pathAsString = path.toString();
- throw new UuidAlreadyExistsException(this.getSourceName(), uuid, pathAsString, request.intoWorkspace());
- }
- }
- }
-
- // Copy the branch ...
- Name desiredName = request.desiredName();
- Path.Segment newSegment = copyNode(intoCache,
- node,
- newParent,
- desiredName,
- null,
- true,
- request.uuidConflictBehavior(),
- null,
- getExecutionContext());
-
- mapUuids(intoCache, Fqn.fromRelativeElements(Fqn.fromList(newParentPath.getSegmentsList()), newSegment));
- Path newPath = pathFactory.create(newParentPath, newSegment);
- request.setActualLocations(Location.create(nodePath), Location.create(newPath));
- recordChange(request);
- }
-
- @SuppressWarnings( "unchecked" )
- private boolean deleteNode( Cache<Name, Object> cache,
- Node<Name, Object> node ) {
- Fqn<Path.Segment> nodeFqn = node.getFqn();
-
- removeUuids(cache, nodeFqn);
- Path.Segment nameOfRemovedNode = (Path.Segment)nodeFqn.getLastElement();
- if (cache.removeNode(node.getFqn())) {
- removeFromChildList(cache, node.getParent(), nameOfRemovedNode, getExecutionContext());
- return true;
- }
- return false;
- }
-
- @Override
- public void process( DeleteBranchRequest request ) {
- // Look up the cache and the node ...
- Cache<Name, Object> cache = getCache(request, request.inWorkspace());
- if (cache == null) return;
- Path nodePath = request.at().getPath();
- Node<Name, Object> node = getNode(request, cache, nodePath);
- if (node == null) return;
-
- if (deleteNode(cache, node)) {
- request.setActualLocationOfNode(Location.create(nodePath));
- recordChange(request);
- } else {
- String msg = JBossCacheConnectorI18n.unableToDeleteBranch.text(getSourceName(), request.inWorkspace(), nodePath);
- request.setError(new RepositorySourceException(msg));
- }
- }
-
- @Override
- @SuppressWarnings( "unchecked" )
- public void process( MoveBranchRequest request ) {
- // Look up the caches ...
- Cache<Name, Object> cache = getCache(request, request.inWorkspace());
- if (cache == null) return;
-
- // Look up the current node and the new parent (both of which must exist) ...
- Path nodePath = request.from().getPath();
- Node<Name, Object> node = getNode(request, cache, nodePath);
- if (node == null) return;
- Path newParentPath;
-
- if (request.into() != null) {
- newParentPath = request.into().getPath();
- } else {
- // into() and before() can't both be null
- assert request.before() != null;
- newParentPath = request.before().getPath().getParent();
- }
-
- Path.Segment beforeNodeName = request.before() != null ? request.before().getPath().getLastSegment() : null;
- Node<Name, Object> newParent = getNode(request, cache, newParentPath);
- if (newParent == null) return;
-
- removeUuids(cache, node.getFqn());
-
- // Copy the branch and use the same UUIDs ...
- Name desiredName = request.desiredName();
- Path.Segment newSegment = copyNode(cache,
- node,
- newParent,
- desiredName,
- beforeNodeName,
- true,
- UuidConflictBehavior.THROW_EXCEPTION,
- null,
- getExecutionContext());
- mapUuids(cache, node.getFqn());
- // Now delete the old node ...
- Node<Name, Object> oldParent = node.getParent();
- boolean removed = oldParent.removeChild(node.getFqn().getLastElement());
- assert removed;
- Path.Segment nameOfRemovedNode = nodePath.getLastSegment();
- removeFromChildList(cache, oldParent, nameOfRemovedNode, getExecutionContext());
-
- Path newPath = pathFactory.create(newParentPath, newSegment);
- request.setActualLocations(Location.create(nodePath), Location.create(newPath));
- recordChange(request);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.VerifyWorkspaceRequest)
- */
- @Override
- public void process( VerifyWorkspaceRequest request ) {
- String workspaceName = request.workspaceName();
- if (workspaceName == null) workspaceName = defaultWorkspaceName;
-
- Cache<Name, Object> cache = workspaces.getWorkspace(workspaceName, false);
- if (cache == null) {
- String msg = JBossCacheConnectorI18n.workspaceDoesNotExist.text(getSourceName(), workspaceName);
- request.setError(new InvalidWorkspaceException(msg));
- } else {
- Fqn<Path.Segment> rootName = Fqn.root();
- UUID uuid = uuidFactory.create(cache.get(rootName, DnaLexicon.UUID));
- if (uuid == null) {
- uuid = uuidFactory.create();
- cache.put(rootName, DnaLexicon.UUID, uuid);
- }
- request.setActualRootLocation(Location.create(pathFactory.createRootPath()));
- request.setActualWorkspaceName(workspaceName);
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.GetWorkspacesRequest)
- */
- @Override
- public void process( GetWorkspacesRequest request ) {
- request.setAvailableWorkspaceNames(workspaces.getWorkspaceNames());
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CreateWorkspaceRequest)
- */
- @Override
- public void process( CreateWorkspaceRequest request ) {
- String workspaceName = request.desiredNameOfNewWorkspace();
- if (!creatingWorkspacesAllowed) {
- String msg = JBossCacheConnectorI18n.unableToCreateWorkspaces.text(getSourceName(), workspaceName);
- request.setError(new InvalidRequestException(msg));
- return;
- }
- // Try to create the workspace ...
- Cache<Name, Object> cache = workspaces.getWorkspace(workspaceName, creatingWorkspacesAllowed);
- if (cache == null) {
- String msg = JBossCacheConnectorI18n.unableToCreateWorkspace.text(getSourceName(), workspaceName);
- request.setError(new InvalidWorkspaceException(msg));
- return;
- }
- // Make sure the root node has a UUID ...
- Fqn<Path.Segment> rootName = Fqn.root();
- UUID uuid = uuidFactory.create(cache.get(rootName, DnaLexicon.UUID));
- if (uuid == null) {
- uuid = uuidFactory.create();
- cache.put(rootName, DnaLexicon.UUID, uuid);
- mapUuid(cache, uuid, rootName);
- }
- request.setActualRootLocation(Location.create(pathFactory.createRootPath()));
- request.setActualWorkspaceName(workspaceName);
- recordChange(request);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CloneWorkspaceRequest)
- */
- @Override
- @SuppressWarnings( "unchecked" )
- public void process( CloneWorkspaceRequest request ) {
- String fromWorkspaceName = request.nameOfWorkspaceToBeCloned();
- String toWorkspaceName = request.desiredNameOfTargetWorkspace();
- if (!creatingWorkspacesAllowed) {
- String msg = JBossCacheConnectorI18n.unableToCloneWorkspaces.text(getSourceName(), fromWorkspaceName, toWorkspaceName);
- request.setError(new InvalidRequestException(msg));
- return;
- }
- // Make sure there is already a workspace that we're cloning ...
- Cache<Name, Object> fromCache = workspaces.getWorkspace(fromWorkspaceName, false);
- if (fromCache == null) {
- String msg = JBossCacheConnectorI18n.workspaceDoesNotExist.text(getSourceName(), fromWorkspaceName);
- request.setError(new InvalidWorkspaceException(msg));
- return;
- }
-
- // Try to create a new workspace with the target name ...
- Cache<Name, Object> intoCache = workspaces.createWorkspace(toWorkspaceName);
- if (intoCache == null) {
- // Couldn't create it because one already exists ...
- String msg = JBossCacheConnectorI18n.workspaceAlreadyExists.text(getSourceName(), toWorkspaceName);
- request.setError(new InvalidWorkspaceException(msg));
- return;
- }
-
- // And finally copy the contents ...
- Fqn<Path.Segment> rootName = Fqn.root();
- Node<Name, Object> fromRoot = fromCache.getNode(rootName);
- Node<Name, Object> intoRoot = intoCache.getNode(rootName);
- intoRoot.clearData();
- intoRoot.putAll(fromRoot.getData());
- ExecutionContext context = getExecutionContext();
-
- // Loop over each child and copy it ...
- for (Node<Name, Object> child : fromRoot.getChildren()) {
- copyNode(intoCache, child, intoRoot, null, null, true, UuidConflictBehavior.THROW_EXCEPTION, null, context);
- }
-
- mapUuids(intoCache, intoRoot.getFqn());
- // Copy the list of child segments in the root (this maintains the order of the children) ...
- Path.Segment[] childNames = (Path.Segment[])fromRoot.get(JBossCacheLexicon.CHILD_PATH_SEGMENT_LIST);
- intoRoot.put(JBossCacheLexicon.CHILD_PATH_SEGMENT_LIST, childNames);
- recordChange(request);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.DestroyWorkspaceRequest)
- */
- @Override
- public void process( DestroyWorkspaceRequest request ) {
- Cache<Name, Object> fromCache = workspaces.getWorkspace(request.workspaceName(), false);
- if (fromCache == null) {
- String msg = JBossCacheConnectorI18n.workspaceDoesNotExist.text(getSourceName(), request.workspaceName());
- request.setError(new InvalidWorkspaceException(msg));
- return;
- }
- request.setActualRootLocation(Location.create(pathFactory.createRootPath()));
- recordChange(request);
- }
-
- // ----------------------------------------------------------------------------------------------------------------
- // Utility methods
- // ----------------------------------------------------------------------------------------------------------------
-
- /**
- * Obtain the appropriate cache for the supplied workspace name, or set an error on the request if the workspace does not
- * exist (and could not or should not be created).
- *
- * @param request the request
- * @param workspaceName the workspace name
- * @return the cache, or null if there is no such workspace
- */
- protected Cache<Name, Object> getCache( Request request,
- String workspaceName ) {
- if (workspaceName == null) workspaceName = defaultWorkspaceName;
- Cache<Name, Object> cache = workspaces.getWorkspace(workspaceName, creatingWorkspacesAllowed);
- if (cache == null && request != null) {
- String msg = JBossCacheConnectorI18n.workspaceDoesNotExist.text(getSourceName(), workspaceName);
- request.setError(new InvalidWorkspaceException(msg));
- }
- return cache;
- }
-
- protected Fqn<Path.Segment> getFullyQualifiedName( Path path ) {
- assert path != null;
- 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 ) {
- assert pathSegment != null;
- return Fqn.fromElements(pathSegment);
- }
-
- @SuppressWarnings( "unchecked" )
- protected Fqn<Path.Segment> getFullyQualifiedName( Cache<Name, Object> cache,
- UUID uuid ) {
- assert cache != null;
- assert uuid != null;
-
- Fqn<Path.Segment> uuidFqn = Fqn.fromElements(dnaUuidsSegment, pathFactory.createSegment(uuid.toString()));
-
- return (Fqn<Path.Segment>)cache.get(uuidFqn, JBossCacheLexicon.FQN);
- }
-
- protected Path getPath( PathFactory factory,
- Fqn<Path.Segment> fqn ) {
- List<Path.Segment> segments = fqn.peekElements();
- return factory.create(factory.createRootPath(), segments);
- }
-
- protected void removeUuid( Cache<Name, Object> cache,
- UUID uuid ) {
- assert cache != null;
- assert uuid != null;
-
- Fqn<Path.Segment> uuidFqn = Fqn.fromElements(pathFactory.createSegment(JBossCacheLexicon.UUIDS),
- pathFactory.createSegment(uuid.toString()));
-
- removeFromChildList(cache,
- getNode(null, cache, pathFactory.create(JBossCacheLexicon.UUIDS)),
- pathFactory.createSegment(uuid.toString()),
- getExecutionContext());
- cache.removeNode(uuidFqn);
- }
-
- @SuppressWarnings( "unchecked" )
- protected void mapUuid( Cache<Name, Object> cache,
- UUID uuid,
- Fqn<Path.Segment> path ) {
- assert cache != null;
- assert uuid != null;
-
- Fqn<Path.Segment> uuidsFqn = Fqn.fromElements(this.dnaUuidsSegment);
-
- Node uuidsNode = cache.getNode(uuidsFqn);
- if (uuidsNode == null) {
- uuidsNode = cache.getRoot().addChild(uuidsFqn);
- updateChildList(cache, cache.getRoot(), this.dnaUuidsSegment.getName(), null, this.getExecutionContext(), true);
- }
-
- assert uuidsNode != null : this.dnaUuidsSegment.getName() + "=" + uuidsFqn;
- Path.Segment uuidSegment = pathFactory.createSegment(uuid.toString());
-
- if (!uuidsNode.getChildrenNames().contains(uuidSegment)) {
- Path.Segment newSegment = updateChildList(cache,
- uuidsNode,
- uuidSegment.getName(),
- null,
- this.getExecutionContext(),
- true);
- assert newSegment.getIndex() == 1 : "Should not have SNS under uuids branch";
- }
-
- Fqn<Path.Segment> uuidFqn = Fqn.fromRelativeElements(uuidsFqn, uuidSegment);
-
- cache.put(uuidFqn, JBossCacheLexicon.FQN, path);
- assert cache.getNode(uuidFqn) != null;
- assert cache.get(uuidFqn, JBossCacheLexicon.FQN) != null;
- assert path.equals(getFullyQualifiedName(cache, uuid)) : path + " => " + getFullyQualifiedName(cache, uuid);
- }
-
- protected void mapUuids( Cache<Name, Object> cache,
- Fqn<Path.Segment> path ) {
- Node<Name, Object> node = cache.getNode(path);
- assert node != null : path.toString();
- UUID uuid = (UUID)node.get(DnaLexicon.UUID);
- if (uuid != null) {
- mapUuid(cache, uuid, path);
- assert getFullyQualifiedName(cache, uuid).equals(path);
- }
-
- Path.Segment[] childNamesProperty = (Path.Segment[])node.get(JBossCacheLexicon.CHILD_PATH_SEGMENT_LIST);
- if (childNamesProperty == null) return;
-
- for (Path.Segment childName : childNamesProperty) {
- Fqn<Path.Segment> childPath = Fqn.fromRelativeElements(path, childName);
- mapUuids(cache, childPath);
- }
- }
-
- protected void removeUuids( Cache<Name, Object> cache,
- Fqn<Path.Segment> path ) {
- Node<Name, Object> node = cache.getNode(path);
- assert node != null : path.toString();
- UUID uuid = (UUID)node.get(DnaLexicon.UUID);
-
- if (uuid != null) removeUuid(cache, uuid);
-
- Path.Segment[] childNamesProperty = (Path.Segment[])node.get(JBossCacheLexicon.CHILD_PATH_SEGMENT_LIST);
- if (childNamesProperty == null) return;
-
- for (Path.Segment childName : childNamesProperty) {
- Fqn<Path.Segment> childPath = Fqn.fromRelativeElements(path, childName);
- removeUuids(cache, childPath);
- }
- }
-
- protected Node<Name, Object> getNode( Request request,
- Cache<Name, Object> cache,
- Path path ) {
- ExecutionContext context = getExecutionContext();
- if (path == null) {
- String msg = JBossCacheConnectorI18n.locationsMustHavePath.text(getSourceName(), request);
- request.setError(new InvalidRequestException(msg));
- return null;
- }
- // Look up the node with the supplied path ...
- Fqn<Path.Segment> fqn = getFullyQualifiedName(path);
- Node<Name, Object> node = cache.getNode(fqn);
-
- if (node == null) {
- String nodePath = path.getString(context.getNamespaceRegistry());
- Path lowestExisting = null;
- while (fqn != null) {
- fqn = fqn.getParent();
- node = cache.getNode(fqn);
- if (node != null) {
- lowestExisting = getPath(context.getValueFactories().getPathFactory(), fqn);
- fqn = null;
- }
- }
- request.setError(new PathNotFoundException(Location.create(path), lowestExisting,
- JBossCacheConnectorI18n.nodeDoesNotExist.text(nodePath)));
- node = null;
- }
- return node;
-
- }
-
- /**
- * @param newCache the cache into which the node is to be copied
- * @param original the node to be copied
- * @param newParent the new parent of the node to be copied
- * @param desiredName the desired name of the node in the new location
- * @param beforeNodeName the node before which the new node should be placed
- * @param recursive if this is a deep copy
- * @param uuidConflictBehavior indicates whether the original UUIDs should be used for the copies or new UUIDs should be used
- * @param count the count of nodes affected by the operation
- * @param context the execution context that provides the path factory to be used to create the new path name
- * @return the path segment that identifies the new node under its new parent
- */
- @SuppressWarnings( "unchecked" )
- protected Path.Segment copyNode( Cache<Name, Object> newCache,
- Node<Name, Object> original,
- Node<Name, Object> newParent,
- Name desiredName,
- Path.Segment beforeNodeName,
- boolean recursive,
- UuidConflictBehavior uuidConflictBehavior,
- AtomicInteger count,
- ExecutionContext context ) {
- assert original != null;
- assert newParent != null;
- // Get or create the new node ...
- Path.Segment name = desiredName != null ? context.getValueFactories().getPathFactory().createSegment(desiredName) : (Path.Segment)original.getFqn()
- .getLastElement();
-
- // Update the children to account for same-name siblings.
- // This not only updates the FQN of the child nodes, but it also sets the property that stores the
- // the array of Path.Segment for the children (since the cache doesn't maintain order).
- Path.Segment newSegment = updateChildList(newCache, newParent, name.getName(), beforeNodeName, context, true);
- Node<Name, Object> copy = newParent.addChild(getFullyQualifiedName(newSegment));
- assert checkChildren(newParent);
- // Copy the properties ...
- copy.clearData();
- copy.putAll(original.getData());
- copy.remove(JBossCacheLexicon.CHILD_PATH_SEGMENT_LIST); // will be reset later ...
-
- UUID uuid;
- switch (uuidConflictBehavior) {
- case ALWAYS_CREATE_NEW_UUID:
- uuid = UUID.randomUUID();
- break;
- case REPLACE_EXISTING_NODE:
- uuid = uuidFactory.create(original.get(DnaLexicon.UUID));
- Fqn<?> existingPath = getFullyQualifiedName(newCache, uuid);
- if (existingPath != null) {
- Node<Name, Object> existingNode = newCache.getNode(existingPath);
- deleteNode(newCache, existingNode);
- }
-
- break;
- case THROW_EXCEPTION:
- uuid = uuidFactory.create(original.get(DnaLexicon.UUID));
- break;
- default:
- throw new IllegalStateException("Unexpected UuidConflictBehavior value: " + uuidConflictBehavior);
- }
- copy.put(DnaLexicon.UUID, uuid);
-
- if (count != null) count.incrementAndGet();
- if (recursive) {
- // Loop over each child and call this method ...
- for (Node<Name, Object> child : original.getChildren()) {
- copyNode(newCache, child, copy, null, null, true, uuidConflictBehavior, count, context);
- }
- }
- mapUuids(newCache, copy.getFqn());
- assert getFullyQualifiedName(newCache, uuid) != null;
- return newSegment;
- }
-
- /**
- * Update (or create) the array of {@link Path.Segment path segments} for the children of the supplied node. This array
- * maintains the ordered list of children (since the {@link Cache} does not maintain the order). Invoking this method will
- * change any existing children that a {@link Path.Segment#getName() name part} that matches the supplied
- * <code>changedName</code> to have the appropriate {@link Path.Segment#getIndex() same-name sibling index}.
- *
- * @param cache the cache in which the parent exists ...
- * @param parent the parent node; may not be null
- * @param changedName the name that should be compared to the existing node siblings to determine whether the same-name
- * sibling indexes should be updated; may not be null
- * @param beforeNodeName the name of the node before which this node should be placed; null indicates that this node should be
- * added as the last child under the node
- * @param context the execution context; may not be null
- * @param addChildWithName true if a new child with the supplied name is to be added to the children (but which does not yet
- * exist in the node's children)
- * @return the path segment for the new child, or null if <code>addChildWithName</code> was false
- */
- protected Path.Segment updateChildList( Cache<Name, Object> cache,
- Node<Name, Object> parent,
- Name changedName,
- Path.Segment beforeNodeName,
- ExecutionContext context,
- boolean addChildWithName ) {
- assert parent != null;
- assert changedName != null;
- assert context != null;
- Set<Node<Name, Object>> children = parent.getChildren();
- if (children.isEmpty() && !addChildWithName) return null;
-
- // Go through the children, looking for any children with the same name as the 'changedName'
- List<ChildInfo> childrenWithChangedName = new LinkedList<ChildInfo>();
- Path.Segment[] childNames = (Path.Segment[])parent.get(JBossCacheLexicon.CHILD_PATH_SEGMENT_LIST);
- int index = 0;
- int snsIndex = 0;
- boolean foundBeforeNode = false;
- if (childNames != null) {
- for (Path.Segment childName : childNames) {
- if (childName.equals(beforeNodeName)) {
- foundBeforeNode = true;
- // And add a child info for the new node ...
- ChildInfo info = new ChildInfo(null, snsIndex++);
- childrenWithChangedName.add(info);
- }
- if (childName.getName().equals(changedName)) {
- ChildInfo info = new ChildInfo(childName, snsIndex);
- childrenWithChangedName.add(info);
- }
-
- snsIndex++;
- if (!foundBeforeNode) index++;
- }
-
- }
- if (addChildWithName) {
- // Make room for the new child at the end of the array ...
- if (childNames == null) {
- childNames = new Path.Segment[1];
- } else {
- int numExisting = childNames.length;
- Path.Segment[] newChildNames = new Path.Segment[numExisting + 1];
- System.arraycopy(childNames, 0, newChildNames, 0, index);
-
- if (index != numExisting) {
- System.arraycopy(childNames, index, newChildNames, index + 1, numExisting - index);
- }
- childNames = newChildNames;
- }
-
- if (!foundBeforeNode) {
- // Make sure that we add a record for the new node if it hasn't previously been added
- ChildInfo info = new ChildInfo(null, index);
- childrenWithChangedName.add(info);
-
- }
- Path.Segment newSegment = context.getValueFactories().getPathFactory().createSegment(changedName);
- childNames[index] = newSegment;
- }
- assert childNames != null;
-
- // Now process the children with the same name, which may include a child info for the new node ...
- assert childrenWithChangedName.isEmpty() == false;
- if (childrenWithChangedName.size() == 1) {
- // The child should have no indexes ...
- ChildInfo child = childrenWithChangedName.get(0);
- if (child.segment != null && child.segment.hasIndex()) {
- // The existing child needs to have a new index ..
- Path.Segment newSegment = context.getValueFactories().getPathFactory().createSegment(changedName);
- // Replace the child with the correct FQN ...
- changeNodeName(cache, parent, child.segment, newSegment, context);
- // Change the segment in the child list ...
- childNames[child.childIndex] = newSegment;
- }
- } else {
- // There is more than one child with the same name ...
- int i = 0;
- for (ChildInfo child : childrenWithChangedName) {
- if (child.segment != null) {
- // Determine the new name and index ...
- Path.Segment newSegment = context.getValueFactories().getPathFactory().createSegment(changedName, i + 1);
- // Replace the child with the correct FQN ...
- changeNodeName(cache, parent, child.segment, newSegment, context);
- // Change the segment in the child list ...
- childNames[child.childIndex] = newSegment;
- } else {
- // Determine the new name and index ...
- Path.Segment newSegment = context.getValueFactories().getPathFactory().createSegment(changedName, i + 1);
- childNames[child.childIndex] = newSegment;
- }
- ++i;
- }
- }
-
- // Record the list of children as a property on the parent ...
- // (Do this last, as it doesn't need to be done if there's an exception in the above logic)
- context.getLogger(getClass()).trace("Updating child list of {0} to: {1}", parent.getFqn(), Arrays.asList(childNames));
- parent.put(JBossCacheLexicon.CHILD_PATH_SEGMENT_LIST, childNames); // replaces any existing value
-
- if (addChildWithName) {
- // Return the segment for the new node ...
- return childNames[index];
- }
- return null;
- }
-
- /**
- * Update the array of {@link Path.Segment path segments} for the children of the supplied node, based upon a node being
- * removed. This array maintains the ordered list of children (since the {@link Cache} does not maintain the order). Invoking
- * this method will change any existing children that a {@link Path.Segment#getName() name part} that matches the supplied
- * <code>changedName</code> to have the appropriate {@link Path.Segment#getIndex() same-name sibling index}.
- *
- * @param cache the cache in which the parent exists ...
- * @param parent the parent node; may not be null
- * @param removedNode the segment of the node that was removed, which signals to look for node with the same name; may not be
- * null
- * @param context the execution context; may not be null
- */
- protected void removeFromChildList( Cache<Name, Object> cache,
- Node<Name, Object> parent,
- Path.Segment removedNode,
- ExecutionContext context ) {
- assert parent != null;
- assert context != null;
- Set<Node<Name, Object>> children = parent.getChildren();
- if (children.isEmpty()) {
- parent.put(JBossCacheLexicon.CHILD_PATH_SEGMENT_LIST, null); // replaces any existing value
- return;
- }
-
- // Go through the children, looking for any children with the same name as the 'changedName'
- Path.Segment[] childNames = (Path.Segment[])parent.get(JBossCacheLexicon.CHILD_PATH_SEGMENT_LIST);
- assert childNames != null;
- int snsIndex = removedNode.getIndex();
- int index = 0;
- Path.Segment[] newChildNames = new Path.Segment[childNames.length - 1];
- for (Path.Segment childName : childNames) {
-
- if (!childName.getName().equals(removedNode.getName())) {
- newChildNames[index] = childName;
- index++;
- } else {
- // The name matches ...
- if (childName.getIndex() < snsIndex) {
- // Just copy ...
- newChildNames[index] = childName;
- index++;
- } else if (childName.getIndex() == snsIndex) {
- // don't copy ...
- } else {
- // Append an updated segment ...
- Path.Segment newSegment = context.getValueFactories()
- .getPathFactory()
- .createSegment(childName.getName(), childName.getIndex() - 1);
- newChildNames[index] = newSegment;
- // Replace the child with the correct FQN ...
- changeNodeName(cache, parent, childName, newSegment, context);
- index++;
- }
- }
- }
- parent.put(JBossCacheLexicon.CHILD_PATH_SEGMENT_LIST, newChildNames); // replaces any existing value
- }
-
- protected boolean checkChildren( Node<Name, Object> parent ) {
- Path.Segment[] childNamesProperty = (Path.Segment[])parent.get(JBossCacheLexicon.CHILD_PATH_SEGMENT_LIST);
- Set<Object> childNames = parent.getChildrenNames();
- boolean result = true;
- if (childNamesProperty.length != childNames.size()) result = false;
- if (!result) throw new IllegalStateException(parent.getFqn().toString());
- for (int i = 0; i != childNamesProperty.length; ++i) {
- if (!childNames.contains(childNamesProperty[i])) result = false;
- }
- if (!result) throw new IllegalStateException(parent.getFqn().toString());
- if (!result) {
- List<Path.Segment> names = new ArrayList<Path.Segment>();
- for (Object name : childNames) {
- assert name instanceof Path.Segment : parent.getFqn().toString() + "/" + name.toString();
- names.add((Path.Segment)name);
- }
- Collections.sort(names);
- Logger.getLogger(getClass()).trace("Child list on {0} is: {1}", parent.getFqn(), childNamesProperty);
- Logger.getLogger(getClass()).trace("Children of {0} is: {1}", parent.getFqn(), names);
- }
- if (!result) throw new IllegalStateException(parent.getFqn().toString());
- return result;
- }
-
- /**
- * Utility class used by the
- * {@link JBossCacheRequestProcessor#updateChildList(Cache, Node, Name, org.jboss.dna.graph.property.Path.Segment, ExecutionContext, boolean)}
- * method.
- *
- * @author Randall Hauch
- */
- private static class ChildInfo {
- protected final Path.Segment segment;
- protected final int childIndex;
-
- protected ChildInfo( Path.Segment childSegment,
- int childIndex ) {
- this.segment = childSegment;
- this.childIndex = childIndex;
- }
-
- @Override
- public String toString() {
- return (segment != null ? segment.getString() : "null") + "@" + childIndex;
- }
-
- }
-
- /**
- * Changes the name of the node in the cache (but does not update the list of child segments stored on the parent).
- *
- * @param cache
- * @param parent
- * @param existing
- * @param newSegment
- * @param context
- */
- @SuppressWarnings( "unchecked" )
- protected void changeNodeName( Cache<Name, Object> cache,
- Node<Name, Object> parent,
- Path.Segment existing,
- Path.Segment newSegment,
- ExecutionContext context ) {
- assert parent != null;
- assert existing != null;
- assert newSegment != null;
- assert context != null;
-
- if (existing.equals(newSegment)) return;
- context.getLogger(getClass()).trace("Renaming {0} to {1} under {2}", existing, newSegment, parent.getFqn());
- Node<Name, Object> existingChild = parent.getChild(existing);
- assert existingChild != null : parent.getFqn().toString() + "/" + existing;
-
- // JBoss Cache can move a node from one node to another node, but the move doesn't change the name;
- // since you provide the FQN of the parent location, the name of the node cannot be changed.
- // Therefore, to compensate, we need to create a new child, copy all of the data, move all of the child
- // nodes of the old node, then remove the old node.
-
- // Create the new node ...
- Node<Name, Object> newChild = parent.addChild(Fqn.fromElements(newSegment));
- Fqn<Path.Segment> newChildFqn = newChild.getFqn();
-
- // Copy the data ...
- newChild.putAll(existingChild.getData());
-
- // Move the children ...
- for (Node<Name, Object> grandChild : existingChild.getChildren()) {
- cache.move(grandChild.getFqn(), newChildFqn);
- }
-
- // Remove the existing ...
- parent.removeChild(existing);
- }
-}
Modified: trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheSource.java
===================================================================
--- trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheSource.java 2009-06-24 22:14:12 UTC (rev 1064)
+++ trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheSource.java 2009-06-27 02:54:06 UTC (rev 1065)
@@ -45,11 +45,14 @@
import javax.naming.Referenceable;
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.cache.config.ConfigurationException;
import org.jboss.dna.common.i18n.I18n;
+import org.jboss.dna.common.util.Logger;
import org.jboss.dna.common.util.StringUtil;
import org.jboss.dna.graph.DnaLexicon;
import org.jboss.dna.graph.cache.CachePolicy;
@@ -58,8 +61,11 @@
import org.jboss.dna.graph.connector.RepositorySource;
import org.jboss.dna.graph.connector.RepositorySourceCapabilities;
import org.jboss.dna.graph.connector.RepositorySourceException;
+import org.jboss.dna.graph.connector.map.MapNode;
+import org.jboss.dna.graph.connector.map.MapRepositoryConnection;
+import org.jboss.dna.graph.connector.map.MapRepositorySource;
import org.jboss.dna.graph.observe.Observer;
-import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.request.CreateWorkspaceRequest.CreateConflictBehavior;
/**
* A repository source that uses a JBoss Cache instance to manage the content. This source is capable of using an existing
@@ -79,7 +85,7 @@
* @author Randall Hauch
*/
@ThreadSafe
-public class JBossCacheSource implements RepositorySource, ObjectFactory {
+public class JBossCacheSource implements MapRepositorySource, ObjectFactory {
private static final long serialVersionUID = 2L;
/**
@@ -114,9 +120,10 @@
private volatile String defaultWorkspace;
private volatile String[] predefinedWorkspaces = new String[] {};
private volatile RepositorySourceCapabilities capabilities = new RepositorySourceCapabilities(true, true, false, true, false);
- private transient JBossCacheWorkspaces workspaces;
+ private transient JBossCacheRepository repository;
private transient Context jndiContext;
private transient RepositoryContext repositoryContext;
+ private final Set<String> repositoryNamesForConfigurationNameProblems = new HashSet<String>();
/**
* Create a repository source instance.
@@ -435,7 +442,7 @@
I18n msg = JBossCacheConnectorI18n.propertyIsRequired;
throw new RepositorySourceException(getName(), msg.text("name"));
}
- if (this.workspaces == null) {
+ if (this.repository == null) {
Context context = getContext();
if (context == null) {
try {
@@ -446,13 +453,13 @@
}
// Look for a cache factory in JNDI ...
- CacheFactory<Name, Object> cacheFactory = null;
+ CacheFactory<UUID, MapNode> cacheFactory = null;
String jndiName = getCacheFactoryJndiName();
if (jndiName != null && jndiName.trim().length() != 0) {
Object object = null;
try {
object = context.lookup(jndiName);
- if (object != null) cacheFactory = (CacheFactory<Name, Object>)object;
+ if (object != null) cacheFactory = (CacheFactory<UUID, MapNode>)object;
} catch (ClassCastException err) {
I18n msg = JBossCacheConnectorI18n.objectFoundInJndiWasNotCacheFactory;
String className = object != null ? object.getClass().getName() : "null";
@@ -462,27 +469,65 @@
throw new RepositorySourceException(getName(), err);
}
}
- if (cacheFactory == null) cacheFactory = new DefaultCacheFactory<Name, Object>();
+ if (cacheFactory == null) cacheFactory = new DefaultCacheFactory<UUID, MapNode>();
- // Get the default cache configuration name
- String configName = this.getCacheConfigurationName();
+ // Now create the repository ...
+ this.repository = new JBossCacheRepository(getName(), this.rootNodeUuid, createNewCache(cacheFactory, getName()));
// Create the set of initial names ...
- Set<String> initialNames = new HashSet<String>();
for (String initialName : getPredefinedWorkspaceNames())
- initialNames.add(initialName);
+ repository.createWorkspace(null, initialName, CreateConflictBehavior.DO_NOT_CREATE);
+
+ }
- // Now create the workspace manager ...
- this.workspaces = new JBossCacheWorkspaces(getName(), cacheFactory, configName, initialNames, context);
+ return new MapRepositoryConnection(this, this.repository);
+ }
+
+ /**
+ * Method that is responsible for attempting to create a new cache given the supplied workspace name. Note that this is
+ * probably called at most once for each workspace name (except if this method fails to create a cache for a given workspace
+ * name).
+ *
+ * @param workspaceName the name of the workspace
+ * @return the new cache that corresponds to the workspace name
+ */
+ @GuardedBy( "writeLock" )
+ protected Cache<UUID, MapNode> createNewCache( CacheFactory<UUID, MapNode> cacheFactory, String repositoryName ) {
+ assert repositoryName != null;
+ if (cacheFactory == null) return null;
+
+ // Try to create the cache using the workspace name as the configuration ...
+ try {
+ return cacheFactory.createCache(repositoryName);
+ } catch (ConfigurationException error) {
+ // The workspace name is probably not the name of a configuration ...
+ I18n msg = JBossCacheConnectorI18n.workspaceNameWasNotValidConfiguration;
+ Logger.getLogger(getClass()).debug(msg.text(repositoryName, error.getMessage()));
}
- return new JBossCacheConnection(this, this.workspaces);
+ if (this.cacheConfigurationName != null) {
+ // Try to create the cache using the default configuration name ...
+ try {
+ return cacheFactory.createCache(getCacheConfigurationName());
+ } catch (ConfigurationException error) {
+ // The default configuration name is not valid ...
+ if (this.repositoryNamesForConfigurationNameProblems.add(repositoryName)) {
+ // Log this problem only the first time ...
+ I18n msg = JBossCacheConnectorI18n.defaultCacheFactoryConfigurationNameWasNotValidConfiguration;
+ Logger.getLogger(getClass()).debug(msg.text(repositoryName));
+ }
+ }
+ }
+
+ // Just create a new cache with the default configuration ...
+ return cacheFactory.createCache();
}
+
/**
* @return repositoryContext
*/
- protected RepositoryContext getRepositoryContext() {
+ public RepositoryContext getRepositoryContext() {
return repositoryContext;
}
Deleted: trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheWorkspaces.java
===================================================================
--- trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheWorkspaces.java 2009-06-24 22:14:12 UTC (rev 1064)
+++ trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheWorkspaces.java 2009-06-27 02:54:06 UTC (rev 1065)
@@ -1,297 +0,0 @@
-/*
- * 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.
- *
- * 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.connector.jbosscache;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-import javax.naming.Context;
-import net.jcip.annotations.GuardedBy;
-import net.jcip.annotations.ThreadSafe;
-import org.jboss.cache.Cache;
-import org.jboss.cache.CacheFactory;
-import org.jboss.cache.config.ConfigurationException;
-import org.jboss.dna.common.i18n.I18n;
-import org.jboss.dna.common.util.Logger;
-import org.jboss.dna.graph.connector.RepositorySourceException;
-import org.jboss.dna.graph.property.Name;
-
-/**
- * This class represents a set of workspaces used by the {@link JBossCacheSource JBoss Cache connector}.
- */
-@ThreadSafe
-public class JBossCacheWorkspaces {
-
- private final String sourceName;
- private final ConcurrentHashMap<String, Cache<Name, Object>> caches = new ConcurrentHashMap<String, Cache<Name, Object>>();
- private final Set<String> initialNames;
- private final CacheFactory<Name, Object> cacheFactory;
- private final String defaultCacheFactoryConfigurationName;
- private final Context jndi;
- private final Set<String> workspaceNamesForJndiClassCastProblems = new HashSet<String>();
- private final Set<String> workspaceNamesForConfigurationNameProblems = new HashSet<String>();
- private final Lock writeLock = new ReentrantLock();
-
- /**
- * Create a new instance of the workspace and cache manager for the JBoss Cache connector.
- *
- * @param sourceName the name of the source that uses this object; may not be null
- * @param cacheFactory the factory that should be used to create new caches; may not be null
- * @param defaultCacheFactoryConfigurationName the name of the configuration that is supplied to the {@link CacheFactory cache
- * factory} to {@link CacheFactory#createCache(String) create the new cache} if the workspace name does not correspond
- * to a configuration; may be null
- * @param initialNames the initial names for the workspaces; may be null or empty
- * @param jndiContext the JNDI context that should be used, or null if JNDI should not be used at all
- */
- public JBossCacheWorkspaces( String sourceName,
- CacheFactory<Name, Object> cacheFactory,
- String defaultCacheFactoryConfigurationName,
- Set<String> initialNames,
- Context jndiContext ) {
- assert sourceName != null;
- this.sourceName = sourceName;
- if (initialNames == null) initialNames = Collections.emptySet();
- this.initialNames = initialNames;
- this.cacheFactory = cacheFactory;
- this.defaultCacheFactoryConfigurationName = defaultCacheFactoryConfigurationName;
- this.jndi = jndiContext;
- }
-
- /**
- * Attempt to create a new workspace with the supplied name.
- *
- * @param workspaceName the name of the new workspace, which may be a valid URI if the cache is to be found in JNDI
- * @return the new workspace, or null if there is already a workspace with the name
- */
- public Cache<Name, Object> createWorkspace( String workspaceName ) {
- try {
- writeLock.lock();
- // First, see if there is already an existing cache ...
- Cache<Name, Object> cache = caches.get(workspaceName);
- if (cache != null) {
- // There is already a workspace, so we can't create ...
- return null;
- }
-
- // There isn't already a cache, but next check the list of initial names ...
- if (initialNames.contains(workspaceName)) {
- // The workspace already exists, but we just haven't accessed it yet
- return null;
- }
-
- // Time to create a new cache. First see if we're supposed to use a cache already in JNDI ...
- cache = findCacheInJndi(workspaceName);
- if (cache == null) {
- // Try to create one ...
- cache = createNewCache(workspaceName);
- }
-
- if (cache != null) {
- // Manage this cache ...
- Cache<Name, Object> existing = caches.putIfAbsent(workspaceName, cache);
- if (existing != null) cache = existing;
- }
- return cache; // may still be null if we couldn't create a new cache
-
- } finally {
- writeLock.unlock();
- }
- }
-
- /**
- * Get the cache that corresponds to the supplied workspace name, and optionally create a new cache if no such cache already
- * exists. This method first checks for {@link Cache} instances previously found for the same workspace name. If no cache is
- * found, this method then checks whether the supplied workspace name is a valid URI, and if so the method looks for a
- * {@link Cache} instance in JNDI at that URI. If none is found (or the name is not a valid URI), this method then creates a
- * new {@link Cache} instance using the {@link CacheFactory} supplied in the constructor.
- *
- * @param workspaceName the name of the workspace, which may be a valid URI if the cache is to be found in JNDI
- * @param createIfMissing true if the cache should be created if no such cache already exists
- * @return the cache that corresponds to the workspace with the supplied name, or null if there is no cache for that workspace
- * (and one could not be or was not created)
- */
- public Cache<Name, Object> getWorkspace( String workspaceName,
- boolean createIfMissing ) {
- // First, see if there is already an existing cache ...
- Cache<Name, Object> cache = caches.get(workspaceName);
- if (cache != null) return cache;
-
- try {
- writeLock.lock();
- // Ensure one didn't get created while we waited for the lock ...
- cache = caches.get(workspaceName);
- if (cache != null) return cache;
-
- // We've not yet come across the cache for the workspace.
-
- // Check whether the workspace name was one of the initial set of names...
- if (this.initialNames.contains(workspaceName)) {
- // This workspace/cache was one of those defined at startup to be available,
- // so we really don't consider this to be "creating a new cache"; it's just the first time we've used it
- // and we're lazily finding the instances. So, just mark 'createIfMissing' to true and continue ...
- createIfMissing = true;
- }
-
- if (!createIfMissing) return null;
-
- // First see if we can find a cache in JNDI ...
- cache = findCacheInJndi(workspaceName);
-
- if (cache == null) {
- // Try to create one ...
- cache = createNewCache(workspaceName);
- }
-
- if (cache != null) {
- Cache<Name, Object> existing = caches.putIfAbsent(workspaceName, cache);
- if (existing != null) cache = existing;
- }
- return cache; // may still be null if we couldn't create a new cache
- } finally {
- writeLock.unlock();
- }
- }
-
- /**
- * Attempt to find an existing {@link Cache} object in JNDI, using the supplied workspace name as the JNDI name.
- *
- * @param workspaceName the name of the workspace
- * @return the cache found in JNDI that corresponds to the workspace name
- */
- @SuppressWarnings( "unchecked" )
- @GuardedBy( "writeLock" )
- protected Cache<Name, Object> findCacheInJndi( String workspaceName ) {
- assert workspaceName != null;
- if (jndi == null) return null;
-
- // Try to look up the cache instance in JDNI ...
- workspaceName = workspaceName.trim();
- if (workspaceName.length() != 0) {
- try {
- new URI(workspaceName.trim());
- Object object = null;
- try {
- object = jndi.lookup(workspaceName);
- if (object != null && object instanceof Cache) {
- return (Cache<Name, Object>)object;
- }
- } catch (ClassCastException err) {
- // The object found in JNDI was not a JBoss Cache instance ...
- if (this.workspaceNamesForJndiClassCastProblems.add(workspaceName)) {
- // Log this problem only the first time ...
- String className = object != null ? object.getClass().getName() : "null";
- I18n msg = JBossCacheConnectorI18n.objectFoundInJndiWasNotCache;
- Logger.getLogger(getClass()).warn(msg, workspaceName, sourceName, className);
- }
- } catch (Throwable error) {
- // try loading
- if (error instanceof RuntimeException) throw (RuntimeException)error;
- throw new RepositorySourceException(sourceName, error);
- }
-
- } catch (URISyntaxException err) {
- // Not a valid URI, so just continue ...
- }
- }
- return null;
- }
-
- /**
- * Method that is responsible for attempting to create a new cache given the supplied workspace name. Note that this is
- * probably called at most once for each workspace name (except if this method fails to create a cache for a given workspace
- * name).
- *
- * @param workspaceName the name of the workspace
- * @return the new cache that corresponds to the workspace name
- */
- @GuardedBy( "writeLock" )
- protected Cache<Name, Object> createNewCache( String workspaceName ) {
- assert workspaceName != null;
- if (this.cacheFactory == null) return null;
-
- // Try to create the cache using the workspace name as the configuration ...
- try {
- return this.cacheFactory.createCache(workspaceName);
- } catch (ConfigurationException error) {
- // The workspace name is probably not the name of a configuration ...
- I18n msg = JBossCacheConnectorI18n.workspaceNameWasNotValidConfiguration;
- Logger.getLogger(getClass()).debug(msg.text(workspaceName, error.getMessage()));
- }
-
- if (this.defaultCacheFactoryConfigurationName != null) {
- // Try to create the cache using the default configuration name ...
- try {
- return this.cacheFactory.createCache(this.defaultCacheFactoryConfigurationName);
- } catch (ConfigurationException error) {
- // The default configuration name is not valid ...
- if (this.workspaceNamesForConfigurationNameProblems.add(workspaceName)) {
- // Log this problem only the first time ...
- I18n msg = JBossCacheConnectorI18n.defaultCacheFactoryConfigurationNameWasNotValidConfiguration;
- Logger.getLogger(getClass()).debug(msg.text(workspaceName));
- }
- }
- }
-
- // Just create a new cache with the default configuration ...
- return this.cacheFactory.createCache();
- }
-
- /**
- * Return an immutable set of names for the currently available workspaces.
- *
- * @return the immutable set of workspace names; never null
- */
- public Set<String> getWorkspaceNames() {
- Set<String> names = new HashSet<String>();
- if (!initialNames.isEmpty()) names.addAll(initialNames);
- names.addAll(caches.keySet());
- return Collections.unmodifiableSet(names);
- }
-
- /**
- * Remove the cache that corresponds to the supplied workspace name as no longer being available. This will remove the cache
- * even if the workspace name is one of the "initial names" provided to this object's constructor.
- *
- * @param workspaceName the name of the existing workspace that is to be removed
- * @return true if there was an existing workspace that was removed by this call, or false if there was no workspace with the
- * supplied name
- */
- public boolean removeWorkspace( String workspaceName ) {
- try {
- writeLock.lock();
-
- // Remove this from both the cache and initialNames ...
- boolean removed = initialNames.remove(workspaceName);
- if (caches.remove(workspaceName) != null) removed = true;
- return removed;
- } finally {
- writeLock.unlock();
- }
- }
-}
Deleted: trunk/extensions/dna-connector-jbosscache/src/test/java/org/jboss/dna/connector/jbosscache/JBossCacheRequestProcessorTest.java
===================================================================
--- trunk/extensions/dna-connector-jbosscache/src/test/java/org/jboss/dna/connector/jbosscache/JBossCacheRequestProcessorTest.java 2009-06-24 22:14:12 UTC (rev 1064)
+++ trunk/extensions/dna-connector-jbosscache/src/test/java/org/jboss/dna/connector/jbosscache/JBossCacheRequestProcessorTest.java 2009-06-27 02:54:06 UTC (rev 1065)
@@ -1,120 +0,0 @@
-/*
- * 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.connector.jbosscache;
-
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-import java.util.HashSet;
-import java.util.Set;
-import javax.naming.Context;
-import org.jboss.cache.CacheFactory;
-import org.jboss.cache.DefaultCacheFactory;
-import org.jboss.cache.Fqn;
-import org.jboss.dna.graph.DnaLexicon;
-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.PathFactory;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.MockitoAnnotations;
-import org.mockito.MockitoAnnotations.Mock;
-
-/**
- * @author Randall Hauch
- */
-public class JBossCacheRequestProcessorTest {
-
- private JBossCacheRequestProcessor processor;
- private JBossCacheWorkspaces workspaces;
- private Set<String> initialWorkspaceNames;
- private String defaultWorkspaceName;
- private String defaultConfigName;
- private CacheFactory<Name, Object> cacheFactory;
- private ExecutionContext context;
- private PathFactory pathFactory;
- @Mock
- private Context jndi;
-
- @Before
- public void beforeEach() throws Exception {
- MockitoAnnotations.initMocks(this);
- context = new ExecutionContext();
- context.getNamespaceRegistry().register(DnaLexicon.Namespace.PREFIX, DnaLexicon.Namespace.URI);
- context.getNamespaceRegistry().register(JBossCacheLexicon.Namespace.PREFIX, JBossCacheLexicon.Namespace.URI);
-
- cacheFactory = new DefaultCacheFactory<Name, Object>();
- defaultConfigName = null;
- initialWorkspaceNames = new HashSet<String>();
- initialWorkspaceNames.add("workspace1");
- initialWorkspaceNames.add("workspace2");
- defaultWorkspaceName = initialWorkspaceNames.iterator().next();
- workspaces = new JBossCacheWorkspaces("source", cacheFactory, defaultConfigName, initialWorkspaceNames, jndi);
- processor = new JBossCacheRequestProcessor("source", context, null, workspaces, defaultWorkspaceName, true);
-
- pathFactory = context.getValueFactories().getPathFactory();
- }
-
- @Test
- public void shouldCreateFullyQualifiedNodeOfPathSegmentsFromPath() {
- Path path = pathFactory.create("/a/b/c/d");
- Fqn<?> fqn = processor.getFullyQualifiedName(path);
- assertThat(fqn.size(), is(4));
- assertThat(fqn.isRoot(), is(false));
- for (int i = 0; i != path.size(); ++i) {
- assertThat((Path.Segment)fqn.get(i), is(path.getSegment(i)));
- }
- }
-
- @Test
- public void shouldCreateFullyQualifiedNodeOfPathSegmentsFromRootPath() {
- Path path = pathFactory.createRootPath();
- Fqn<?> fqn = processor.getFullyQualifiedName(path);
- assertThat(fqn.size(), is(0));
- assertThat(fqn.isRoot(), is(true));
- }
-
- @Test
- public void shouldCreateFullyQualifiedNodeFromPathSegment() {
- Path.Segment segment = pathFactory.createSegment("a");
- Fqn<?> fqn = processor.getFullyQualifiedName(segment);
- assertThat(fqn.size(), is(1));
- assertThat(fqn.isRoot(), is(false));
- assertThat((Path.Segment)fqn.get(0), is(segment));
- }
-
- @Test
- public void shouldCreatePathFromFullyQualifiedNode() {
- Path path = pathFactory.create("/a/b/c/d");
- Fqn<Path.Segment> fqn = processor.getFullyQualifiedName(path);
- assertThat(processor.getPath(pathFactory, fqn), is(path));
- }
-
- @Test
- public void shouldCreateRootPathFromRootFullyQualifiedNode() {
- Path path = pathFactory.createRootPath();
- Fqn<Path.Segment> fqn = processor.getFullyQualifiedName(path);
- assertThat(processor.getPath(pathFactory, fqn), is(path));
- }
-}
14 years, 10 months
DNA SVN: r1064 - in branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt: actions and 1 other directories.
by dna-commits@lists.jboss.org
Author: elvisisking
Date: 2009-06-24 18:14:12 -0400 (Wed, 24 Jun 2009)
New Revision: 1064
Added:
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/actions/BasePublishingAction.java
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/PublishOperation.java
Modified:
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/I18n.java
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/actions/PublishAction.java
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/actions/UnpublishAction.java
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/i18n.properties
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/PublishPage.java
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/PublishWizard.java
Log:
More UI implementation.
Modified: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/I18n.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/I18n.java 2009-06-24 18:31:40 UTC (rev 1063)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/I18n.java 2009-06-24 22:14:12 UTC (rev 1064)
@@ -45,6 +45,13 @@
public static String EditServerActionText;
public static String EditServerActionToolTip;
+ public static String ErrorDialogTitle;
+
+ public static String PublishOperationPublishTaskName;
+ public static String PublishOperationPublishTitle;
+ public static String PublishOperationUnpublishTaskName;
+ public static String PublishOperationUnpublishTitle;
+
public static String PublishPagePublishTitle;
public static String PublishPageLocationGroupTitle;
public static String PublishPageMissingRepositoryStatusMsg;
@@ -67,8 +74,10 @@
public static String PublishPageWorkspacePublishToolTip;
public static String PublishPageWorkspaceUnpublishToolTip;
+ public static String PublishWizardPublishErrorMsg;
public static String PublishWizardPublishTitle;
public static String PublishWizardUnpublishTitle;
+ public static String PublishWizardUnpublishErrorMsg;
public static String ServerPageAuthenticationGroupTitle;
public static String ServerPageInvalidServerProperties;
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/actions/BasePublishingAction.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/actions/BasePublishingAction.java (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/actions/BasePublishingAction.java 2009-06-24 22:14:12 UTC (rev 1064)
@@ -0,0 +1,140 @@
+/*
+ * 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.publish.ui.swt.actions;
+
+import java.util.Collections;
+import java.util.List;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IObjectActionDelegate;
+import org.eclipse.ui.IWorkbenchPart;
+import org.jboss.dna.publish.ui.swt.Activator;
+import org.jboss.dna.publish.ui.swt.wizards.PublishWizard;
+import org.jboss.dna.publish.ui.swt.wizards.PublishOperation.Type;
+
+/**
+ * @author Dan Florian
+ * @since 0.6
+ */
+public abstract class BasePublishingAction implements IObjectActionDelegate {
+
+ // ===========================================================================================================================
+ // Fields
+ // ===========================================================================================================================
+
+ /**
+ * The current workspace selection.
+ *
+ * @since 0.6
+ */
+ private IStructuredSelection selection;
+
+ /**
+ * The active part's Shell.
+ *
+ * @since 0.6
+ */
+ private Shell shell;
+
+ /**
+ * Indicates if this is a publishing or unpublishing action.
+ *
+ * @since 0.6
+ */
+ private final Type type;
+
+ // ===========================================================================================================================
+ // Constructors
+ // ===========================================================================================================================
+
+ /**
+ * @param type indicates the type of action
+ * @since 0.6
+ */
+ public BasePublishingAction(Type type) {
+ this.type = type;
+ }
+
+ // ===========================================================================================================================
+ // Methods
+ // ===========================================================================================================================
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
+ * @since 0.6
+ */
+ @Override
+ @SuppressWarnings( "unchecked" )
+ public void run( IAction action ) {
+ assert (this.selection != null);
+ assert (!this.selection.isEmpty());
+
+ List<IResource> resources;
+
+ if (this.selection.size() == 1) {
+ resources = Collections.singletonList((IResource)this.selection.getFirstElement());
+ } else {
+ resources = this.selection.toList();
+ }
+
+ // run wizard
+ new WizardDialog(shell, new PublishWizard(this.type, resources, Activator.getDefault().getServerManager()));
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction,
+ * org.eclipse.jface.viewers.ISelection)
+ * @since 0.6
+ */
+ @Override
+ public void selectionChanged( IAction action,
+ ISelection selection ) {
+ if (selection instanceof IStructuredSelection) {
+ this.selection = (IStructuredSelection)selection;
+ } else {
+ this.selection = null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.action.IAction, org.eclipse.ui.IWorkbenchPart)
+ * @since 0.6
+ */
+ @Override
+ public void setActivePart( IAction action,
+ IWorkbenchPart targetPart ) {
+ this.shell = targetPart.getSite().getShell();
+ }
+
+}
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/actions/BasePublishingAction.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/actions/PublishAction.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/actions/PublishAction.java 2009-06-24 18:31:40 UTC (rev 1063)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/actions/PublishAction.java 2009-06-24 22:14:12 UTC (rev 1064)
@@ -23,20 +23,7 @@
*/
package org.jboss.dna.publish.ui.swt.actions;
-import java.util.Collections;
-import java.util.List;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.window.Window;
-import org.eclipse.jface.wizard.WizardDialog;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.IObjectActionDelegate;
-import org.eclipse.ui.IWorkbenchPart;
-import org.jboss.dna.publish.ui.swt.Activator;
-import org.jboss.dna.publish.ui.swt.wizards.PublishWizard;
-import org.jboss.dna.publish.ui.swt.wizards.PublishWizard.Type;
+import org.jboss.dna.publish.ui.swt.wizards.PublishOperation.Type;
/**
* The PublishAction controls the publishing of one or more {@link org.eclipse.core.resources.IResource}s to a DNA repository.
@@ -44,80 +31,17 @@
* @author Dan Florian
* @since 0.6
*/
-public final class PublishAction implements IObjectActionDelegate {
+public final class PublishAction extends BasePublishingAction {
// ===========================================================================================================================
- // Fields
+ // Constructors
// ===========================================================================================================================
- private IStructuredSelection selection;
-
/**
- * The active part's Shell.
- *
* @since 0.6
*/
- private Shell shell;
-
- // ===========================================================================================================================
- // Constants
- // ===========================================================================================================================
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
- * @since 0.6
- */
- @Override
- @SuppressWarnings( "unchecked" )
- public void run( IAction action ) {
- assert (this.selection != null);
- assert (!this.selection.isEmpty());
-
- List<IResource> resources;
-
- if (this.selection.size() == 1) {
- resources = Collections.singletonList((IResource)this.selection.getFirstElement());
- } else {
- resources = this.selection.toList();
- }
-
- WizardDialog dialog = new WizardDialog(shell, new PublishWizard(Type.PUBLISH, resources,
- Activator.getDefault().getServerManager()));
-
- if (dialog.getReturnCode() == Window.OK) {
- // TODO implement run publish
- }
+ public PublishAction() {
+ super(Type.PUBLISH);
}
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction,
- * org.eclipse.jface.viewers.ISelection)
- * @since 0.6
- */
- @Override
- public void selectionChanged( IAction action,
- ISelection selection ) {
- if (selection instanceof IStructuredSelection) {
- this.selection = (IStructuredSelection)selection;
- } else {
- this.selection = null;
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.action.IAction, org.eclipse.ui.IWorkbenchPart)
- * @since 0.6
- */
- @Override
- public void setActivePart( IAction action,
- IWorkbenchPart targetPart ) {
- this.shell = targetPart.getSite().getShell();
- }
-
}
Modified: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/actions/UnpublishAction.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/actions/UnpublishAction.java 2009-06-24 18:31:40 UTC (rev 1063)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/actions/UnpublishAction.java 2009-06-24 22:14:12 UTC (rev 1064)
@@ -23,10 +23,7 @@
*/
package org.jboss.dna.publish.ui.swt.actions;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.ui.IObjectActionDelegate;
-import org.eclipse.ui.IWorkbenchPart;
+import org.jboss.dna.publish.ui.swt.wizards.PublishOperation.Type;
/**
* The UnpublishAction controls the unpublishing of on or more {@link org.eclipse.core.resources.IResource}s from a DNA
@@ -35,45 +32,17 @@
* @author Dan Florian
* @since 0.6
*/
-public final class UnpublishAction implements IObjectActionDelegate {
+public final class UnpublishAction extends BasePublishingAction {
- /**
- * The active part's Shell.
- *
- * @since 0.6
- */
-// private Shell shell;
+ // ===========================================================================================================================
+ // Constructors
+ // ===========================================================================================================================
/**
- * {@inheritDoc}
- *
- * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
* @since 0.6
*/
- public void run( IAction action ) {
- // TODO implement
+ public UnpublishAction() {
+ super(Type.UNPUBLISH);
}
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction,
- * org.eclipse.jface.viewers.ISelection)
- * @since 0.6
- */
- public void selectionChanged( IAction action,
- ISelection selection ) {
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.action.IAction, org.eclipse.ui.IWorkbenchPart)
- * @since 0.6
- */
- public void setActivePart( IAction action,
- IWorkbenchPart targetPart ) {
-// this.shell = targetPart.getSite().getShell();
- }
-
}
Modified: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/i18n.properties
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/i18n.properties 2009-06-24 18:31:40 UTC (rev 1063)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/i18n.properties 2009-06-24 22:14:12 UTC (rev 1064)
@@ -10,9 +10,16 @@
EditServerActionText = Edit Server
EditServerActionToolTip = Edit Server
+ErrorDialogTitle = Error
+
NewServerActionText = New Server
NewServerActionToolTip = New Server
+PublishOperationPublishTaskName = Publishing resources
+PublishOperationPublishTitle = Publish
+PublishOperationUnpublishTaskName = Unpublishing resources
+PublishOperationUnpublishTitle = Unpublish
+
PublishPagePublishTitle = Publish the selected resources
PublishPageLocationGroupTitle = Location
PublishPageMissingRepositoryStatusMsg = A repository must be selected
@@ -35,7 +42,9 @@
PublishPageWorkspacePublishToolTip = The workspace where the resources are being published
PublishPageWorkspaceUnpublishToolTip = The workspace where the resources are being unpublished
+PublishWizardPublishErrorMsg = Error Publishing
PublishWizardPublishTitle = Publish
+PublishWizardUnpublishErrorMsg = Error Unpublishing
PublishWizardUnpublishTitle = Unpublish
ServerPageAuthenticationGroupTitle = Authentication
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/PublishOperation.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/PublishOperation.java (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/PublishOperation.java 2009-06-24 22:14:12 UTC (rev 1064)
@@ -0,0 +1,168 @@
+/*
+ * 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.publish.ui.swt.wizards;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collection;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.jboss.dna.publish.domain.Workspace;
+import org.jboss.dna.publish.ui.swt.I18n;
+
+/**
+ * @author Dan Florian
+ * @since 0.6
+ */
+public class PublishOperation implements IRunnableWithProgress {
+
+ // ===========================================================================================================================
+ // Constants
+ // ===========================================================================================================================
+
+ /**
+ * The wizard type.
+ *
+ * @since 0.6
+ */
+ public enum Type {
+ /**
+ * Indicates the wizard will be used to publish.
+ *
+ * @since 0.6
+ */
+ PUBLISH,
+
+ /**
+ * Indicates the wizard will be used to unpublish.
+ *
+ * @since 0.6
+ */
+ UNPUBLISH
+ }
+
+ // ===========================================================================================================================
+ // Fields
+ // ===========================================================================================================================
+
+ /**
+ * The resources being published or unpublished.
+ *
+ * @since 0.6
+ */
+ private final Collection<IResource> resources;
+
+ /**
+ * The operation type.
+ *
+ * @since 0.6
+ */
+ private final Type type;
+
+ /**
+ * The workspace to use when publishing or unpublishing.
+ *
+ * @since 0.6
+ */
+ private Workspace workspace;
+
+ // ===========================================================================================================================
+ // Constructors
+ // ===========================================================================================================================
+
+ /**
+ * @param type the operation type
+ * @param resources the resources being published or unpublished
+ */
+ public PublishOperation( Type type,
+ Collection<IResource> resources ) {
+ this.type = type;
+ this.resources = resources;
+ }
+
+ // ===========================================================================================================================
+ // Methods
+ // ===========================================================================================================================
+
+ /**
+ * @return the operation title
+ * @since 0.6
+ */
+ public String getTitle() {
+ return ((this.type == Type.PUBLISH) ? I18n.PublishOperationPublishTitle : I18n.PublishOperationUnpublishTitle);
+ }
+
+ /**
+ * @return <code>true</code> if a publishing operation
+ * @since 0.6
+ */
+ public boolean isPublishing() {
+ return (this.type == Type.PUBLISH);
+ }
+
+ /**
+ * @return <code>true</code> if an unpublishing operation
+ * @since 0.6
+ */
+ public boolean isUnpublishing() {
+ return this.type == Type.UNPUBLISH;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse.core.runtime.IProgressMonitor)
+ * @since 0.6
+ */
+ @Override
+ public void run( IProgressMonitor monitor ) throws InvocationTargetException, InterruptedException {
+ assert (this.workspace != null);
+
+ try {
+ // TODO
+ String name = (isPublishing() ? I18n.PublishOperationPublishTaskName : I18n.PublishOperationUnpublishTaskName);
+ monitor.beginTask(name, this.resources.size());
+
+ for (IResource resource : this.resources) {
+ // TODO call publisher here
+ monitor.worked(1);
+ }
+ } catch (Exception e) {
+ throw new InvocationTargetException(e);
+ } finally {
+ monitor.done();
+ }
+ }
+
+ /**
+ * The workspace must be set prior to executing the operation.
+ *
+ * @param workspace the workspace used when publishing or unpublishing (never <code>null</code>)
+ * @since 0.6
+ */
+ protected void setWorkspace( Workspace workspace ) {
+ this.workspace = workspace;
+ }
+
+}
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/PublishOperation.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/PublishPage.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/PublishPage.java 2009-06-24 18:31:40 UTC (rev 1063)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/PublishPage.java 2009-06-24 22:14:12 UTC (rev 1064)
@@ -45,7 +45,7 @@
import org.jboss.dna.publish.domain.Server;
import org.jboss.dna.publish.domain.Workspace;
import org.jboss.dna.publish.ui.swt.I18n;
-import org.jboss.dna.publish.ui.swt.wizards.PublishWizard.Type;
+import org.jboss.dna.publish.ui.swt.wizards.PublishOperation.Type;
/**
* @author Dan Florian
@@ -79,19 +79,31 @@
private Combo cbxWorkspace;
/**
- * Indicates if the resources are being published or unpublished.
+ * Indicates if publishing or unpublishing is being done.
*
* @since 0.6
*/
private final Type type;
/**
+ * The collection of resources being published/unpublished.
+ *
+ * @since 0.6
+ */
+ private final List<IResource> resources;
+
+ /**
* The repository where the workspace is located.
*
* @since 0.6
*/
private Repository repository;
+ /**
+ * A collection of repositories for the selected server (never <code>null</code>).
+ *
+ * @since 0.6
+ */
private List<Repository> repositories;
/**
@@ -101,37 +113,40 @@
*/
private Server server;
+ /**
+ * A collection of servers from the server registry (never <code>null</code>).
+ *
+ * @since 0.6
+ */
private List<Server> servers;
/**
- * The workspace where the resources are being published/unpublished.
+ * The current validation status.
*
* @since 0.6
*/
- private Workspace workspace;
+ private Status status;
- private List<Workspace> workspaces;
-
/**
- * The collection of resources being published/unpublished.
+ * The workspace where the resources are being published/unpublished (may be <code>null</code>).
*
* @since 0.6
*/
- private final List<IResource> resources;
+ private Workspace workspace;
/**
- * The current validation status.
+ * A collection of workspaces for the selected server repository (never <code>null</code>).
*
* @since 0.6
*/
- private Status status;
+ private List<Workspace> workspaces;
// ===========================================================================================================================
// Constructors
// ===========================================================================================================================
/**
- * @param type the publish or unpublish indicator
+ * @param type indicates if publishing or unpublishing is being done
* @param resources the resources being published or unpublished (never <code>null</code>)
* @since 0.6
*/
Modified: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/PublishWizard.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/PublishWizard.java 2009-06-24 18:31:40 UTC (rev 1063)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/PublishWizard.java 2009-06-24 22:14:12 UTC (rev 1064)
@@ -23,14 +23,21 @@
*/
package org.jboss.dna.publish.ui.swt.wizards;
+import java.lang.reflect.InvocationTargetException;
import java.util.List;
import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.jboss.dna.publish.ServerManager;
+import org.jboss.dna.publish.Status;
+import org.jboss.dna.publish.Status.Severity;
+import org.jboss.dna.publish.domain.Workspace;
+import org.jboss.dna.publish.ui.swt.Activator;
import org.jboss.dna.publish.ui.swt.I18n;
+import org.jboss.dna.publish.ui.swt.wizards.PublishOperation.Type;
/**
* @author Dan Florian
@@ -39,34 +46,16 @@
public final class PublishWizard extends Wizard {
// ===========================================================================================================================
- // Constants
+ // Fields
// ===========================================================================================================================
/**
- * The wizard type.
+ * The publishing or unpublishing operation.
*
* @since 0.6
*/
- public enum Type {
- /**
- * Indicates the wizard will be used to publish.
- *
- * @since 0.6
- */
- PUBLISH,
-
- /**
- * Indicates the wizard will be used to unpublish.
- *
- * @since 0.6
- */
- UNPUBLISH
- }
-
- // ===========================================================================================================================
- // Fields
- // ===========================================================================================================================
-
+ private final PublishOperation operation;
+
/**
* The wizard page containing all the controls that allow publishing/unpublishing of resources.
*
@@ -94,9 +83,11 @@
public PublishWizard( Type type,
List<IResource> resources,
ServerManager serverManager ) {
+ this.operation = new PublishOperation(type, resources);
this.page = new PublishPage(type, resources);
this.serverManager = serverManager;
- setWindowTitle((type == Type.PUBLISH) ? I18n.PublishWizardPublishTitle : I18n.PublishWizardUnpublishTitle);
+
+ setWindowTitle(this.operation.isPublishing() ? I18n.PublishWizardPublishTitle : I18n.PublishWizardUnpublishTitle);
}
// ===========================================================================================================================
@@ -130,8 +121,20 @@
*/
@Override
public boolean performFinish() {
- // TODO implement performFinish()
- // Status status = null;
+ Workspace workspace = this.page.getWorkspace();
+ this.operation.setWorkspace(workspace);
+
+ try {
+ getContainer().run(true, true, this.operation);
+ } catch (InterruptedException e) {
+ return false;
+ } catch (InvocationTargetException e) {
+ String message = (this.operation.isPublishing() ? I18n.PublishWizardPublishErrorMsg : I18n.PublishWizardUnpublishErrorMsg);
+ Activator.getDefault().log(getClass(), new Status(Severity.ERROR, message, e.getTargetException()));
+ MessageDialog.openError(getContainer().getShell(), I18n.ErrorDialogTitle, message);
+ return false;
+ }
+
return true; //!status.isError();
}
14 years, 10 months
DNA SVN: r1063 - in branches/eclipse: org.jboss.dna.publish/META-INF and 5 other directories.
by dna-commits@lists.jboss.org
Author: elvisisking
Date: 2009-06-24 14:31:40 -0400 (Wed, 24 Jun 2009)
New Revision: 1063
Added:
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/EclipseStatus.java
branches/eclipse/org.jboss.dna.publish/slf4j-api-1.5.8-sources.jar
branches/eclipse/org.jboss.dna.publish/slf4j-api-1.5.8.jar
branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Logger.java
Modified:
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/Activator.java
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/actions/PublishAction.java
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/PublishPage.java
branches/eclipse/org.jboss.dna.publish/.classpath
branches/eclipse/org.jboss.dna.publish/META-INF/MANIFEST.MF
branches/eclipse/org.jboss.dna.publish/build.properties
branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/IConstants.java
branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Messages.properties
branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Publisher.java
branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ServerManager.java
branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Status.java
branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/Repository.java
branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/Workspace.java
Log:
Added logging and more UI implementation.
Modified: branches/eclipse/org.jboss.dna.publish/.classpath
===================================================================
--- branches/eclipse/org.jboss.dna.publish/.classpath 2009-06-23 18:44:56 UTC (rev 1062)
+++ branches/eclipse/org.jboss.dna.publish/.classpath 2009-06-24 18:31:40 UTC (rev 1063)
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
+ <classpathentry exported="true" kind="lib" path="slf4j-api-1.5.8.jar"/>
<classpathentry exported="true" kind="lib" path="jettison-1.1.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
Modified: branches/eclipse/org.jboss.dna.publish/META-INF/MANIFEST.MF
===================================================================
--- branches/eclipse/org.jboss.dna.publish/META-INF/MANIFEST.MF 2009-06-23 18:44:56 UTC (rev 1062)
+++ branches/eclipse/org.jboss.dna.publish/META-INF/MANIFEST.MF 2009-06-24 18:31:40 UTC (rev 1063)
@@ -8,7 +8,8 @@
Bundle-ActivationPolicy: lazy
Bundle-Localization: plugin
Bundle-ClassPath: dnaPublish.jar,
- jettison-1.1.jar
+ jettison-1.1.jar,
+ slf4j-api-1.5.8.jar
Export-Package: org.jboss.dna.publish,
org.jboss.dna.publish.domain,
org.jboss.dna.publish.domain.validation
Modified: branches/eclipse/org.jboss.dna.publish/build.properties
===================================================================
--- branches/eclipse/org.jboss.dna.publish/build.properties 2009-06-23 18:44:56 UTC (rev 1062)
+++ branches/eclipse/org.jboss.dna.publish/build.properties 2009-06-24 18:31:40 UTC (rev 1063)
@@ -1,7 +1,8 @@
bin.includes = META-INF/,\
plugin.properties,\
jettison-1.1.jar,\
- dnaPublish.jar
+ dnaPublish.jar,\
+ slf4j-api-1.5.8.jar
jars.compile.order = dnaPublish.jar
src.includes = src/
source.dnaPublish.jar = src/
Added: branches/eclipse/org.jboss.dna.publish/slf4j-api-1.5.8-sources.jar
===================================================================
(Binary files differ)
Property changes on: branches/eclipse/org.jboss.dna.publish/slf4j-api-1.5.8-sources.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/eclipse/org.jboss.dna.publish/slf4j-api-1.5.8.jar
===================================================================
(Binary files differ)
Property changes on: branches/eclipse/org.jboss.dna.publish/slf4j-api-1.5.8.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Modified: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/IConstants.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/IConstants.java 2009-06-23 18:44:56 UTC (rev 1062)
+++ branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/IConstants.java 2009-06-24 18:31:40 UTC (rev 1063)
@@ -33,6 +33,12 @@
ResourceBundle MESSAGES = ResourceBundle.getBundle(IConstants.class.getPackage().getName() + ".Messages"); //$NON-NLS-1$
+ String ErrorDeletingServerRegistryFile = "ErrorDeletingServerRegistryFile"; //$NON-NLS-1$
+
+ String ErrorRestoringServerRegistry = "ErrorRestoringServerRegistry"; //$NON-NLS-1$
+
+ String ErrorSavingServerRegistry = "ErrorSavingServerRegistry"; //$NON-NLS-1$
+
String RemovingServerProblemMsg = "RemovingServerProblemMsg"; //$NON-NLS-1$
String RepositoryEmptyNameMsg = "RepositoryEmptyNameMsg"; //$NON-NLS-1$
Added: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Logger.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Logger.java (rev 0)
+++ branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Logger.java 2009-06-24 18:31:40 UTC (rev 1063)
@@ -0,0 +1,84 @@
+/*
+ * 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.publish;
+
+import java.text.MessageFormat;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Dan Florian
+ */
+public final class Logger {
+
+ // ===========================================================================================================================
+ // Class Methods
+ // ===========================================================================================================================
+
+ /**
+ * @param clazz the class whose logger will be used
+ * @param error the error being logged
+ * @param message the message being logged
+ * @since 0.6
+ */
+ public static void error( Class<?> clazz,
+ Throwable error,
+ String message ) {
+ org.slf4j.Logger delegate = LoggerFactory.getLogger(clazz);
+
+ if (delegate.isErrorEnabled()) {
+ delegate.error(message, error);
+ }
+ }
+
+ /**
+ * @param clazz the class whose logger will be used
+ * @param error the error being logged
+ * @param pattern the message format pattern
+ * @param arguments the arguments to be inserted into the pattern
+ * @since 0.6
+ */
+ public static void error( Class<?> clazz,
+ Throwable error,
+ String pattern,
+ Object... arguments ) {
+ org.slf4j.Logger delegate = LoggerFactory.getLogger(clazz);
+
+ if (delegate.isErrorEnabled()) {
+ delegate.error(MessageFormat.format(pattern, arguments), error);
+ }
+ }
+
+ // ===========================================================================================================================
+ // Constructors
+ // ===========================================================================================================================
+
+ /**
+ * Don't allow construction.
+ *
+ * @since 0.6
+ */
+ private Logger() {
+ // nothing to do
+ }
+}
Property changes on: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Logger.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Messages.properties
===================================================================
--- branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Messages.properties 2009-06-23 18:44:56 UTC (rev 1062)
+++ branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Messages.properties 2009-06-24 18:31:40 UTC (rev 1063)
@@ -1,3 +1,7 @@
+ErrorDeletingServerRegistryFile = There was a problem deleting server registry file "{0}"
+ErrorRestoringServerRegistry = Error trying to restore the server registry from file "{0}"
+ErrorSavingServerRegistry = Error trying to save the server registry to "{0}"
+
RemovingServerProblemMsg = {0} cannot be removed as it has not been registered
RepositoryEmptyNameMsg = A repository name cannot be empty
Modified: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Publisher.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Publisher.java 2009-06-23 18:44:56 UTC (rev 1062)
+++ branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Publisher.java 2009-06-24 18:31:40 UTC (rev 1063)
@@ -24,8 +24,11 @@
package org.jboss.dna.publish;
import java.io.File;
+import java.net.Authenticator;
+import java.net.PasswordAuthentication;
import java.util.Collection;
import org.jboss.dna.publish.domain.Server;
+import org.jboss.dna.publish.domain.Workspace;
/**
* @author Dan Florian
@@ -33,13 +36,39 @@
*/
public class Publisher {
- public Status publish( Server server,
+ // ===========================================================================================================================
+ // Constants
+ // ===========================================================================================================================
+
+// private static final String SERVER_CONTEXT = "/resources"; //$NON-NLS-1$
+
+ // ===========================================================================================================================
+ // Class Methods
+ // ===========================================================================================================================
+
+ private static void setAuthenticator(final Server server) {
+ Authenticator.setDefault(new Authenticator() {
+ @Override
+ protected PasswordAuthentication getPasswordAuthentication() {
+ return new PasswordAuthentication(server.getUser(), server.getPassword().toCharArray());
+ }
+ });
+ }
+
+ // ===========================================================================================================================
+ // Methods
+ // ===========================================================================================================================
+
+ public Status publish( Workspace workspace,
Collection<File> files ) {
// TODO implement
+ Server server = workspace.getServer();
+ setAuthenticator(server);
+
return null;
}
- public Status unpublish( Server server,
+ public Status unpublish( Workspace workspace,
Collection<File> files ) {
// TODO implement
return null;
Modified: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ServerManager.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ServerManager.java 2009-06-23 18:44:56 UTC (rev 1062)
+++ branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ServerManager.java 2009-06-24 18:31:40 UTC (rev 1063)
@@ -125,7 +125,6 @@
public ServerManager( String stateLocationPath ) {
this.servers = Collections.synchronizedList(new ArrayList<Server>());
this.stateLocationPath = stateLocationPath;
- restoreState();
}
// ===========================================================================================================================
@@ -159,13 +158,19 @@
public Collection<Server> getServers() {
return Collections.unmodifiableCollection(this.servers);
}
-
+
/**
- * @return the name of the state file that the server registry is persisted to
+ * @return the name of the state file that the server registry is persisted to or <code>null</code>
* @since 0.6
*/
private String getStateFileName() {
- return this.stateLocationPath + File.separatorChar + REGISTRY_FILE;
+ String name = this.stateLocationPath;
+
+ if (this.stateLocationPath != null) {
+ name += File.separatorChar + REGISTRY_FILE;
+ }
+
+ return name;
}
/**
@@ -195,10 +200,10 @@
}
/**
- * @return a status indicating if the previous session state was restored
+ * @return a status indicating if the previous session state was restored successfully
* @since 0.6
*/
- private Status restoreState() {
+ public Status restoreState() {
if (this.stateLocationPath != null) {
if (stateFileExists()) {
try {
@@ -207,15 +212,15 @@
Document doc = docBuilder.parse(new File(getStateFileName()));
Node root = doc.getDocumentElement();
NodeList servers = root.getChildNodes();
-
+
for (int size = servers.getLength(), i = 0; i < size; ++i) {
Node server = servers.item(i);
-
+
if (server.getNodeType() != Node.TEXT_NODE) {
NamedNodeMap attributeMap = server.getAttributes();
-
+
if (attributeMap == null) continue;
-
+
for (int numAttrs = attributeMap.getLength(), j = 0; j < numAttrs; ++j) {
Node urlNode = attributeMap.getNamedItem(URL_TAG);
Node userNode = attributeMap.getNamedItem(USER_TAG);
@@ -225,12 +230,13 @@
}
}
} catch (Exception e) {
- // TODO log
+ String pattern = MESSAGES.getString(ErrorRestoringServerRegistry);
+ return new Status(Severity.ERROR, MessageFormat.format(pattern, getStateFileName()), e);
}
}
}
- // do nothing of there is no save location
+ // do nothing of there is no save location or state file does not exist
return Status.OK_STATUS;
}
@@ -241,8 +247,8 @@
* @since 0.6
*/
public Status saveState() {
- try {
- if ((this.stateLocationPath != null) && !getServers().isEmpty()) {
+ if ((this.stateLocationPath != null) && !getServers().isEmpty()) {
+ try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = factory.newDocumentBuilder();
Document doc = docBuilder.newDocument();
@@ -259,7 +265,7 @@
serverElement.setAttribute(USER_TAG, server.getUser());
serverElement.setAttribute(PASSWORD_TAG, server.getPassword());
}
-
+
DOMSource source = new DOMSource(doc);
StreamResult resultXML = new StreamResult(new FileOutputStream(getStateFileName()));
TransformerFactory transFactory = TransformerFactory.newInstance();
@@ -267,12 +273,18 @@
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); //$NON-NLS-1$ //$NON-NLS-2$
transformer.transform(source, resultXML);
- } else if ((this.stateLocationPath != null) && stateFileExists()) {
- // delete current registry file is all servers have been deleted
+ } catch (Exception e) {
+ String pattern = MESSAGES.getString(ErrorSavingServerRegistry);
+ return new Status(Severity.ERROR, MessageFormat.format(pattern, getStateFileName()), e);
+ }
+ } else if ((this.stateLocationPath != null) && stateFileExists()) {
+ // delete current registry file since all servers have been deleted
+ try {
new File(getStateFileName()).delete();
+ } catch (Exception e) {
+ String pattern = MESSAGES.getString(ErrorDeletingServerRegistryFile);
+ return new Status(Severity.ERROR, MessageFormat.format(pattern, getStateFileName()), e);
}
- } catch (Exception e) {
- // TODO log
}
return Status.OK_STATUS;
@@ -299,7 +311,7 @@
mgr.addServer(new Server("http://server" + i + ".com", "user" + i, "password" + i)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
}
}
-
+
mgr.saveState();
}
Modified: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Status.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Status.java 2009-06-23 18:44:56 UTC (rev 1062)
+++ branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Status.java 2009-06-24 18:31:40 UTC (rev 1063)
@@ -92,27 +92,34 @@
*
* @since 0.6
*/
- private final Throwable exception;
+ protected Throwable exception;
/**
* The localized message of this status (never <code>null</code>).
*
* @since 0.6
*/
- private final String message;
+ protected String message;
/**
* The severity level of this status.
*
* @since 0.6
*/
- private final Severity severity;
+ protected Severity severity;
// ===========================================================================================================================
// Constructors
// ===========================================================================================================================
/**
+ * @since 0.6
+ */
+ protected Status() {
+ // nothing to do
+ }
+
+ /**
* @param severity the status severity (<code>null</code> will be converted to {@link Severity#UNKNOWN}.
* @param message the status message or <code>null</code>
* @param exception the status exception or <code>null</code>
@@ -147,6 +154,14 @@
}
/**
+ * @return severity the status severity
+ * @since 0.6
+ */
+ public Severity getSeverity() {
+ return severity;
+ }
+
+ /**
* @return <code>true</code> if the status is an error
* @see Severity#ERROR
* @since 0.6
Modified: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/Repository.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/Repository.java 2009-06-23 18:44:56 UTC (rev 1062)
+++ branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/Repository.java 2009-06-24 18:31:40 UTC (rev 1063)
@@ -144,7 +144,7 @@
}
/**
- * @return the server where this repository is located
+ * @return the server where this repository is located (never <code>null</code>)
* @since 0.6
*/
public Server getServer() {
Modified: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/Workspace.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/Workspace.java 2009-06-23 18:44:56 UTC (rev 1062)
+++ branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/Workspace.java 2009-06-24 18:31:40 UTC (rev 1063)
@@ -134,9 +134,24 @@
*/
@Override
public IDnaObject getParent() {
- // a workspace's parent is a repository
+ return getRepository();
+ }
+
+ /**
+ * @return the repository where this workspace is located (never <code>null</code>)
+ * @since 0.6
+ */
+ public Repository getRepository() {
return this.repository;
}
+
+ /**
+ * @return the server where this workspace is located (never <code>null</code>)
+ * @since 0.6
+ */
+ public Server getServer() {
+ return this.repository.getServer();
+ }
/**
* {@inheritDoc}
Modified: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/Activator.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/Activator.java 2009-06-23 18:44:56 UTC (rev 1062)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/Activator.java 2009-06-24 18:31:40 UTC (rev 1063)
@@ -23,10 +23,14 @@
*/
package org.jboss.dna.publish.ui.swt;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.jboss.dna.publish.Logger;
import org.jboss.dna.publish.ServerManager;
+import org.jboss.dna.publish.Status;
import org.jboss.dna.publish.domain.IDnaObject;
import org.jboss.dna.publish.domain.Repository;
import org.jboss.dna.publish.domain.Server;
@@ -166,13 +170,44 @@
* Note: This should <strong>ONLY</strong> be called when the OSGi framework is not running (i.e., {@link BundleContext bundle
* context} is <code>null</code>) and should be called instead of calling {@link #start(BundleContext)}.
*
- * @param stateLocationPath
+ * @param stateLocationPath the file system directory where state files can be stored or <code>null</code> if saving state is
+ * not desired
* @since 0.6
*/
public void initialize( String stateLocationPath ) {
this.serverMgr = new ServerManager(stateLocationPath);
+ Status status = this.serverMgr.restoreState();
+
+ // problem restoring server registry
+ if (status.isError()) {
+ log(getClass(), status);
+ }
}
+ public void log( Class<?> sourceClass,
+ Status status ) {
+ if (Platform.isRunning()) {
+ IStatus eclipseStatus;
+
+ if (status instanceof EclipseStatus) {
+ eclipseStatus = ((EclipseStatus)status).getDelegate();
+ } else {
+ eclipseStatus = new org.eclipse.core.runtime.Status(EclipseStatus.convertSeverity(status.getSeverity()),
+ IUiConstants.PLUGIN_ID, status.getMessage(),
+ status.getException());
+ }
+
+ getLog().log(eclipseStatus);
+ } else {
+ Logger.error(getClass(), status.getException(), status.getMessage());
+ }
+ }
+
+ public void log( Class<?> sourceClass,
+ IStatus status ) {
+ log(sourceClass, new EclipseStatus(status));
+ }
+
/**
* {@inheritDoc}
* <p>
@@ -199,8 +234,10 @@
@Override
public void stop( BundleContext context ) throws Exception {
if (this.serverMgr != null) {
- if (this.serverMgr.saveState().isError()) {
- // TODO log this
+ Status status = this.serverMgr.saveState();
+
+ if (status.isError()) {
+ log(getClass(), status);
}
this.serverMgr = null;
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/EclipseStatus.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/EclipseStatus.java (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/EclipseStatus.java 2009-06-24 18:31:40 UTC (rev 1063)
@@ -0,0 +1,112 @@
+/*
+ * 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.publish.ui.swt;
+
+import org.eclipse.core.runtime.IStatus;
+import org.jboss.dna.publish.Status;
+
+/**
+ * Converts an Eclipse status into an non-Eclipse status.
+ *
+ * @author Dan Florian
+ * @since 0.6
+ */
+public class EclipseStatus extends Status {
+
+ // ===========================================================================================================================
+ // Class Methods
+ // ===========================================================================================================================
+
+ /**
+ * Converts the non-Eclipse status severity to an Eclipse severity level. An {@link Status.Severity#UNKNOWN unknown status} is
+ * converted to {@link IStatus#CANCEL cancel}. A {@link Status.Severity} is
+ *
+ * @param severity the eclipse status severity level
+ * @return the converted severity level
+ * @see IStatus
+ * @since 0.6
+ */
+ public static int convertSeverity( Severity severity ) {
+ if (severity == Severity.OK) return IStatus.OK;
+ if (severity == Severity.ERROR) return IStatus.ERROR;
+ if (severity == Severity.WARNING) return IStatus.WARNING;
+ if (severity == Severity.INFO) return IStatus.INFO;
+ return IStatus.CANCEL;
+ }
+
+ /**
+ * Converts the Eclipse status severity level to a non-Eclipse severity.
+ *
+ * @param severity the eclipse status severity level
+ * @return the converted severity level
+ * @see IStatus
+ * @since 0.6
+ */
+ public static Severity convertSeverity( int severity ) {
+ if (severity == IStatus.OK) return Severity.OK;
+ if (severity == IStatus.ERROR) return Severity.ERROR;
+ if (severity == IStatus.WARNING) return Severity.WARNING;
+ if (severity == IStatus.INFO) return Severity.INFO;
+ return Severity.UNKNOWN;
+ }
+
+ // ===========================================================================================================================
+ // Fields
+ // ===========================================================================================================================
+
+ /**
+ * The Eclipse status.
+ *
+ * @since 0.6
+ */
+ private final IStatus delegate;
+
+ // ===========================================================================================================================
+ // Constructors
+ // ===========================================================================================================================
+
+ /**
+ * @param delegate the eclipse status delegate
+ * @since 0.6
+ */
+ public EclipseStatus( IStatus delegate ) {
+ this.delegate = delegate;
+ this.severity = convertSeverity(delegate.getSeverity());
+ this.message = delegate.getMessage();
+ this.exception = delegate.getException();
+ }
+
+ // ===========================================================================================================================
+ // Methods
+ // ===========================================================================================================================
+
+ /**
+ * @return the Eclipse status object
+ * @since 0.6
+ */
+ public IStatus getDelegate() {
+ return this.delegate;
+ }
+
+}
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/EclipseStatus.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/actions/PublishAction.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/actions/PublishAction.java 2009-06-23 18:44:56 UTC (rev 1062)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/actions/PublishAction.java 2009-06-24 18:31:40 UTC (rev 1063)
@@ -23,13 +23,20 @@
*/
package org.jboss.dna.publish.ui.swt.actions;
-import java.util.Iterator;
+import java.util.Collections;
+import java.util.List;
import org.eclipse.core.resources.IResource;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IObjectActionDelegate;
import org.eclipse.ui.IWorkbenchPart;
+import org.jboss.dna.publish.ui.swt.Activator;
+import org.jboss.dna.publish.ui.swt.wizards.PublishWizard;
+import org.jboss.dna.publish.ui.swt.wizards.PublishWizard.Type;
/**
* The PublishAction controls the publishing of one or more {@link org.eclipse.core.resources.IResource}s to a DNA repository.
@@ -50,7 +57,7 @@
*
* @since 0.6
*/
-// private Shell shell;
+ private Shell shell;
// ===========================================================================================================================
// Constants
@@ -58,24 +65,37 @@
/**
* {@inheritDoc}
- *
+ *
* @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
* @since 0.6
*/
@Override
- @SuppressWarnings("unchecked")
+ @SuppressWarnings( "unchecked" )
public void run( IAction action ) {
- for (Iterator itr = this.selection.iterator(); itr.hasNext();) {
- // TODO implement run(IAction) - display publish wizard
- IResource resource = (IResource)itr.next();
- resource.getFullPath().toFile();
+ assert (this.selection != null);
+ assert (!this.selection.isEmpty());
+
+ List<IResource> resources;
+
+ if (this.selection.size() == 1) {
+ resources = Collections.singletonList((IResource)this.selection.getFirstElement());
+ } else {
+ resources = this.selection.toList();
}
+
+ WizardDialog dialog = new WizardDialog(shell, new PublishWizard(Type.PUBLISH, resources,
+ Activator.getDefault().getServerManager()));
+
+ if (dialog.getReturnCode() == Window.OK) {
+ // TODO implement run publish
+ }
}
-
+
/**
* {@inheritDoc}
- *
- * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)
+ *
+ * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction,
+ * org.eclipse.jface.viewers.ISelection)
* @since 0.6
*/
@Override
@@ -87,7 +107,7 @@
this.selection = null;
}
}
-
+
/**
* {@inheritDoc}
*
@@ -97,7 +117,7 @@
@Override
public void setActivePart( IAction action,
IWorkbenchPart targetPart ) {
-// this.shell = targetPart.getSite().getShell();
+ this.shell = targetPart.getSite().getShell();
}
}
Modified: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/PublishPage.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/PublishPage.java 2009-06-23 18:44:56 UTC (rev 1062)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/PublishPage.java 2009-06-24 18:31:40 UTC (rev 1063)
@@ -23,6 +23,8 @@
*/
package org.jboss.dna.publish.ui.swt.wizards;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import org.eclipse.core.resources.IResource;
import org.eclipse.jface.dialogs.IMessageProvider;
@@ -36,8 +38,12 @@
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
+import org.jboss.dna.publish.ServerManager;
import org.jboss.dna.publish.Status;
import org.jboss.dna.publish.Status.Severity;
+import org.jboss.dna.publish.domain.Repository;
+import org.jboss.dna.publish.domain.Server;
+import org.jboss.dna.publish.domain.Workspace;
import org.jboss.dna.publish.ui.swt.I18n;
import org.jboss.dna.publish.ui.swt.wizards.PublishWizard.Type;
@@ -84,22 +90,28 @@
*
* @since 0.6
*/
- private String repository;
+ private Repository repository;
+ private List<Repository> repositories;
+
/**
* The server where the repository is located.
*
* @since 0.6
*/
- private String server;
+ private Server server;
+ private List<Server> servers;
+
/**
* The workspace where the resources are being published/unpublished.
*
* @since 0.6
*/
- private String workspace;
+ private Workspace workspace;
+ private List<Workspace> workspaces;
+
/**
* The collection of resources being published/unpublished.
*
@@ -198,8 +210,9 @@
// set initial value
// TODO implement load resources
- String[] data = new String[20];
- for (int i = 0; i < 20; ++i) data[i] = "my/resource" + i + ".xmi"; //$NON-NLS-1$ //$NON-NLS-2$
+ String[] data = new String[20];
+ for (int i = 0; i < 20; ++i)
+ data[i] = "my/resource" + i + ".xmi"; //$NON-NLS-1$ //$NON-NLS-2$
lstResources.setItems(data);
}
@@ -217,25 +230,40 @@
constructResourcesPanel(pnlMain);
setControl(pnlMain);
- loadServers();
+ resetServers();
installLocationListeners();
}
/**
+ * @return the server manager obtained from the wizard
+ * @since 0.6
+ */
+ private ServerManager getServerManager() {
+ return ((ServerWizard)getWizard()).getServerManager();
+ }
+
+ /**
+ * @return thw workspace to use when publishing or unpublishing
+ * @since 0.6
+ */
+ public Workspace getWorkspace() {
+ assert isPageComplete();
+ return this.workspace;
+ }
+
+ /**
* Handler for when the repository control value is modified
*
* @since 0.6
*/
void handleRepositoryModified() {
- this.repository = this.cbxRepository.getText();
- this.workspace = null;
+ int index = this.cbxRepository.getSelectionIndex();
+ this.repository = this.repositories.get(index);
// clear loaded workspaces
- uninstallLocationListeners();
- this.cbxWorkspace.removeAll();
- reloadWorkspaces();
- installLocationListeners();
+ resetWorkspaces();
+ // update page state
updateState();
}
@@ -245,17 +273,12 @@
* @since 0.6
*/
void handleServerModified() {
- this.server = this.cbxServer.getText();
- this.repository = null;
- this.workspace = null;
+ this.server = this.servers.get(this.cbxServer.getSelectionIndex());
- // clear loaded repositories and workspaces
- uninstallLocationListeners();
- this.cbxRepository.removeAll();
- this.cbxWorkspace.removeAll();
- reloadRepositories();
- installLocationListeners();
+ // need to reload repositories since server changed
+ resetRepositories();
+ // update page state
updateState();
}
@@ -265,7 +288,7 @@
* @since 0.6
*/
void handleWorkspaceModified() {
- this.workspace = this.cbxWorkspace.getText();
+ this.workspace = this.workspaces.get(this.cbxWorkspace.getSelectionIndex());
updateState();
}
@@ -280,13 +303,6 @@
this.cbxWorkspace.addModifyListener(this);
}
- private void loadServers() {
- // TODO implement loadServers()
- String[] data = new String[20];
- for (int i = 0; i < 20; ++i) data[i] = "server" + i; //$NON-NLS-1$
- this.cbxServer.setItems(data);
- }
-
/**
* {@inheritDoc}
*
@@ -301,34 +317,155 @@
} else if (e.widget == this.cbxRepository) {
handleWorkspaceModified();
} else {
- // should not happen
- // TODO log
+ assert false; // should not happen
}
}
/**
- * Reloads the repository combobox based on the newly selected server.
+ * Resets the repository-related fields and controls.
*
* @since 0.6
*/
- private void reloadRepositories() {
- // TODO implement reloadRepositories()
- // if only one repository set it on the combobox
- // if no repositories ???
+ private void resetRepositories() {
+ this.repository = null;
+
+ if (this.server == null) {
+ this.repositories = Collections.emptyList();
+ } else {
+ this.repositories = new ArrayList<Repository>(this.server.getRepositories());
+ }
+
+ // uninstall listeners to prevent handling events
+ uninstallLocationListeners();
+
+ // clear items
+ this.cbxRepository.removeAll();
+
+ // reload
+ if (this.repositories.isEmpty()) {
+ // disable control if necessary
+ if (this.cbxRepository.getEnabled()) {
+ this.cbxRepository.setEnabled(false);
+ }
+ } else if (this.repositories.size() == 1) {
+ this.repository = this.repositories.get(0);
+ this.cbxRepository.add(this.repository.getName());
+ this.cbxRepository.select(0);
+
+ // enable control if necessary
+ if (!this.cbxRepository.getEnabled()) {
+ this.cbxRepository.setEnabled(true);
+ }
+ } else {
+ // add an item for each repository
+ for (Repository repository : this.repositories) {
+ this.cbxRepository.add(repository.getName());
+ }
+
+ // enable control if necessary
+ if (!this.cbxRepository.getEnabled()) {
+ this.cbxRepository.setEnabled(true);
+ }
+ }
+
+ // must reload workspaces
+ resetWorkspaces();
+
+ // reinstall listening
+ installLocationListeners();
}
/**
- * Reloads the repository combobox based on the newly selected server.
+ * Resets the server-related fields and controls.
*
* @since 0.6
*/
- private void reloadWorkspaces() {
- // TODO implement reloadRepositories()
- // if only one workspace set it on the combobox
- // if no workspaces ???
+ private void resetServers() {
+ this.server = null;
+ this.servers = new ArrayList<Server>(getServerManager().getServers());
+
+ if (this.servers.size() == 0) {
+ // disable control if necessary
+ if (this.cbxServer.getEnabled()) {
+ this.cbxServer.setEnabled(false);
+ }
+ } else if (this.servers.size() == 1) {
+ this.server = this.servers.get(0);
+ this.cbxServer.add(this.server.getName());
+ this.cbxServer.select(0);
+
+ // enable control if necessary
+ if (!this.cbxServer.getEnabled()) {
+ this.cbxServer.setEnabled(true);
+ }
+ } else {
+ // add an item for each server
+ for (Server server : this.servers) {
+ this.cbxServer.add(server.getName());
+ }
+
+ // enable control if necessary
+ if (!this.cbxServer.getEnabled()) {
+ this.cbxServer.setEnabled(true);
+ }
+ }
+
+ // must reload repositories
+ resetRepositories();
}
/**
+ * Resets the workspace-related fields and controls.
+ *
+ * @since 0.6
+ */
+ private void resetWorkspaces() {
+ this.workspace = null;
+
+ if (this.repository == null) {
+ this.workspaces = Collections.emptyList();
+ } else {
+ this.workspaces = new ArrayList<Workspace>(this.repository.getWorkspaces());
+ }
+
+ // uninstall listeners to prevent handling events
+ uninstallLocationListeners();
+
+ // clear items
+ this.cbxWorkspace.removeAll();
+
+ // reload
+ if (this.workspaces.isEmpty()) {
+ // disable control if necessary
+ if (this.cbxWorkspace.getEnabled()) {
+ this.cbxWorkspace.setEnabled(false);
+ }
+ } else if (this.workspaces.size() == 1) {
+ this.workspace = this.workspaces.get(0);
+ this.cbxWorkspace.add(this.workspace.getName());
+ this.cbxWorkspace.select(0);
+
+ // enable control if necessary
+ if (!this.cbxWorkspace.getEnabled()) {
+ this.cbxWorkspace.setEnabled(true);
+ }
+ } else {
+ // add an item for each workspace
+ for (Workspace workspace : this.workspaces) {
+ this.cbxWorkspace.add(workspace.getName());
+ }
+
+ // enable control if necessary
+ if (!this.cbxWorkspace.getEnabled()) {
+ this.cbxWorkspace.setEnabled(true);
+ }
+ }
+
+ // reinstall listening
+ installLocationListeners();
+ }
+
+ /**
* {@inheritDoc}
*
* @see org.eclipse.jface.dialogs.DialogPage#setVisible(boolean)
@@ -403,7 +540,7 @@
int count = this.cbxRepository.getItemCount();
msg = ((count == 0) ? I18n.PublishPageNoAvailableRepositoriesStatusMsg : I18n.PublishPageMissingRepositoryStatusMsg);
} else if (this.workspace == null) {
- int count = this.cbxServer.getItemCount();
+ int count = this.cbxWorkspace.getItemCount();
msg = ((count == 0) ? I18n.PublishPageNoAvailableWorkspacesStatusMsg : I18n.PublishPageMissingWorkspaceStatusMsg);
} else {
severity = Severity.OK;
@@ -412,4 +549,5 @@
this.status = new Status(severity, msg, null);
}
+
}
14 years, 10 months
DNA SVN: r1062 - in branches/eclipse/org.jboss.dna.publish.ui.swt: .settings and 16 other directories.
by dna-commits@lists.jboss.org
Author: elvisisking
Date: 2009-06-23 14:44:56 -0400 (Tue, 23 Jun 2009)
New Revision: 1062
Added:
branches/eclipse/org.jboss.dna.publish.ui.swt/.classpath
branches/eclipse/org.jboss.dna.publish.ui.swt/.project
branches/eclipse/org.jboss.dna.publish.ui.swt/.settings/
branches/eclipse/org.jboss.dna.publish.ui.swt/.settings/org.eclipse.jdt.core.prefs
branches/eclipse/org.jboss.dna.publish.ui.swt/META-INF/
branches/eclipse/org.jboss.dna.publish.ui.swt/META-INF/MANIFEST.MF
branches/eclipse/org.jboss.dna.publish.ui.swt/build.properties
branches/eclipse/org.jboss.dna.publish.ui.swt/icons/
branches/eclipse/org.jboss.dna.publish.ui.swt/icons/full/
branches/eclipse/org.jboss.dna.publish.ui.swt/icons/full/cview16/
branches/eclipse/org.jboss.dna.publish.ui.swt/icons/full/cview16/repository.gif
branches/eclipse/org.jboss.dna.publish.ui.swt/icons/full/obj16/
branches/eclipse/org.jboss.dna.publish.ui.swt/icons/full/obj16/repository.gif
branches/eclipse/org.jboss.dna.publish.ui.swt/icons/full/obj16/server.gif
branches/eclipse/org.jboss.dna.publish.ui.swt/icons/full/obj16/workspace.gif
branches/eclipse/org.jboss.dna.publish.ui.swt/plugin.properties
branches/eclipse/org.jboss.dna.publish.ui.swt/plugin.xml
branches/eclipse/org.jboss.dna.publish.ui.swt/slf4j-api-1.5.8-sources.jar
branches/eclipse/org.jboss.dna.publish.ui.swt/slf4j-api-1.5.8.jar
branches/eclipse/org.jboss.dna.publish.ui.swt/src/
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/Activator.java
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/I18n.java
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/IUiConstants.java
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/actions/
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/actions/PublishAction.java
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/actions/UnpublishAction.java
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/dialogs/
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/dialogs/DeleteServerDialog.java
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/i18n.properties
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/views/
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/views/RepositoryContentProvider.java
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/views/RepositoryView.java
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/PublishPage.java
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/PublishWizard.java
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/ServerPage.java
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/ServerWizard.java
Log:
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/.classpath
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/.classpath (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/.classpath 2009-06-23 18:44:56 UTC (rev 1062)
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/.classpath
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/.project
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/.project (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/.project 2009-06-23 18:44:56 UTC (rev 1062)
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.jboss.dna.publish.ui.swt.swt</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/.project
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/.settings/org.eclipse.jdt.core.prefs (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/.settings/org.eclipse.jdt.core.prefs 2009-06-23 18:44:56 UTC (rev 1062)
@@ -0,0 +1,7 @@
+#Wed Jun 17 07:47:51 CDT 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/.settings/org.eclipse.jdt.core.prefs
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/META-INF/MANIFEST.MF
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/META-INF/MANIFEST.MF (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/META-INF/MANIFEST.MF 2009-06-23 18:44:56 UTC (rev 1062)
@@ -0,0 +1,13 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %bundleName
+Bundle-SymbolicName: org.jboss.dna.publish.ui.swt;singleton:=true
+Bundle-Version: 1.0.0
+Bundle-Activator: org.jboss.dna.publish.ui.swt.Activator
+Bundle-Vendor: %bundleVendor
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.jboss.dna.publish,
+ org.eclipse.core.resources;bundle-version="3.4.2"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Bundle-ActivationPolicy: lazy
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/META-INF/MANIFEST.MF
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/build.properties
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/build.properties (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/build.properties 2009-06-23 18:44:56 UTC (rev 1062)
@@ -0,0 +1,7 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.properties,\
+ icons/,\
+ plugin.xml
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/build.properties
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/icons/full/cview16/repository.gif
===================================================================
(Binary files differ)
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/icons/full/cview16/repository.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/icons/full/obj16/repository.gif
===================================================================
(Binary files differ)
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/icons/full/obj16/repository.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/icons/full/obj16/server.gif
===================================================================
(Binary files differ)
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/icons/full/obj16/server.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/icons/full/obj16/workspace.gif
===================================================================
(Binary files differ)
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/icons/full/obj16/workspace.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/plugin.properties
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/plugin.properties (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/plugin.properties 2009-06-23 18:44:56 UTC (rev 1062)
@@ -0,0 +1,30 @@
+#
+# 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.
+#
+bundleName = DNA Eclipse Publishing UI Plug-in
+bundleVendor = Red Hat, Inc.
+contextMenu.label = DNA
+dnaCategory = DNA
+publishAction.label = Publish
+repositoryView = DNA Repositories
+unpublishAction.label = Unpublish
\ No newline at end of file
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/plugin.properties
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/plugin.xml
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/plugin.xml (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/plugin.xml 2009-06-23 18:44:56 UTC (rev 1062)
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+
+<!-- Define the IResource object contribution actions to all popup menus -->
+ <extension
+ point="org.eclipse.ui.popupMenus">
+ <objectContribution
+ id="org.jboss.dna.publish.iresourcepopupmenucontribution"
+ objectClass="org.eclipse.core.resources.IResource">
+ <menu
+ id="org.jboss.dna.publish.contextMenu"
+ label="%contextMenu.label"
+ path="additions">
+ <separator
+ name="group1">
+ </separator>
+ </menu>
+
+ <!-- Unpublish action -->
+ <action
+ id="org.jboss.dna.publish.ui.swt.unpublishAction"
+ label="%unpublishAction.label"
+ class="org.jboss.dna.publish.ui.swt.actions.UnpublishAction"
+ menubarPath="org.jboss.dna.publish.contextMenu/group1"
+ enablesFor="*">
+ </action>
+
+ <!-- Publish action -->
+ <action
+ id="org.jboss.dna.publish.ui.swt.publishAction"
+ label="%publishAction.label"
+ class="org.jboss.dna.publish.ui.swt.actions.PublishAction"
+ menubarPath="org.jboss.dna.publish.contextMenu/group1"
+ enablesFor="*">
+ </action>
+ </objectContribution>
+ </extension>
+
+<!-- View extensions -->
+ <extension
+ point="org.eclipse.ui.views">
+ <category
+ id="org.jboss.dna"
+ name="%dnaCategory">
+ </category>
+
+ <!-- Repository view -->
+ <view
+ id="respositoryView"
+ name="%repositoryView"
+ category="org.jboss.dna"
+ class="org.jboss.dna.publish.ui.swt.views.RepositoryView"
+ fastViewWidthRatio="0.25"
+ icon="icons/full/cview16/repository.gif">
+ </view>
+ </extension>
+
+</plugin>
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/plugin.xml
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/slf4j-api-1.5.8-sources.jar
===================================================================
(Binary files differ)
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/slf4j-api-1.5.8-sources.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/slf4j-api-1.5.8.jar
===================================================================
(Binary files differ)
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/slf4j-api-1.5.8.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/Activator.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/Activator.java (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/Activator.java 2009-06-23 18:44:56 UTC (rev 1062)
@@ -0,0 +1,216 @@
+/*
+ * 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.publish.ui.swt;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.jboss.dna.publish.ServerManager;
+import org.jboss.dna.publish.domain.IDnaObject;
+import org.jboss.dna.publish.domain.Repository;
+import org.jboss.dna.publish.domain.Server;
+import org.jboss.dna.publish.domain.Workspace;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle.
+ *
+ * @author Dan Florian
+ * @since 0.6
+ */
+public class Activator extends AbstractUIPlugin implements IUiConstants {
+
+ // ===========================================================================================================================
+ // Class Fields
+ // ===========================================================================================================================
+
+ /**
+ * The shared plugin instance.
+ *
+ * @since 0.6
+ */
+ private static Activator plugin;
+
+ // ===========================================================================================================================
+ // Class Methods
+ // ===========================================================================================================================
+
+ /**
+ * @return the shared instance or <code>null</code> if not constructed
+ * @since 0.6
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+ // ===========================================================================================================================
+ // Fields
+ // ===========================================================================================================================
+
+ /**
+ * The manager in charge of the server registry.
+ *
+ * @since 0.6
+ */
+ private ServerManager serverMgr;
+
+ // ===========================================================================================================================
+ // Constructors
+ // ===========================================================================================================================
+
+ /**
+ * Constructs the plugin activator. If constructed outside of Eclipse the {@link #initialize(String)} method must be called to
+ * construct the {@link ServerManager server manager}.
+ *
+ * @since 0.6
+ */
+ public Activator() {
+ super();
+ plugin = this;
+ }
+
+ // ===========================================================================================================================
+ // Methods
+ // ===========================================================================================================================
+
+ /**
+ * @param object the object whose image is being requested
+ * @return the image or <code>null</code> if not found
+ * @since 0.6
+ */
+ public Image getImage( Object object ) {
+ String key = null;
+
+ if (object instanceof Workspace) {
+ key = WORKSPACE_IMAGE_PATH;
+ } else if (object instanceof Repository) {
+ key = REPOSITORY_IMAGE_PATH;
+ } else if (object instanceof Server) {
+ key = SERVER_IMAGE_PATH;
+ } else if (object instanceof IDnaObject) {
+ // should have an icon for every business object
+ assert false;
+ } else if (object instanceof String) {
+ key = (String)object;
+ }
+
+ if (key != null) {
+ return getImageRegistry().get(key);
+ }
+
+ return null;
+ }
+
+ /**
+ * @param object the object whose image descriptor is being requested
+ * @return the image descriptor or <code>null</code> if not found
+ * @since 0.6
+ */
+ public ImageDescriptor getImageDescriptor( Object object ) {
+ String key = null;
+
+ if (object instanceof Workspace) {
+ key = WORKSPACE_IMAGE_PATH;
+ } else if (object instanceof Repository) {
+ key = REPOSITORY_IMAGE_PATH;
+ } else if (object instanceof Server) {
+ key = SERVER_IMAGE_PATH;
+ } else if (object instanceof IDnaObject) {
+ // should have an icon for every business object
+ assert false;
+ } else if (object instanceof String) {
+ key = (String)object;
+ }
+
+ if (key != null) {
+ return AbstractUIPlugin.imageDescriptorFromPlugin(PLUGIN_ID, ((String)object));
+ }
+
+ return null;
+ }
+
+ /**
+ * @return the server manager or <code>null</code> if activator has not been initialized or started
+ * @see #initialize(String)
+ * @see #start(BundleContext)
+ * @since 0.6
+ */
+ public ServerManager getServerManager() {
+ return this.serverMgr;
+ }
+
+ /**
+ * Performs plugin initialization. One thing it does is initialize the {@link ServerManager server manager}.
+ * <p>
+ * Note: This should <strong>ONLY</strong> be called when the OSGi framework is not running (i.e., {@link BundleContext bundle
+ * context} is <code>null</code>) and should be called instead of calling {@link #start(BundleContext)}.
+ *
+ * @param stateLocationPath
+ * @since 0.6
+ */
+ public void initialize( String stateLocationPath ) {
+ this.serverMgr = new ServerManager(stateLocationPath);
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * If OSGi is not running this does nothing.
+ *
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ * @since 0.6
+ */
+ @Override
+ public void start( BundleContext context ) throws Exception {
+ if (context != null) {
+ // OSGi is running
+ super.start(context);
+ initialize(plugin.getStateLocation().toFile().getAbsolutePath());
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ * @since 0.6
+ */
+ @Override
+ public void stop( BundleContext context ) throws Exception {
+ if (this.serverMgr != null) {
+ if (this.serverMgr.saveState().isError()) {
+ // TODO log this
+ }
+
+ this.serverMgr = null;
+ }
+
+ if (context != null) {
+ super.stop(context);
+ }
+
+ plugin = null;
+ }
+
+}
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/Activator.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/I18n.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/I18n.java (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/I18n.java 2009-06-23 18:44:56 UTC (rev 1062)
@@ -0,0 +1,98 @@
+/*
+ * 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.publish.ui.swt;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * The I18n class handles localization messages.
+ *
+ * @author Dan Florian
+ * @since 0.6
+ */
+public final class I18n extends NLS {
+
+ public static String CollapseActionToolTip;
+
+ public static String DeleteServerActionText;
+ public static String DeleteServerActionToolTip;
+
+ public static String DeleteServerDialogTitle;
+ public static String DeleteServerDialogOneServerMessage;
+ public static String DeleteServerDialogMultipleServersMessage;
+
+ public static String EditServerActionText;
+ public static String EditServerActionToolTip;
+
+ public static String PublishPagePublishTitle;
+ public static String PublishPageLocationGroupTitle;
+ public static String PublishPageMissingRepositoryStatusMsg;
+ public static String PublishPageMissingServerStatusMsg;
+ public static String PublishPageMissingWorkspaceStatusMsg;
+ public static String PublishPageNoAvailableRepositoriesStatusMsg;
+ public static String PublishPageNoAvailableServersStatusMsg;
+ public static String PublishPageNoAvailableWorkspacesStatusMsg;
+ public static String PublishPageNoResourcesStatusMsg;
+ public static String PublishPagePublishOkStatusMsg;
+ public static String PublishPagePublishResourcesLabel;
+ public static String PublishPageRepositoryLabel;
+ public static String PublishPageRepositoryToolTip;
+ public static String PublishPageServerLabel;
+ public static String PublishPageServerToolTip;
+ public static String PublishPageUnpublishOkStatusMsg;
+ public static String PublishPageUnpublishResourcesLabel;
+ public static String PublishPageUnpublishTitle;
+ public static String PublishPageWorkspaceLabel;
+ public static String PublishPageWorkspacePublishToolTip;
+ public static String PublishPageWorkspaceUnpublishToolTip;
+
+ public static String PublishWizardPublishTitle;
+ public static String PublishWizardUnpublishTitle;
+
+ public static String ServerPageAuthenticationGroupTitle;
+ public static String ServerPageInvalidServerProperties;
+ public static String ServerPageOkStatusMsg;
+ public static String ServerPagePasswordLabel;
+ public static String ServerPagePasswordToolTip;
+ public static String ServerPageSavePasswordButton;
+ public static String ServerPageSavePasswordLabel;
+ public static String ServerPageSavePasswordToolTip;
+ public static String ServerPageTitle;
+ public static String ServerPageUrlLabel;
+ public static String ServerPageUrlToolTip;
+ public static String ServerPageUserLabel;
+ public static String ServerPageUserToolTip;
+
+ public static String ServerWizardEditServerTitle;
+ public static String ServerWizardNewServerTitle;
+
+ public static String NewServerActionText;
+ public static String NewServerActionToolTip;
+
+ static {
+ // load message bundle
+ NLS.initializeMessages(I18n.class.getPackage().getName() + ".i18n", I18n.class); //$NON-NLS-1$
+ }
+
+}
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/I18n.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/IUiConstants.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/IUiConstants.java (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/IUiConstants.java 2009-06-23 18:44:56 UTC (rev 1062)
@@ -0,0 +1,49 @@
+/*
+ * 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.publish.ui.swt;
+
+/**
+ * @author Dan Florian
+ * @since 0.6
+ */
+public interface IUiConstants {
+
+ /**
+ * The Plug-in's identifier.
+ *
+ * @since 0.6
+ */
+ String PLUGIN_ID = "org.jboss.dna.publish.ui.swt"; //$NON-NLS-1$
+
+ String ICON_PATH = "icons/full/"; //$NON-NLS-1$
+
+ String OBJ16 = ICON_PATH + "obj16/"; //$NON-NLS-1$
+
+ String REPOSITORY_IMAGE_PATH = OBJ16 + "repository.gif"; //$NON-NLS-1$
+
+ String SERVER_IMAGE_PATH = OBJ16 + "server.gif"; //$NON-NLS-1$
+
+ String WORKSPACE_IMAGE_PATH = OBJ16 + "workspace.gif"; //$NON-NLS-1$
+
+}
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/IUiConstants.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/actions/PublishAction.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/actions/PublishAction.java (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/actions/PublishAction.java 2009-06-23 18:44:56 UTC (rev 1062)
@@ -0,0 +1,103 @@
+/*
+ * 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.publish.ui.swt.actions;
+
+import java.util.Iterator;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.IObjectActionDelegate;
+import org.eclipse.ui.IWorkbenchPart;
+
+/**
+ * The PublishAction controls the publishing of one or more {@link org.eclipse.core.resources.IResource}s to a DNA repository.
+ *
+ * @author Dan Florian
+ * @since 0.6
+ */
+public final class PublishAction implements IObjectActionDelegate {
+
+ // ===========================================================================================================================
+ // Fields
+ // ===========================================================================================================================
+
+ private IStructuredSelection selection;
+
+ /**
+ * The active part's Shell.
+ *
+ * @since 0.6
+ */
+// private Shell shell;
+
+ // ===========================================================================================================================
+ // Constants
+ // ===========================================================================================================================
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
+ * @since 0.6
+ */
+ @Override
+ @SuppressWarnings("unchecked")
+ public void run( IAction action ) {
+ for (Iterator itr = this.selection.iterator(); itr.hasNext();) {
+ // TODO implement run(IAction) - display publish wizard
+ IResource resource = (IResource)itr.next();
+ resource.getFullPath().toFile();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)
+ * @since 0.6
+ */
+ @Override
+ public void selectionChanged( IAction action,
+ ISelection selection ) {
+ if (selection instanceof IStructuredSelection) {
+ this.selection = (IStructuredSelection)selection;
+ } else {
+ this.selection = null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.action.IAction, org.eclipse.ui.IWorkbenchPart)
+ * @since 0.6
+ */
+ @Override
+ public void setActivePart( IAction action,
+ IWorkbenchPart targetPart ) {
+// this.shell = targetPart.getSite().getShell();
+ }
+
+}
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/actions/PublishAction.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/actions/UnpublishAction.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/actions/UnpublishAction.java (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/actions/UnpublishAction.java 2009-06-23 18:44:56 UTC (rev 1062)
@@ -0,0 +1,79 @@
+/*
+ * 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.publish.ui.swt.actions;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IObjectActionDelegate;
+import org.eclipse.ui.IWorkbenchPart;
+
+/**
+ * The UnpublishAction controls the unpublishing of on or more {@link org.eclipse.core.resources.IResource}s from a DNA
+ * repository.
+ *
+ * @author Dan Florian
+ * @since 0.6
+ */
+public final class UnpublishAction implements IObjectActionDelegate {
+
+ /**
+ * The active part's Shell.
+ *
+ * @since 0.6
+ */
+// private Shell shell;
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
+ * @since 0.6
+ */
+ public void run( IAction action ) {
+ // TODO implement
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction,
+ * org.eclipse.jface.viewers.ISelection)
+ * @since 0.6
+ */
+ public void selectionChanged( IAction action,
+ ISelection selection ) {
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.action.IAction, org.eclipse.ui.IWorkbenchPart)
+ * @since 0.6
+ */
+ public void setActivePart( IAction action,
+ IWorkbenchPart targetPart ) {
+// this.shell = targetPart.getSite().getShell();
+ }
+
+}
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/actions/UnpublishAction.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/dialogs/DeleteServerDialog.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/dialogs/DeleteServerDialog.java (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/dialogs/DeleteServerDialog.java 2009-06-23 18:44:56 UTC (rev 1062)
@@ -0,0 +1,122 @@
+/*
+ * 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.publish.ui.swt.dialogs;
+
+import java.util.Collection;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.swt.widgets.Shell;
+import org.jboss.dna.publish.domain.IDnaObject;
+import org.jboss.dna.publish.domain.Server;
+import org.jboss.dna.publish.ui.swt.I18n;
+
+/**
+ * The <code>DeleteServerDialog</code> class provides a UI for deleting a {@link org.jboss.dna.publish.domain.Server server}.
+ *
+ * @author Dan Florian
+ * @since 0.6
+ */
+public class DeleteServerDialog extends MessageDialog {
+
+ // ===========================================================================================================================
+ // Fields
+ // ===========================================================================================================================
+
+ /**
+ * Collection of servers which will be deleted.
+ *
+ * @since 0.6
+ */
+ private final Collection<Server> serversBeingDeleted;
+
+ // ===========================================================================================================================
+ // Constructors
+ // ===========================================================================================================================
+
+ /**
+ * @param parentShell the dialog parent
+ * @param serversBeingDeleted the servers being deleted (may not be <code>null</code>)
+ * @since 0.6
+ */
+ public DeleteServerDialog( Shell parentShell,
+ Collection<Server> serversBeingDeleted ) {
+ super(parentShell, I18n.DeleteServerDialogTitle, null, null, MessageDialog.QUESTION, new String[] {
+ IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL}, 0);
+ this.serversBeingDeleted = serversBeingDeleted;
+ }
+
+ // ===========================================================================================================================
+ // Methods
+ // ===========================================================================================================================
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.dialogs.MessageDialog#configureShell(org.eclipse.swt.widgets.Shell)
+ * @since 0.6
+ */
+ @Override
+ protected void configureShell( Shell shell ) {
+ super.configureShell(shell);
+
+ // now set title
+ String title;
+
+ if (this.serversBeingDeleted.size() == 1) {
+ IDnaObject server = this.serversBeingDeleted.iterator().next();
+ title = NLS.bind(I18n.DeleteServerDialogOneServerMessage, server.getName());
+ } else {
+ title = NLS.bind(I18n.DeleteServerDialogOneServerMessage, this.serversBeingDeleted.size());
+ }
+
+ shell.setText(title);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.dialogs.MessageDialog#createCustomArea(org.eclipse.swt.widgets.Composite)
+ * @since 0.6
+ */
+ @Override
+ protected Control createCustomArea( Composite parent ) {
+ if (this.serversBeingDeleted.size() != 1) {
+ List serverList = new List(parent, SWT.NONE);
+ serverList.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
+
+ for (IDnaObject server : this.serversBeingDeleted) {
+ serverList.add(server.getName());
+ }
+ }
+
+ return null;
+ }
+
+}
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/dialogs/DeleteServerDialog.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/i18n.properties
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/i18n.properties (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/i18n.properties 2009-06-23 18:44:56 UTC (rev 1062)
@@ -0,0 +1,56 @@
+CollapseActionToolTip = Collapse All
+
+DeleteServerActionText = Delete Server
+DeleteServerActionToolTip = Delete Server
+
+DeleteServerDialogTitle = Confirm Delete Server
+DeleteServerDialogOneServerMessage = Are you sure you want to delete the "{0}" server?
+DeleteServerDialogMultipleServersMessage = Are you sure you want to delete these {0} servers?
+
+EditServerActionText = Edit Server
+EditServerActionToolTip = Edit Server
+
+NewServerActionText = New Server
+NewServerActionToolTip = New Server
+
+PublishPagePublishTitle = Publish the selected resources
+PublishPageLocationGroupTitle = Location
+PublishPageMissingRepositoryStatusMsg = A repository must be selected
+PublishPageMissingServerStatusMsg = A server must be selected
+PublishPageMissingWorkspaceStatusMsg = A workspace must be selected
+PublishPageNoAvailableRepositoriesStatusMsg = There are no repositories available on that server
+PublishPageNoAvailableServersStatusMsg = A server must be created first
+PublishPageNoAvailableWorkspacesStatusMsg = There are no workspaces availabe on that server and repository
+PublishPageNoResourcesStatusMsg = You must select one or more workspace resources
+PublishPagePublishOkStatusMsg = Choose the server, repository, and workspace where the selected resources will be published.
+PublishPagePublishResourcesLabel = These resources will be published to the specified DNA repository:
+PublishPageRepositoryLabel = Repository:
+PublishPageRepositoryToolTip = The repository where the workspace is located
+PublishPageServerLabel = Server:
+PublishPageServerToolTip = The server where the repository is located
+PublishPageUnpublishOkStatusMsg = Choose the server, repository, and workspace where the selected resources will be unpublished.
+PublishPageUnpublishResourcesLabel = These resources will be unpublished from the specified DNA repository:
+PublishPageUnpublishTitle = Unpublish the selected resources
+PublishPageWorkspaceLabel = Workspace:
+PublishPageWorkspacePublishToolTip = The workspace where the resources are being published
+PublishPageWorkspaceUnpublishToolTip = The workspace where the resources are being unpublished
+
+PublishWizardPublishTitle = Publish
+PublishWizardUnpublishTitle = Unpublish
+
+ServerPageAuthenticationGroupTitle = Authentication
+ServerPageInvalidServerProperties = Cannot construct a server because all server properties are not valid
+ServerPageOkStatusMsg = Define the server information where the DNA repositories are located.
+ServerPagePasswordLabel = Password:
+ServerPagePasswordToolTip = The password used to authenticate the user when connecting to the server
+ServerPageSavePasswordButton = Save password
+ServerPageSavePasswordLabel = Saved secret data is stored on your computer in a file that's difficult, but not impossible, for an intruder to read.
+ServerPageSavePasswordToolTip = Indicates if the clear text password should be stored on the local file system
+ServerPageTitle = Enter Server Information
+ServerPageUrlLabel = URL:
+ServerPageUrlToolTip = The URL used to connect to the server
+ServerPageUserLabel = User:
+ServerPageUserToolTip = The user login used when connecting to the server
+
+ServerWizardEditServerTitle = Edit Server
+ServerWizardNewServerTitle = New Server
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/i18n.properties
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/views/RepositoryContentProvider.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/views/RepositoryContentProvider.java (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/views/RepositoryContentProvider.java 2009-06-23 18:44:56 UTC (rev 1062)
@@ -0,0 +1,184 @@
+/*
+ * 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.publish.ui.swt.views;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.graphics.Image;
+import org.jboss.dna.publish.domain.IDnaObject;
+import org.jboss.dna.publish.ui.swt.Activator;
+
+/**
+ * The RepositoryContentProvider is a content and label provider for DNA repositories.
+ *
+ * @author Dan Florian
+ * @since 0.6
+ */
+public final class RepositoryContentProvider implements ITreeContentProvider, ILabelProvider {
+
+ // ===========================================================================================================================
+ // Methods
+ // ===========================================================================================================================
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener)
+ * @since 0.6
+ */
+ @Override
+ public void addListener( ILabelProviderListener listener ) {
+ // nothing to do
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+ * @since 0.6
+ */
+ @Override
+ public void dispose() {
+ // nothing to do
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
+ * @since 0.6
+ */
+ @Override
+ public Object[] getChildren( Object parentElement ) {
+ if (parentElement instanceof IDnaObject) {
+ return ((IDnaObject)parentElement).getChildren().toArray();
+ }
+
+ // should not happen
+ assert false;
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+ * @since 0.6
+ */
+ @Override
+ public Object[] getElements( Object inputElement ) {
+ return Activator.getDefault().getServerManager().getServers().toArray();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
+ * @since 0.6
+ */
+ @Override
+ public Image getImage( Object element ) {
+ return Activator.getDefault().getImage(element);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
+ * @since 0.6
+ */
+ @Override
+ public Object getParent( Object element ) {
+ if (element instanceof IDnaObject) {
+ return ((IDnaObject)element).getParent();
+ }
+
+ // should not happen
+ assert false;
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
+ * @since 0.6
+ */
+ @Override
+ public String getText( Object element ) {
+ assert (element instanceof IDnaObject);
+ return ((IDnaObject)element).getName();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
+ * @since 0.6
+ */
+ @Override
+ public boolean hasChildren( Object element ) {
+ return getChildren(element).length > 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object,
+ * java.lang.Object)
+ * @since 0.6
+ */
+ @Override
+ public void inputChanged( Viewer viewer,
+ Object oldInput,
+ Object newInput ) {
+ // nothing to do
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object, java.lang.String)
+ * @since 0.6
+ */
+ @Override
+ public boolean isLabelProperty( Object element,
+ String property ) {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener)
+ * @since 0.6
+ */
+ @Override
+ public void removeListener( ILabelProviderListener listener ) {
+ // nothing to do
+ }
+
+}
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/views/RepositoryContentProvider.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/views/RepositoryView.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/views/RepositoryView.java (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/views/RepositoryView.java 2009-06-23 18:44:56 UTC (rev 1062)
@@ -0,0 +1,257 @@
+/*
+ * 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.publish.ui.swt.views;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.ui.part.ViewPart;
+import org.jboss.dna.publish.domain.IDnaObject;
+import org.jboss.dna.publish.domain.Server;
+import org.jboss.dna.publish.ui.swt.I18n;
+
+/**
+ * The RepositoryView shows all defined servers and their DNA repositories.
+ *
+ * @author Dan Florian
+ * @since 0.6
+ */
+public final class RepositoryView extends ViewPart {
+
+ // ===========================================================================================================================
+ // Fields
+ // ===========================================================================================================================
+
+ /**
+ * Collapses all tree nodes.
+ *
+ * @since 0.6
+ */
+ private IAction collapseAllAction;
+
+ /**
+ * Deletes a server.
+ *
+ * @since 0.6
+ */
+ private IAction deleteAction;
+
+ /**
+ * Edits a server's properties.
+ *
+ * @since 0.6
+ */
+ private IAction editAction;
+
+ /**
+ * Creates a new server.
+ *
+ * @since 0.6
+ */
+ private IAction newAction;
+
+ /**
+ * The viewer's content and label provider.
+ *
+ * @since 0.6
+ */
+ private RepositoryContentProvider provider;
+
+ /**
+ * @since 0.6
+ */
+ private TreeViewer viewer;
+
+ // ===========================================================================================================================
+ // Methods
+ // ===========================================================================================================================
+
+ /**
+ * @since 0.6
+ */
+ private void constructActions() {
+ // the collapse all action is always enabled
+ this.collapseAllAction = new Action() {
+ @Override
+ public void run() {
+ getViewer().collapseAll();
+ }
+ };
+
+ this.collapseAllAction.setToolTipText(I18n.CollapseActionToolTip);
+ this.collapseAllAction.setImageDescriptor(null);
+
+ // the delete action will delete one or more servers
+ this.deleteAction = null;
+ this.deleteAction.setText(I18n.DeleteServerActionText);
+ this.deleteAction.setToolTipText(I18n.DeleteServerActionToolTip);
+ this.deleteAction.setImageDescriptor(null);
+ this.deleteAction.setEnabled(false);
+
+ // the edit action is only enabled when one server is selected
+ this.editAction = null;
+ this.editAction.setText(I18n.EditServerActionText);
+ this.editAction.setToolTipText(I18n.EditServerActionToolTip);
+ this.editAction.setImageDescriptor(null);
+ this.editAction.setEnabled(false);
+
+ // the new server action is always enabled
+ this.newAction = null;
+ this.newAction.setText(I18n.NewServerActionText);
+ this.newAction.setToolTipText(I18n.NewServerActionToolTip);
+ this.newAction.setImageDescriptor(null);
+ }
+
+ /**
+ * @since 0.6
+ */
+ private void constructContextMenu() {
+ MenuManager menuMgr = new MenuManager();
+ menuMgr.add(this.newAction);
+ menuMgr.add(this.editAction);
+ menuMgr.add(this.deleteAction);
+ // menuMgr.setRemoveAllWhenShown(true);
+
+ Menu menu = menuMgr.createContextMenu(this.viewer.getTree());
+ this.viewer.getTree().setMenu(menu);
+ getSite().registerContextMenu(menuMgr, this.viewer);
+ }
+
+ /**
+ * @since 0.6
+ */
+ private void constructToolBar() {
+ IToolBarManager toolBar = getViewSite().getActionBars().getToolBarManager();
+ toolBar.add(this.newAction);
+ toolBar.add(this.editAction);
+ toolBar.add(this.deleteAction);
+ toolBar.add(this.collapseAllAction);
+ }
+
+ /**
+ * @param parent the viewer's parent
+ * @since 0.6
+ */
+ private void constructTreeViewer( Composite parent ) {
+ this.provider = new RepositoryContentProvider();
+ this.viewer = new TreeViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL);
+ this.viewer.setContentProvider(this.provider);
+ this.viewer.setLabelProvider(this.provider);
+ this.viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
+ */
+ @Override
+ public void selectionChanged( SelectionChangedEvent event ) {
+ handleSelectionChanged(event);
+ }
+ });
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
+ * @since 0.6
+ */
+ @Override
+ public void createPartControl( Composite parent ) {
+ constructTreeViewer(parent);
+ constructActions();
+ constructToolBar();
+ constructContextMenu();
+ }
+
+ /**
+ * @return the tree viewer
+ * @since 0.6
+ */
+ TreeViewer getViewer() {
+ return this.viewer;
+ }
+
+ /**
+ * @param event the event being processed
+ * @since 0.6
+ */
+ void handleSelectionChanged( SelectionChangedEvent event ) {
+ IStructuredSelection selection = (IStructuredSelection)event.getSelection();
+ updateStatusLine(selection);
+ updateActionBars(selection);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
+ * @since 0.6
+ */
+ @Override
+ public void setFocus() {
+ if (!this.viewer.getControl().isDisposed()) {
+ this.viewer.getControl().setFocus();
+ }
+ }
+
+ /**
+ * @param selection the current viewer selection (never <code>null</code>)
+ * @since 0.6
+ */
+ private void updateActionBars( IStructuredSelection selection ) {
+ if (selection.isEmpty()) {
+ this.deleteAction.setEnabled(false);
+ this.editAction.setEnabled(false);
+ } else {
+ assert (selection.size() == 1);
+
+ IDnaObject obj = (IDnaObject)selection.getFirstElement();
+ boolean enable = (obj instanceof Server);
+ this.deleteAction.setEnabled(enable);
+ this.editAction.setEnabled(enable);
+ }
+ }
+
+ /**
+ * @param selection the current viewer selection (never <code>null</code>)
+ * @since 0.6
+ */
+ private void updateStatusLine( IStructuredSelection selection ) {
+ assert (selection.size() < 2);
+
+ String msg = (selection.isEmpty() ? "" : ((IDnaObject)selection.getFirstElement()).getShortDescription()); //$NON-NLS-1$
+ getViewSite().getActionBars().getStatusLineManager().setMessage(msg);
+ }
+
+}
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/views/RepositoryView.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/PublishPage.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/PublishPage.java (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/PublishPage.java 2009-06-23 18:44:56 UTC (rev 1062)
@@ -0,0 +1,415 @@
+/*
+ * 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.publish.ui.swt.wizards;
+
+import java.util.List;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.jboss.dna.publish.Status;
+import org.jboss.dna.publish.Status.Severity;
+import org.jboss.dna.publish.ui.swt.I18n;
+import org.jboss.dna.publish.ui.swt.wizards.PublishWizard.Type;
+
+/**
+ * @author Dan Florian
+ * @since 0.6
+ */
+public final class PublishPage extends WizardPage implements ModifyListener {
+
+ // ===========================================================================================================================
+ // Fields
+ // ===========================================================================================================================
+
+ /**
+ * The repository control.
+ *
+ * @since 0.6
+ */
+ private Combo cbxRepository;
+
+ /**
+ * The server control.
+ *
+ * @since 0.6
+ */
+ private Combo cbxServer;
+
+ /**
+ * The workspace control.
+ *
+ * @since 0.6
+ */
+ private Combo cbxWorkspace;
+
+ /**
+ * Indicates if the resources are being published or unpublished.
+ *
+ * @since 0.6
+ */
+ private final Type type;
+
+ /**
+ * The repository where the workspace is located.
+ *
+ * @since 0.6
+ */
+ private String repository;
+
+ /**
+ * The server where the repository is located.
+ *
+ * @since 0.6
+ */
+ private String server;
+
+ /**
+ * The workspace where the resources are being published/unpublished.
+ *
+ * @since 0.6
+ */
+ private String workspace;
+
+ /**
+ * The collection of resources being published/unpublished.
+ *
+ * @since 0.6
+ */
+ private final List<IResource> resources;
+
+ /**
+ * The current validation status.
+ *
+ * @since 0.6
+ */
+ private Status status;
+
+ // ===========================================================================================================================
+ // Constructors
+ // ===========================================================================================================================
+
+ /**
+ * @param type the publish or unpublish indicator
+ * @param resources the resources being published or unpublished (never <code>null</code>)
+ * @since 0.6
+ */
+ public PublishPage( Type type,
+ List<IResource> resources ) {
+ super(PublishPage.class.getSimpleName());
+ setTitle((type == Type.PUBLISH) ? I18n.PublishPagePublishTitle : I18n.PublishPageUnpublishTitle);
+
+ this.type = type;
+ this.resources = resources;
+ }
+
+ // ===========================================================================================================================
+ // Methods
+ // ===========================================================================================================================
+
+ private void constructLocationPanel( Composite parent ) {
+ Group pnl = new Group(parent, SWT.NONE);
+ pnl.setText(I18n.PublishPageLocationGroupTitle);
+ pnl.setLayout(new GridLayout(2, false));
+ pnl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+
+ { // server row
+ Label lblServer = new Label(pnl, SWT.LEFT);
+ lblServer.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
+ lblServer.setText(I18n.PublishPageServerLabel);
+
+ this.cbxServer = new Combo(pnl, SWT.DROP_DOWN | SWT.READ_ONLY);
+ this.cbxServer.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ this.cbxServer.setToolTipText(I18n.PublishPageServerToolTip);
+ }
+
+ { // repository row
+ Label lblRepository = new Label(pnl, SWT.LEFT);
+ lblRepository.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
+ lblRepository.setText(I18n.PublishPageRepositoryLabel);
+
+ this.cbxRepository = new Combo(pnl, SWT.DROP_DOWN | SWT.READ_ONLY);
+ this.cbxRepository.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ this.cbxRepository.setToolTipText(I18n.PublishPageRepositoryToolTip);
+ }
+
+ { // workspace row
+ Label lblWorkspace = new Label(pnl, SWT.LEFT);
+ lblWorkspace.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
+ lblWorkspace.setText(I18n.PublishPageWorkspaceLabel);
+
+ this.cbxWorkspace = new Combo(pnl, SWT.DROP_DOWN | SWT.READ_ONLY);
+ this.cbxWorkspace.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+
+ if (type == Type.PUBLISH) {
+ this.cbxWorkspace.setToolTipText(I18n.PublishPageWorkspacePublishToolTip);
+ } else {
+ this.cbxWorkspace.setToolTipText(I18n.PublishPageWorkspaceUnpublishToolTip);
+ }
+ }
+ }
+
+ private void constructResourcesPanel( Composite parent ) {
+ Composite pnl = new Composite(parent, SWT.NONE);
+ pnl.setLayout(new GridLayout());
+ pnl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ Label lbl = new Label(pnl, SWT.LEFT);
+ lbl.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
+
+ if (type == Type.PUBLISH) {
+ lbl.setText(I18n.PublishPagePublishResourcesLabel);
+ } else {
+ lbl.setText(I18n.PublishPageUnpublishResourcesLabel);
+ }
+
+ org.eclipse.swt.widgets.List lstResources = new org.eclipse.swt.widgets.List(pnl, SWT.BORDER | SWT.H_SCROLL
+ | SWT.V_SCROLL);
+ lstResources.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ // set initial value
+ // TODO implement load resources
+ String[] data = new String[20];
+ for (int i = 0; i < 20; ++i) data[i] = "my/resource" + i + ".xmi"; //$NON-NLS-1$ //$NON-NLS-2$
+ lstResources.setItems(data);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ public void createControl( Composite parent ) {
+ Composite pnlMain = new Composite(parent, SWT.NONE);
+ pnlMain.setLayout(new GridLayout());
+ pnlMain.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+ constructLocationPanel(pnlMain);
+ constructResourcesPanel(pnlMain);
+ setControl(pnlMain);
+
+ loadServers();
+ installLocationListeners();
+ }
+
+ /**
+ * Handler for when the repository control value is modified
+ *
+ * @since 0.6
+ */
+ void handleRepositoryModified() {
+ this.repository = this.cbxRepository.getText();
+ this.workspace = null;
+
+ // clear loaded workspaces
+ uninstallLocationListeners();
+ this.cbxWorkspace.removeAll();
+ reloadWorkspaces();
+ installLocationListeners();
+
+ updateState();
+ }
+
+ /**
+ * Handler for when the server control value is modified
+ *
+ * @since 0.6
+ */
+ void handleServerModified() {
+ this.server = this.cbxServer.getText();
+ this.repository = null;
+ this.workspace = null;
+
+ // clear loaded repositories and workspaces
+ uninstallLocationListeners();
+ this.cbxRepository.removeAll();
+ this.cbxWorkspace.removeAll();
+ reloadRepositories();
+ installLocationListeners();
+
+ updateState();
+ }
+
+ /**
+ * Handler for when the workspace control value is modified
+ *
+ * @since 0.6
+ */
+ void handleWorkspaceModified() {
+ this.workspace = this.cbxWorkspace.getText();
+ updateState();
+ }
+
+ /**
+ * Installs the combobox listeners.
+ *
+ * @since 0.6
+ */
+ private void installLocationListeners() {
+ this.cbxRepository.addModifyListener(this);
+ this.cbxServer.addModifyListener(this);
+ this.cbxWorkspace.addModifyListener(this);
+ }
+
+ private void loadServers() {
+ // TODO implement loadServers()
+ String[] data = new String[20];
+ for (int i = 0; i < 20; ++i) data[i] = "server" + i; //$NON-NLS-1$
+ this.cbxServer.setItems(data);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent)
+ */
+ @Override
+ public void modifyText( ModifyEvent e ) {
+ if (e.widget == this.cbxServer) {
+ handleServerModified();
+ } else if (e.widget == this.cbxRepository) {
+ handleRepositoryModified();
+ } else if (e.widget == this.cbxRepository) {
+ handleWorkspaceModified();
+ } else {
+ // should not happen
+ // TODO log
+ }
+ }
+
+ /**
+ * Reloads the repository combobox based on the newly selected server.
+ *
+ * @since 0.6
+ */
+ private void reloadRepositories() {
+ // TODO implement reloadRepositories()
+ // if only one repository set it on the combobox
+ // if no repositories ???
+ }
+
+ /**
+ * Reloads the repository combobox based on the newly selected server.
+ *
+ * @since 0.6
+ */
+ private void reloadWorkspaces() {
+ // TODO implement reloadRepositories()
+ // if only one workspace set it on the combobox
+ // if no workspaces ???
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.dialogs.DialogPage#setVisible(boolean)
+ * @since 0.6
+ */
+ @Override
+ public void setVisible( boolean visible ) {
+ super.setVisible(visible);
+
+ if (visible) {
+ // set initial state
+ validate();
+
+ // set initial message
+ setMessage((type == Type.PUBLISH) ? I18n.PublishPagePublishOkStatusMsg : I18n.PublishPageUnpublishOkStatusMsg);
+ }
+ }
+
+ /**
+ * Uninstalls the combobox listeners.
+ *
+ * @since 0.6
+ */
+ private void uninstallLocationListeners() {
+ this.cbxRepository.removeModifyListener(this);
+ this.cbxServer.removeModifyListener(this);
+ this.cbxWorkspace.removeModifyListener(this);
+ }
+
+ /**
+ * Updates message, message icon, and OK button enablement based on validation results
+ *
+ * @since 0.6
+ */
+ private void updateState() {
+ // get the current state
+ validate();
+
+ // update OK/Finish button enablement
+ setPageComplete(!this.status.isError());
+
+ // update page message
+ if (this.status.isError()) {
+ setMessage(this.status.getMessage(), IMessageProvider.ERROR);
+ } else {
+ if (this.status.isWarning()) {
+ setMessage(this.status.getMessage(), IMessageProvider.WARNING);
+ } else if (this.status.isInfo()) {
+ setMessage(this.status.getMessage(), IMessageProvider.INFORMATION);
+ } else {
+ setMessage(I18n.ServerPageOkStatusMsg);
+ }
+ }
+ }
+
+ /**
+ * Validates all inputs and sets the validation status.
+ *
+ * @since 0.6
+ */
+ private void validate() {
+ String msg = null;
+ Severity severity = Severity.ERROR;
+
+ if (this.resources != null && this.resources.isEmpty()) {
+ // should not happen since action should not enable if nothing selected
+ msg = I18n.PublishPageNoResourcesStatusMsg;
+ } else if (this.server == null) {
+ int count = this.cbxServer.getItemCount();
+ msg = ((count == 0) ? I18n.PublishPageNoAvailableServersStatusMsg : I18n.PublishPageMissingServerStatusMsg);
+ } else if (this.repository == null) {
+ int count = this.cbxRepository.getItemCount();
+ msg = ((count == 0) ? I18n.PublishPageNoAvailableRepositoriesStatusMsg : I18n.PublishPageMissingRepositoryStatusMsg);
+ } else if (this.workspace == null) {
+ int count = this.cbxServer.getItemCount();
+ msg = ((count == 0) ? I18n.PublishPageNoAvailableWorkspacesStatusMsg : I18n.PublishPageMissingWorkspaceStatusMsg);
+ } else {
+ severity = Severity.OK;
+ msg = ((type == Type.PUBLISH) ? I18n.PublishPagePublishOkStatusMsg : I18n.PublishPageUnpublishOkStatusMsg);
+ }
+
+ this.status = new Status(severity, msg, null);
+ }
+}
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/PublishPage.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/PublishWizard.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/PublishWizard.java (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/PublishWizard.java 2009-06-23 18:44:56 UTC (rev 1062)
@@ -0,0 +1,160 @@
+/*
+ * 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.publish.ui.swt.wizards;
+
+import java.util.List;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.jboss.dna.publish.ServerManager;
+import org.jboss.dna.publish.ui.swt.I18n;
+
+/**
+ * @author Dan Florian
+ * @since 0.6
+ */
+public final class PublishWizard extends Wizard {
+
+ // ===========================================================================================================================
+ // Constants
+ // ===========================================================================================================================
+
+ /**
+ * The wizard type.
+ *
+ * @since 0.6
+ */
+ public enum Type {
+ /**
+ * Indicates the wizard will be used to publish.
+ *
+ * @since 0.6
+ */
+ PUBLISH,
+
+ /**
+ * Indicates the wizard will be used to unpublish.
+ *
+ * @since 0.6
+ */
+ UNPUBLISH
+ }
+
+ // ===========================================================================================================================
+ // Fields
+ // ===========================================================================================================================
+
+ /**
+ * The wizard page containing all the controls that allow publishing/unpublishing of resources.
+ *
+ * @since 0.6
+ */
+ private final PublishPage page;
+
+ /**
+ * The manager in charge of the server registry.
+ *
+ * @since 0.6
+ */
+ private final ServerManager serverManager;
+
+ // ===========================================================================================================================
+ // Constructors
+ // ===========================================================================================================================
+
+ /**
+ * @param type the publishing or unpublishing indicator
+ * @param resources the resources being published or unpublished (never <code>null</code>)
+ * @param serverManager the server manager in charge of the server registry (never <code>null</code>)
+ * @since 0.6
+ */
+ public PublishWizard( Type type,
+ List<IResource> resources,
+ ServerManager serverManager ) {
+ this.page = new PublishPage(type, resources);
+ this.serverManager = serverManager;
+ setWindowTitle((type == Type.PUBLISH) ? I18n.PublishWizardPublishTitle : I18n.PublishWizardUnpublishTitle);
+ }
+
+ // ===========================================================================================================================
+ // Methods
+ // ===========================================================================================================================
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.wizard.Wizard#addPages()
+ * @since 0.6
+ */
+ @Override
+ public void addPages() {
+ addPage(this.page);
+ }
+
+ /**
+ * @return the server manager (never <code>null</code>)
+ * @since 0.6
+ */
+ protected ServerManager getServerManager() {
+ return this.serverManager;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.wizard.Wizard#performFinish()
+ * @since 0.6
+ */
+ @Override
+ public boolean performFinish() {
+ // TODO implement performFinish()
+ // Status status = null;
+ return true; //!status.isError();
+ }
+
+ // ===========================================================================================================================
+ // Test UI
+ // ===========================================================================================================================
+
+ public static void main( String[] args ) {
+ Display display = new Display();
+
+ Shell shell = new Shell(display);
+ shell.setText("Shell"); //$NON-NLS-1$
+ shell.setSize(200, 200);
+ shell.open();
+
+ WizardDialog dialog = new WizardDialog(shell, new PublishWizard(Type.PUBLISH, null, new ServerManager("/home/dan"))); //$NON-NLS-1$
+ dialog.open();
+
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch()) display.sleep();
+ }
+
+ display.dispose();
+ }
+
+}
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/PublishWizard.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/ServerPage.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/ServerPage.java (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/ServerPage.java 2009-06-23 18:44:56 UTC (rev 1062)
@@ -0,0 +1,334 @@
+/*
+ * 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.publish.ui.swt.wizards;
+
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.jboss.dna.publish.ServerManager;
+import org.jboss.dna.publish.Status;
+import org.jboss.dna.publish.domain.Server;
+import org.jboss.dna.publish.domain.validation.ServerValidator;
+import org.jboss.dna.publish.ui.swt.I18n;
+
+/**
+ * @author Dan Florian
+ * @since 0.6
+ */
+public final class ServerPage extends WizardPage {
+
+ // ===========================================================================================================================
+ // Fields
+ // ===========================================================================================================================
+
+ /**
+ * The user password needed to login to the server.
+ *
+ * @since 0.6
+ */
+ private String password;
+
+ /**
+ * The current validation status.
+ *
+ * @since 0.6
+ */
+ private Status status;
+
+ /**
+ * The server URL.
+ *
+ * @since 0.6
+ */
+ private String url;
+
+ /**
+ * The user needed to login to the server.
+ *
+ * @since 0.6
+ */
+ private String user;
+
+ // ===========================================================================================================================
+ // Constructors
+ // ===========================================================================================================================
+
+ public ServerPage() {
+ super(ServerPage.class.getSimpleName());
+ setTitle(I18n.ServerPageTitle);
+ }
+
+ public ServerPage( Server server ) {
+ super(ServerPage.class.getSimpleName());
+ setTitle(I18n.ServerPageTitle);
+
+ this.url = server.getUrl();
+ this.user = server.getUser();
+ this.password = server.getPassword();
+ }
+
+ // ===========================================================================================================================
+ // Methods
+ // ===========================================================================================================================
+
+ private void constructAuthenticationPanel( Composite parent ) {
+ Group pnl = new Group(parent, SWT.NONE);
+ pnl.setText(I18n.ServerPageAuthenticationGroupTitle);
+ pnl.setLayout(new GridLayout(2, false));
+ pnl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+
+ { // user row
+ Label lblUser = new Label(pnl, SWT.LEFT);
+ lblUser.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
+ lblUser.setText(I18n.ServerPageUserLabel);
+
+ Text txtUser = new Text(pnl, SWT.BORDER);
+ txtUser.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ txtUser.setToolTipText(I18n.ServerPageUserToolTip);
+
+ // set initial value
+ if (this.user != null) {
+ txtUser.setText(this.user);
+ }
+
+ txtUser.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText( ModifyEvent e ) {
+ handleUserModified(((Text)e.widget).getText());
+ }
+ });
+ }
+
+ { // password row
+ Label lblPassword = new Label(pnl, SWT.LEFT);
+ lblPassword.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
+ lblPassword.setText(I18n.ServerPagePasswordLabel);
+
+ Text txtPassword = new Text(pnl, SWT.BORDER);
+ txtPassword.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+ txtPassword.setToolTipText(I18n.ServerPagePasswordToolTip);
+ txtPassword.setEchoChar('*');
+
+ // set initial value
+ if (this.password != null) {
+ txtPassword.setText(this.password);
+ }
+
+ txtPassword.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText( ModifyEvent e ) {
+ handlePasswordModified(((Text)e.widget).getText());
+ }
+ });
+ }
+
+ { // save button row
+ Button btn = new Button(pnl, SWT.CHECK | SWT.LEFT);
+ btn.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
+ ((GridData)btn.getLayoutData()).horizontalSpan = 2;
+ btn.setText(I18n.ServerPageSavePasswordButton);
+ btn.setToolTipText(I18n.ServerPageSavePasswordToolTip);
+ }
+
+ { // save password message row
+ Label lblImage = new Label(pnl, SWT.NONE);
+ lblImage.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
+ lblImage.setImage(Display.getDefault().getSystemImage(SWT.ICON_INFORMATION));
+
+ StyledText st = new StyledText(pnl, SWT.READ_ONLY | SWT.MULTI | SWT.NO_FOCUS | SWT.WRAP);
+ st.setText(I18n.ServerPageSavePasswordLabel);
+ st.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
+ st.setCaret(null);
+ GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, true);
+ gd.grabExcessVerticalSpace = false;
+ gd.horizontalIndent = 4;
+ gd.verticalIndent = 8;
+ gd.widthHint = 100;
+ st.setLayoutData(gd);
+ }
+ }
+
+ private void constructUrlPanel( Composite parent ) {
+ Composite pnl = new Composite(parent, SWT.NONE);
+ pnl.setLayout(new GridLayout(2, false));
+ pnl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+
+ Label lblUrl = new Label(pnl, SWT.LEFT);
+ lblUrl.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
+ lblUrl.setText(I18n.ServerPageUrlLabel);
+
+ Text txtUrl = new Text(pnl, SWT.BORDER);
+ txtUrl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+ txtUrl.setToolTipText(I18n.ServerPageUrlToolTip);
+
+ // set initial value
+ if (this.url != null) {
+ txtUrl.setText(this.url);
+ }
+
+ txtUrl.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText( ModifyEvent e ) {
+ handleUrlModified(((Text)e.widget).getText());
+ }
+ });
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ public void createControl( Composite parent ) {
+ Composite pnlMain = new Composite(parent, SWT.NONE);
+ pnlMain.setLayout(new GridLayout());
+ pnlMain.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+ constructUrlPanel(pnlMain);
+ constructAuthenticationPanel(pnlMain);
+ setControl(pnlMain);
+ }
+
+ /**
+ * @return the server represented by the dialog inputs
+ * @throws RuntimeException if called when all inputs are not valid
+ * @see #isPageComplete()
+ * @since 0.6
+ */
+ public Server getServer() {
+ if (!this.status.isError()) {
+ return new Server(this.url, this.user, this.password);
+ }
+
+ // should never be called if error status
+ throw new RuntimeException(I18n.ServerPageInvalidServerProperties);
+ }
+
+ /**
+ * @return the server manager obtained from the wizard
+ * @since 0.6
+ */
+ private ServerManager getServerManager() {
+ return ((ServerWizard)getWizard()).getServerManager();
+ }
+
+ /**
+ * Handler for when the password control value is modified
+ *
+ * @param newPassword the new password value
+ * @since 0.6
+ */
+ void handlePasswordModified( String newPassword ) {
+ this.password = newPassword;
+ updateState();
+ }
+
+ /**
+ * Handler for when the URL control value is modified
+ *
+ * @param newUrl the new URL value
+ * @since 0.6
+ */
+ void handleUrlModified( String newUrl ) {
+ this.url = newUrl;
+ updateState();
+ }
+
+ /**
+ * Handler for when the user control value is modified
+ *
+ * @param newUser the new user value
+ * @since 0.6
+ */
+ void handleUserModified( String newUser ) {
+ this.user = newUser;
+ updateState();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.dialogs.DialogPage#setVisible(boolean)
+ * @since 0.6
+ */
+ @Override
+ public void setVisible( boolean visible ) {
+ super.setVisible(visible);
+
+ if (visible) {
+ // set initial state
+ validate();
+
+ // set initial message
+ setMessage(I18n.ServerPageOkStatusMsg);
+ }
+ }
+
+ /**
+ * Updates message, message icon, and OK button enablement based on validation results
+ *
+ * @since 0.6
+ */
+ private void updateState() {
+ // get the current status
+ validate();
+
+ // update OK/Finish button enablement
+ setPageComplete(!this.status.isError());
+
+ // update message
+ if (this.status.isError()) {
+ setMessage(this.status.getMessage(), IMessageProvider.ERROR);
+ } else {
+ if (this.status.isWarning()) {
+ setMessage(this.status.getMessage(), IMessageProvider.WARNING);
+ } else if (this.status.isInfo()) {
+ setMessage(this.status.getMessage(), IMessageProvider.INFORMATION);
+ } else {
+ setMessage(I18n.ServerPageOkStatusMsg);
+ }
+ }
+ }
+
+ /**
+ * Validates all inputs and sets the validation status.
+ *
+ * @since 0.6
+ */
+ private void validate() {
+ this.status = ServerValidator.isValid(this.url, this.user, this.password, getServerManager());
+ }
+
+}
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/ServerPage.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/ServerWizard.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/ServerWizard.java (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/ServerWizard.java 2009-06-23 18:44:56 UTC (rev 1062)
@@ -0,0 +1,144 @@
+/*
+ * 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.publish.ui.swt.wizards;
+
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.jboss.dna.publish.ServerManager;
+import org.jboss.dna.publish.Status;
+import org.jboss.dna.publish.domain.Server;
+import org.jboss.dna.publish.ui.swt.I18n;
+
+/**
+ * @author Dan Florian
+ * @since 0.6
+ */
+public final class ServerWizard extends Wizard {
+
+ // ===========================================================================================================================
+ // Fields
+ // ===========================================================================================================================
+
+ /**
+ * The wizard page containing all the controls that allow editing of server properties.
+ *
+ * @since 0.6
+ */
+ private final ServerPage page;
+
+ /**
+ * The manager in charge of the server registry.
+ *
+ * @since 0.6
+ */
+ private final ServerManager serverManager;
+
+ // ===========================================================================================================================
+ // Constructors
+ // ===========================================================================================================================
+
+ /**
+ * @param serverManager the server manager in charge of the server registry (never <code>null</code>)
+ * @since 0.6
+ */
+ public ServerWizard( ServerManager serverManager ) {
+ this.page = new ServerPage();
+ this.serverManager = serverManager;
+ setWindowTitle(I18n.ServerWizardNewServerTitle);
+ }
+
+ /**
+ * @param serverManager the server manager in charge of the server registry (never <code>null</code>)
+ * @param server the server whose properties are being edited (never <code>null</code>)
+ * @since 0.6
+ */
+ public ServerWizard( ServerManager serverManager,
+ Server server ) {
+ this.page = new ServerPage(server);
+ this.serverManager = serverManager;
+ setWindowTitle(I18n.ServerWizardEditServerTitle);
+ }
+
+ // ===========================================================================================================================
+ // Methods
+ // ===========================================================================================================================
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.wizard.Wizard#addPages()
+ * @since 0.6
+ */
+ @Override
+ public void addPages() {
+ addPage(this.page);
+ }
+
+ /**
+ * @return the server manager (never <code>null</code>)
+ * @since 0.6
+ */
+ protected ServerManager getServerManager() {
+ return this.serverManager;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.wizard.Wizard#performFinish()
+ * @since 0.6
+ */
+ @Override
+ public boolean performFinish() {
+ Server server = this.page.getServer();
+ Status status = this.serverManager.addServer(server);
+ return !status.isError();
+ }
+
+ // ===========================================================================================================================
+ // Test UI
+ // ===========================================================================================================================
+
+ public static void main( String[] args ) {
+ Display display = new Display();
+
+ Shell shell = new Shell(display);
+ shell.setText("Shell"); //$NON-NLS-1$
+ shell.setSize(200, 200);
+ shell.open();
+
+ WizardDialog dialog = new WizardDialog(shell, new ServerWizard(new ServerManager("/home/dan"))); //$NON-NLS-1$
+// WizardDialog dialog = new WizardDialog(shell, new ServerWizard(new ServerManager("/home/dan"), new Server("file:", "user", null)));
+ dialog.open();
+
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch()) display.sleep();
+ }
+
+ display.dispose();
+ }
+
+}
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/publish/ui/swt/wizards/ServerWizard.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
14 years, 10 months
DNA SVN: r1060 - in branches/eclipse/org.jboss.dna.publish: META-INF and 7 other directories.
by dna-commits@lists.jboss.org
Author: elvisisking
Date: 2009-06-22 17:28:39 -0400 (Mon, 22 Jun 2009)
New Revision: 1060
Added:
branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Messages.properties
branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Publisher.java
branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Status.java
branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/validation/
branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/validation/RepositoryValidator.java
branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/validation/ServerValidator.java
branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/validation/WorkspaceValidator.java
Removed:
branches/eclipse/org.jboss.dna.publish/icons/
branches/eclipse/org.jboss.dna.publish/plugin.xml
branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Activator.java
branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/I18n.java
branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/actions/PublishAction.java
branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/actions/UnpublishAction.java
branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/i18n.properties
branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ui/IUiConstants.java
branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ui/UiUtil.java
branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ui/dialogs/DeleteServerDialog.java
branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ui/dialogs/ServerDialog.java
branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ui/views/RepositoryContentProvider.java
branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ui/views/RepositoryView.java
Modified:
branches/eclipse/org.jboss.dna.publish/META-INF/MANIFEST.MF
branches/eclipse/org.jboss.dna.publish/build.properties
branches/eclipse/org.jboss.dna.publish/plugin.properties
branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/IConstants.java
branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ServerManager.java
branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/Repository.java
branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/Server.java
branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/Workspace.java
Log:
Refactored UI code to new project.
Modified: branches/eclipse/org.jboss.dna.publish/META-INF/MANIFEST.MF
===================================================================
--- branches/eclipse/org.jboss.dna.publish/META-INF/MANIFEST.MF 2009-06-22 16:50:22 UTC (rev 1059)
+++ branches/eclipse/org.jboss.dna.publish/META-INF/MANIFEST.MF 2009-06-22 21:28:39 UTC (rev 1060)
@@ -3,13 +3,12 @@
Bundle-Name: %bundleName
Bundle-SymbolicName: org.jboss.dna.publish; singleton:=true
Bundle-Version: 1.0.0
-Bundle-Activator: org.jboss.dna.publish.Activator
Bundle-Vendor: %bundleVendor
-Require-Bundle: org.eclipse.ui,
- org.eclipse.core.runtime,
- org.eclipse.core.resources
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-ActivationPolicy: lazy
Bundle-Localization: plugin
Bundle-ClassPath: dnaPublish.jar,
jettison-1.1.jar
+Export-Package: org.jboss.dna.publish,
+ org.jboss.dna.publish.domain,
+ org.jboss.dna.publish.domain.validation
Modified: branches/eclipse/org.jboss.dna.publish/build.properties
===================================================================
--- branches/eclipse/org.jboss.dna.publish/build.properties 2009-06-22 16:50:22 UTC (rev 1059)
+++ branches/eclipse/org.jboss.dna.publish/build.properties 2009-06-22 21:28:39 UTC (rev 1060)
@@ -1,8 +1,6 @@
-bin.includes = plugin.xml,\
- META-INF/,\
+bin.includes = META-INF/,\
plugin.properties,\
jettison-1.1.jar,\
- icons/,\
dnaPublish.jar
jars.compile.order = dnaPublish.jar
src.includes = src/
Modified: branches/eclipse/org.jboss.dna.publish/plugin.properties
===================================================================
--- branches/eclipse/org.jboss.dna.publish/plugin.properties 2009-06-22 16:50:22 UTC (rev 1059)
+++ branches/eclipse/org.jboss.dna.publish/plugin.properties 2009-06-22 21:28:39 UTC (rev 1060)
@@ -23,8 +23,3 @@
#
bundleName = DNA Eclipse Publishing Plug-in
bundleVendor = Red Hat, Inc.
-contextMenu.label = DNA
-dnaCategory = DNA
-publishAction.label = Publish
-repositoryView = DNA Repositories
-unpublishAction.label = Unpublish
\ No newline at end of file
Deleted: branches/eclipse/org.jboss.dna.publish/plugin.xml
===================================================================
--- branches/eclipse/org.jboss.dna.publish/plugin.xml 2009-06-22 16:50:22 UTC (rev 1059)
+++ branches/eclipse/org.jboss.dna.publish/plugin.xml 2009-06-22 21:28:39 UTC (rev 1060)
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<?eclipse version="3.2"?>
-<plugin>
-
-<!-- Define the IResource object contribution actions to all popup menus -->
- <extension
- point="org.eclipse.ui.popupMenus">
- <objectContribution
- id="org.jboss.dna.publish.iresourcepopupmenucontribution"
- objectClass="org.eclipse.core.resources.IResource">
- <menu
- id="org.jboss.dna.publish.contextMenu"
- label="%contextMenu.label"
- path="additions">
- <separator
- name="group1">
- </separator>
- </menu>
-
- <!-- Unpublish action -->
- <action
- id="org.jboss.dna.publish.unpublishAction"
- label="%unpublishAction.label"
- class="org.jboss.dna.publish.actions.UnpublishAction"
- menubarPath="org.jboss.dna.publish.contextMenu/group1"
- enablesFor="*">
- </action>
-
- <!-- Publish action -->
- <action
- id="org.jboss.dna.publish.publishAction"
- label="%publishAction.label"
- class="org.jboss.dna.publish.actions.PublishAction"
- menubarPath="org.jboss.dna.publish.contextMenu/group1"
- enablesFor="*">
- </action>
- </objectContribution>
- </extension>
-
-<!-- View extensions -->
- <extension
- point="org.eclipse.ui.views">
- <category
- id="org.jboss.dna"
- name="%dnaCategory">
- </category>
-
- <!-- Repository view -->
- <view
- id="respositoryView"
- name="%repositoryView"
- category="org.jboss.dna"
- class="org.jboss.dna.publish.ui.views.RepositoryView"
- fastViewWidthRatio="0.25"
- icon="icons/full/cview16/repository.gif">
- </view>
- </extension>
-
-</plugin>
Deleted: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Activator.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Activator.java 2009-06-22 16:50:22 UTC (rev 1059)
+++ branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Activator.java 2009-06-22 21:28:39 UTC (rev 1060)
@@ -1,216 +0,0 @@
-/*
- * 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.publish;
-
-import static org.jboss.dna.publish.IConstants.PLUGIN_ID;
-import java.net.MalformedURLException;
-import java.net.URL;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.jface.resource.ImageRegistry;
-import org.eclipse.swt.SWTException;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.ui.plugin.AbstractUIPlugin;
-import org.osgi.framework.BundleContext;
-
-/**
- * The activator class controls the plug-in life cycle.
- *
- * @author Dan Florian
- * @since 0.6
- */
-public final class Activator extends AbstractUIPlugin {
-
- // ===========================================================================================================================
- // Class Fields
- // ===========================================================================================================================
-
- /**
- * The shared plugin instance.
- *
- * @since 0.6
- */
- private static Activator plugin;
-
- // ===========================================================================================================================
- // Class Methods
- // ===========================================================================================================================
-
- /**
- * @param key the relative path to the image file
- * @return the image descriptor or <code>null</code>
- * @since 0.6
- */
- private ImageDescriptor createImageDescriptor( String key ) {
- try {
- URL url = new URL(getBundle().getEntry("/").toString() + key); //$NON-NLS-1$
- ImageDescriptor descriptor = ImageDescriptor.createFromURL(url);
- ImageRegistry registry = getImageRegistry();
- registry.put(key, descriptor);
- return descriptor;
- } catch (final MalformedURLException e) {
- // TODO log this or return missing image
- return null;
- }
- }
-
- /**
- * @return the shared instance or <code>null</code> if bundle is not started
- * @since 0.6
- */
- public static Activator getDefault() {
- return plugin;
- }
-
- /**
- * @param path the path
- * @return the image descriptor for the image file at the given plug-in relative path
- * @since 0.6
- */
- public static ImageDescriptor getImageDescriptor( String path ) {
- return imageDescriptorFromPlugin(PLUGIN_ID, path);
- }
-
- /**
- * Retrieves the image associated with the specified key from the {@link org.eclipse.jface.resource.ImageRegistry image
- * registry}, creating the image and registering it if it doesn't already exist. A <code>null</code> key will cause the
- * missing image descriptor to be returned.
- *
- * @param relativePathToImage the relative path to the image to retrieve. This must be in the form of the path to the image
- * file relative to this plug-in's folder (can be <code>null</code>).
- * @return the image associated with the specified path or the default missing image
- * @since 0.6
- */
- public final Image getImage( String relativePathToImage ) {
- final ImageRegistry registry = getImageRegistry();
- Image img = registry.get(relativePathToImage);
-
- if (img != null) {
- return img;
- }
-
- // image has never been cached
- try {
- createImageDescriptor(relativePathToImage);
- img = registry.get(relativePathToImage);
- return (img != null ? img : ImageDescriptor.getMissingImageDescriptor().createImage());
- } catch (SWTException e) {
- // TODO log this or return missing image
- return null;
- }
- }
-
- // ===========================================================================================================================
- // Fields
- // ===========================================================================================================================
-
- /**
- * The server manager of this plugin.
- *
- * @since 0.6
- */
- private ServerManager serverMgr;
-
- // ===========================================================================================================================
- // Constructors
- // ===========================================================================================================================
-
- /**
- * Constructs the plugin activator.
- * <p>
- * Note: If this is called outside the OSGi framework you <strong>MUST</strong> also call {@link #initialize(String)}.
- *
- * @since 0.6
- * @see #initialize(String)
- */
- public Activator() {
- // nothing to do but wanted javadocs for the default constructor
- }
-
- // ===========================================================================================================================
- // Methods
- // ===========================================================================================================================
-
- /**
- * @return the {@link ServerManager Server Manager} or <code>null</code> if not plugin is not initialized
- * @see #initialize(String)
- * @since 0.6
- */
- public ServerManager getServerManager() {
- return this.serverMgr;
- }
-
- /**
- * Performs plugin initialization. One thing it does is initialize the {@link ServerManager}.
- * <p>
- * Note: This should <strong>ONLY</strong> be called when the OSGi framework is not running (i.e., {@link BundleContext bundle
- * context} is <code>null</code>).
- *
- * @since 0.6
- */
- public void initialize( String stateLocationPath ) {
- plugin = this;
- serverMgr = new ServerManager(stateLocationPath);
- }
-
- /**
- * {@inheritDoc}
- * <p>
- * When the OSGi framework is not running (i.e., <code>context</code> is <code>null</code>) you <strong>MUST</strong> also
- * call {@link #initialize(String)}.
- *
- * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
- * @since 0.6
- * @see #initialize(String)
- */
- @Override
- public void start( BundleContext context ) throws Exception {
- if (context != null) {
- super.start(context);
- initialize(plugin.getStateLocation().toFile().getAbsolutePath());
- }
- }
-
- /**
- * {@inheritDoc}
- * <p>
- * Also informs the {@link ServerManager} to shutdown.
- * <p>
- * Note: This can safely be called when the OSGi framework is not running (i.e., <code>context</code> is <code>null</code>).
- *
- * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
- * @since 0.6
- */
- @Override
- public void stop( BundleContext context ) throws Exception {
- serverMgr.saveState();
-
- if (context != null) {
- super.stop(context);
- }
-
- plugin = null;
- serverMgr = null;
- }
-
-}
Deleted: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/I18n.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/I18n.java 2009-06-22 16:50:22 UTC (rev 1059)
+++ branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/I18n.java 2009-06-22 21:28:39 UTC (rev 1060)
@@ -1,76 +0,0 @@
-/*
- * 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.publish;
-
-import org.eclipse.osgi.util.NLS;
-
-/**
- * The I18n class handles localization messages.
- *
- * @author Dan Florian
- * @since 0.6
- */
-public final class I18n extends NLS {
-
- public static String CollapseActionToolTip;
-
- public static String DeleteServerActionText;
- public static String DeleteServerActionToolTip;
-
- public static String DeleteServerDialogTitle;
- public static String DeleteServerDialogOneServerMessage;
- public static String DeleteServerDialogMultipleServersMessage;
-
- public static String EditServerActionText;
- public static String EditServerActionToolTip;
-
- public static String ServerDialogEditTitle;
- public static String ServerDialogNewTitle;
- public static String ServerDialogPasswordLabel;
- public static String ServerDialogSavePasswordButton;
- public static String ServerDialogSavePasswordLabel;
- public static String ServerDialogUserLabel;
- public static String ServerDialogUrlLabel;
-
- public static String NewServerActionText;
- public static String NewServerActionToolTip;
-
- public static String RepositoryInvalidNameMsg;
- public static String RepositoryInvalidServerMsg;
- public static String RepositoryShortDescription;
-
- public static String ServerShortDescription;
- public static String ServerInvalidPasswordMsg;
- public static String ServerInvalidUrlMsg;
- public static String ServerInvalidUserMsg;
-
- public static String WorkspaceInvalidNameMsg;
- public static String WorkspaceInvalidRepositoryMsg;
- public static String WorkspaceShortDescription;
-
- static {
- // load message bundle
- NLS.initializeMessages(I18n.class.getPackage() + "i18n", I18n.class); //$NON-NLS-1$
- }
-}
Modified: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/IConstants.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/IConstants.java 2009-06-22 16:50:22 UTC (rev 1059)
+++ branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/IConstants.java 2009-06-22 21:28:39 UTC (rev 1060)
@@ -1,12 +1,60 @@
+/*
+ * 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.publish;
+import java.util.ResourceBundle;
+
+/**
+ * @author Dan Florian
+ * @since 0.6
+ */
public interface IConstants {
+
+ ResourceBundle MESSAGES = ResourceBundle.getBundle(IConstants.class.getPackage().getName() + ".Messages"); //$NON-NLS-1$
+
+ String RemovingServerProblemMsg = "RemovingServerProblemMsg"; //$NON-NLS-1$
+
+ String RepositoryEmptyNameMsg = "RepositoryEmptyNameMsg"; //$NON-NLS-1$
+
+ String RepositoryNullServerMsg = "RepositoryNullServerMsg"; //$NON-NLS-1$
+
+ String RepositoryShortDescription = "RepositoryShortDescription"; //$NON-NLS-1$
+
+ String ServerEmptyUrlMsg = "ServerEmptyUrlMsg"; //$NON-NLS-1$
+
+ String ServerInvalidUrlMsg = "ServerInvalidUrlMsg"; //$NON-NLS-1$
+
+ String ServerEmptyUserMsg = "ServerEmptyUserMsg"; //$NON-NLS-1$
+
+ String ServerExistsMsg = "ServerExistsMsg"; //$NON-NLS-1$
+
+ String ServerShortDescription = "ServerShortDescription"; //$NON-NLS-1$
+
+ String WorkspaceEmptyNameMsg = "WorkspaceEmptyNameMsg"; //$NON-NLS-1$
+
+ String WorkspaceNullRepositoryMsg = "WorkspaceNullRepositoryMsg"; //$NON-NLS-1$
+
+ String WorkspaceShortDescription = "WorkspaceShortDescription"; //$NON-NLS-1$
- /**
- * The Plug-in's identifier.
- *
- * @since 0.6
- */
- public static final String PLUGIN_ID = "org.jboss.dna.publish"; //$NON-NLS-1$
-
}
Added: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Messages.properties
===================================================================
--- branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Messages.properties (rev 0)
+++ branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Messages.properties 2009-06-22 21:28:39 UTC (rev 1060)
@@ -0,0 +1,15 @@
+RemovingServerProblemMsg = {0} cannot be removed as it has not been registered
+
+RepositoryEmptyNameMsg = A repository name cannot be empty
+RepositoryNullServerMsg = A repository server cannot be null
+RepositoryShortDescription = DNA Repository: Name: {0}, {1}
+
+ServerEmptyUserMsg = The user cannot be empty
+ServerEmptyUrlMsg = A server URL cannot be empty
+ServerExistsMsg = {0} already exists so it cannot be added
+ServerInvalidUrlMsg = The value "{0}" is not a valid server URL
+ServerShortDescription = DNA Server: URL={0} User={1}
+
+WorkspaceEmptyNameMsg = A workspace name cannot be empty
+WorkspaceNullRepositoryMsg = A workspace repository cannot be null
+WorkspaceShortDescription = DNA Repository Workspace: Name: {0}, {1}
Property changes on: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Messages.properties
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Publisher.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Publisher.java (rev 0)
+++ branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Publisher.java 2009-06-22 21:28:39 UTC (rev 1060)
@@ -0,0 +1,48 @@
+/*
+ * 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.publish;
+
+import java.io.File;
+import java.util.Collection;
+import org.jboss.dna.publish.domain.Server;
+
+/**
+ * @author Dan Florian
+ * @since 0.6
+ */
+public class Publisher {
+
+ public Status publish( Server server,
+ Collection<File> files ) {
+ // TODO implement
+ return null;
+ }
+
+ public Status unpublish( Server server,
+ Collection<File> files ) {
+ // TODO implement
+ return null;
+ }
+
+}
Property changes on: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Publisher.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ServerManager.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ServerManager.java 2009-06-22 16:50:22 UTC (rev 1059)
+++ branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ServerManager.java 2009-06-22 21:28:39 UTC (rev 1060)
@@ -23,13 +23,27 @@
*/
package org.jboss.dna.publish;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import org.jboss.dna.publish.Status.Severity;
import org.jboss.dna.publish.domain.Server;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
/**
* The Server Manager class managers the creation, deletion, and editing of servers.
@@ -37,9 +51,55 @@
* @author Dan Florian
* @since 0.6
*/
-public final class ServerManager {
+public final class ServerManager implements IConstants {
// ===========================================================================================================================
+ // Constants
+ // ===========================================================================================================================
+
+ /**
+ * The tag used to persist a server's login password.
+ *
+ * @since 0.6
+ */
+ private static final String PASSWORD_TAG = "password"; //$NON-NLS-1$
+
+ /**
+ * The file name used when persisting the server registry.
+ *
+ * @since 0.6
+ */
+ private static final String REGISTRY_FILE = "serverRegistry.xml"; //$NON-NLS-1$
+
+ /**
+ * The tag used when persisting a server.
+ *
+ * @since 0.6
+ */
+ private static final String SERVER_TAG = "server"; //$NON-NLS-1$
+
+ /**
+ * The server collection tag used when persisting the server registry.
+ *
+ * @since 0.6
+ */
+ private static final String SERVERS_TAG = "servers"; //$NON-NLS-1$
+
+ /**
+ * The tag used to persist a server's URL.
+ *
+ * @since 0.6
+ */
+ private static final String URL_TAG = "url"; //$NON-NLS-1$
+
+ /**
+ * The tag used to persist a server's login user.
+ *
+ * @since 0.6
+ */
+ private static final String USER_TAG = "user"; //$NON-NLS-1$
+
+ // ===========================================================================================================================
// Fields
// ===========================================================================================================================
@@ -62,9 +122,9 @@
* persistence is not desired)
* @since 0.6
*/
- public ServerManager( String path ) {
+ public ServerManager( String stateLocationPath ) {
this.servers = Collections.synchronizedList(new ArrayList<Server>());
- this.stateLocationPath = path;
+ this.stateLocationPath = stateLocationPath;
restoreState();
}
@@ -79,14 +139,17 @@
* @return a status indicating if the server was added to the registry
* @since 0.6
*/
- public IStatus addServer( Server server ) {
+ public Status addServer( Server server ) {
if (!this.servers.contains(server)) {
this.servers.add(server);
return Status.OK_STATUS;
}
- // TODO implement error status
- return null;
+ // server already exists
+ String pattern = MESSAGES.getString(ServerExistsMsg);
+ String msg = MessageFormat.format(pattern, server.getShortDescription());
+ Status status = new Status(Severity.ERROR, msg, null);
+ return status;
}
/**
@@ -96,27 +159,75 @@
public Collection<Server> getServers() {
return Collections.unmodifiableCollection(this.servers);
}
+
+ /**
+ * @return the name of the state file that the server registry is persisted to
+ * @since 0.6
+ */
+ private String getStateFileName() {
+ return this.stateLocationPath + File.separatorChar + REGISTRY_FILE;
+ }
/**
+ * @param server the server being tested
+ * @return <code>true</code> if the server has been registered
+ * @since 0.6
+ */
+ public boolean isRegistered( Server server ) {
+ return this.servers.contains(server);
+ }
+
+ /**
* @param server the server being removed
* @return a status indicating if the specified server was removed from the registry
* @since 0.6
*/
- public IStatus removeServer( Server server ) {
+ public Status removeServer( Server server ) {
if (this.servers.remove(server)) {
return Status.OK_STATUS;
}
- // TODO implement error status
- return null;
+ // server could not be removed
+ String pattern = MESSAGES.getString(RemovingServerProblemMsg);
+ String msg = MessageFormat.format(pattern, server.getShortDescription());
+ Status status = new Status(Severity.ERROR, msg, null);
+ return status;
}
/**
+ * @return a status indicating if the previous session state was restored
* @since 0.6
*/
- private IStatus restoreState() {
+ private Status restoreState() {
if (this.stateLocationPath != null) {
- // TODO implement
+ if (stateFileExists()) {
+ try {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder docBuilder = factory.newDocumentBuilder();
+ Document doc = docBuilder.parse(new File(getStateFileName()));
+ Node root = doc.getDocumentElement();
+ NodeList servers = root.getChildNodes();
+
+ for (int size = servers.getLength(), i = 0; i < size; ++i) {
+ Node server = servers.item(i);
+
+ if (server.getNodeType() != Node.TEXT_NODE) {
+ NamedNodeMap attributeMap = server.getAttributes();
+
+ if (attributeMap == null) continue;
+
+ for (int numAttrs = attributeMap.getLength(), j = 0; j < numAttrs; ++j) {
+ Node urlNode = attributeMap.getNamedItem(URL_TAG);
+ Node userNode = attributeMap.getNamedItem(USER_TAG);
+ Node passwordNode = attributeMap.getNamedItem(PASSWORD_TAG);
+ addServer(new Server(urlNode.getNodeValue(), userNode.getNodeValue(), passwordNode.getNodeValue()));
+ }
+ }
+ }
+ } catch (Exception e) {
+ // TODO log
+ }
+ }
}
// do nothing of there is no save location
@@ -129,13 +240,67 @@
* @return a status indicating if the registry was successfully saved
* @since 0.6
*/
- public IStatus saveState() {
- if (this.stateLocationPath != null) {
- // TODO implement
+ public Status saveState() {
+ try {
+ if ((this.stateLocationPath != null) && !getServers().isEmpty()) {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder docBuilder = factory.newDocumentBuilder();
+ Document doc = docBuilder.newDocument();
+
+ // create root element
+ Element root = doc.createElement(SERVERS_TAG);
+ doc.appendChild(root);
+
+ for (Server server : getServers()) {
+ Element serverElement = doc.createElement(SERVER_TAG);
+ root.appendChild(serverElement);
+
+ serverElement.setAttribute(URL_TAG, server.getUrl());
+ serverElement.setAttribute(USER_TAG, server.getUser());
+ serverElement.setAttribute(PASSWORD_TAG, server.getPassword());
+ }
+
+ DOMSource source = new DOMSource(doc);
+ StreamResult resultXML = new StreamResult(new FileOutputStream(getStateFileName()));
+ TransformerFactory transFactory = TransformerFactory.newInstance();
+ Transformer transformer = transFactory.newTransformer();
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
+ transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); //$NON-NLS-1$ //$NON-NLS-2$
+ transformer.transform(source, resultXML);
+ } else if ((this.stateLocationPath != null) && stateFileExists()) {
+ // delete current registry file is all servers have been deleted
+ new File(getStateFileName()).delete();
+ }
+ } catch (Exception e) {
+ // TODO log
}
- // do nothing of there is no save location
return Status.OK_STATUS;
}
+ /**
+ * @return <code>true</code> if the state file already exists
+ * @since 0.6
+ */
+ private boolean stateFileExists() {
+ return new File(getStateFileName()).exists();
+ }
+
+ // ===========================================================================================================================
+ // Methods
+ // ===========================================================================================================================
+
+ public static void main( String[] args ) {
+ ServerManager mgr = new ServerManager("/home/dan"); //$NON-NLS-1$
+
+ // populate registry
+ if (mgr.servers.isEmpty()) {
+ for (int i = 0; i < 10; ++i) {
+ mgr.addServer(new Server("http://server" + i + ".com", "user" + i, "password" + i)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ }
+ }
+
+ mgr.saveState();
+ }
+
}
Added: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Status.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Status.java (rev 0)
+++ branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Status.java 2009-06-22 21:28:39 UTC (rev 1060)
@@ -0,0 +1,198 @@
+/*
+ * 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.publish;
+
+/**
+ * @author Dan Florian
+ * @since 0.6
+ */
+public class Status {
+
+ // ===========================================================================================================================
+ // Constants
+ // ===========================================================================================================================
+
+ /**
+ * The status severity levels.
+ *
+ * @since 0.6
+ */
+ public enum Severity {
+ /**
+ * Indicates an error status.
+ *
+ * @since 0.6
+ */
+ ERROR,
+
+ /**
+ * Indicates an informational status.
+ *
+ * @since 0.6
+ */
+ INFO,
+
+ /**
+ * Indicates an OK status.
+ *
+ * @since 0.6
+ */
+ OK,
+
+ /**
+ * Indicates an unknown status. This is automatically assigned if status is constructed with a <code>null</code> severity.
+ *
+ * @since 0.6
+ */
+ UNKNOWN,
+
+ /**
+ * Indicates a warning status.
+ *
+ * @since 0.6
+ */
+ WARNING
+ }
+
+ /**
+ * A status with an OK severity and no message and no exception.
+ *
+ * @see Severity#OK
+ * @since 0.6
+ */
+ public static final Status OK_STATUS = new Status(Severity.OK, null, null);
+
+ // ===========================================================================================================================
+ // Fields
+ // ===========================================================================================================================
+
+ /**
+ * The exception of this status or <code>null</code>.
+ *
+ * @since 0.6
+ */
+ private final Throwable exception;
+
+ /**
+ * The localized message of this status (never <code>null</code>).
+ *
+ * @since 0.6
+ */
+ private final String message;
+
+ /**
+ * The severity level of this status.
+ *
+ * @since 0.6
+ */
+ private final Severity severity;
+
+ // ===========================================================================================================================
+ // Constructors
+ // ===========================================================================================================================
+
+ /**
+ * @param severity the status severity (<code>null</code> will be converted to {@link Severity#UNKNOWN}.
+ * @param message the status message or <code>null</code>
+ * @param exception the status exception or <code>null</code>
+ * @since 0.6
+ */
+ public Status( Severity severity,
+ String message,
+ Throwable exception ) {
+ this.severity = ((severity == null) ? Severity.UNKNOWN : severity);
+ this.message = message;
+ this.exception = exception;
+ }
+
+ // ===========================================================================================================================
+ // Methods
+ // ===========================================================================================================================
+
+ /**
+ * @return the status exception (may be <code>null</code>)
+ * @since 0.6
+ */
+ public Throwable getException() {
+ return this.exception;
+ }
+
+ /**
+ * @return the status message (never <code>null</code> but can be empty)
+ * @since 0.6
+ */
+ public String getMessage() {
+ return ((this.message == null) ? "" : this.message); //$NON-NLS-1$
+ }
+
+ /**
+ * @return <code>true</code> if the status is an error
+ * @see Severity#ERROR
+ * @since 0.6
+ */
+ public boolean isError() {
+ return (this.severity == Severity.ERROR);
+ }
+
+ /**
+ * @return <code>true</code> if the status is an info
+ * @see Severity#INFO
+ * @since 0.6
+ */
+ public boolean isInfo() {
+ return (this.severity == Severity.INFO);
+ }
+
+ /**
+ * @return <code>true</code> if the status is OK
+ * @see Severity#OK
+ * @since 0.6
+ */
+ public boolean isOk() {
+ return (this.severity == Severity.OK);
+ }
+
+ /**
+ * @return <code>true</code> if the status is a warning
+ * @see Severity#WARNING
+ * @since 0.6
+ */
+ public boolean isWarning() {
+ return (this.severity == Severity.WARNING);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ * @since 0.6
+ */
+ @Override
+ public String toString() {
+ StringBuilder txt = new StringBuilder("Status "); //$NON-NLS-1$
+ txt.append(this.severity.toString()).append(": ").append(getMessage()).append(": ").append(getException()); //$NON-NLS-1$ //$NON-NLS-2$
+ return txt.toString();
+ }
+
+}
Property changes on: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/Status.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Deleted: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/actions/PublishAction.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/actions/PublishAction.java 2009-06-22 16:50:22 UTC (rev 1059)
+++ branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/actions/PublishAction.java 2009-06-22 21:28:39 UTC (rev 1060)
@@ -1,78 +0,0 @@
-/*
- * 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.publish.actions;
-
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.ui.IObjectActionDelegate;
-import org.eclipse.ui.IWorkbenchPart;
-
-/**
- * The PublishAction controls the publishing of one or more {@link org.eclipse.core.resources.IResource}s to a DNA repository.
- *
- * @author Dan Florian
- * @since 0.6
- */
-public final class PublishAction implements IObjectActionDelegate {
-
- /**
- * The active part's Shell.
- *
- * @since 0.6
- */
-// private Shell shell;
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
- * @since 0.6
- */
- public void run( IAction action ) {
- // TODO implement
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction,
- * org.eclipse.jface.viewers.ISelection)
- * @since 0.6
- */
- public void selectionChanged( IAction action,
- ISelection selection ) {
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.action.IAction, org.eclipse.ui.IWorkbenchPart)
- * @since 0.6
- */
- public void setActivePart( IAction action,
- IWorkbenchPart targetPart ) {
-// this.shell = targetPart.getSite().getShell();
- }
-
-}
Deleted: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/actions/UnpublishAction.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/actions/UnpublishAction.java 2009-06-22 16:50:22 UTC (rev 1059)
+++ branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/actions/UnpublishAction.java 2009-06-22 21:28:39 UTC (rev 1060)
@@ -1,79 +0,0 @@
-/*
- * 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.publish.actions;
-
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.ui.IObjectActionDelegate;
-import org.eclipse.ui.IWorkbenchPart;
-
-/**
- * The UnpublishAction controls the unpublishing of on or more {@link org.eclipse.core.resources.IResource}s from a DNA
- * repository.
- *
- * @author Dan Florian
- * @since 0.6
- */
-public final class UnpublishAction implements IObjectActionDelegate {
-
- /**
- * The active part's Shell.
- *
- * @since 0.6
- */
-// private Shell shell;
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
- * @since 0.6
- */
- public void run( IAction action ) {
- // TODO implement
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction,
- * org.eclipse.jface.viewers.ISelection)
- * @since 0.6
- */
- public void selectionChanged( IAction action,
- ISelection selection ) {
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.action.IAction, org.eclipse.ui.IWorkbenchPart)
- * @since 0.6
- */
- public void setActivePart( IAction action,
- IWorkbenchPart targetPart ) {
-// this.shell = targetPart.getSite().getShell();
- }
-
-}
Modified: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/Repository.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/Repository.java 2009-06-22 16:50:22 UTC (rev 1059)
+++ branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/Repository.java 2009-06-22 21:28:39 UTC (rev 1060)
@@ -23,12 +23,14 @@
*/
package org.jboss.dna.publish.domain;
+import java.text.MessageFormat;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
-import org.eclipse.osgi.util.NLS;
-import org.jboss.dna.publish.I18n;
+import org.jboss.dna.publish.IConstants;
+import org.jboss.dna.publish.Status;
+import org.jboss.dna.publish.domain.validation.RepositoryValidator;
/**
* The Repository class is the business object for a DNA repository.
@@ -36,34 +38,9 @@
* @author Dan Florian
* @since 0.6
*/
-public final class Repository implements IDnaObject {
+public final class Repository implements IConstants, IDnaObject {
// ===========================================================================================================================
- // Class Methods
- // ===========================================================================================================================
-
- /**
- * This method validates a proposed name and should be called before constructing a {@link Repository}.
- *
- * @param proposedName the name being validated
- * @return <code>true</code> if the name is valid
- * @since 0.6
- */
- public static boolean validateName( String proposedName ) {
- return ((proposedName != null) && (proposedName.length() != 0));
- }
-
- /**
- * This method validates a proposed {@link Server server} and should be called before constructing a {@link Repository}.
- *
- * @param proposedServer the server being tested
- * @return <code>true</code> if the server is valid
- */
- public static boolean validateServer( Server proposedServer ) {
- return (proposedServer != null);
- }
-
- // ===========================================================================================================================
// Fields
// ===========================================================================================================================
@@ -92,23 +69,20 @@
*
* @param name the repository name
* @param server the server where this repository resides
- * @see #validateName(String)
- * @see #validateServer(Server)
+ * @see RepositoryValidator
* @throws RuntimeException if any of the input parameters are invalid
* @since 0.6
*/
public Repository( String name,
Server server ) {
- // validate inputs first
- if (!validateName(name)) {
- throw new RuntimeException(NLS.bind(I18n.RepositoryInvalidNameMsg, name));
+ // validate inputs
+ Status status = RepositoryValidator.isValid(name, server);
+
+ if (status.isError()) {
+ throw new RuntimeException(status.getMessage(), status.getException());
}
- if (!validateServer(server)) {
- throw new RuntimeException(I18n.RepositoryInvalidServerMsg);
- }
-
- // OK to construct
+ // valid so construct
this.name = name;
this.server = server;
}
@@ -185,7 +159,8 @@
*/
@Override
public String getShortDescription() {
- return NLS.bind(I18n.RepositoryShortDescription, this.name, this.server.getShortDescription());
+ String pattern = MESSAGES.getString(RepositoryShortDescription);
+ return MessageFormat.format(pattern, this.name, this.server.getShortDescription());
}
/**
@@ -193,7 +168,7 @@
* @since 0.6
*/
public Collection<Workspace> getWorkspaces() {
- // TODO implement
+ // TODO implement getWorkspaces()
return Collections.emptyList();
}
Modified: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/Server.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/Server.java 2009-06-22 16:50:22 UTC (rev 1059)
+++ branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/Server.java 2009-06-22 21:28:39 UTC (rev 1060)
@@ -23,12 +23,16 @@
*/
package org.jboss.dna.publish.domain;
+import java.text.MessageFormat;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
-import org.eclipse.osgi.util.NLS;
-import org.jboss.dna.publish.I18n;
+import org.jboss.dna.publish.IConstants;
+import org.jboss.dna.publish.ServerManager;
+import org.jboss.dna.publish.Status;
+import org.jboss.dna.publish.domain.validation.RepositoryValidator;
+import org.jboss.dna.publish.domain.validation.ServerValidator;
/**
* The Server class is the business object for a server that is hosting one or more DNA repositories.
@@ -36,50 +40,27 @@
* @author Dan Florian
* @since 0.6
*/
-public final class Server implements IDnaObject {
+public final class Server implements IConstants, IDnaObject {
// ===========================================================================================================================
- // Class Methods
+ // Fields
// ===========================================================================================================================
/**
- * This method validates a proposed server URL and should be called before constructing a {@link Server}.
+ * The password to use when logging on to the server.
*
- * @param proposedUrl the URL being validated
- * @return <code>true</code> if the URL is valid
* @since 0.6
*/
- public static boolean validateUrl( String proposedUrl ) {
- return ((proposedUrl != null) && (proposedUrl.length() != 0));
- }
-
+ private final String password;
+
/**
- * This method validates a proposed server authentication user and should be called before constructing a {@link Server}.
+ * The server manager that manages the server registry.
*
- * @param proposedUser the user being validated
- * @return <code>true</code> if the user is valid
* @since 0.6
*/
- public static boolean validateUser( String proposedUser ) {
- return ((proposedUser != null) && (proposedUser.length() != 0));
- }
+ private ServerManager serverManager;
/**
- * This method validates a proposed server authentication password and should be called before constructing a {@link Server}.
- *
- * @param proposedPassword the password being validated
- * @return <code>true</code> if the password is valid
- * @since 0.6
- */
- public static boolean validatePassword( String proposedPassword ) {
- return ((proposedPassword != null) && (proposedPassword.length() != 0));
- }
-
- // ===========================================================================================================================
- // Fields
- // ===========================================================================================================================
-
- /**
* The server URL.
*
* @since 0.6
@@ -93,13 +74,6 @@
*/
private final String user;
- /**
- * The password to use when logging on to the server.
- *
- * @since 0.6
- */
- private final String pswd;
-
// ===========================================================================================================================
// Constructors
// ===========================================================================================================================
@@ -108,34 +82,26 @@
* Constructs on new <code>Server</code>.
*
* @param url the server URL
- * @param user the server authentication user
- * @param pswd the server authentication password
- * @see #validateUrl(String)
- * @see #validateUser(String)
- * @see #validatePassword(String)
+ * @param user the server user
+ * @param password the server password
+ * @see RepositoryValidator
* @throws RuntimeException if any of the input parameters are invalid
* @since 0.6
*/
public Server( String url,
String user,
- String pswd ) {
- // valid inputs first
- if (!validateUrl(url)) {
- throw new RuntimeException(NLS.bind(I18n.ServerInvalidUrlMsg, url));
- }
+ String password ) {
+ // valid inputs
+ Status status = ServerValidator.isValid(url, user, password);
- if (!validateUrl(user)) {
- throw new RuntimeException(NLS.bind(I18n.ServerInvalidUserMsg, user));
+ if (status.isError()) {
+ throw new RuntimeException(status.getMessage(), status.getException());
}
- if (!validateUrl(pswd)) {
- throw new RuntimeException(NLS.bind(I18n.ServerInvalidPasswordMsg, pswd));
- }
-
- // OK to construct
+ // valid so construct
this.url = url;
this.user = user;
- this.pswd = pswd;
+ this.password = password;
}
// ===========================================================================================================================
@@ -200,7 +166,7 @@
* @since 0.6
*/
public String getPassword() {
- return this.pswd;
+ return this.password;
}
/**
@@ -208,7 +174,10 @@
* @since 0.6
*/
public Collection<Repository> getRepositories() {
- // TODO implement
+ if (this.serverManager != null) {
+ // TODO implement getRepositories()
+ }
+
return Collections.emptyList();
}
@@ -220,7 +189,8 @@
*/
@Override
public String getShortDescription() {
- return NLS.bind(I18n.ServerShortDescription, this.url, this.user);
+ String pattern = MESSAGES.getString(ServerShortDescription);
+ return MessageFormat.format(pattern, this.url, this.user);
}
/**
@@ -253,4 +223,12 @@
return hash;
}
+ /**
+ * @param serverManager the server manager (may be <code>null</code>)
+ * @since 0.6
+ */
+ public void setServerManager( ServerManager serverManager ) {
+ this.serverManager = serverManager;
+ }
+
}
Modified: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/Workspace.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/Workspace.java 2009-06-22 16:50:22 UTC (rev 1059)
+++ branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/Workspace.java 2009-06-22 21:28:39 UTC (rev 1060)
@@ -23,10 +23,12 @@
*/
package org.jboss.dna.publish.domain;
+import java.text.MessageFormat;
import java.util.Collections;
import java.util.List;
-import org.eclipse.osgi.util.NLS;
-import org.jboss.dna.publish.I18n;
+import org.jboss.dna.publish.IConstants;
+import org.jboss.dna.publish.Status;
+import org.jboss.dna.publish.domain.validation.WorkspaceValidator;
/**
* The Workspace class is the business object for a DNA repository workspace.
@@ -34,35 +36,9 @@
* @author Dan Florian
* @since 0.6
*/
-public class Workspace implements IDnaObject {
+public final class Workspace implements IConstants, IDnaObject {
// ===========================================================================================================================
- // Class Methods
- // ===========================================================================================================================
-
- /**
- * This method validates a proposed name and should be called before constructing a {@link Workspace}.
- *
- * @param proposedName the name being validated
- * @return <code>true</code> if the name is valid
- * @since 0.6
- */
- public static boolean validateName( String proposedName ) {
- return ((proposedName != null) && (proposedName.length() != 0));
- }
-
- /**
- * This method validates a proposed {@link Repository repository} and should be called before constructing a {@link Workspace}
- * .
- *
- * @param proposedRepository the repository being tested
- * @return <code>true</code> if the repository is valid
- */
- public static boolean validateRepository( Repository proposedRepository ) {
- return (proposedRepository != null);
- }
-
- // ===========================================================================================================================
// Fields
// ===========================================================================================================================
@@ -88,24 +64,21 @@
* Constructs a new <code>Workspace</code>.
*
* @param name the workspace name
- * @param server the repository where this workspace resides
- * @see #validateName(String)
- * @see #validateRepository(Server)
+ * @param repository the repository where this workspace resides
+ * @see WorkspaceValidator
* @throws RuntimeException if any of the input parameters are invalid
* @since 0.6
*/
public Workspace( String name,
Repository repository ) {
- // validate inputs first
- if (!validateName(name)) {
- throw new RuntimeException(NLS.bind(I18n.WorkspaceInvalidNameMsg, name));
+ // validate inputs
+ Status status = WorkspaceValidator.isValid(name, repository);
+
+ if (status.isError()) {
+ throw new RuntimeException(status.getMessage(), status.getException());
}
- if (!validateRepository(repository)) {
- throw new RuntimeException(I18n.WorkspaceInvalidRepositoryMsg);
- }
-
- // OK to construct
+ // valid so construct
this.name = name;
this.repository = repository;
}
@@ -173,7 +146,22 @@
*/
@Override
public String getShortDescription() {
- return NLS.bind(I18n.WorkspaceShortDescription, this.name, this.repository.getShortDescription());
+ String pattern = MESSAGES.getString(WorkspaceShortDescription);
+ return MessageFormat.format(pattern, this.name, this.repository.getShortDescription());
}
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#hashCode()
+ * @since 0.6
+ */
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 31 * hash + this.name.hashCode();
+ hash = 31 * hash + this.repository.hashCode();
+ return hash;
+ }
}
Added: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/validation/RepositoryValidator.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/validation/RepositoryValidator.java (rev 0)
+++ branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/validation/RepositoryValidator.java 2009-06-22 21:28:39 UTC (rev 1060)
@@ -0,0 +1,97 @@
+/*
+ * 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.publish.domain.validation;
+
+import org.jboss.dna.publish.IConstants;
+import org.jboss.dna.publish.Status;
+import org.jboss.dna.publish.Status.Severity;
+import org.jboss.dna.publish.domain.Server;
+
+/**
+ * @author Dan Florian
+ * @since 0.6
+ */
+public final class RepositoryValidator implements IConstants {
+
+ // ===========================================================================================================================
+ // Class Methods
+ // ===========================================================================================================================
+
+ /**
+ * @param name the name being validated
+ * @return a validation status (never <code>null</code>)
+ * @since 0.6
+ */
+ public static Status isNameValid( String name ) {
+ if ((name == null) || (name.length() == 0)) {
+ return new Status(Severity.ERROR, MESSAGES.getString(RepositoryEmptyNameMsg), null);
+ }
+
+ return Status.OK_STATUS;
+ }
+
+ /**
+ * @param server the server being validated
+ * @return a validation status (never <code>null</code>)
+ * @since 0.6
+ */
+ public static Status isServerValid( Server server ) {
+ if (server == null) {
+ return new Status(Severity.ERROR, MESSAGES.getString(RepositoryNullServerMsg), null);
+ }
+
+ return Status.OK_STATUS;
+ }
+
+ /**
+ * @param name the name being validated
+ * @param server the server being validated
+ * @return a validation status (never <code>null</code>)
+ * @since 0.6
+ */
+ public static Status isValid( String name,
+ Server server ) {
+ Status status = isNameValid(name);
+
+ if (!status.isError()) {
+ status = isServerValid(server);
+ }
+
+ return status;
+ }
+
+ // ===========================================================================================================================
+ // Constructors
+ // ===========================================================================================================================
+
+ /**
+ * Disallow construction.
+ *
+ * @since 0.6
+ */
+ private RepositoryValidator() {
+ // nothing to do
+ }
+
+}
Property changes on: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/validation/RepositoryValidator.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/validation/ServerValidator.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/validation/ServerValidator.java (rev 0)
+++ branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/validation/ServerValidator.java 2009-06-22 21:28:39 UTC (rev 1060)
@@ -0,0 +1,152 @@
+/*
+ * 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.publish.domain.validation;
+
+import java.net.URL;
+import java.text.MessageFormat;
+import org.jboss.dna.publish.IConstants;
+import org.jboss.dna.publish.ServerManager;
+import org.jboss.dna.publish.Status;
+import org.jboss.dna.publish.Status.Severity;
+import org.jboss.dna.publish.domain.Server;
+
+/**
+ * @author Dan Florian
+ * @since 0.6
+ */
+public final class ServerValidator implements IConstants {
+
+ // ===========================================================================================================================
+ // Class Methods
+ // ===========================================================================================================================
+
+ /**
+ * @param password the password being validated
+ * @return a validation status (never <code>null</code>)
+ * @since 0.6
+ */
+ public static Status isPasswordValid( String password ) {
+ return Status.OK_STATUS;
+ }
+
+ /**
+ * @param url the URL being validated
+ * @return a validation status (never <code>null</code>)
+ * @since 0.6
+ */
+ public static Status isUrlValid( String url ) {
+ if ((url == null) || (url.length() == 0)) {
+ return new Status(Severity.ERROR, MESSAGES.getString(ServerEmptyUrlMsg), null);
+ }
+
+ try {
+ new URL(url);
+ } catch (Exception e) {
+ String pattern = MESSAGES.getString(ServerInvalidUrlMsg);
+ String msg = MessageFormat.format(pattern, url);
+ return new Status(Severity.ERROR, msg, null);
+ }
+
+ return Status.OK_STATUS;
+ }
+
+ /**
+ * @param user the user being validated
+ * @return a validation status (never <code>null</code>)
+ * @since 0.6
+ */
+ public static Status isUserValid( String user ) {
+ if ((user == null) || (user.length() == 0)) {
+ return new Status(Severity.ERROR, MESSAGES.getString(ServerEmptyUserMsg), null);
+ }
+
+ return Status.OK_STATUS;
+ }
+
+ /**
+ * @param url the URL being validated
+ * @param user the user being validated
+ * @param password the password being validated
+ * @return a validation status (never <code>null</code>)
+ * @since 0.6
+ */
+ public static Status isValid( String url,
+ String user,
+ String password ) {
+ Status status = isUrlValid(url);
+
+ if (!status.isError()) {
+ status = isUserValid(user);
+
+ if (!status.isError()) {
+ status = isPasswordValid(password);
+ }
+ }
+
+ return status;
+ }
+
+ /**
+ * @param url the URL being validated
+ * @param user the user being validated
+ * @param password the password being validated
+ * @param serverManager the server manager controlling the server registry (may not be <code>null</code>)
+ * @return a validation status (never <code>null</code>)
+ * @see #isValid(String, String, String)
+ * @since 0.6
+ */
+ public static Status isValid( String url,
+ String user,
+ String password,
+ ServerManager serverManager ) {
+ Status status = isValid(url, user, password);
+
+ // make sure a server with the same properties does not exist
+ if (!status.isError()) {
+ Server newServer = new Server(url, user, password);
+
+ if (serverManager.isRegistered(newServer)) {
+ String pattern = MESSAGES.getString(ServerExistsMsg);
+ String msg = MessageFormat.format(pattern, newServer.getShortDescription());
+ status = new Status(Severity.ERROR, msg, null);
+ }
+ }
+
+ return status;
+ }
+
+ // ===========================================================================================================================
+ // Constructors
+ // ===========================================================================================================================
+
+ /**
+ * Disallow construction.
+ *
+ * @since 0.6
+ */
+ private ServerValidator() {
+ // nothing to do
+ }
+
+}
Property changes on: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/validation/ServerValidator.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/validation/WorkspaceValidator.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/validation/WorkspaceValidator.java (rev 0)
+++ branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/validation/WorkspaceValidator.java 2009-06-22 21:28:39 UTC (rev 1060)
@@ -0,0 +1,97 @@
+/*
+ * 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.publish.domain.validation;
+
+import org.jboss.dna.publish.IConstants;
+import org.jboss.dna.publish.Status;
+import org.jboss.dna.publish.Status.Severity;
+import org.jboss.dna.publish.domain.Repository;
+
+/**
+ * @author Dan Florian
+ * @since 0.6
+ */
+public final class WorkspaceValidator implements IConstants {
+
+ // ===========================================================================================================================
+ // Class Methods
+ // ===========================================================================================================================
+
+ /**
+ * @param name the name being validated
+ * @return a validation status (never <code>null</code>)
+ * @since 0.6
+ */
+ public static Status isNameValid( String name ) {
+ if ((name == null) || (name.length() == 0)) {
+ return new Status(Severity.ERROR, MESSAGES.getString(WorkspaceEmptyNameMsg), null);
+ }
+
+ return Status.OK_STATUS;
+ }
+
+ /**
+ * @param repository the repository being validated
+ * @return a validation status (never <code>null</code>)
+ * @since 0.6
+ */
+ public static Status isRepositoryValid( Repository repository ) {
+ if (repository == null) {
+ return new Status(Severity.ERROR, MESSAGES.getString(WorkspaceNullRepositoryMsg), null);
+ }
+
+ return Status.OK_STATUS;
+ }
+
+ /**
+ * @param name the name being validated
+ * @param repository the repository being validated
+ * @return a validation status (never <code>null</code>)
+ * @since 0.6
+ */
+ public static Status isValid( String name,
+ Repository repository ) {
+ Status status = isNameValid(name);
+
+ if (!status.isError()) {
+ status = isRepositoryValid(repository);
+ }
+
+ return status;
+ }
+
+ // ===========================================================================================================================
+ // Constructors
+ // ===========================================================================================================================
+
+ /**
+ * Disallow construction.
+ *
+ * @since 0.6
+ */
+ private WorkspaceValidator() {
+ // nothing to do
+ }
+
+}
Property changes on: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/domain/validation/WorkspaceValidator.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Deleted: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/i18n.properties
===================================================================
--- branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/i18n.properties 2009-06-22 16:50:22 UTC (rev 1059)
+++ branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/i18n.properties 2009-06-22 21:28:39 UTC (rev 1060)
@@ -1,35 +0,0 @@
-CollapseActionToolTip = Collapse All
-
-DeleteServerActionText = Delete Server
-DeleteServerActionToolTip = Delete Server
-
-DeleteServerDialogTitle = Confirm Delete Server
-DeleteServerDialogOneServerMessage = Are you sure you want to delete the "{0}" server?
-DeleteServerDialogMultipleServersMessage = Are you sure you want to delete these {0} servers?
-
-EditServerActionText = Edit Server
-EditServerActionToolTip = Edit Server
-
-NewServerActionText = New Server
-NewServerActionToolTip = New Server
-
-RepositoryInvalidNameMsg = The value "{0}" is not a valid repository name
-RepositoryInvalidServerMsg = A repository server cannot be null
-RepositoryShortDescription = DNA Repository: Name: {0}, {1}
-
-ServerDialogEditTitle = Edit Server
-ServerDialogNewTitle = New Server
-ServerDialogPasswordLabel = Password:
-ServerDialogSavePasswordButton = Save password
-ServerDialogSavePasswordLabel = Saved secret data is stored on your computer in a file that's difficult, but not impossible, for an intruder to read.
-ServerDialogUserLabel = User:
-ServerDialogUrlLabel = URL:
-
-ServerShortDescription = DNA Server: URL={0} User={1}
-ServerInvalidPasswordMsg = The value "{0}" is not a valid server authentication password
-ServerInvalidUrlMsg = The value "{0}" is not a valid server URL
-ServerInvalidUserMsg = The value "{0}" is not a valid server authentication user
-
-WorkspaceInvalidNameMsg = The value "{0}" is not a valid repository name
-WorkspaceInvalidRepositoryMsg = A workspace repository cannot be null
-WorkspaceShortDescription = DNA Repository Workspace: Name: {0}, {1}
Deleted: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ui/IUiConstants.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ui/IUiConstants.java 2009-06-22 16:50:22 UTC (rev 1059)
+++ branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ui/IUiConstants.java 2009-06-22 21:28:39 UTC (rev 1060)
@@ -1,27 +0,0 @@
-/*
- * 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.publish.ui;
-
-public interface IUiConstants {
-}
Deleted: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ui/UiUtil.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ui/UiUtil.java 2009-06-22 16:50:22 UTC (rev 1059)
+++ branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ui/UiUtil.java 2009-06-22 21:28:39 UTC (rev 1060)
@@ -1,94 +0,0 @@
-/*
- * 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.publish.ui;
-
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.jboss.dna.publish.Activator;
-import org.jboss.dna.publish.domain.IDnaObject;
-import org.jboss.dna.publish.domain.Repository;
-import org.jboss.dna.publish.domain.Server;
-import org.jboss.dna.publish.domain.Workspace;
-
-/**
- * @author Dan Florian
- * @since 0.6
- */
-public final class UiUtil {
-
- // ===========================================================================================================================
- // Constants
- // ===========================================================================================================================
-
- private static final String ICON_PATH = "icons/full/"; //$NON-NLS-1$
-
- public static final String OBJ16 = ICON_PATH + "obj16/"; //$NON-NLS-1$
-
- private static final String REPOSITORY_IMAGE_PATH = OBJ16 + "repository.gif"; //$NON-NLS-1$
-
- private static final String SERVER_IMAGE_PATH = OBJ16 + "server.gif"; //$NON-NLS-1$
-
- private static final String WORKSPACE_IMAGE_PATH = OBJ16 + "workspace.gif"; //$NON-NLS-1$
-
- // ===========================================================================================================================
- // Class Methods
- // ===========================================================================================================================
-
- /**
- * @param obj the object whose image is being requested
- * @return the image or <code>null</code>
- * @since 0.6
- */
- public static ImageDescriptor getImage( Object obj ) {
- if (obj instanceof Workspace) {
- return Activator.getImageDescriptor(WORKSPACE_IMAGE_PATH);
- }
-
- if (obj instanceof Repository) {
- return Activator.getImageDescriptor(REPOSITORY_IMAGE_PATH);
- }
-
- if (obj instanceof Server) {
- return Activator.getImageDescriptor(SERVER_IMAGE_PATH);
- }
-
- // should have an icon for every business object
- assert (!(obj instanceof IDnaObject));
-
- return null;
- }
-
- // ===========================================================================================================================
- // Constructors
- // ===========================================================================================================================
-
- /**
- * Don't allow public construction.
- *
- * @since 0.6
- */
- private UiUtil() {
- // nothing to do
- }
-
-}
Deleted: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ui/dialogs/DeleteServerDialog.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ui/dialogs/DeleteServerDialog.java 2009-06-22 16:50:22 UTC (rev 1059)
+++ branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ui/dialogs/DeleteServerDialog.java 2009-06-22 21:28:39 UTC (rev 1060)
@@ -1,121 +0,0 @@
-/*
- * 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.publish.ui.dialogs;
-
-import java.util.Collection;
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.osgi.util.NLS;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.List;
-import org.eclipse.swt.widgets.Shell;
-import org.jboss.dna.publish.I18n;
-import org.jboss.dna.publish.domain.IDnaObject;
-import org.jboss.dna.publish.domain.Server;
-
-/**
- * The <code>DeleteServerDialog</code> class provides a UI for deleting a {@link org.jboss.dna.publish.domain.Server server}.
- *
- * @author Dan Florian
- * @since 0.6
- */
-public class DeleteServerDialog extends MessageDialog {
-
- // ===========================================================================================================================
- // Fields
- // ===========================================================================================================================
-
- /**
- * Collection of servers which will be deleted.
- *
- * @since 0.6
- */
- private final Collection<Server> serversBeingDeleted;
-
- // ===========================================================================================================================
- // Constructors
- // ===========================================================================================================================
-
- /**
- * @param parentShell the dialog parent
- * @param serversBeingDeleted the servers being deleted (may not be <code>null</code>)
- * @since 0.6
- */
- public DeleteServerDialog( Shell parentShell,
- Collection<Server> serversBeingDeleted ) {
- super(parentShell, I18n.DeleteServerDialogTitle, null, null, MessageDialog.QUESTION, new String[] {
- IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL}, 0);
- this.serversBeingDeleted = serversBeingDeleted;
- }
-
- // ===========================================================================================================================
- // Methods
- // ===========================================================================================================================
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.dialogs.MessageDialog#configureShell(org.eclipse.swt.widgets.Shell)
- * @since 0.6
- */
- @Override
- protected void configureShell( Shell shell ) {
- super.configureShell(shell);
-
- // now set title
- String title;
-
- if (this.serversBeingDeleted.size() == 1) {
- IDnaObject server = this.serversBeingDeleted.iterator().next();
- title = NLS.bind(I18n.DeleteServerDialogOneServerMessage, server.getName());
- } else {
- title = NLS.bind(I18n.DeleteServerDialogOneServerMessage, this.serversBeingDeleted.size());
- }
-
- shell.setText(title);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.dialogs.MessageDialog#createCustomArea(org.eclipse.swt.widgets.Composite)
- * @since 0.6
- */
- @Override
- protected Control createCustomArea( Composite parent ) {
- if (this.serversBeingDeleted.size() != 1) {
- List serverList = new List(parent, SWT.NONE);
- serverList.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
-
- for (IDnaObject server : this.serversBeingDeleted) {
- serverList.add(server.getName());
- }
- }
-
- return null;
- }
-}
Deleted: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ui/dialogs/ServerDialog.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ui/dialogs/ServerDialog.java 2009-06-22 16:50:22 UTC (rev 1059)
+++ branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ui/dialogs/ServerDialog.java 2009-06-22 21:28:39 UTC (rev 1060)
@@ -1,192 +0,0 @@
-/*
- * 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.publish.ui.dialogs;
-
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.window.Window;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.StyledText;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Group;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.jboss.dna.publish.I18n;
-import org.jboss.dna.publish.domain.Server;
-
-/**
- * The <code>EditServerDialog</code> class provides a UI for editing a {@link org.jboss.dna.publish.domain.Server server}'s
- * properties.
- *
- * @author Dan Florian
- * @since 0.6
- */
-public class ServerDialog extends Dialog {
-
- // ===========================================================================================================================
- // Fields
- // ===========================================================================================================================
-
- private String pswd;
-
- private String url;
-
- private String user;
-
- // ===========================================================================================================================
- // Constructors
- // ===========================================================================================================================
-
- public ServerDialog( Shell parent ) {
- super(parent);
- setShellStyle(getShellStyle() | SWT.RESIZE);
- }
-
- public ServerDialog( Shell parent,
- Server server ) {
- this(parent);
-
- this.url = server.getUrl();
- this.user = server.getUser();
- this.pswd = server.getPassword();
- }
-
- // ===========================================================================================================================
- // Methods
- // ===========================================================================================================================
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.dialogs.Dialog#close()
- */
- @Override
- public boolean close() {
- boolean closed = super.close();
-
- // make sure if cancel was pressed that the call to get classpath jars does not return anything
- if (getReturnCode() != Window.OK) {
- this.pswd = null;
- this.url = null;
- this.user = null;
- }
-
- return closed;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
- * @since 0.6
- */
- @Override
- protected void configureShell( Shell shell ) {
- super.configureShell(shell);
- shell.setText(this.url == null ? I18n.ServerDialogNewTitle : I18n.ServerDialogEditTitle);
- }
-
- private void constructAuthenticationPanel( Composite parent ) {
- Group pnl = new Group(parent, SWT.NONE);
- GridLayout layout = new GridLayout(2, false);
- layout.marginWidth = 0;
- layout.marginHeight = 0;
- pnl.setLayout(layout);
-
- GridData gd = new GridData(SWT.LEFT, SWT.TOP, true, false);
- pnl.setLayoutData(gd);
-
- // user row
- Label lbl = new Label(pnl, SWT.LEFT);
- lbl.setText(I18n.ServerDialogUserLabel);
-
- // password row
- lbl = new Label(pnl, SWT.LEFT);
- lbl.setText(I18n.ServerDialogPasswordLabel);
-
- // save password row
- Button btn = new Button(parent, SWT.CHECK | SWT.LEFT);
- btn.setText(I18n.ServerDialogSavePasswordButton);
-
- // save password message row
- StyledText st = new StyledText(parent, SWT.READ_ONLY | SWT.MULTI | SWT.NO_FOCUS | SWT.WRAP);
- st.setText(I18n.ServerDialogSavePasswordLabel);
- st.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
- st.setCaret(null);
- gd = new GridData(GridData.FILL_BOTH);
- gd.grabExcessVerticalSpace = false;
- gd.horizontalIndent = 4;
- gd.verticalIndent = 8;
- st.setLayoutData(gd);
- }
-
- private void constructUrlPanel( Composite parent ) {
- // Composite pnl = new Composite(parent, SWT.NONE);
-
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
- * @since 0.6
- */
- @Override
- protected Control createDialogArea( Composite parent ) {
- Composite pnlMain = new Composite(parent, SWT.NONE);
- constructUrlPanel(parent);
- constructAuthenticationPanel(parent);
-
- return pnlMain;
- }
-
- /**
- * @return the server authentication password
- * @since 0.6
- */
- public String getPassword() {
- return this.pswd;
- }
-
- /**
- * @return the server authentication user
- * @since 0.6
- */
- public String getUser() {
- return this.user;
- }
-
- /**
- * @return the server URL
- * @since 0.6
- */
- public String getUrl() {
- return this.url;
- }
-
-}
Deleted: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ui/views/RepositoryContentProvider.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ui/views/RepositoryContentProvider.java 2009-06-22 16:50:22 UTC (rev 1059)
+++ branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ui/views/RepositoryContentProvider.java 2009-06-22 21:28:39 UTC (rev 1060)
@@ -1,181 +0,0 @@
-/*
- * 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.publish.ui.views;
-
-import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.jface.viewers.ILabelProviderListener;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.graphics.Image;
-import org.jboss.dna.publish.Activator;
-import org.jboss.dna.publish.domain.IDnaObject;
-
-/**
- * The RepositoryContentProvider is a content and label provider for DNA repositories.
- *
- * @author Dan Florian
- * @since 0.6
- */
-public final class RepositoryContentProvider implements ITreeContentProvider, ILabelProvider {
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener)
- * @since 0.6
- */
- @Override
- public void addListener( ILabelProviderListener listener ) {
- // nothing to do
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.IContentProvider#dispose()
- * @since 0.6
- */
- @Override
- public void dispose() {
- // nothing to do
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
- * @since 0.6
- */
- @Override
- public Object[] getChildren( Object parentElement ) {
- if (parentElement instanceof IDnaObject) {
- return ((IDnaObject)parentElement).getChildren().toArray();
- }
-
- // should not happen
- assert false;
- return null;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
- * @since 0.6
- */
- @Override
- public Object[] getElements( Object inputElement ) {
- return Activator.getDefault().getServerManager().getServers().toArray();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
- * @since 0.6
- */
- @Override
- public Image getImage( Object element ) {
- // TODO implement
- return null;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
- * @since 0.6
- */
- @Override
- public Object getParent( Object element ) {
- if (element instanceof IDnaObject) {
- return ((IDnaObject)element).getParent();
- }
-
- // should not happen
- assert false;
- return null;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
- * @since 0.6
- */
- @Override
- public String getText( Object element ) {
- assert (element instanceof IDnaObject);
- return ((IDnaObject)element).getName();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
- * @since 0.6
- */
- @Override
- public boolean hasChildren( Object element ) {
- return getChildren(element).length > 0;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object,
- * java.lang.Object)
- * @since 0.6
- */
- @Override
- public void inputChanged( Viewer viewer,
- Object oldInput,
- Object newInput ) {
- // nothing to do
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object, java.lang.String)
- * @since 0.6
- */
- @Override
- public boolean isLabelProperty( Object element,
- String property ) {
- return false;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener)
- * @since 0.6
- */
- @Override
- public void removeListener( ILabelProviderListener listener ) {
- // nothing to do
- }
-
-}
Deleted: branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ui/views/RepositoryView.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ui/views/RepositoryView.java 2009-06-22 16:50:22 UTC (rev 1059)
+++ branches/eclipse/org.jboss.dna.publish/src/org/jboss/dna/publish/ui/views/RepositoryView.java 2009-06-22 21:28:39 UTC (rev 1060)
@@ -1,256 +0,0 @@
-/*
- * 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.publish.ui.views;
-
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.action.IToolBarManager;
-import org.eclipse.jface.action.MenuManager;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Menu;
-import org.eclipse.ui.part.ViewPart;
-import org.jboss.dna.publish.I18n;
-import org.jboss.dna.publish.domain.IDnaObject;
-import org.jboss.dna.publish.domain.Server;
-
-/**
- * The RepositoryView shows all defined servers and their DNA repositories.
- *
- * @author Dan Florian
- * @since 0.6
- */
-public final class RepositoryView extends ViewPart {
-
- // ===========================================================================================================================
- // Fields
- // ===========================================================================================================================
-
- /**
- * Collapses all tree nodes.
- *
- * @since 0.6
- */
- private IAction collapseAllAction;
-
- /**
- * Deletes a server.
- *
- * @since 0.6
- */
- private IAction deleteAction;
-
- /**
- * Edits a server's properties.
- *
- * @since 0.6
- */
- private IAction editAction;
-
- /**
- * Creates a new server.
- *
- * @since 0.6
- */
- private IAction newAction;
-
- /**
- * The viewer's content and label provider.
- *
- * @since 0.6
- */
- private RepositoryContentProvider provider;
-
- /**
- * @since 0.6
- */
- private TreeViewer viewer;
-
- // ===========================================================================================================================
- // Methods
- // ===========================================================================================================================
-
- /**
- * @since 0.6
- */
- private void constructActions() {
- // the collapse all action is always enabled
- this.collapseAllAction = new Action() {
- @Override
- public void run() {
- getViewer().collapseAll();
- }
- };
-
- this.collapseAllAction.setToolTipText(I18n.CollapseActionToolTip);
- this.collapseAllAction.setImageDescriptor(null);
-
- // the delete action will delete one or more servers
- this.deleteAction = null;
- this.deleteAction.setText(I18n.DeleteServerActionText);
- this.deleteAction.setToolTipText(I18n.DeleteServerActionToolTip);
- this.deleteAction.setImageDescriptor(null);
- this.deleteAction.setEnabled(false);
-
- // the edit action is only enabled when one server is selected
- this.editAction = null;
- this.editAction.setText(I18n.EditServerActionText);
- this.editAction.setToolTipText(I18n.EditServerActionToolTip);
- this.editAction.setImageDescriptor(null);
- this.editAction.setEnabled(false);
-
- // the new server action is always enabled
- this.newAction = null;
- this.newAction.setText(I18n.NewServerActionText);
- this.newAction.setToolTipText(I18n.NewServerActionToolTip);
- this.newAction.setImageDescriptor(null);
- }
-
- /**
- * @since 0.6
- */
- private void constructContextMenu() {
- MenuManager menuMgr = new MenuManager();
- menuMgr.add(this.newAction);
- menuMgr.add(this.editAction);
- menuMgr.add(this.deleteAction);
- // menuMgr.setRemoveAllWhenShown(true);
-
- Menu menu = menuMgr.createContextMenu(this.viewer.getTree());
- this.viewer.getTree().setMenu(menu);
- getSite().registerContextMenu(menuMgr, this.viewer);
- }
-
- /**
- * @since 0.6
- */
- private void constructToolBar() {
- IToolBarManager toolBar = getViewSite().getActionBars().getToolBarManager();
- toolBar.add(this.newAction);
- toolBar.add(this.editAction);
- toolBar.add(this.deleteAction);
- toolBar.add(this.collapseAllAction);
- }
-
- /**
- * @param parent the viewer's parent
- * @since 0.6
- */
- private void constructTreeViewer( Composite parent ) {
- this.provider = new RepositoryContentProvider();
- this.viewer = new TreeViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL);
- this.viewer.setContentProvider(this.provider);
- this.viewer.setLabelProvider(this.provider);
- this.viewer.addSelectionChangedListener(new ISelectionChangedListener() {
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
- */
- @Override
- public void selectionChanged( SelectionChangedEvent event ) {
- handleSelectionChanged(event);
- }
- });
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
- * @since 0.6
- */
- @Override
- public void createPartControl( Composite parent ) {
- constructTreeViewer(parent);
- constructActions();
- constructToolBar();
- constructContextMenu();
- }
-
- /**
- * @return the tree viewer
- * @since 0.6
- */
- TreeViewer getViewer() {
- return this.viewer;
- }
-
- /**
- * @param event the event being processed
- * @since 0.6
- */
- void handleSelectionChanged( SelectionChangedEvent event ) {
- IStructuredSelection selection = (IStructuredSelection)event.getSelection();
- updateStatusLine(selection);
- updateActionBars(selection);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
- * @since 0.6
- */
- @Override
- public void setFocus() {
- if (!this.viewer.getControl().isDisposed()) {
- this.viewer.getControl().setFocus();
- }
- }
-
- /**
- * @param selection the current viewer selection (never <code>null</code>)
- * @since 0.6
- */
- private void updateActionBars( IStructuredSelection selection ) {
- if (selection.isEmpty()) {
- this.deleteAction.setEnabled(false);
- this.editAction.setEnabled(false);
- } else {
- assert (selection.size() == 1);
-
- IDnaObject obj = (IDnaObject)selection.getFirstElement();
- boolean enable = (obj instanceof Server);
- this.deleteAction.setEnabled(enable);
- this.editAction.setEnabled(enable);
- }
- }
-
- /**
- * @param selection the current viewer selection (never <code>null</code>)
- * @since 0.6
- */
- private void updateStatusLine( IStructuredSelection selection ) {
- assert (selection.size() < 2);
-
- String msg = (selection.isEmpty() ? "" : ((IDnaObject)selection.getFirstElement()).getShortDescription()); //$NON-NLS-1$
- getViewSite().getActionBars().getStatusLineManager().setMessage(msg);
- }
-}
14 years, 10 months
DNA SVN: r1059 - in trunk: dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory and 4 other directories.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2009-06-22 12:50:22 -0400 (Mon, 22 Jun 2009)
New Revision: 1059
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/UuidAlreadyExistsException.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepository.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrNode.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNode.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrRootNode.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrNodeTest.java
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrRepositoryTest.java
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheRequestProcessor.java
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicRequestProcessor.java
Log:
DNA-370 JcrWorkspace.clone Is Not Implemented
Corrected compilation warnings and errors. The errors were due primarily to JDK 6 methods being used.
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/UuidAlreadyExistsException.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/UuidAlreadyExistsException.java 2009-06-21 00:45:14 UTC (rev 1058)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/UuidAlreadyExistsException.java 2009-06-22 16:50:22 UTC (rev 1059)
@@ -1,3 +1,26 @@
+/*
+ * 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;
import java.util.UUID;
Modified: 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 2009-06-21 00:45:14 UTC (rev 1058)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepository.java 2009-06-22 16:50:22 UTC (rev 1059)
@@ -466,6 +466,7 @@
UUID uuidForCopy = reuseUuids ? original.getUuid() : UUID.randomUUID();
InMemoryNode copy = newWorkspace.createNode(context, newParent, childName, uuidForCopy);
if (!reuseUuids) {
+ assert oldToNewUuids != null;
oldToNewUuids.put(original.getUuid(), copy.getUuid());
}
@@ -480,6 +481,7 @@
}
if (!reuseUuids) {
+ assert oldToNewUuids != null;
// 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();
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrNode.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrNode.java 2009-06-21 00:45:14 UTC (rev 1058)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrNode.java 2009-06-22 16:50:22 UTC (rev 1059)
@@ -717,7 +717,8 @@
JcrNodeDefinition match = this.cache.nodeTypes().findChildNodeDefinition(mixinCandidateType.getInternalName(),
Collections.<Name>emptyList(),
nodeName,
- childNode.getPrimaryNodeType().getInternalName(),
+ childNode.getPrimaryNodeType()
+ .getInternalName(),
snsCount,
false);
@@ -1356,9 +1357,13 @@
}
/**
- * {@inheritDoc}
+ * Obtain the corresponding node path from the supplied workspace name.
*
- * @see javax.jcr.Node#getCorrespondingNodePath(java.lang.String)
+ * @param workspaceName
+ * @return the path of the corresponding node in the supplied workspace
+ * @throws NoSuchWorkspaceException if the workspace does not exist
+ * @throws ItemNotFoundException if there is no corresponding node in the supplied workspace
+ * @throws RepositoryException if there is another problem
*/
final Path correspondingNodePathFrom( String workspaceName )
throws NoSuchWorkspaceException, ItemNotFoundException, RepositoryException {
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNode.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNode.java 2009-06-21 00:45:14 UTC (rev 1058)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNode.java 2009-06-22 16:50:22 UTC (rev 1059)
@@ -72,6 +72,7 @@
*
* @see javax.jcr.Item#getParent()
*/
+ @Override
public AbstractJcrNode getParent() throws ItemNotFoundException, RepositoryException {
return cache.findJcrNode(nodeInfo().getParent());
}
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrRootNode.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrRootNode.java 2009-06-21 00:45:14 UTC (rev 1058)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrRootNode.java 2009-06-22 16:50:22 UTC (rev 1059)
@@ -88,6 +88,7 @@
* @throws ItemNotFoundException always
* @see javax.jcr.Item#getParent()
*/
+ @Override
public AbstractJcrNode getParent() throws ItemNotFoundException {
throw new ItemNotFoundException(JcrI18n.rootNodeHasNoParent.text());
}
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java 2009-06-21 00:45:14 UTC (rev 1058)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java 2009-06-22 16:50:22 UTC (rev 1059)
@@ -355,10 +355,10 @@
Set<UUID> sourceUuids = new HashSet<UUID>();
LinkedList<SubgraphNode> nodesToVisit = new LinkedList<SubgraphNode>();
- nodesToVisit.push(sourceTree.getRoot());
+ nodesToVisit.addFirst(sourceTree.getRoot());
while (!nodesToVisit.isEmpty()) {
- SubgraphNode node = nodesToVisit.pop();
+ SubgraphNode node = nodesToVisit.removeFirst();
UUID uuid = uuidFactory.create(node.getProperty(DnaLexicon.UUID).getFirstValue().toString());
if (uuid != null) {
Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrNodeTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrNodeTest.java 2009-06-21 00:45:14 UTC (rev 1058)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrNodeTest.java 2009-06-22 16:50:22 UTC (rev 1059)
@@ -87,6 +87,7 @@
return cache.getPathFor(nodeInfo()).getLastSegment().getString(namespaces());
}
+ @Override
public AbstractJcrNode getParent() throws RepositoryException {
return cache.findJcrNode(nodeInfo().getParent());
}
Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrRepositoryTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrRepositoryTest.java 2009-06-21 00:45:14 UTC (rev 1058)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrRepositoryTest.java 2009-06-22 16:50:22 UTC (rev 1059)
@@ -184,7 +184,6 @@
repository.login();
}
- @SuppressWarnings("cast")
@Test
public void shouldAllowLoginWithNoCredentialsInPrivilegedBlock() throws Exception {
LoginContext login = new LoginContext("dna-jcr", new UserPasswordCallbackHandler("superuser", "superuser".toCharArray()));
Modified: trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheRequestProcessor.java
===================================================================
--- trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheRequestProcessor.java 2009-06-21 00:45:14 UTC (rev 1058)
+++ trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheRequestProcessor.java 2009-06-22 16:50:22 UTC (rev 1059)
@@ -250,7 +250,7 @@
nodesToVisit.add(node);
while (!nodesToVisit.isEmpty()) {
- Node<Name, Object> nodeToCheck = nodesToVisit.pop();
+ Node<Name, Object> nodeToCheck = nodesToVisit.removeFirst();
UUID uuid = uuidFactory.create(nodeToCheck.get(DnaLexicon.UUID));
if (uuid != null) uuidsFromSource.add(uuid);
@@ -688,8 +688,7 @@
* @param desiredName the desired name of the node in the new location
* @param beforeNodeName the node before which the new node should be placed
* @param recursive if this is a deep copy
- * @param reuseOriginalUuids indicates whether the original UUIDs should be used for the copies or new UUIDs should be used
- * @param uuidForCopyOfOriginal pre-determined UUID for copy of node; ignored if reuseOriginalUuids is true
+ * @param uuidConflictBehavior indicates whether the original UUIDs should be used for the copies or new UUIDs should be used
* @param count the count of nodes affected by the operation
* @param context the execution context that provides the path factory to be used to create the new path name
* @return the path segment that identifies the new node under its new parent
@@ -707,7 +706,8 @@
assert original != null;
assert newParent != null;
// Get or create the new node ...
- Path.Segment name = desiredName != null ? context.getValueFactories().getPathFactory().createSegment(desiredName) : (Path.Segment)original.getFqn().getLastElement();
+ Path.Segment name = desiredName != null ? context.getValueFactories().getPathFactory().createSegment(desiredName) : (Path.Segment)original.getFqn()
+ .getLastElement();
// Update the children to account for same-name siblings.
// This not only updates the FQN of the child nodes, but it also sets the property that stores the
@@ -923,8 +923,9 @@
// don't copy ...
} else {
// Append an updated segment ...
- Path.Segment newSegment = context.getValueFactories().getPathFactory().createSegment(childName.getName(),
- childName.getIndex() - 1);
+ Path.Segment newSegment = context.getValueFactories()
+ .getPathFactory()
+ .createSegment(childName.getName(), childName.getIndex() - 1);
newChildNames[index] = newSegment;
// Replace the child with the correct FQN ...
changeNodeName(cache, parent, childName, newSegment, context);
Modified: trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicRequestProcessor.java
===================================================================
--- trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicRequestProcessor.java 2009-06-21 00:45:14 UTC (rev 1058)
+++ trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicRequestProcessor.java 2009-06-22 16:50:22 UTC (rev 1059)
@@ -2094,7 +2094,7 @@
/**
* Attempt to resolve the reference.
*
- * @param workspaceId the ID of the workspace in which the reference occurs; may not be null
+ * @param workspace the workspace in which the reference occurs; may not be null
* @param reference the reference
* @return the UUID of the node to which the reference points, or null if the reference could not be resolved
*/
@@ -2135,7 +2135,7 @@
* This method will also find the path when the location contains just the UUID.
* </p>
*
- * @param workspaceId the ID of the workspace; may not be null
+ * @param workspace the workspace; may not be null
* @param original the original location; may not be null
* @return the actual location, which includes the verified location and additional information needed by this method that may
* be usable after this method is called
14 years, 10 months
DNA SVN: r1058 - in trunk: dna-jcr/src/main/java/org/jboss/dna/jcr and 2 other directories.
by dna-commits@lists.jboss.org
Author: bcarothers
Date: 2009-06-20 20:45:14 -0400 (Sat, 20 Jun 2009)
New Revision: 1058
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/SetPropertyRequest.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrI18n.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNodeType.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java
trunk/dna-jcr/src/main/resources/org/jboss/dna/jcr/JcrI18n.properties
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/DnaTckTest.java
Log:
DNA-370 JcrWorkspace.clone Is Not Implemented
Committed patch to add constraint checking to clone with removeExisting = true.
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/SetPropertyRequest.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/SetPropertyRequest.java 2009-06-21 00:16:03 UTC (rev 1057)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/SetPropertyRequest.java 2009-06-21 00:45:14 UTC (rev 1058)
@@ -23,6 +23,7 @@
*/
package org.jboss.dna.graph.request;
+import java.util.Arrays;
import org.jboss.dna.common.util.CheckArg;
import org.jboss.dna.common.util.HashCode;
import org.jboss.dna.graph.GraphI18n;
@@ -209,6 +210,6 @@
@Override
public String toString() {
return "set property " + property().getName() + " on " + on() + " in the \"" + workspaceName + "\" workspace to "
- + property().getValuesAsArray();
+ + Arrays.asList(property().getValuesAsArray()).toString();
}
}
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrI18n.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrI18n.java 2009-06-21 00:16:03 UTC (rev 1057)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrI18n.java 2009-06-21 00:45:14 UTC (rev 1058)
@@ -89,6 +89,7 @@
public static I18n unableToSetSingleValuedPropertyUsingMultipleValues;
public static I18n unableToRefreshBranchSinceAtLeastOneNodeMovedToParentOutsideOfBranch;
public static I18n allPropertyValuesMustHaveSameType;
+ public static I18n cannotRemoveNodeFromClone;
public static I18n unableToRemoveRootNode;
public static I18n unableToMoveNodeToBeChildOfDecendent;
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNodeType.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNodeType.java 2009-06-21 00:16:03 UTC (rev 1057)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNodeType.java 2009-06-21 00:45:14 UTC (rev 1058)
@@ -24,6 +24,7 @@
package org.jboss.dna.jcr;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -113,7 +114,7 @@
boolean mixin,
boolean orderableChildNodes ) {
assert context != null;
-
+
this.context = context;
this.nodeTypeManager = nodeTypeManager;
this.name = name;
@@ -140,12 +141,12 @@
JcrNodeType superType = thisAndAllSupertypes.get(i);
for (NodeType superSuperType : superType.getDeclaredSupertypes()) {
JcrNodeType jcrSuperSuperType = (JcrNodeType)superSuperType;
-
+
if (jcrSuperSuperType == null) {
assert JcrNtLexicon.BASE.equals(name);
continue;
}
-
+
if (typeNames.add(jcrSuperSuperType.getInternalName())) {
thisAndAllSupertypes.add(jcrSuperSuperType);
}
@@ -208,6 +209,17 @@
return allDefinitions.allChildNodeDefinitions(childName);
}
+ JcrNodeDefinition childNodeDefinition( NodeDefinitionId nodeDefnId ) {
+ List<Name> requiredPrimaryTypeNames = Arrays.asList(nodeDefnId.getRequiredPrimaryTypes());
+ for (JcrNodeDefinition nodeDefn : allChildNodeDefinitions(nodeDefnId.getChildDefinitionName())) {
+ if (nodeDefn.getRequiredPrimaryTypeNames().size() == requiredPrimaryTypeNames.size()
+ && nodeDefn.getRequiredPrimaryTypeNames().containsAll(requiredPrimaryTypeNames)) {
+ return nodeDefn;
+ }
+ }
+ return null;
+ }
+
/**
* {@inheritDoc}
*
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java 2009-06-21 00:16:03 UTC (rev 1057)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java 2009-06-21 00:45:14 UTC (rev 1058)
@@ -26,12 +26,15 @@
import java.io.IOException;
import java.io.InputStream;
import java.security.AccessControlException;
+import java.util.HashSet;
+import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import javax.jcr.AccessDeniedException;
import javax.jcr.InvalidSerializedDataException;
import javax.jcr.ItemExistsException;
+import javax.jcr.ItemNotFoundException;
import javax.jcr.NamespaceRegistry;
import javax.jcr.NoSuchWorkspaceException;
import javax.jcr.PathNotFoundException;
@@ -50,6 +53,8 @@
import org.jboss.dna.common.util.CheckArg;
import org.jboss.dna.graph.ExecutionContext;
import org.jboss.dna.graph.Graph;
+import org.jboss.dna.graph.Subgraph;
+import org.jboss.dna.graph.SubgraphNode;
import org.jboss.dna.graph.connector.RepositoryConnectionFactory;
import org.jboss.dna.graph.connector.RepositorySource;
import org.jboss.dna.graph.connector.RepositorySourceException;
@@ -60,8 +65,10 @@
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.UuidFactory;
import org.jboss.dna.graph.property.ValueFormatException;
import org.jboss.dna.graph.property.basic.GraphNamespaceRegistry;
+import org.jboss.dna.graph.request.ReadBranchRequest;
import org.jboss.dna.jcr.JcrContentHandler.EnclosingSAXException;
import org.jboss.dna.jcr.JcrContentHandler.SaveMode;
import org.jboss.dna.jcr.JcrRepository.Option;
@@ -308,12 +315,20 @@
Name newNodeName = destPath.getLastSegment().getName();
String parentPath = destPath.getParent().getString(this.context.getNamespaceRegistry());
+ Subgraph sourceTree = null;
// This will check for a definition and throw a ConstraintViolationException or ItemExistsException if none is found
graph.useWorkspace(srcWorkspace);
Property primaryTypeProp;
Property uuidProp;
try {
- Map<Name, Property> props = graph.getNodeAt(srcPath).getPropertiesByName();
+ Map<Name, Property> props;
+
+ if (removeExisting) {
+ sourceTree = graph.getSubgraphOfDepth(ReadBranchRequest.NO_MAXIMUM_DEPTH).at(srcPath);
+ props = sourceTree.getRoot().getPropertiesByName();
+ } else {
+ props = graph.getNodeAt(srcPath).getPropertiesByName();
+ }
primaryTypeProp = props.get(JcrLexicon.PRIMARY_TYPE);
uuidProp = props.get(DnaLexicon.UUID);
} catch (org.jboss.dna.graph.property.PathNotFoundException pnfe) {
@@ -331,12 +346,56 @@
newNodeName,
nameFactory.create(primaryTypeProp.getFirstValue()));
- // Perform the copy operation, but use the "to" form (not the "into", which takes the parent) ...
- // graph.copy(srcPath).fromWorkspace(srcWorkspace).to(destPath);
if (removeExisting) {
+ assert sourceTree != null;
+
+ // Find all of the UUIDS in the source tree
+ UuidFactory uuidFactory = context().getValueFactories().getUuidFactory();
+ PathFactory pathFactory = context().getValueFactories().getPathFactory();
+
+ Set<UUID> sourceUuids = new HashSet<UUID>();
+ LinkedList<SubgraphNode> nodesToVisit = new LinkedList<SubgraphNode>();
+ nodesToVisit.push(sourceTree.getRoot());
+
+ while (!nodesToVisit.isEmpty()) {
+ SubgraphNode node = nodesToVisit.pop();
+
+ UUID uuid = uuidFactory.create(node.getProperty(DnaLexicon.UUID).getFirstValue().toString());
+ if (uuid != null) {
+ sourceUuids.add(uuid);
+ }
+ for (Path.Segment childSegment : node.getChildrenSegments()) {
+ nodesToVisit.add(node.getNode(pathFactory.createRelativePath(childSegment)));
+ }
+ }
+
+ // See if the nodes exist in the current workspace outside of the current tree
+ for (UUID uuid : sourceUuids) {
+ NodeInfo nodeInfo = null;
+ try {
+ nodeInfo = session.cache().findNodeInfo(uuid);
+ } catch (ItemNotFoundException infe) {
+ continue;
+ }
+ assert nodeInfo != null;
+
+ NodeDefinitionId nodeDefnId = nodeInfo.getDefinitionId();
+
+ JcrNodeType nodeType = nodeTypeManager.getNodeType(nodeDefnId.getNodeTypeName());
+ JcrNodeDefinition nodeDefn = nodeType.childNodeDefinition(nodeDefnId);
+ if (nodeDefn.isMandatory()) {
+ // We can't just remove a mandatory node... unless its parent will be removed too!
+ String path = session.cache().getPathFor(nodeInfo).getString(context().getNamespaceRegistry());
+ throw new ConstraintViolationException(JcrI18n.cannotRemoveNodeFromClone.text(path, uuid));
+
+ }
+ }
+
+ // Perform the copy operation, but use the "to" form (not the "into", which takes the parent) ...
graph.copy(srcPath).replacingExistingNodesWithSameUuids().fromWorkspace(srcWorkspace).to(destPath);
} else {
try {
+ // Perform the copy operation, but use the "to" form (not the "into", which takes the parent) ...
graph.copy(srcPath).failingIfUuidsMatch().fromWorkspace(srcWorkspace).to(destPath);
} catch (UuidAlreadyExistsException uaee) {
throw new ItemExistsException(uaee.getMessage());
Modified: trunk/dna-jcr/src/main/resources/org/jboss/dna/jcr/JcrI18n.properties
===================================================================
--- trunk/dna-jcr/src/main/resources/org/jboss/dna/jcr/JcrI18n.properties 2009-06-21 00:16:03 UTC (rev 1057)
+++ trunk/dna-jcr/src/main/resources/org/jboss/dna/jcr/JcrI18n.properties 2009-06-21 00:45:14 UTC (rev 1058)
@@ -79,6 +79,7 @@
unableToSetSingleValuedPropertyUsingMultipleValues = Unable to set existing single-valued property "{0}" on node "{1}" in workspace "{2}" using multi-value setter methods
unableToRefreshBranchSinceAtLeastOneNodeMovedToParentOutsideOfBranch = Unable to refresh "{0}" in workspace "{2}" because at least one of its decendants was moved to another node outside of the branch that is not being refreshed
allPropertyValuesMustHaveSameType = All values of property "{0}" on node "{3}" in workspace "{4}" must all be {2} values (values were: {1})
+cannotRemoveNodeFromClone = The node at "{0}" with UUID "{1}" exists in the current workspace but cannot be removed because it is a mandatory child node
unableToRemoveRootNode = Unable to remove the root node in workspace "{1}"
unableToMoveNodeToBeChildOfDecendent = Node "{0}" in workspace "{2}" cannot be moved under a decendant node ("{1}")
Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/DnaTckTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/DnaTckTest.java 2009-06-21 00:16:03 UTC (rev 1057)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/DnaTckTest.java 2009-06-21 00:45:14 UTC (rev 1058)
@@ -1,5 +1,7 @@
package org.jboss.dna.jcr;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
import javax.jcr.AccessDeniedException;
import javax.jcr.Credentials;
import javax.jcr.Node;
@@ -8,6 +10,7 @@
import javax.jcr.Property;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
+import javax.jcr.nodetype.ConstraintViolationException;
import org.apache.jackrabbit.test.AbstractJCRTest;
/**
@@ -197,4 +200,74 @@
assertNotNull(node4node1node2);
}
+
+ /**
+ * A clone operation with removeExisting = true should fail if it would require removing an existing node that is a mandatory
+ * child node of some other parent (and not replacing it as part of the clone operation).
+ *
+ * @throws Exception if an error occurs
+ */
+ public void testShouldNotCloneIfItWouldViolateTypeSemantics() throws Exception {
+ session = helper.getSuperuserSession("otherWorkspace");
+ assertThat(session.getWorkspace().getName(), is("otherWorkspace"));
+
+ String nodetype1 = this.getProperty("nodetype");
+ Node node1 = session.getRootNode().addNode("cloneSource", nodetype1);
+ // This node is not a mandatory child of nodetype1 (dnatest:referenceableUnstructured)
+ node1.addNode("dnatest:mandatoryChild", nodetype1);
+
+ session.save();
+ session.logout();
+
+ // /node4 in the default workspace is type dna:referenceableUnstructured
+ superuser.getRootNode().addNode("cloneTarget", nodetype1);
+
+ // /node3 in the default workspace is type dna:referenceableUnstructured
+ superuser.getRootNode().addNode(nodeName3, nodetype1);
+ superuser.save();
+
+ // Throw the cloned items under node4
+ superuser.getWorkspace().clone("otherWorkspace", "/cloneSource", "/cloneTarget/cloneSource", false);
+
+ superuser.refresh(false);
+ Node node3 = (Node)superuser.getItem("/node3");
+ assertThat(node3.getNodes().getSize(), is(0L));
+
+ Node node4node1 = (Node)superuser.getItem("/cloneTarget/cloneSource");
+ assertThat(node4node1.getNodes().getSize(), is(1L));
+
+ // Now clone from the same source under node3 and remove the existing records
+ superuser.getWorkspace().clone("otherWorkspace", "/cloneSource", "/" + nodeName3 + "/cloneSource", true);
+ superuser.refresh(false);
+
+ Node node3node1 = (Node)superuser.getItem("/node3/cloneSource");
+ assertThat(node3node1.getNodes().getSize(), is(1L));
+
+ // Check that the nodes were indeed removed
+ Node node4 = (Node)superuser.getItem("/cloneTarget");
+
+ assertThat(node4.getNodes().getSize(), is(0L));
+
+ superuser.getRootNode().addNode("nodeWithMandatoryChild", "dnatest:nodeWithMandatoryChild");
+ try {
+ superuser.save();
+ fail("A node with type dnatest:nodeWithMandatoryChild should not be savable until the child is added");
+ } catch (ConstraintViolationException cve) {
+ // Expected
+ }
+
+ superuser.move("/node3/cloneSource/dnatest:mandatoryChild", "/nodeWithMandatoryChild/dnatest:mandatoryChild");
+ superuser.save();
+ superuser.refresh(false);
+
+ // Now clone from the same source under node3 and remove the existing records
+ try {
+ superuser.getWorkspace().clone("otherWorkspace", "/cloneSource", "/" + nodeName3 + "/cloneSource", true);
+ fail("Should not be able to use clone to remove the mandatory child node at /nodeWithMandatoryChild/dnatest:mandatoryChild");
+ } catch (ConstraintViolationException cve) {
+ // expected
+ }
+
+ }
+
}
14 years, 10 months