Author: rhauch
Date: 2008-08-19 15:34:42 -0400 (Tue, 19 Aug 2008)
New Revision: 449
Added:
trunk/extensions/dna-connector-federation/src/test/java/org/jboss/dna/connector/federation/merge/OneContributionMergeStrategyTest.java
Modified:
trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/executor/FederatingCommandExecutor.java
trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/merge/FederatedNode.java
trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/merge/MergeStrategy.java
trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/merge/OneContributionMergeStrategy.java
Log:
DNA-188 - Complete the federating command executor
http://jira.jboss.com/jira/browse/DNA-188
Added more unit tests for the OneContributionMergeStrategy class.
Modified:
trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/executor/FederatingCommandExecutor.java
===================================================================
---
trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/executor/FederatingCommandExecutor.java 2008-08-19
19:34:20 UTC (rev 448)
+++
trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/executor/FederatingCommandExecutor.java 2008-08-19
19:34:42 UTC (rev 449)
@@ -381,6 +381,7 @@
// If there are no contributions from any source ...
boolean foundNonEmptyContribution = false;
for (Contribution contribution : contributions) {
+ assert contribution != null;
if (!contribution.isEmpty()) {
foundNonEmptyContribution = true;
break;
@@ -398,6 +399,8 @@
// Merge the results into a single set of results ...
FederatedNode mergedNode = new FederatedNode(path, UUID.randomUUID());
ExecutionContext context = getExecutionContext();
+ assert contributions.size() > 0;
+ assert context != null;
mergingStrategy.merge(mergedNode, contributions, context);
if (mergedNode.getCachePolicy() == null) {
mergedNode.setCachePolicy(defaultCachePolicy);
@@ -522,138 +525,6 @@
}
}
- // /**
- // * Load the node at the supplied path, returning the information. This method
always obtains the information from the
- // sources
- // * and does not use or update the cache.
- // *
- // * @param path the path of the node that is to be loaded
- // * @return the federated node containing information loaded from the sources, or
null if none of the sources had a
- // * contribution
- // * @throws InterruptedException
- // * @throws RepositorySourceException
- // */
- // protected FederatedNode loadFromSources( Path path ) throws
RepositorySourceException, InterruptedException {
- // // At this point, there is no merge plan, so read information from the sources
...
- // ExecutionContext context = getExecutionContext();
- // PathFactory pathFactory = context.getValueFactories().getPathFactory();
- // DateTimeFactory timeFactory = context.getValueFactories().getDateFactory();
- // List<Contribution> contributions = new LinkedList<Contribution>();
- // boolean foundContribution = false;
- // for (Projection projection : this.sourceProjections) {
- // final String source = projection.getSourceName();
- // final RepositoryConnection sourceConnection = getConnection(projection);
- // if (sourceConnection == null) continue; // No source exists by this name
- // try {
- // // Get the cached information ...
- // CachePolicy cachePolicy = sourceConnection.getDefaultCachePolicy();
- // if (cachePolicy == null) cachePolicy = this.defaultCachePolicy;
- // DateTime expirationTime = null;
- // if (cachePolicy != null) {
- // expirationTime = getCurrentTimeInUtc().plus(cachePolicy.getTimeToLive(),
TimeUnit.MILLISECONDS);
- // }
- // // Get the paths-in-source where we should fetch node contributions ...
- // Set<Path> pathsInSource = projection.getPathsInSource(path, pathFactory);
- // if (pathsInSource.isEmpty()) {
- // // The source has no contributions, but see whether the project exists BELOW this
path.
- // // We do this by getting the top-level repository paths of the projection, and
then
- // // use those to figure out the children of the nodes.
- // Contribution contribution = null;
- // Set<Path> topLevelPaths =
projection.getTopLevelPathsInRepository(pathFactory);
- // switch (topLevelPaths.size()) {
- // case 0:
- // break;
- // case 1: {
- // Path topLevelPath = topLevelPaths.iterator().next();
- // if (path.isAncestorOf(topLevelPath)) {
- // assert topLevelPath.size() > path.size();
- // Path.Segment child = topLevelPath.getSegment(path.size());
- // contribution = Contribution.create(source, path, expirationTime, null, child);
- // foundContribution = true;
- // }
- // break;
- // }
- // default: {
- // Set<Path.Segment> children = new HashSet<Path.Segment>();
- // for (Path topLevelPath : topLevelPaths) {
- // if (path.isAncestorOf(topLevelPath)) {
- // assert topLevelPath.size() > path.size();
- // Path.Segment child = topLevelPath.getSegment(path.size());
- // children.add(child);
- // }
- // }
- // if (children.size() > 0) {
- // contribution = Contribution.create(source, path, expirationTime, null, children);
- // foundContribution = true;
- // }
- // }
- // }
- // if (contribution == null) contribution = Contribution.create(source,
expirationTime);
- // contributions.add(contribution);
- // } else {
- // // There is at least one (real) contribution ...
- //
- // // Get the contributions ...
- // final int numPaths = pathsInSource.size();
- // if (numPaths == 1) {
- // Path pathInSource = pathsInSource.iterator().next();
- // BasicGetNodeCommand fromSource = new BasicGetNodeCommand(pathInSource);
- // sourceConnection.execute(getExecutionContext(), fromSource);
- // if (!fromSource.hasError()) {
- // Collection<Property> properties = fromSource.getProperties();
- // Collection<Segment> children = fromSource.getChildren();
- // DateTime expTime = fromSource.getCachePolicy() == null ? expirationTime :
timeFactory.create(getCurrentTimeInUtc(),
- // fromSource.getCachePolicy().getTimeToLive());
- // Contribution contribution = Contribution.create(source, pathInSource, expTime,
properties, children);
- // if (!contribution.isEmpty()) foundContribution = true;
- // contributions.add(contribution);
- // }
- // } else {
- // BasicGetNodeCommand[] fromSourceCommands = new BasicGetNodeCommand[numPaths];
- // int i = 0;
- // for (Path pathInSource : pathsInSource) {
- // fromSourceCommands[i++] = new BasicGetNodeCommand(pathInSource);
- // }
- // sourceConnection.execute(context, fromSourceCommands);
- // for (BasicGetNodeCommand fromSource : fromSourceCommands) {
- // if (fromSource.hasError()) continue;
- // Collection<Property> properties = fromSource.getProperties();
- // Collection<Segment> children = fromSource.getChildren();
- // DateTime expTime = fromSource.getCachePolicy() == null ? expirationTime :
timeFactory.create(getCurrentTimeInUtc(),
- // fromSource.getCachePolicy().getTimeToLive());
- // Contribution contribution = Contribution.create(source,
- // fromSource.getPath(),
- // expTime,
- // properties,
- // children);
- // if (!contribution.isEmpty()) foundContribution = true;
- // contributions.add(contribution);
- // }
- // }
- // }
- // } finally {
- // sourceConnection.close();
- // }
- // }
- // // If there are no contributions from any source ...
- // if (!foundContribution) return null;
- // if (logger.isTraceEnabled()) {
- // logger.trace("Loaded {0} from sources, resulting in these
contributions:", path);
- // int i = 0;
- // for (Contribution contribution : contributions) {
- // logger.trace(" {0} {1}", ++i, contribution);
- // }
- // }
- //
- // // Merge the results into a single set of results ...
- // FederatedNode mergedNode = new FederatedNode(path, UUID.randomUUID());
- // mergingStrategy.merge(mergedNode, contributions, context);
- // if (mergedNode.getCachePolicy() == null) {
- // mergedNode.setCachePolicy(defaultCachePolicy);
- // }
- // return mergedNode;
- // }
- //
protected MergePlan getMergePlan( BasicGetNodeCommand command ) {
Property mergePlanProperty =
command.getPropertiesByName().get(mergePlanPropertyName);
if (mergePlanProperty == null || mergePlanProperty.isEmpty()) {
Modified:
trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/merge/FederatedNode.java
===================================================================
---
trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/merge/FederatedNode.java 2008-08-19
19:34:20 UTC (rev 448)
+++
trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/merge/FederatedNode.java 2008-08-19
19:34:42 UTC (rev 449)
@@ -38,7 +38,7 @@
private static final long serialVersionUID = 1L;
- private final UUID uuid;
+ private UUID uuid;
private MergePlan mergePlan;
private NodeConflictBehavior nodeConflictBehavior = DEFAULT_CONFLICT_BEHAVIOR;
@@ -65,6 +65,13 @@
}
/**
+ * @param uuid Sets uuid to the specified value.
+ */
+ public void setUuid( UUID uuid ) {
+ this.uuid = uuid;
+ }
+
+ /**
* Get the merge plan for this federated node
*
* @return the merge plan, or null if there is no merge plan
Modified:
trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/merge/MergeStrategy.java
===================================================================
---
trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/merge/MergeStrategy.java 2008-08-19
19:34:20 UTC (rev 448)
+++
trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/merge/MergeStrategy.java 2008-08-19
19:34:42 UTC (rev 449)
@@ -34,7 +34,7 @@
* Merge the contributions into a single
*
* @param federatedNode the federated node into which the contributions are to be
merged; never null
- * @param contributions the contributions to the node; never null
+ * @param contributions the contributions to the node; never null, never empty, and
never containing nulls
* @param context the context in which this operation is to be performed; never null
*/
public void merge( FederatedNode federatedNode,
Modified:
trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/merge/OneContributionMergeStrategy.java
===================================================================
---
trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/merge/OneContributionMergeStrategy.java 2008-08-19
19:34:20 UTC (rev 448)
+++
trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/merge/OneContributionMergeStrategy.java 2008-08-19
19:34:42 UTC (rev 449)
@@ -24,10 +24,13 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.UUID;
import org.jboss.dna.connector.federation.contribution.Contribution;
import org.jboss.dna.spi.ExecutionContext;
+import org.jboss.dna.spi.graph.IoException;
import org.jboss.dna.spi.graph.Name;
import org.jboss.dna.spi.graph.Property;
+import org.jboss.dna.spi.graph.UuidFactory;
import org.jboss.dna.spi.graph.Path.Segment;
/**
@@ -37,6 +40,9 @@
/**
* {@inheritDoc}
+ * <p>
+ * This method only uses the one and only one non-null {@link Contribution} in the
<code>contributions</code>.
+ * </p>
*
* @see
org.jboss.dna.connector.federation.merge.MergeStrategy#merge(org.jboss.dna.connector.federation.merge.FederatedNode,
* java.util.List, org.jboss.dna.spi.ExecutionContext)
@@ -46,8 +52,9 @@
ExecutionContext context ) {
assert federatedNode != null;
assert contributions != null;
- assert contributions.size() == 1;
+ assert contributions.size() > 0;
Contribution contribution = contributions.get(0);
+ assert contribution != null;
// Copy the children ...
List<Segment> children = federatedNode.getChildren();
children.clear();
@@ -59,11 +66,26 @@
// Copy the properties ...
Map<Name, Property> properties = federatedNode.getPropertiesByName();
properties.clear();
+ UUID uuid = null;
+ UuidFactory uuidFactory = null;
Iterator<Property> propertyIterator = contribution.getProperties();
while (propertyIterator.hasNext()) {
Property property = propertyIterator.next();
properties.put(property.getName(), property);
+ if (uuid == null &&
property.getName().getLocalName().equals("uuid") && property.isSingle())
{
+ if (uuidFactory == null) uuidFactory =
context.getValueFactories().getUuidFactory();
+ try {
+ uuid = uuidFactory.create(property.getValues().next());
+ } catch (IoException e) {
+ // Ignore conversion exceptions
+ }
+ }
}
+ // If we found a single "uuid" property whose value is a valid UUID ..
+ if (uuid != null) {
+ // then set the UUID on the federated node ...
+ federatedNode.setUuid(uuid);
+ }
// Assign the merge plan ...
MergePlan mergePlan = MergePlan.create(contributions);
federatedNode.setMergePlan(mergePlan);
Added:
trunk/extensions/dna-connector-federation/src/test/java/org/jboss/dna/connector/federation/merge/OneContributionMergeStrategyTest.java
===================================================================
---
trunk/extensions/dna-connector-federation/src/test/java/org/jboss/dna/connector/federation/merge/OneContributionMergeStrategyTest.java
(rev 0)
+++
trunk/extensions/dna-connector-federation/src/test/java/org/jboss/dna/connector/federation/merge/OneContributionMergeStrategyTest.java 2008-08-19
19:34:42 UTC (rev 449)
@@ -0,0 +1,207 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.connector.federation.merge;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNot.not;
+import static org.hamcrest.core.IsSame.sameInstance;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.stub;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import org.jboss.dna.connector.federation.contribution.Contribution;
+import org.jboss.dna.spi.ExecutionContext;
+import org.jboss.dna.spi.connector.BasicExecutionContext;
+import org.jboss.dna.spi.graph.Name;
+import org.jboss.dna.spi.graph.Path;
+import org.jboss.dna.spi.graph.Property;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.mockito.MockitoAnnotations;
+import org.mockito.MockitoAnnotations.Mock;
+
+/**
+ * @author Randall Hauch
+ */
+public class OneContributionMergeStrategyTest {
+
+ private OneContributionMergeStrategy strategy;
+ private List<Contribution> contributions;
+ private ExecutionContext context;
+ private FederatedNode node;
+ private Map<Name, Property> properties;
+ private List<Path.Segment> children;
+ @Mock
+ private Contribution contribution;
+
+ @Before
+ public void beforeEach() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ Path path = mock(Path.class);
+ node = new FederatedNode(path, UUID.randomUUID());
+ strategy = new OneContributionMergeStrategy();
+ contributions = new LinkedList<Contribution>();
+ contributions.add(contribution);
+ context = new BasicExecutionContext();
+ context.getNamespaceRegistry().register("dna",
"http://www.jboss.org/dna/something");
+ context.getNamespaceRegistry().register("jcr",
"http://www.jcr.org");
+ stub(contribution.getSourceName()).toReturn("source name");
+ children = new LinkedList<Path.Segment>();
+ for (int i = 0; i != 10; ++i) {
+
children.add(context.getValueFactories().getPathFactory().createSegment("a" +
i));
+ }
+ properties = new HashMap<Name, Property>();
+ for (int i = 0; i != 10; ++i) {
+ Name propertyName =
context.getValueFactories().getNameFactory().create("property" + i);
+ properties.put(propertyName,
context.getPropertyFactory().create(propertyName, "value"));
+ }
+ }
+
+ @Test
+ public void shouldMegeTheChildrenFromTheFirstContribution() {
+ stub(contribution.getChildren()).toReturn(children.iterator());
+ stub(contribution.getProperties()).toReturn(properties.values().iterator());
+ strategy.merge(node, contributions, context);
+ assertThat(node.getChildren(), is(children));
+ }
+
+ @Test
+ public void shouldMegeThePropertiesFromTheFirstContribution() {
+ stub(contribution.getChildren()).toReturn(children.iterator());
+ stub(contribution.getProperties()).toReturn(properties.values().iterator());
+ stub(contribution.getProperties()).toReturn(properties.values().iterator());
+ strategy.merge(node, contributions, context);
+ assertThat(node.getPropertiesByName(), is(properties));
+ }
+
+ @Test
+ public void shouldCreateMergePlanInTheFederatedNode() {
+ stub(contribution.getChildren()).toReturn(children.iterator());
+ stub(contribution.getProperties()).toReturn(properties.values().iterator());
+ strategy.merge(node, contributions, context);
+ MergePlan mergePlan = node.getMergePlan();
+ assertThat(mergePlan.getContributionFrom(contribution.getSourceName()),
is(sameInstance(contribution)));
+ assertThat(mergePlan.getContributionCount(), is(1));
+ }
+
+ @Test
+ public void
shouldSetTheUuidOnTheNodeIfThereIsASingleValuedPropertyNamedUuidWithValueThatConvertsToUuidInstance()
{
+ // Test the "dna:uuid" property ...
+ Name uuidName =
context.getValueFactories().getNameFactory().create("dna:uuid");
+ UUID uuid = UUID.randomUUID();
+ Property uuidProperty = context.getPropertyFactory().create(uuidName, uuid);
+ properties.put(uuidProperty.getName(), uuidProperty);
+ stub(contribution.getChildren()).toReturn(children.iterator());
+ stub(contribution.getProperties()).toReturn(properties.values().iterator());
+ assertThat(node.getUuid(), is(not(uuid)));
+ strategy.merge(node, contributions, context);
+ assertThat(node.getUuid(), is(uuid));
+ properties.remove(uuidProperty.getName());
+
+ // Test the "jcr:uuid" property ...
+ uuidName =
context.getValueFactories().getNameFactory().create("jcr:uuid");
+ uuid = UUID.randomUUID();
+ uuidProperty = context.getPropertyFactory().create(uuidName, uuid);
+ properties.put(uuidProperty.getName(), uuidProperty);
+ stub(contribution.getChildren()).toReturn(children.iterator());
+ stub(contribution.getProperties()).toReturn(properties.values().iterator());
+ assertThat(node.getUuid(), is(not(uuid)));
+ strategy.merge(node, contributions, context);
+ assertThat(node.getUuid(), is(uuid));
+ properties.remove(uuidProperty.getName());
+
+ // Test the "uuid" property ...
+ uuidName =
context.getValueFactories().getNameFactory().create("uuid");
+ uuid = UUID.randomUUID();
+ uuidProperty = context.getPropertyFactory().create(uuidName, uuid);
+ properties.put(uuidProperty.getName(), uuidProperty);
+ stub(contribution.getChildren()).toReturn(children.iterator());
+ stub(contribution.getProperties()).toReturn(properties.values().iterator());
+ assertThat(node.getUuid(), is(not(uuid)));
+ strategy.merge(node, contributions, context);
+ assertThat(node.getUuid(), is(uuid));
+ properties.remove(uuidProperty.getName());
+
+ // Test the "uuid" property whose value is a String ...
+ uuidName =
context.getValueFactories().getNameFactory().create("uuid");
+ uuid = UUID.randomUUID();
+ uuidProperty = context.getPropertyFactory().create(uuidName, uuid.toString());
+ properties.put(uuidProperty.getName(), uuidProperty);
+ stub(contribution.getChildren()).toReturn(children.iterator());
+ stub(contribution.getProperties()).toReturn(properties.values().iterator());
+ assertThat(node.getUuid(), is(not(uuid)));
+ strategy.merge(node, contributions, context);
+ assertThat(node.getUuid(), is(uuid));
+ properties.remove(uuidProperty.getName());
+ }
+
+ @Test
+ public void shouldNotSetTheUuidOnTheNodeIfThereIsNoPropertyNamedUuid() {
+ // Test the "dna:uuid" property ...
+ Name uuidName =
context.getValueFactories().getNameFactory().create("dna:uuid");
+ UUID uuid = UUID.randomUUID();
+ Property uuidProperty = context.getPropertyFactory().create(uuidName, uuid);
+ properties.put(uuidProperty.getName(), uuidProperty);
+ stub(contribution.getChildren()).toReturn(children.iterator());
+ stub(contribution.getProperties()).toReturn(properties.values().iterator());
+ assertThat(node.getUuid(), is(not(uuid)));
+ strategy.merge(node, contributions, context);
+ assertThat(node.getUuid(), is(uuid));
+ properties.remove(uuidProperty.getName());
+ }
+
+ @Test
+ public void shouldNotSetTheUuidOnTheNodeIfThereIsAMultiValuedPropertyNamedUuid() {
+ final UUID originalUuid = node.getUuid();
+ // Test the "dna:uuid" property ...
+ Name uuidName =
context.getValueFactories().getNameFactory().create("dna:uuid");
+ Property uuidProperty = context.getPropertyFactory().create(uuidName,
+ UUID.randomUUID(),
+ UUID.randomUUID(),
+ UUID.randomUUID());
+ properties.put(uuidProperty.getName(), uuidProperty);
+ stub(contribution.getChildren()).toReturn(children.iterator());
+ stub(contribution.getProperties()).toReturn(properties.values().iterator());
+ strategy.merge(node, contributions, context);
+ assertThat(node.getUuid(), is(originalUuid));
+ }
+
+ @Ignore
+ @Test
+ public void
shouldNotSetTheUuidOnTheNodeIfThereIsASingleValuedPropertyNamedUuidWithValueThatDoesNotConvertToUuidInstance()
{
+ final UUID originalUuid = node.getUuid();
+ // Test the "dna:uuid" property ...
+ Name uuidName =
context.getValueFactories().getNameFactory().create("dna:uuid");
+ Property uuidProperty = context.getPropertyFactory().create(uuidName, 3.33d);
+ properties.put(uuidProperty.getName(), uuidProperty);
+ stub(contribution.getChildren()).toReturn(children.iterator());
+ stub(contribution.getProperties()).toReturn(properties.values().iterator());
+ strategy.merge(node, contributions, context);
+ assertThat(node.getUuid(), is(originalUuid));
+ }
+
+}
Property changes on:
trunk/extensions/dna-connector-federation/src/test/java/org/jboss/dna/connector/federation/merge/OneContributionMergeStrategyTest.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain