[dna-commits] DNA SVN: r862 - in trunk: dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory and 10 other directories.

dna-commits at lists.jboss.org dna-commits at lists.jboss.org
Wed Apr 29 08:58:43 EDT 2009


Author: rhauch
Date: 2009-04-29 08:58:43 -0400 (Wed, 29 Apr 2009)
New Revision: 862

Modified:
   trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithPathAndProperty.java
   trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositorySource.java
   trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/basic/JodaDateTime.java
   trunk/dna-graph/src/main/java/org/jboss/dna/graph/xml/XmlHandler.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/main/java/org/jboss/dna/jcr/SessionCache.java
   trunk/docs/examples/gettingstarted/repositories/src/main/java/org/jboss/example/dna/repository/RepositoryClient.java
   trunk/docs/examples/gettingstarted/repositories/src/main/resources/configRepository.xml
   trunk/docs/examples/gettingstarted/repositories/src/test/java/org/jboss/example/dna/repository/RepositoryClientTest.java
   trunk/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/contribution/Contribution.java
   trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/merge/MergePlan.java
   trunk/extensions/dna-connector-federation/src/test/java/org/jboss/dna/connector/federation/FederatedRepositorySourceIntegrationTest.java
Log:
DNA-282 Federation connector improperly handles root-level node with one projection of a non-root node from a single source

Corrected the connector to properly handle root-level nodes in this particular case.  The problem was in how the UUIDs were being handled.  Fixed a couple of other minor issues as well.  

Found another issue while getting the Getting Started repository examples running (see DNA-387).

Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithPathAndProperty.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithPathAndProperty.java	2009-04-28 19:33:35 UTC (rev 861)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithPathAndProperty.java	2009-04-29 12:58:43 UTC (rev 862)
@@ -182,8 +182,8 @@
     @Override
     public Location with( UUID uuid ) {
         Property idProperty = idProperties.get(0); // fast
+        if (uuid == null) return Location.create(path);
         assert !DnaLexicon.UUID.equals(idProperty.getName());
-        if (uuid == null) return Location.create(path);
         Property newUuidProperty = new BasicSingleValueProperty(DnaLexicon.UUID, uuid);
         return Location.create(path, idProperty, newUuidProperty);
     }

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-04-28 19:33:35 UTC (rev 861)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositorySource.java	2009-04-29 12:58:43 UTC (rev 862)
@@ -71,21 +71,26 @@
      */
     public static final int DEFAULT_RETRY_LIMIT = 0;
 
+    /**
+     * The default name for the workspace used by this source, which is a blank string.
+     */
+    public static final String DEFAULT_WORKSPACE_NAME = "";
+
     protected static final RepositorySourceCapabilities CAPABILITIES = new RepositorySourceCapabilities(true, true, false, true,
                                                                                                         true);
 
-    protected static final String ROOT_NODE_UUID = "rootNodeUuid";
-    protected static final String SOURCE_NAME = "sourceName";
-    protected static final String DEFAULT_WORKSPACE_NAME = "defaultWorkspaceName";
-    protected static final String DEFAULT_CACHE_POLICY = "defaultCachePolicy";
-    protected static final String JNDI_NAME = "jndiName";
-    protected static final String RETRY_LIMIT = "retryLimit";
+    protected static final String ROOT_NODE_UUID_ATTR = "rootNodeUuid";
+    protected static final String SOURCE_NAME_ATTR = "sourceName";
+    protected static final String DEFAULT_WORKSPACE_NAME_ATTR = "defaultWorkspaceName";
+    protected static final String DEFAULT_CACHE_POLICY_ATTR = "defaultCachePolicy";
+    protected static final String JNDI_NAME_ATTR = "jndiName";
+    protected static final String RETRY_LIMIT_ATTR = "retryLimit";
 
     @GuardedBy( "sourcesLock" )
     private String name;
     @GuardedBy( "this" )
     private String jndiName;
-    private String defaultWorkspaceName;
+    private String defaultWorkspaceName = DEFAULT_WORKSPACE_NAME;
     private UUID rootNodeUuid = UUID.randomUUID();
     private CachePolicy defaultCachePolicy;
     private final AtomicInteger retryLimit = new AtomicInteger(DEFAULT_RETRY_LIMIT);
@@ -164,7 +169,7 @@
      * @param defaultWorkspaceName the name of the workspace that should be used by default, or null if "" should be used
      */
     public void setDefaultWorkspaceName( String defaultWorkspaceName ) {
-        this.defaultWorkspaceName = defaultWorkspaceName;
+        this.defaultWorkspaceName = defaultWorkspaceName != null ? defaultWorkspaceName : DEFAULT_WORKSPACE_NAME;
     }
 
     /**
@@ -265,16 +270,16 @@
         Reference ref = new Reference(className, factoryClassName, null);
 
         if (getName() != null) {
-            ref.add(new StringRefAddr(SOURCE_NAME, getName()));
+            ref.add(new StringRefAddr(SOURCE_NAME_ATTR, getName()));
         }
         if (getRootNodeUuid() != null) {
-            ref.add(new StringRefAddr(ROOT_NODE_UUID, getRootNodeUuid().toString()));
+            ref.add(new StringRefAddr(ROOT_NODE_UUID_ATTR, getRootNodeUuid().toString()));
         }
         if (getJndiName() != null) {
-            ref.add(new StringRefAddr(JNDI_NAME, getJndiName()));
+            ref.add(new StringRefAddr(JNDI_NAME_ATTR, getJndiName()));
         }
         if (getDefaultWorkspaceName() != null) {
-            ref.add(new StringRefAddr(DEFAULT_WORKSPACE_NAME, getDefaultWorkspaceName()));
+            ref.add(new StringRefAddr(DEFAULT_WORKSPACE_NAME_ATTR, getDefaultWorkspaceName()));
         }
         if (getDefaultCachePolicy() != null) {
             ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -282,13 +287,13 @@
             try {
                 ObjectOutputStream oos = new ObjectOutputStream(baos);
                 oos.writeObject(policy);
-                ref.add(new BinaryRefAddr(DEFAULT_CACHE_POLICY, baos.toByteArray()));
+                ref.add(new BinaryRefAddr(DEFAULT_CACHE_POLICY_ATTR, baos.toByteArray()));
             } catch (IOException e) {
                 I18n msg = GraphI18n.errorSerializingInMemoryCachePolicyInSource;
                 throw new RepositorySourceException(getName(), msg.text(policy.getClass().getName(), getName()), e);
             }
         }
-        ref.add(new StringRefAddr(RETRY_LIMIT, Integer.toString(getRetryLimit())));
+        ref.add(new StringRefAddr(RETRY_LIMIT_ATTR, Integer.toString(getRetryLimit())));
         return ref;
     }
 
@@ -321,12 +326,12 @@
                     }
                 }
             }
-            String sourceName = (String)values.get(SOURCE_NAME);
-            String rootNodeUuidString = (String)values.get(ROOT_NODE_UUID);
-            String jndiName = (String)values.get(JNDI_NAME);
-            String defaultWorkspaceName = (String)values.get(DEFAULT_WORKSPACE_NAME);
-            Object defaultCachePolicy = values.get(DEFAULT_CACHE_POLICY);
-            String retryLimit = (String)values.get(RETRY_LIMIT);
+            String sourceName = (String)values.get(SOURCE_NAME_ATTR);
+            String rootNodeUuidString = (String)values.get(ROOT_NODE_UUID_ATTR);
+            String jndiName = (String)values.get(JNDI_NAME_ATTR);
+            String defaultWorkspaceName = (String)values.get(DEFAULT_WORKSPACE_NAME_ATTR);
+            Object defaultCachePolicy = values.get(DEFAULT_CACHE_POLICY_ATTR);
+            String retryLimit = (String)values.get(RETRY_LIMIT_ATTR);
 
             // Create the source instance ...
             InMemoryRepositorySource source = new InMemoryRepositorySource();

Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/basic/JodaDateTime.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/basic/JodaDateTime.java	2009-04-28 19:33:35 UTC (rev 861)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/basic/JodaDateTime.java	2009-04-29 12:58:43 UTC (rev 862)
@@ -320,6 +320,7 @@
         if (that instanceof JodaDateTime) {
             return this.instance.compareTo(((JodaDateTime)that).instance);
         }
+        if (that == null) return 1;
         long diff = this.toUtcTimeZone().getMilliseconds() - that.toUtcTimeZone().getMilliseconds();
         return (int)diff;
     }
@@ -406,7 +407,7 @@
      * @see org.jboss.dna.graph.property.DateTime#minus(long, java.util.concurrent.TimeUnit)
      */
     public org.jboss.dna.graph.property.DateTime minus( long timeAmount,
-                                                          TimeUnit unit ) {
+                                                        TimeUnit unit ) {
         CheckArg.isNotNull(unit, "unit");
         return new JodaDateTime(this.instance.minus(TimeUnit.MILLISECONDS.convert(timeAmount, unit)));
     }
@@ -489,7 +490,7 @@
      * @see org.jboss.dna.graph.property.DateTime#plus(long, java.util.concurrent.TimeUnit)
      */
     public org.jboss.dna.graph.property.DateTime plus( long timeAmount,
-                                                         TimeUnit unit ) {
+                                                       TimeUnit unit ) {
         CheckArg.isNotNull(unit, "unit");
         return new JodaDateTime(this.instance.plus(TimeUnit.MILLISECONDS.convert(timeAmount, unit)));
     }

Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/xml/XmlHandler.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/xml/XmlHandler.java	2009-04-28 19:33:35 UTC (rev 861)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/xml/XmlHandler.java	2009-04-29 12:58:43 UTC (rev 862)
@@ -348,7 +348,7 @@
             // No attribute defines the node name ...
             nodeName = nameFactory.create(uri, localName, decoder);
         } else {
-            typePropertyValue = nameFactory.create(uri, localName, decoder);
+            if (typePropertyValue == null) typePropertyValue = nameFactory.create(uri, localName, decoder);
         }
         if (typeAttribute != null) {
             // A attribute defines the node name. Set the type property, if required

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-04-28 19:33:35 UTC (rev 861)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrRepository.java	2009-04-29 12:58:43 UTC (rev 862)
@@ -305,7 +305,7 @@
                                        String workspaceName ) throws RepositoryException {
         // Ensure credentials are either null or provide a JAAS method
         Map<String, Object> sessionAttributes = new HashMap<String, Object>();
-        ExecutionContext execContext;
+        ExecutionContext execContext = null;
         if (credentials == null) {
             execContext = executionContext;
         } else {
@@ -371,7 +371,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));
                 }
-                workspaceName = graph.getCurrentWorkspace().getName();
+                graph.useWorkspace(workspaceName);
             } catch (InvalidWorkspaceException e) {
                 throw new NoSuchWorkspaceException(JcrI18n.workspaceNameIsInvalid.text(sourceName, workspaceName), e);
             } catch (RepositorySourceException e) {

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-04-28 19:33:35 UTC (rev 861)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSession.java	2009-04-29 12:58:43 UTC (rev 862)
@@ -147,6 +147,7 @@
         this.graph = Graph.create(this.repository.getRepositorySourceName(),
                                   this.repository.getConnectionFactory(),
                                   this.executionContext);
+        this.graph.useWorkspace(workspace.getName());
 
         this.cache = new SessionCache(this, workspace.getName(), this.executionContext, this.workspace.nodeTypeManager(),
                                       this.graph);

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-04-28 19:33:35 UTC (rev 861)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java	2009-04-29 12:58:43 UTC (rev 862)
@@ -139,6 +139,8 @@
         Graph namespaceGraph = Graph.create(this.repository.getRepositorySourceName(),
                                             this.repository.getConnectionFactory(),
                                             context);
+        namespaceGraph.useWorkspace(workspaceName);
+
         Name uriProperty = DnaLexicon.NAMESPACE_URI;
         PathFactory pathFactory = context.getValueFactories().getPathFactory();
         Path root = pathFactory.createRootPath();

Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java	2009-04-28 19:33:35 UTC (rev 861)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java	2009-04-29 12:58:43 UTC (rev 862)
@@ -2134,6 +2134,11 @@
 
         // Start with the primary type ...
         JcrNodeType primaryType = nodeTypes().getNodeType(primaryTypeName);
+        if (primaryType == null) {
+            Path path = location.getPath();
+            String msg = JcrI18n.missingNodeTypeForExistingNode.text(primaryTypeName.getString(namespaces), path, workspaceName);
+            throw new RepositorySourceException(msg);
+        }
         if (primaryType.isNodeType(JcrMixLexicon.REFERENCEABLE)) referenceable = true;
 
         // The process the mixin types ...

Modified: trunk/docs/examples/gettingstarted/repositories/src/main/java/org/jboss/example/dna/repository/RepositoryClient.java
===================================================================
--- trunk/docs/examples/gettingstarted/repositories/src/main/java/org/jboss/example/dna/repository/RepositoryClient.java	2009-04-28 19:33:35 UTC (rev 861)
+++ trunk/docs/examples/gettingstarted/repositories/src/main/java/org/jboss/example/dna/repository/RepositoryClient.java	2009-04-29 12:58:43 UTC (rev 862)
@@ -149,16 +149,15 @@
         config.importXmlFrom(location + "/configRepository.xml").into("/");
 
         // Now instantiate the Repository Service ...
-        repositoryService = new RepositoryService(sources, configSource.getName(), "default", context);
+        Path configRoot = context.getValueFactories().getPathFactory().create("/jcr:system");
+        repositoryService = new RepositoryService(sources, configSource.getName(), "default", configRoot, context);
         repositoryService.getAdministrator().start();
 
         // Now import the conten for two of the other in-memory repositories ...
         Graph cars = Graph.create("Cars", sources, context);
-        cars.createWorkspace().named("default");
         cars.importXmlFrom(location + "/cars.xml").into("/");
 
         Graph aircraft = Graph.create("Aircraft", sources, context);
-        aircraft.createWorkspace().named("default");
         aircraft.importXmlFrom(location + "/aircraft.xml").into("/");
     }
 
@@ -249,9 +248,9 @@
                 Session session = null;
                 if (loginContext != null) {
                     Credentials credentials = new JaasCredentials(loginContext);
-                    session = jcrRepository.login(credentials, sourceName);
+                    session = jcrRepository.login(credentials, "default");
                 } else {
-                    session = jcrRepository.login(sourceName);
+                    session = jcrRepository.login("default");
                 }
                 try {
                     // Make the path relative to the root by removing the leading slash(es) ...

Modified: trunk/docs/examples/gettingstarted/repositories/src/main/resources/configRepository.xml
===================================================================
--- trunk/docs/examples/gettingstarted/repositories/src/main/resources/configRepository.xml	2009-04-28 19:33:35 UTC (rev 861)
+++ trunk/docs/examples/gettingstarted/repositories/src/main/resources/configRepository.xml	2009-04-29 12:58:43 UTC (rev 862)
@@ -24,39 +24,41 @@
   ~ 51 Franklin Street, Fifth Floor
   ~ Boston, MA  02110-1301  USA
   -->
-<dna:system xmlns:dna="http://www.jboss.org/dna/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0">
+<jcr:system xmlns:dna="http://www.jboss.org/dna/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0">
+    <dna:namespaces jcr:primaryType="dna:namespaces">
+    </dna:namespaces>
     <!-- Define the sources from which content is made available -->
-    <dna:sources>
-        <dna:source jcr:name="SourceA" dna:name="Cars" dna:classname="org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource" dna:retryLimit="3" />
-        <dna:source jcr:name="SourceB" dna:name="Aircraft" dna:classname="org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource" />
-        <dna:source jcr:name="SourceC" dna:name="Vehicles" dna:classname="org.jboss.dna.connector.federation.FederatedRepositorySource" 
+    <dna:sources jcr:primaryType="nt:unstructured">
+        <dna:source jcr:name="SourceA" jcr:primaryType="nt:unstructured" dna:name="Cars" dna:classname="org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource" dna:retryLimit="3" defaultWorkspaceName="default"/>
+        <dna:source jcr:name="SourceB" jcr:primaryType="nt:unstructured" dna:name="Aircraft" dna:classname="org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource" defaultWorkspaceName="default"/>
+        <dna:source jcr:name="SourceC" jcr:primaryType="nt:unstructured" dna:name="Vehicles" dna:classname="org.jboss.dna.connector.federation.FederatedRepositorySource" 
                     dna:repositoryName="Configuration Repository"
                     dna:configurationSourceName="Configuration" 
                     dna:configurationWorkspaceName="default"
-                    dna:configurationSourcePath="/dna:system/dna:federatedRepositories/Vehicles" 
+                    dna:configurationSourcePath="/jcr:system/dna:federatedRepositories/Vehicles" 
                     dna:repositoryConnectionFactoryJndiName="/dna/connectionFactory"
                     dna:executionContextFactoryJndiName="/dna/contextFactory"/>
-        <dna:source jcr:name="SourceD" dna:name="Cache" dna:classname="org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource" />
+        <dna:source jcr:name="SourceD" jcr:primaryType="nt:unstructured" dna:name="Cache" dna:classname="org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource" defaultWorkspaceName="default"/>
     </dna:sources>
-    <dna:federatedRepositories>
+    <dna:federatedRepositories jcr:primaryType="nt:unstructured">
         <!-- This section defines from where the content of the 'Vehicles' federated repository is obtained.
              The name of this node must match the 'name' of the source listed above. -->
-        <dna:federatedRepository jcr:name="Vehicles">
+        <dna:federatedRepository jcr:name="Vehicles" jcr:primaryType="nt:unstructured">
             <!-- Define the workspace(s) for this repository -->
-            <dna:workspaces>
-                <dna:workspace jcr:name="default">
+            <dna:workspaces jcr:primaryType="nt:unstructured">
+                <dna:workspace jcr:name="default" jcr:primaryType="nt:unstructured">
                     <!-- Define how the content in the 'Cache' source is to map to the federated cache -->
-                    <dna:cache dna:sourceName="Cache" dna:workspaceName="default" dna:projectionRules="/ => /" />
+                    <dna:cache jcr:primaryType="nt:unstructured" dna:sourceName="Cache" dna:workspaceName="default" dna:projectionRules="/ => /" />
                     <!-- Define how the content in the difference sources maps to the federated/unified repository.
                          This example puts the 'Cars' and 'Aircraft' content underneath '/vehicles', but the
                          'Configuration' content (which is defined by this file) will appear under '/'. -->
-                    <dna:projections>
-                        <dna:projection jcr:name="Cars" dna:workspaceName="default"  dna:projectionRules="/Vehicles => /" />
-                        <dna:projection jcr:name="Aircraft" dna:workspaceName="default"  dna:projectionRules="/Vehicles => /" />
-                        <dna:projection jcr:name="Configuration" dna:workspaceName="default"  dna:projectionRules="/ => /" />
+                    <dna:projections jcr:primaryType="nt:unstructured">
+                        <dna:projection jcr:primaryType="nt:unstructured" jcr:name="Cars" dna:workspaceName="default"  dna:projectionRules="/Vehicles => /" />
+                        <dna:projection jcr:primaryType="nt:unstructured" jcr:name="Aircraft" dna:workspaceName="default"  dna:projectionRules="/Vehicles => /" />
+                        <dna:projection jcr:primaryType="nt:unstructured" jcr:name="Configuration" dna:workspaceName="default"  dna:projectionRules="/ => /" />
                     </dna:projections>
                 </dna:workspace>
             </dna:workspaces>
         </dna:federatedRepository>
     </dna:federatedRepositories>
-</dna:system>
\ No newline at end of file
+</jcr:system>
\ No newline at end of file

Modified: trunk/docs/examples/gettingstarted/repositories/src/test/java/org/jboss/example/dna/repository/RepositoryClientTest.java
===================================================================
--- trunk/docs/examples/gettingstarted/repositories/src/test/java/org/jboss/example/dna/repository/RepositoryClientTest.java	2009-04-28 19:33:35 UTC (rev 861)
+++ trunk/docs/examples/gettingstarted/repositories/src/test/java/org/jboss/example/dna/repository/RepositoryClientTest.java	2009-04-29 12:58:43 UTC (rev 862)
@@ -109,26 +109,27 @@
     public void shouldHaveContentFromConfigurationRepository() throws Throwable {
         client.startRepositories();
 
-        getNodeInfo("Configuration", "/dna:system");
+        getNodeInfo("Configuration", "/jcr:system");
         assertThat(children, hasItems("dna:sources", "dna:federatedRepositories"));
         assertThat(properties.containsKey("jcr:primaryType"), is(true));
-        assertThat(properties.containsKey("dna:uuid"), is(true));
-        assertThat(properties.size(), is(2));
+        // assertThat(properties.containsKey("dna:uuid"), is(true));
+        assertThat(properties.size() >= 1, is(true));
 
-        getNodeInfo("Configuration", "/dna:system/dna:sources");
+        getNodeInfo("Configuration", "/jcr:system/dna:sources");
         assertThat(children, hasItems("SourceA", "SourceB", "SourceC", "SourceD"));
         assertThat(properties.containsKey("jcr:primaryType"), is(true));
-        assertThat(properties.containsKey("dna:uuid"), is(true));
-        assertThat(properties.size(), is(2));
+        // assertThat(properties.containsKey("dna:uuid"), is(true));
+        assertThat(properties.size() >= 1, is(true));
 
-        getNodeInfo("Configuration", "/dna:system/dna:sources/SourceA");
+        getNodeInfo("Configuration", "/jcr:system/dna:sources/SourceA");
         assertThat(children.size(), is(0));
         assertThat(properties.containsKey("jcr:primaryType"), is(true));
-        assertThat(properties.containsKey("dna:uuid"), is(true));
+        // assertThat(properties.containsKey("dna:uuid"), is(true));
         assertProperty("dna:classname", org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource.class.getName());
         assertProperty("dna:name", "Cars");
         assertProperty("dna:retryLimit", "3");
-        assertThat(properties.size(), is(5));
+        assertProperty("defaultWorkspaceName", "default");
+        assertThat(properties.size() >= 5, is(true));
     }
 
     @Test
@@ -206,7 +207,7 @@
         client.startRepositories();
 
         getNodeInfo("Vehicles", "/");
-        assertThat(children, hasItems("Vehicles"));
+        assertThat(children, hasItems("Vehicles", "jcr:system"));
         assertThat(properties.containsKey("dna:uuid"), is(true));
         assertThat(properties.size(), is(1));
 
@@ -216,7 +217,7 @@
         assertThat(properties.size(), is(1));
 
         getNodeInfo("Vehicles", "/");
-        assertThat(children, hasItems("Vehicles"));
+        assertThat(children, hasItems("Vehicles", "jcr:system"));
         assertThat(properties.containsKey("dna:uuid"), is(true));
         assertThat(properties.size(), is(1));
 

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-04-28 19:33:35 UTC (rev 861)
+++ trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatingRequestProcessor.java	2009-04-29 12:58:43 UTC (rev 862)
@@ -25,12 +25,14 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 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 java.util.concurrent.TimeUnit;
 import net.jcip.annotations.NotThreadSafe;
 import org.jboss.dna.common.i18n.I18n;
@@ -78,6 +80,8 @@
 @NotThreadSafe
 public class FederatingRequestProcessor extends RequestProcessor {
 
+    private static final Set<Name> HIDDEN_PROPERTIES = Collections.singleton(DnaLexicon.MERGE_PLAN);
+
     private final Map<String, FederatedWorkspace> workspaces;
     private final FederatedWorkspace defaultWorkspace;
     private final RepositoryConnectionFactory connectionFactory;
@@ -214,6 +218,7 @@
         ReadNodeRequest nodeInfo = getNode(request.at(), workspace);
         if (nodeInfo.hasError()) return;
         for (Property property : nodeInfo.getProperties()) {
+            if (HIDDEN_PROPERTIES.contains(property.getName())) continue;
             request.addProperty(property);
         }
         request.setActualLocationOfNode(nodeInfo.getActualLocationOfNode());
@@ -231,6 +236,7 @@
         ReadNodeRequest nodeInfo = getNode(request.at(), workspace);
         if (nodeInfo.hasError()) return;
         for (Property property : nodeInfo.getProperties()) {
+            if (HIDDEN_PROPERTIES.contains(property.getName())) continue;
             request.addProperty(property);
         }
         for (Location child : nodeInfo.getChildren()) {
@@ -357,8 +363,9 @@
      */
     protected ReadNodeRequest getNode( Location location,
                                        FederatedWorkspace workspace ) throws RepositorySourceException {
+        final ExecutionContext context = getExecutionContext();
+
         // Check the cache first ...
-        final ExecutionContext context = getExecutionContext();
         RepositoryConnection cacheConnection = getConnectionToCacheFor(workspace);
         ReadNodeRequest fromCache = new ReadNodeRequest(location, workspace.getCacheProjection().getWorkspaceName());
         cacheConnection.execute(context, fromCache);
@@ -410,7 +417,7 @@
             if (mergePlan != null) {
                 // We found the merge plan, so check whether it's still valid ...
                 final DateTime now = getCurrentTimeInUtc();
-                if (mergePlan.isExpired(now)) {
+                if (!mergePlan.isExpired(now)) {
                     // It is still valid, so check whether any contribution is from a non-existant projection ...
                     for (Contribution contribution : mergePlan) {
                         if (!workspace.contains(contribution.getSourceName(), contribution.getWorkspaceName())) {
@@ -424,10 +431,10 @@
                 // the valid contributions in the 'contributions' list; any expired contribution
                 // needs to be loaded by adding the name to the 'sourceNames'
                 if (mergePlan.getContributionCount() > 0) {
-                    sourceNames = new HashSet<String>(sourceNames);
+                    sourceNames = new HashSet<String>();
                     for (Contribution contribution : mergePlan) {
-                        if (!contribution.isExpired(now)) {
-                            sourceNames.remove(contribution.getSourceName());
+                        if (contribution.isExpired(now)) {
+                            sourceNames.add(contribution.getSourceName());
                             contributions.add(contribution);
                         }
                     }
@@ -437,7 +444,10 @@
 
         // Get the contributions from the sources given their names ...
         location = fromCache.getActualLocationOfNode();
-        if (location == null) location = fromCache.at(); // not yet in the cache
+        if (location == null) {
+            // Not yet in the cache ...
+            location = fromCache.at();
+        }
         loadContributionsFromSources(location, workspace, sourceNames, contributions); // sourceNames may be null or empty
         FederatedNode mergedNode = createFederatedNode(location, workspace, contributions, true);
         if (mergedNode == null) {
@@ -482,7 +492,7 @@
         // Create the node, and use the existing UUID if one is found in the cache ...
         ExecutionContext context = getExecutionContext();
         assert context != null;
-        FederatedNode mergedNode = new FederatedNode(location, federatedWorkspace.getName());
+        FederatedNode mergedNode = new FederatedNode(location.with((UUID)null), federatedWorkspace.getName());
 
         // Merge the results into a single set of results ...
         assert contributions.size() > 0;
@@ -719,7 +729,21 @@
         assert path != null;
         List<Request> requests = new ArrayList<Request>();
         Name childName = null;
-        if (!path.isRoot()) {
+
+        // If the merged node has a merge plan, then add it to the properties if it is not already there ...
+        Map<Name, Property> properties = mergedNode.getPropertiesByName();
+        MergePlan mergePlan = mergedNode.getMergePlan();
+        if (mergePlan != null) {
+            // Record the merge plan on the merged node ...
+            Property mergePlanProperty = getExecutionContext().getPropertyFactory().create(DnaLexicon.MERGE_PLAN,
+                                                                                           (Object)mergePlan);
+            properties.put(mergePlanProperty.getName(), mergePlanProperty);
+        }
+
+        if (path.isRoot()) {
+            // Set the properties ...
+            requests.add(new UpdatePropertiesRequest(location, cacheWorkspace, properties));
+        } else {
             // This is not the root node, so we need to create the node ...
             final Location parentLocation = Location.create(path.getParent());
             childName = path.getLastSegment().getName();

Modified: trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/contribution/Contribution.java
===================================================================
--- trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/contribution/Contribution.java	2009-04-28 19:33:35 UTC (rev 861)
+++ trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/contribution/Contribution.java	2009-04-29 12:58:43 UTC (rev 862)
@@ -303,6 +303,7 @@
     public boolean isExpired( DateTime utcTime ) {
         assert utcTime != null;
         assert utcTime.toUtcTimeZone().equals(utcTime); // check that it is passed UTC time
+        if (expirationTimeInUtc == null) return false;
         return !expirationTimeInUtc.isAfter(utcTime);
     }
 

Modified: trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/merge/MergePlan.java
===================================================================
--- trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/merge/MergePlan.java	2009-04-28 19:33:35 UTC (rev 861)
+++ trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/merge/MergePlan.java	2009-04-29 12:58:43 UTC (rev 862)
@@ -196,7 +196,8 @@
     public boolean isExpired( DateTime utcTime ) {
         assert utcTime != null;
         assert utcTime.toUtcTimeZone().equals(utcTime); // check that it is passed UTC time
-        return utcTime.isAfter(getExpirationTimeInUtc());
+        DateTime expirationTimeInUtc = getExpirationTimeInUtc();
+        return expirationTimeInUtc == null ? false : utcTime.isAfter(expirationTimeInUtc);
     }
 
     /**

Modified: trunk/extensions/dna-connector-federation/src/test/java/org/jboss/dna/connector/federation/FederatedRepositorySourceIntegrationTest.java
===================================================================
--- trunk/extensions/dna-connector-federation/src/test/java/org/jboss/dna/connector/federation/FederatedRepositorySourceIntegrationTest.java	2009-04-28 19:33:35 UTC (rev 861)
+++ trunk/extensions/dna-connector-federation/src/test/java/org/jboss/dna/connector/federation/FederatedRepositorySourceIntegrationTest.java	2009-04-29 12:58:43 UTC (rev 862)
@@ -51,7 +51,6 @@
 import org.jboss.dna.graph.property.PathNotFoundException;
 import org.jboss.dna.graph.property.Property;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.mockito.ArgumentMatcher;
 import org.mockito.MockitoAnnotations;
@@ -227,7 +226,6 @@
         }
     }
 
-    @Ignore
     @Test
     public void shouldProvideReadAccessToContentFederatedFromOneSourceThatMatchesTheContentFromTheSource() throws Exception {
         // Set up the configuration to use a single source.
@@ -292,7 +290,6 @@
         assertChildren(source, "/b/c");
     }
 
-    @Ignore
     @Test
     public void shouldProvideReadAccessToContentFederatedFromMultipleSources() throws Exception {
         // Set up the configuration to use multiple sources.
@@ -312,12 +309,12 @@
         batch.create("/repos/RepoX/dna:workspaces/fedSpace/dna:projections/projection1")
              .with(FederatedLexicon.PROJECTION_RULES, "/ => /s1")
              .with(FederatedLexicon.SOURCE_NAME, "source 1")
-             .with(FederatedLexicon.WORKSPACE_NAME, "s1 workspace")
+             .with(FederatedLexicon.WORKSPACE_NAME, "s1Space")
              .and();
         batch.create("/repos/RepoX/dna:workspaces/fedSpace/dna:projections/projection2")
              .with(FederatedLexicon.PROJECTION_RULES, "/ => /s2")
              .with(FederatedLexicon.SOURCE_NAME, "source 2")
-             .with(FederatedLexicon.WORKSPACE_NAME, "s2 worskspace")
+             .with(FederatedLexicon.WORKSPACE_NAME, "s2 workspace")
              .and();
         batch.execute();
 




More information about the dna-commits mailing list