DNA SVN: r1542 - in trunk/extensions: dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache and 1 other directory.
by dna-commits@lists.jboss.org
Author: bcarothers
Date: 2010-01-06 20:16:33 -0500 (Wed, 06 Jan 2010)
New Revision: 1542
Modified:
trunk/extensions/dna-connector-infinispan/src/main/java/org/jboss/dna/connector/infinispan/InfinispanSource.java
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheSource.java
Log:
Fixed eclipse warnings
Modified: trunk/extensions/dna-connector-infinispan/src/main/java/org/jboss/dna/connector/infinispan/InfinispanSource.java
===================================================================
--- trunk/extensions/dna-connector-infinispan/src/main/java/org/jboss/dna/connector/infinispan/InfinispanSource.java 2010-01-07 01:13:22 UTC (rev 1541)
+++ trunk/extensions/dna-connector-infinispan/src/main/java/org/jboss/dna/connector/infinispan/InfinispanSource.java 2010-01-07 01:16:33 UTC (rev 1542)
@@ -48,6 +48,7 @@
import org.infinispan.manager.CacheManager;
import org.infinispan.manager.DefaultCacheManager;
import org.jboss.dna.common.i18n.I18n;
+import org.jboss.dna.common.util.HashCode;
import org.jboss.dna.common.util.StringUtil;
import org.jboss.dna.graph.cache.CachePolicy;
import org.jboss.dna.graph.connector.RepositoryConnection;
@@ -481,6 +482,11 @@
return false;
}
+ @Override
+ public int hashCode() {
+ return HashCode.compute(getName());
+ }
+
/**
* {@inheritDoc}
*/
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 2010-01-07 01:13:22 UTC (rev 1541)
+++ trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheSource.java 2010-01-07 01:16:33 UTC (rev 1542)
@@ -52,6 +52,7 @@
import org.jboss.cache.DefaultCacheFactory;
import org.jboss.cache.config.ConfigurationException;
import org.jboss.dna.common.i18n.I18n;
+import org.jboss.dna.common.util.HashCode;
import org.jboss.dna.common.util.Logger;
import org.jboss.dna.common.util.StringUtil;
import org.jboss.dna.graph.DnaLexicon;
@@ -586,6 +587,11 @@
return false;
}
+ @Override
+ public int hashCode() {
+ return HashCode.compute(getName());
+ }
+
/**
* {@inheritDoc}
*/
14 years, 5 months
DNA SVN: r1541 - trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/svn.
by dna-commits@lists.jboss.org
Author: bcarothers
Date: 2010-01-06 20:13:22 -0500 (Wed, 06 Jan 2010)
New Revision: 1541
Modified:
trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/svn/SvnAndJcrIntegrationTest.java
Log:
DNA-618 SVN connector integration tests are failing with '404 Not Found'
Applied patch that shrinks the size of the repo, making it run dramatically more quickly from sites outside of the jboss.org network. Prior to the search code, there was no particular penalty for having a huge repo as long as you didn't try to read every node. But the search code has to read the whole repo to build the search index. In this case, that required reading several thousand files, each requiring two network calls (one for the file and one for its contents).
Modified: trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/svn/SvnAndJcrIntegrationTest.java
===================================================================
--- trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/svn/SvnAndJcrIntegrationTest.java 2010-01-07 00:14:25 UTC (rev 1540)
+++ trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/svn/SvnAndJcrIntegrationTest.java 2010-01-07 01:13:22 UTC (rev 1541)
@@ -51,7 +51,7 @@
@Before
public void beforeEach() throws Exception {
final String repositoryUrl = "http://anonsvn.jboss.org/repos/dna/";
- final String[] predefinedWorkspaceNames = {"trunk", "tags", "branches"};
+ final String[] predefinedWorkspaceNames = {"trunk/dna-common/src/main/java/org/jboss/dna/common/xml",};
final String svnRepositorySource = "svnRepositorySource";
final String repositoryName = "svnRepository";
final JcrConfiguration configuration = new JcrConfiguration();
@@ -61,11 +61,10 @@
.setProperty("username", "anonymous")
.setProperty("repositoryRootUrl", repositoryUrl)
.setProperty("predefinedWorkspaceNames", predefinedWorkspaceNames)
-.setProperty("defaultWorkspaceName",
- predefinedWorkspaceNames[0])
+ .setProperty("defaultWorkspaceName", predefinedWorkspaceNames[0])
.setProperty("creatingWorkspacesAllowed", false);
- configuration.repository(repositoryName).setSource(svnRepositorySource).setOption(Option.QUERY_EXECUTION_ENABLED, "false");
+ configuration.repository(repositoryName).setSource(svnRepositorySource).setOption(Option.QUERY_EXECUTION_ENABLED, "true");
configuration.save();
this.engine = configuration.build();
@@ -94,13 +93,13 @@
while (nodeIterator.hasNext()) {
System.out.println(nodeIterator.nextNode());
}
- assertThat(this.session.getRootNode().getNode("dna-graph"), is(notNullValue()));
+ assertThat(this.session.getRootNode().getNode("XmlCharacters.java"), is(notNullValue()));
}
@Test
public void shouldProvideAccessToJcrDataNodeUnderFileNode() throws Exception {
- System.out.println("Getting /pom.xml/jcr:content and then walking its properties ...");
- Node resourceNodeOfPomFile = this.session.getRootNode().getNode("pom.xml/jcr:content");
+ System.out.println("Getting /package-info.java/jcr:content and then walking its properties ...");
+ Node resourceNodeOfPomFile = this.session.getRootNode().getNode("package-info.java/jcr:content");
assertThat(resourceNodeOfPomFile, is(notNullValue()));
for (PropertyIterator iter = resourceNodeOfPomFile.getProperties(); iter.hasNext();) {
@@ -109,19 +108,6 @@
}
}
- @Test
- public void shouldProvideAccessToJcrDataNodeUnderDeepFileNode() throws Exception {
- String path = "extensions/dna-sequencer-text/src/test/resources/delimited/multiLineCommaDelimitedFile.csv/jcr:content";
- System.out.println("Getting " + path + " and then walking its properties ...");
- Node resourceNodeOfPomFile = this.session.getRootNode().getNode(path);
- assertThat(resourceNodeOfPomFile, is(notNullValue()));
-
- for (PropertyIterator iter = resourceNodeOfPomFile.getProperties(); iter.hasNext();) {
- Property property = iter.nextProperty();
- assertThat(property.getName(), is(notNullValue()));
- }
- }
-
protected class MyCustomSecurityContext implements SecurityContext {
/**
* {@inheritDoc}
14 years, 5 months
DNA SVN: r1540 - trunk/dna-graph/src/main/java/org/jboss/dna/graph/search.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2010-01-06 19:14:25 -0500 (Wed, 06 Jan 2010)
New Revision: 1540
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/search/SearchEngineIndexer.java
Log:
DNA-617 Fix for the NPE in the search indexer (in the case when there isn't even a root in the source).
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/search/SearchEngineIndexer.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/search/SearchEngineIndexer.java 2010-01-06 23:50:22 UTC (rev 1539)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/search/SearchEngineIndexer.java 2010-01-07 00:14:25 UTC (rev 1540)
@@ -288,6 +288,7 @@
Location topNode = locationIter.next();
assert topNode.equals(startingLocation);
Map<Name, Property> properties = readSubgraph.getPropertiesFor(topNode);
+ if (properties == null) return;
if (startingLocation.getPath().isRoot()) {
// The properties of the root node generally don't include the primary type, but we need to add it here ...
Property rootPrimaryType = context.getPropertyFactory().create(JcrLexicon.PRIMARY_TYPE, DnaLexicon.ROOT);
14 years, 5 months
DNA SVN: r1539 - in trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector: path/cache and 1 other directory.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2010-01-06 18:50:22 -0500 (Wed, 06 Jan 2010)
New Revision: 1539
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/path/cache/InMemoryWorkspaceCache.java
Log:
Corrected several compiler warnings for potential null pointers. These warnings were correct.
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 2010-01-06 23:49:59 UTC (rev 1538)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/JoinRequestProcessor.java 2010-01-06 23:50:22 UTC (rev 1539)
@@ -838,9 +838,11 @@
@Override
public void process( CreateNodeRequest request ) {
ProjectedRequest projected = federatedRequest.getFirstProjectedRequest();
+ // Check the projection first ...
+ if (checkErrorOrCancel(request, federatedRequest)) return;
- Request projectedRequest = projected == null ? null : projected.getRequest();
- // Check the error first ...
+ Request projectedRequest = projected.getRequest();
+ // Check the error on the projected request ...
if (checkErrorOrCancel(request, projectedRequest)) return;
// No error, so project the results back to the federated repository ...
@@ -866,8 +868,10 @@
@Override
public void process( UpdatePropertiesRequest request ) {
ProjectedRequest projected = federatedRequest.getFirstProjectedRequest();
+ // Check the projection first ...
+ if (checkErrorOrCancel(request, federatedRequest)) return;
- UpdatePropertiesRequest source = projected == null ? null : (UpdatePropertiesRequest)projected.getRequest();
+ UpdatePropertiesRequest source = (UpdatePropertiesRequest)projected.getRequest();
if (checkErrorOrCancel(request, source)) return;
Location sourceLocation = source.getActualLocationOfNode();
request.setActualLocationOfNode(projectToFederated(request.on(), projected.getProjection(), sourceLocation, request));
@@ -882,8 +886,10 @@
@Override
public void process( SetPropertyRequest request ) {
ProjectedRequest projected = federatedRequest.getFirstProjectedRequest();
+ // Check the projection first ...
+ if (checkErrorOrCancel(request, federatedRequest)) return;
- SetPropertyRequest source = projected == null ? null : (SetPropertyRequest)projected.getRequest();
+ SetPropertyRequest source = (SetPropertyRequest)projected.getRequest();
if (checkErrorOrCancel(request, source)) return;
// Set the actual location and created flags ...
Location sourceLocation = source.getActualLocationOfNode();
@@ -899,8 +905,10 @@
@Override
public void process( RemovePropertyRequest request ) {
ProjectedRequest projected = federatedRequest.getFirstProjectedRequest();
+ // Check the projection first ...
+ if (checkErrorOrCancel(request, federatedRequest)) return;
- SetPropertyRequest source = projected == null ? null : (SetPropertyRequest)projected.getRequest();
+ SetPropertyRequest source = (SetPropertyRequest)projected.getRequest();
if (checkErrorOrCancel(request, source)) return;
Location sourceLocation = source.getActualLocationOfNode();
request.setActualLocationOfNode(projectToFederated(request.from(), projected.getProjection(), sourceLocation, request));
@@ -914,9 +922,11 @@
@Override
public void process( DeleteBranchRequest request ) {
ProjectedRequest projected = federatedRequest.getFirstProjectedRequest();
+ // Check the projection first ...
+ if (checkErrorOrCancel(request, federatedRequest)) return;
// Do an initial check to make sure that there was no error on the source that prevented projection
- Request projectedSource = projected == null ? null : projected.getRequest();
+ Request projectedSource = projected.getRequest();
if (checkErrorOrCancel(request, projectedSource)) return;
// Go through the projected requests, and look for the top-most node ...
@@ -954,9 +964,11 @@
@Override
public void process( DeleteChildrenRequest request ) {
ProjectedRequest projected = federatedRequest.getFirstProjectedRequest();
+ // Check the projection first ...
+ if (checkErrorOrCancel(request, federatedRequest)) return;
// Do an initial check to make sure that there was no error on the source that prevented projection
- Request projectedSource = projected == null ? null : projected.getRequest();
+ Request projectedSource = projected.getRequest();
if (checkErrorOrCancel(request, projectedSource)) return;
// Go through the projected requests, and look for the top-most node ...
@@ -986,8 +998,10 @@
@Override
public void process( RenameNodeRequest request ) {
ProjectedRequest projected = federatedRequest.getFirstProjectedRequest();
+ // Check the projection first ...
+ if (checkErrorOrCancel(request, federatedRequest)) return;
- RenameNodeRequest source = projected == null ? null : (RenameNodeRequest)projected.getRequest();
+ RenameNodeRequest source = (RenameNodeRequest)projected.getRequest();
if (checkErrorOrCancel(request, source)) return;
Location locationBefore = source.getActualLocationBefore();
Location locationAfter = source.getActualLocationBefore();
@@ -1004,8 +1018,10 @@
@Override
public void process( CopyBranchRequest request ) {
ProjectedRequest projected = federatedRequest.getFirstProjectedRequest();
+ // Check the projection first ...
+ if (checkErrorOrCancel(request, federatedRequest)) return;
- CopyBranchRequest source = projected == null ? null : (CopyBranchRequest)projected.getRequest();
+ CopyBranchRequest source = (CopyBranchRequest)projected.getRequest();
if (checkErrorOrCancel(request, source)) return;
Location locationBefore = source.getActualLocationBefore();
Location locationAfter = source.getActualLocationBefore();
@@ -1022,8 +1038,10 @@
@Override
public void process( CloneBranchRequest request ) {
ProjectedRequest projected = federatedRequest.getFirstProjectedRequest();
+ // Check the projection first ...
+ if (checkErrorOrCancel(request, federatedRequest)) return;
- CloneBranchRequest source = projected == null ? null : (CloneBranchRequest)projected.getRequest();
+ CloneBranchRequest source = (CloneBranchRequest)projected.getRequest();
if (checkErrorOrCancel(request, source)) return;
Location locationBefore = source.getActualLocationBefore();
Location locationAfter = source.getActualLocationBefore();
@@ -1047,8 +1065,10 @@
@Override
public void process( MoveBranchRequest request ) {
ProjectedRequest projected = federatedRequest.getFirstProjectedRequest();
+ // Check the projection first ...
+ if (checkErrorOrCancel(request, federatedRequest)) return;
- MoveBranchRequest source = projected == null ? null : (MoveBranchRequest)projected.getRequest();
+ MoveBranchRequest source = (MoveBranchRequest)projected.getRequest();
if (checkErrorOrCancel(request, source)) return;
Location locationBefore = source.getActualLocationBefore();
Location locationAfter = source.getActualLocationBefore();
@@ -1160,6 +1180,22 @@
}
protected boolean checkErrorOrCancel( Request request,
+ FederatedRequest federatedRequest ) {
+ if (federatedRequest.getFirstProjectedRequest() == null) {
+ Request original = federatedRequest.original();
+ if (original.hasError()) {
+ // No source requests had results ...
+ request.setError(original.getError());
+ return true;
+ }
+ assert original.isCancelled();
+ request.cancel();
+ return true;
+ }
+ return false;
+ }
+
+ protected boolean checkErrorOrCancel( Request request,
Request sourceRequest ) {
if (sourceRequest.hasError()) {
request.setError(sourceRequest.getError());
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/path/cache/InMemoryWorkspaceCache.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/path/cache/InMemoryWorkspaceCache.java 2010-01-06 23:49:59 UTC (rev 1538)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/path/cache/InMemoryWorkspaceCache.java 2010-01-06 23:50:22 UTC (rev 1539)
@@ -62,18 +62,18 @@
CacheEntry entry = nodesByPath.get(path);
if (entry == null) {
- statistics.misses.getAndIncrement();
+ statistics.incrementMisses();
return null;
}
PathNode node = entry.getNode();
if (node != null) {
- statistics.hits.getAndIncrement();
+ statistics.incrementHits();
return node;
}
nodesByPath.remove(path, entry);
- statistics.expirations.getAndIncrement();
+ statistics.incrementExpirations();
return null;
}
@@ -81,8 +81,8 @@
assert node != null;
if (!policy.shouldCache(node)) return;
-
- statistics.writes.getAndIncrement();
+
+ statistics.incrementWrites();
nodesByPath.put(node.getPath(), new CacheEntry(node));
}
@@ -104,13 +104,17 @@
this.statistics = null;
}
+ protected PathCachePolicy policy() {
+ return this.policy;
+ }
+
class CacheEntry {
private final SoftReference<PathNode> ref;
private final long expiryTime;
CacheEntry( PathNode node ) {
ref = new SoftReference<PathNode>(node);
- expiryTime = System.currentTimeMillis() + (policy.getTimeToLive() * 1000);
+ expiryTime = System.currentTimeMillis() + (policy().getTimeToLive() * 1000);
}
PathNode getNode() {
@@ -143,5 +147,21 @@
public long getExpirations() {
return expirations.get();
}
+
+ public long incrementWrites() {
+ return writes.getAndIncrement();
+ }
+
+ public long incrementHits() {
+ return hits.getAndIncrement();
+ }
+
+ public long incrementMisses() {
+ return misses.getAndIncrement();
+ }
+
+ public long incrementExpirations() {
+ return expirations.getAndIncrement();
+ }
}
}
14 years, 5 months
DNA SVN: r1538 - in trunk: dna-graph/src/test/java/org/jboss/dna/graph/connector/test and 2 other directories.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2010-01-06 18:49:59 -0500 (Wed, 06 Jan 2010)
New Revision: 1538
Modified:
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/test/ReadableConnectorTest.java
trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorNoCreateWorkspaceTest.java
trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorReadingTest.java
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/TestEnvironment.java
trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/model/basic/BasicCreateWorkspacesTest.java
trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/model/basic/BasicNoCreateWorkspaceTest.java
trunk/pom.xml
Log:
Changes to the JPA connector test cases and the database test environment to use in-memory HSQLDB databases and to lessen the chance of mixing the Basic and Simple models during the tests.
Modified: trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/test/ReadableConnectorTest.java
===================================================================
--- trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/test/ReadableConnectorTest.java 2010-01-06 23:49:23 UTC (rev 1537)
+++ trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/test/ReadableConnectorTest.java 2010-01-06 23:49:59 UTC (rev 1538)
@@ -45,6 +45,7 @@
import org.jboss.dna.graph.request.ReadNextBlockOfChildrenRequest;
import org.jboss.dna.graph.request.ReadNodeRequest;
import org.jboss.dna.graph.request.ReadPropertyRequest;
+import org.junit.After;
import org.junit.Test;
/**
@@ -58,18 +59,17 @@
*/
public abstract class ReadableConnectorTest extends AbstractConnectorTest {
- // /**
- // * Method that is executed after each test. This method does nothing, since the repository is set up once for all of the
- // tests
- // * and then shutdown after all tests have completed.
- // *
- // * @throws Exception
- // */
- // @Override
- // @After
- // public void afterEach() throws Exception {
- // // Don't shut down the repository
- // }
+ /**
+ * Method that is executed after each test. This method does nothing, since the repository is set up once for all of the tests
+ * and then shutdown after all tests have completed.
+ *
+ * @throws Exception
+ */
+ @Override
+ @After
+ public void afterEach() throws Exception {
+ // Don't shut down the repository
+ }
@Test
public void shouldAlwaysBeAbleToReadRootNode() {
Modified: trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorNoCreateWorkspaceTest.java
===================================================================
--- trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorNoCreateWorkspaceTest.java 2010-01-06 23:49:23 UTC (rev 1537)
+++ trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorNoCreateWorkspaceTest.java 2010-01-06 23:49:59 UTC (rev 1538)
@@ -49,7 +49,7 @@
*/
@Override
protected RepositorySource setUpSource() {
- predefinedWorkspaces = new String[] {"workspace1", "workspace2", "workspace3"};
+ predefinedWorkspaces = new String[] {"default", "workspace1", "workspace2", "workspace3"};
// Set the connection properties using the environment defined in the POM files ...
JpaSource source = TestEnvironment.configureJpaSource("Test Repository", this);
Modified: trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorReadingTest.java
===================================================================
--- trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorReadingTest.java 2010-01-06 23:49:23 UTC (rev 1537)
+++ trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorReadingTest.java 2010-01-06 23:49:59 UTC (rev 1538)
@@ -24,7 +24,6 @@
package org.jboss.dna.connector.store.jpa;
import org.jboss.dna.common.statistic.Stopwatch;
-import org.jboss.dna.common.util.Logger;
import org.jboss.dna.graph.Graph;
import org.jboss.dna.graph.connector.RepositorySource;
import org.jboss.dna.graph.connector.test.ReadableConnectorTest;
@@ -44,17 +43,6 @@
// Set the connection properties using the environment defined in the POM files ...
JpaSource source = TestEnvironment.configureJpaSource("Test Repository", this);
- // Create a graph and look up the root node. We do this to initialize the connection pool and
- // force the database to be setup at this point. By doing it now, we don't include this overhead
- // in our test timings.
- try {
- Graph graph = Graph.create(source, context);
- graph.getNodeAt("/");
- } catch (Throwable t) {
- Logger.getLogger(getClass()).debug("Unable to read the root node while setting up the \"" + source.getName()
- + "\" JPA source");
- }
-
return source;
}
@@ -71,7 +59,11 @@
int numPropertiesPerNode = 7;
Stopwatch sw = new Stopwatch();
boolean batch = true;
- graph.createWorkspace().named("default");
+ if (!graph.getWorkspaces().contains("default")) {
+ graph.createWorkspace().named("default");
+ } else {
+ graph.useWorkspace("default");
+ }
createSubgraph(graph, initialPath, depth, numChildrenPerNode, numPropertiesPerNode, batch, sw, System.out, null);
graph.createWorkspace().named("other workspace");
createSubgraph(graph, initialPath, depth, numChildrenPerNode, numPropertiesPerNode, batch, sw, System.out, null);
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 2010-01-06 23:49:23 UTC (rev 1537)
+++ trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorWritingTest.java 2010-01-06 23:49:59 UTC (rev 1538)
@@ -23,8 +23,10 @@
*/
package org.jboss.dna.connector.store.jpa;
+import java.util.UUID;
import org.jboss.dna.common.statistic.Stopwatch;
import org.jboss.dna.graph.Graph;
+import org.jboss.dna.graph.Location;
import org.jboss.dna.graph.connector.RepositorySource;
import org.jboss.dna.graph.connector.test.WritableConnectorTest;
import org.jboss.dna.graph.property.ReferentialIntegrityException;
@@ -35,6 +37,8 @@
*/
public class JpaConnectorWritingTest extends WritableConnectorTest {
+ private boolean isReferentialIntegrityEnforced = false;
+
/**
* {@inheritDoc}
*
@@ -46,7 +50,7 @@
JpaSource source = TestEnvironment.configureJpaSource("Test Repository", this);
// Override the inherited properties ...
- source.setReferentialIntegrityEnforced(true);
+ source.setReferentialIntegrityEnforced(isReferentialIntegrityEnforced);
source.setCompressData(true);
return source;
@@ -59,12 +63,20 @@
*/
@Override
protected void initializeContent( Graph graph ) {
- graph.createWorkspace().named("default");
+ if (!graph.getWorkspaces().contains("default")) {
+ graph.createWorkspace().named("default");
+ } else {
+ graph.useWorkspace("default");
+ }
}
@Test( expected = ReferentialIntegrityException.class )
public void shouldNotCopyChildrenBetweenWorkspacesAndRemoveExistingNodesWithSameUuidIfSpecifiedIfReferentialIntegrityIsViolated()
throws Exception {
+ if (!isReferentialIntegrityEnforced) {
+ throw new ReferentialIntegrityException(Location.create(UUID.randomUUID()));
+ }
+
String defaultWorkspaceName = graph.getCurrentWorkspaceName();
String workspaceName = "copyChildrenSource";
Modified: trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/TestEnvironment.java
===================================================================
--- trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/TestEnvironment.java 2010-01-06 23:49:23 UTC (rev 1537)
+++ trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/TestEnvironment.java 2010-01-06 23:49:59 UTC (rev 1538)
@@ -32,7 +32,7 @@
Object testCase ) {
Properties properties = new Properties();
ClassLoader loader = testCase instanceof Class<?> ? ((Class<?>)testCase).getClassLoader() : testCase.getClass()
- .getClassLoader();
+ .getClassLoader();
try {
properties.load(loader.getResourceAsStream("database.properties"));
} catch (IOException e) {
@@ -42,7 +42,6 @@
// Set the connection properties to be an in-memory HSQL database ...
JpaSource source = new JpaSource();
source.setName(sourceName);
- source.setModel(JpaSource.Models.BASIC.getName());
source.setDialect(properties.getProperty("jpaSource.dialect"));
source.setDriverClassName(properties.getProperty("jpaSource.driverClassName"));
source.setUsername(properties.getProperty("jpaSource.username"));
Modified: trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/model/basic/BasicCreateWorkspacesTest.java
===================================================================
--- trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/model/basic/BasicCreateWorkspacesTest.java 2010-01-06 23:49:23 UTC (rev 1537)
+++ trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/model/basic/BasicCreateWorkspacesTest.java 2010-01-06 23:49:59 UTC (rev 1538)
@@ -36,6 +36,7 @@
// Set the connection properties using the environment defined in the POM files ...
JpaSource source = TestEnvironment.configureJpaSource("Test Repository", this);
+ source.setModel(JpaSource.Models.BASIC.getName());
// Override the inherited properties, since that's the focus of these tests ...
source.setCreatingWorkspacesAllowed(true);
Modified: trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/model/basic/BasicNoCreateWorkspaceTest.java
===================================================================
--- trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/model/basic/BasicNoCreateWorkspaceTest.java 2010-01-06 23:49:23 UTC (rev 1537)
+++ trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/model/basic/BasicNoCreateWorkspaceTest.java 2010-01-06 23:49:59 UTC (rev 1538)
@@ -36,6 +36,7 @@
// Set the connection properties using the environment defined in the POM files ...
JpaSource source = TestEnvironment.configureJpaSource("Test Repository", this);
+ source.setModel(JpaSource.Models.BASIC.getName());
// Override the inherited properties, since that's the focus of these tests ...
source.setCreatingWorkspacesAllowed(true);
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2010-01-06 23:49:23 UTC (rev 1537)
+++ trunk/pom.xml 2010-01-06 23:49:59 UTC (rev 1538)
@@ -382,7 +382,7 @@
<database>hsqldb</database>
<jpaSource.dialect>org.hibernate.dialect.HSQLDialect</jpaSource.dialect>
<jpaSource.driverClassName>org.hsqldb.jdbcDriver</jpaSource.driverClassName>
- <jpaSource.url>jdbc:hsqldb:target/test/db/hsqldb/dna</jpaSource.url>
+ <jpaSource.url>jdbc:hsqldb:mem:dna</jpaSource.url>
<jpaSource.username>sa</jpaSource.username>
<jpaSource.password />
</properties>
@@ -409,7 +409,7 @@
<database>hsqldb</database>
<jpaSource.dialect>org.hibernate.dialect.HSQLDialect</jpaSource.dialect>
<jpaSource.driverClassName>org.hsqldb.jdbcDriver</jpaSource.driverClassName>
- <jpaSource.url>jdbc:hsqldb:target/test/db/hsqldb/dna</jpaSource.url>
+ <jpaSource.url>jdbc:hsqldb:mem:dna</jpaSource.url>
<jpaSource.username>sa</jpaSource.username>
<jpaSource.password />
</properties>
14 years, 5 months
DNA SVN: r1537 - in trunk: dna-graph/src/test/java/org/jboss/dna/graph/connector/path and 3 other directories.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2010-01-06 18:49:23 -0500 (Wed, 06 Jan 2010)
New Revision: 1537
Modified:
trunk/.gitignore
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/path/AbstractPathRepositorySourceTest.java
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepository.java
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositorySourceTest.java
trunk/extensions/dna-sequencer-classfile/src/test/java/org/jboss/dna/sequencer/classfile/metadata/ClassFileMetadataReaderTest.java
Log:
Minor modifications to correct or suppress 'unchecked' warnings. Also updated .gitignore file with new 'dna-sequencer-classfile' project.
Modified: trunk/.gitignore
===================================================================
--- trunk/.gitignore 2010-01-06 23:48:32 UTC (rev 1536)
+++ trunk/.gitignore 2010-01-06 23:49:23 UTC (rev 1537)
@@ -56,6 +56,7 @@
/extensions/dna-connector-svn/target
/extensions/dna-mimetype-detector-aperture/.settings
/extensions/dna-mimetype-detector-aperture/target
+/extensions/dna-sequencer-classfile/target
/extensions/dna-sequencer-cnd/target
/extensions/dna-sequencer-ddl/target
/extensions/dna-sequencer-esbMessage/target
Modified: trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/path/AbstractPathRepositorySourceTest.java
===================================================================
--- trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/path/AbstractPathRepositorySourceTest.java 2010-01-06 23:48:32 UTC (rev 1536)
+++ trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/path/AbstractPathRepositorySourceTest.java 2010-01-06 23:49:23 UTC (rev 1537)
@@ -23,12 +23,10 @@
*/
package org.jboss.dna.graph.connector.path;
-
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNot.not;
import static org.hamcrest.core.IsNull.notNullValue;
import static org.junit.Assert.assertThat;
-import javax.naming.NamingException;
import javax.naming.Reference;
import org.jboss.dna.graph.connector.RepositoryConnection;
import org.jboss.dna.graph.connector.RepositorySourceCapabilities;
@@ -65,7 +63,7 @@
return null;
}
- public Reference getReference() throws NamingException {
+ public Reference getReference() {
return null;
}
};
Modified: trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepository.java
===================================================================
--- trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepository.java 2010-01-06 23:48:32 UTC (rev 1536)
+++ trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepository.java 2010-01-06 23:49:23 UTC (rev 1537)
@@ -59,7 +59,7 @@
public class SvnRepository extends WritablePathRepository {
- protected static final String DEFAULT_MIME_TYPE = "application/octet-stream";
+ private static final String DEFAULT_MIME_TYPE = "application/octet-stream";
protected static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
protected final SvnRepositorySource source;
Modified: trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositorySourceTest.java
===================================================================
--- trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositorySourceTest.java 2010-01-06 23:48:32 UTC (rev 1536)
+++ trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositorySourceTest.java 2010-01-06 23:49:23 UTC (rev 1537)
@@ -154,12 +154,11 @@
assertThat(source.getName(), is(isNull()));
}
-
@Test
public void shouldHaveDefaultRetryLimit() {
assertThat(source.getRetryLimit(), is(SvnRepositorySource.DEFAULT_RETRY_LIMIT));
}
-
+
@Test( expected = IllegalArgumentException.class )
public void shouldNotAllowNullSVNUrl() {
source.setRepositoryRootUrl(null);
@@ -187,31 +186,30 @@
assertThat(source.getRetryLimit(), is(i));
}
}
-
+
@Test( expected = RepositorySourceException.class )
public void shouldFailToCreateConnectionIfSourceHasNoName() {
source.setName(null);
source.getConnection();
}
-
+
@Test( expected = RepositorySourceException.class )
public void shouldFailToCreateConnectionIfSourceHasNoUsername() {
source.setUsername(null);
source.getConnection();
}
-
+
@Test( expected = RepositorySourceException.class )
public void shouldFailToCreateConnectionIfSourceHasNoPassword() {
source.setPassword(null);
source.getConnection();
}
-
+
@Test
public void shouldCreateConnection() throws Exception {
connection = source.getConnection();
assertThat(connection, is(notNullValue()));
}
-
@Test
public void shouldCreateJndiReferenceAndRecreatedObjectFromReference() throws Exception {
Modified: trunk/extensions/dna-sequencer-classfile/src/test/java/org/jboss/dna/sequencer/classfile/metadata/ClassFileMetadataReaderTest.java
===================================================================
--- trunk/extensions/dna-sequencer-classfile/src/test/java/org/jboss/dna/sequencer/classfile/metadata/ClassFileMetadataReaderTest.java 2010-01-06 23:48:32 UTC (rev 1536)
+++ trunk/extensions/dna-sequencer-classfile/src/test/java/org/jboss/dna/sequencer/classfile/metadata/ClassFileMetadataReaderTest.java 2010-01-06 23:49:23 UTC (rev 1537)
@@ -92,11 +92,11 @@
ClassMetadata cmd = ClassFileMetadataReader.instance(input);
assertThat(cmd, instanceOf(EnumMetadata.class));
- EnumMetadata emd = (EnumMetadata) cmd;
-
+ EnumMetadata emd = (EnumMetadata)cmd;
+
List<String> enumValues = Arrays.asList(new String[] {"VALUE_A", "VALUE_B", "VALUE_C"});
assertThat(emd.getValues(), is(enumValues));
-
+
for (FieldMetadata fmd : emd.getFields()) {
assertThat(fmd.getName(), not(anyOf(is("VALUE_A"), is("VALUE_B"), is("VALUE_C"))));
}
@@ -141,7 +141,7 @@
checkConstructors(cmd, clazz);
}
- @SuppressWarnings( "unchecked" )
+ @SuppressWarnings( {"unchecked", "synthetic-access"} )
private void checkFields( ClassMetadata cmd,
Class<?> clazz ) throws Exception {
Map<FieldKey, Field> clazzFields = new HashMap<FieldKey, Field>();
@@ -181,6 +181,7 @@
}
}
+ @SuppressWarnings( "synthetic-access" )
private void checkMethods( ClassMetadata cmd,
Class<?> clazz ) throws Exception {
Map<MethodKey, Method> clazzMethods = new HashMap<MethodKey, Method>();
@@ -218,7 +219,6 @@
assertThat(metaMethod.getAnnotations().size(), is(clazzMethod.getDeclaredAnnotations().length));
-
// Can't really check this since some annotations are not runtime annotations
// for (AnnotationMetadata amd : metaMethod.getAnnotations()) {
// Class<Annotation> annotationClass = (Class<Annotation>)Class.forName(amd.getAnnotationClassName());
@@ -229,7 +229,7 @@
}
}
- @SuppressWarnings( "unchecked" )
+ @SuppressWarnings( {"unchecked", "synthetic-access"} )
private void checkConstructors( ClassMetadata cmd,
Class<?> clazz ) throws Exception {
Map<MethodKey, Constructor> clazzCtors = new HashMap<MethodKey, Constructor>();
14 years, 5 months
DNA SVN: r1536 - in trunk: dna-graph/src/main/java/org/jboss/dna/graph/query and 15 other directories.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2010-01-06 18:48:32 -0500 (Wed, 06 Jan 2010)
New Revision: 1536
Added:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/ArithmeticOperand.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/ArithmeticOperator.java
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/GraphI18n.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/QueryBuilder.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/QueryResults.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/DynamicOperand.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/FullTextSearchScore.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Length.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/LowerCase.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodeDepth.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodeLocalName.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodeName.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodePath.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/PropertyValue.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/UpperCase.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Visitor.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Visitors.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/parse/SqlQueryParser.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/plan/CanonicalPlanner.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/plan/PlanHints.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/plan/PlanUtil.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/process/ProcessingComponent.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/process/QueryProcessor.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/process/QueryResults.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/process/SortValuesComponent.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/validate/Validator.java
trunk/dna-graph/src/main/resources/org/jboss/dna/graph/GraphI18n.properties
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/QueryBuilderTest.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/RuleBasedOptimizerTest.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/plan/CanonicalPlannerTest.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/process/QueryResultColumnsTest.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrQueryManager.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPath.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPathParser.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPathToQueryTranslator.java
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrQueryManagerTest.java
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrTckTest.java
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/xpath/XPathParserTest.java
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/xpath/XPathToQueryTranslatorTest.java
trunk/dna-jcr/src/test/resources/tck/repositoryForTckTests.xml
Log:
DNA-613 One problem was when there was an ORDER BY SCORE(selectorName) when the selector was a view that joined multiple tables. In this case, the score function would need to be resolved against the scores from multiple source tables. The existing FullTextSearchScore subclass of DynamicOperand required a single selector name, so it was not possible to represent a single DynamicOperand that represented the score from multiple tables.
One option considered was the creation of a FullTextSearchCompositeScore that would accept multiple selector names. Unfortunately, DynamicOperand makes the assumption that it only applies to a single selector, and thus has a 'getSelectorName()' method. This could be changed to no longer make this assumption (as well as adjust all places that use this method), but the composite score DynamicOperand seems to be a bit of a hack.
Instead, I decided that it was better to support a DynamicOperand that represented an arithmetic operation between two other DynamicOperands, and thus there is a new ArithmeticOperand class that contains a left DynamicOperand, an arithmetic operator, and a right DynamicOperand. And of course, ArithmeticOperands can be nested inside each other to create relatively complex operations. Because an ArithmeticOperand applies to two DynamicOperands, those DynamicOperands might apply to different selectors. Thus, this approach also required changing DynamicOperand.getSelectorName():SelectorName to getSelectorNames():Set<SelectorName>. Also, it was critical for this set to maintain the order of insertion of the set, so a LinkedHashSet was used.
This addition required changes to the SQL parser, the planner, and the optimizer (along with the corresponding tests). The change to multiple selector names for DynamicOperand also required changes to all other DynamicOperand subclasses, and the code that used these methods.
Another change was made to the PlanHints so that a string representation of the query plan could be requested and placed in the results. In the JCR layer, this was leveraged by always requesting the plan and then making the string representation of the plan publicly available on the JcrQueryResult class.
Finally, there were changes made to the way the XPath-to-SQL translator works (along with the test cases).
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 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/GraphI18n.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -143,6 +143,8 @@
public static I18n columnDoesNotExistInQuery;
public static I18n columnIsNotFullTextSearchable;
public static I18n tableIsNotFullTextSearchable;
+ public static I18n columnTypeCannotBeUsedInArithmeticOperation;
+ public static I18n dynamicOperandCannotBeUsedInArithmeticOperation;
public static I18n selectorDoesNotExistInQuery;
public static I18n propertyOnSelectorIsNotUsedInQuery;
public static I18n errorResolvingNodesFromLocationsUsingSourceAndWorkspace;
@@ -167,6 +169,7 @@
public static I18n expectingLiteralAndUnableToParseAsLong;
public static I18n expectingLiteralAndUnableToParseAsDouble;
public static I18n expectingLiteralAndUnableToParseAsDate;
+ public static I18n unexpectedClosingParenthesis;
/* Search */
public static I18n interruptedWhileClosingChannel;
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/QueryBuilder.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/QueryBuilder.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/QueryBuilder.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -41,6 +41,8 @@
import org.jboss.dna.graph.property.PropertyType;
import org.jboss.dna.graph.query.model.AllNodes;
import org.jboss.dna.graph.query.model.And;
+import org.jboss.dna.graph.query.model.ArithmeticOperand;
+import org.jboss.dna.graph.query.model.ArithmeticOperator;
import org.jboss.dna.graph.query.model.Between;
import org.jboss.dna.graph.query.model.BindVariableName;
import org.jboss.dna.graph.query.model.ChildNode;
@@ -69,6 +71,7 @@
import org.jboss.dna.graph.query.model.Not;
import org.jboss.dna.graph.query.model.Operator;
import org.jboss.dna.graph.query.model.Or;
+import org.jboss.dna.graph.query.model.Order;
import org.jboss.dna.graph.query.model.Ordering;
import org.jboss.dna.graph.query.model.PropertyExistence;
import org.jboss.dna.graph.query.model.PropertyValue;
@@ -703,6 +706,17 @@
}
/**
+ * Obtain a builder that will create the order-by clause (with one or more {@link Ordering} statements) for the query. This
+ * method need be called only once to build the order-by clause, but can be called multiple times (it merely adds additional
+ * {@link Ordering} statements).
+ *
+ * @return the order-by builder; never null
+ */
+ public OrderByBuilder orderBy() {
+ return new OrderByBuilder();
+ }
+
+ /**
* Return a {@link QueryCommand} representing the currently-built query.
*
* @return the resulting query command; never null
@@ -726,7 +740,256 @@
return result;
}
+ public interface OrderByOperandBuilder {
+ /**
+ * Adds to the order-by clause by using the length of the value for the given table and property.
+ *
+ * @param table the name of the table; may not be null and must refer to a valid name or alias of a table appearing in the
+ * FROM clause
+ * @param property the name of the property; may not be null and must refer to a valid property name
+ * @return the interface for completing the order-by specification; never null
+ */
+ public OrderByBuilder length( String table,
+ String property );
+
+ /**
+ * Adds to the order-by clause by using the value for the given table and property.
+ *
+ * @param table the name of the table; may not be null and must refer to a valid name or alias of a table appearing in the
+ * FROM clause
+ * @param property the name of the property; may not be null and must refer to a valid property name
+ * @return the interface for completing the order-by specification; never null
+ */
+ public OrderByBuilder propertyValue( String table,
+ String property );
+
+ /**
+ * Adds to the order-by clause by using the full-text search score for the given table.
+ *
+ * @param table the name of the table; may not be null and must refer to a valid name or alias of a table appearing in the
+ * FROM clause
+ * @return the interface for completing the order-by specification; never null
+ */
+ public OrderByBuilder fullTextSearchScore( String table );
+
+ /**
+ * Adds to the order-by clause by using the depth of the node given by the named table.
+ *
+ * @param table the name of the table; may not be null and must refer to a valid name or alias of a table appearing in the
+ * FROM clause
+ * @return the interface for completing the order-by specification; never null
+ */
+ public OrderByBuilder depth( String table );
+
+ /**
+ * Adds to the order-by clause by using the path of the node given by the named table.
+ *
+ * @param table the name of the table; may not be null and must refer to a valid name or alias of a table appearing in the
+ * FROM clause
+ * @return the interface for completing the order-by specification; never null
+ */
+ public OrderByBuilder path( String table );
+
+ /**
+ * Adds to the order-by clause by using the local name of the node given by the named table.
+ *
+ * @param table the name of the table; may not be null and must refer to a valid name or alias of a table appearing in the
+ * FROM clause
+ * @return the interface for completing the order-by specification; never null
+ */
+ public OrderByBuilder nodeLocalName( String table );
+
+ /**
+ * Adds to the order-by clause by using the node name (including namespace) of the node given by the named table.
+ *
+ * @param table the name of the table; may not be null and must refer to a valid name or alias of a table appearing in the
+ * FROM clause
+ * @return the interface for completing the order-by specification; never null
+ */
+ public OrderByBuilder nodeName( String table );
+
+ /**
+ * Adds to the order-by clause by using the uppercase form of the next operand.
+ *
+ * @return the interface for completing the order-by specification; never null
+ */
+ public OrderByOperandBuilder upperCaseOf();
+
+ /**
+ * Adds to the order-by clause by using the lowercase form of the next operand.
+ *
+ * @return the interface for completing the order-by specification; never null
+ */
+ public OrderByOperandBuilder lowerCaseOf();
+ }
+
/**
+ * The component used to build the order-by clause. When the clause is completed, {@link #end()} should be called to return to
+ * the {@link QueryBuilder} instance.
+ */
+ public class OrderByBuilder {
+
+ protected OrderByBuilder() {
+ }
+
+ /**
+ * Begin specifying an order-by specification using {@link Order#ASCENDING ascending order}.
+ *
+ * @return the interface for specifying the operand that is to be ordered; never null
+ */
+ public OrderByOperandBuilder ascending() {
+ return new SingleOrderByOperandBuilder(this, Order.ASCENDING);
+ }
+
+ /**
+ * Begin specifying an order-by specification using {@link Order#DESCENDING descending order}.
+ *
+ * @return the interface for specifying the operand that is to be ordered; never null
+ */
+ public OrderByOperandBuilder descending() {
+ return new SingleOrderByOperandBuilder(this, Order.DESCENDING);
+ }
+
+ /**
+ * An optional convenience method that returns this builder, but which makes the code using this builder more readable.
+ *
+ * @return this builder; never null
+ */
+ public OrderByBuilder then() {
+ return this;
+ }
+
+ /**
+ * Complete the order-by clause and return the QueryBuilder instance.
+ *
+ * @return the query builder instance; never null
+ */
+ public QueryBuilder end() {
+ return QueryBuilder.this;
+ }
+ }
+
+ protected class SingleOrderByOperandBuilder implements OrderByOperandBuilder {
+ private final Order order;
+ private final OrderByBuilder builder;
+
+ protected SingleOrderByOperandBuilder( OrderByBuilder builder,
+ Order order ) {
+ this.order = order;
+ this.builder = builder;
+ }
+
+ protected OrderByBuilder addOrdering( DynamicOperand operand ) {
+ Ordering ordering = new Ordering(operand, order);
+ QueryBuilder.this.orderings.add(ordering);
+ return builder;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.query.QueryBuilder.OrderByOperandBuilder#propertyValue(java.lang.String, java.lang.String)
+ */
+ public OrderByBuilder propertyValue( String table,
+ String property ) {
+ return addOrdering(new PropertyValue(selector(table), property));
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.query.QueryBuilder.OrderByOperandBuilder#length(java.lang.String, java.lang.String)
+ */
+ public OrderByBuilder length( String table,
+ String property ) {
+ return addOrdering(new Length(new PropertyValue(selector(table), property)));
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.query.QueryBuilder.OrderByOperandBuilder#fullTextSearchScore(java.lang.String)
+ */
+ public OrderByBuilder fullTextSearchScore( String table ) {
+ return addOrdering(new FullTextSearchScore(selector(table)));
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.query.QueryBuilder.OrderByOperandBuilder#depth(java.lang.String)
+ */
+ public OrderByBuilder depth( String table ) {
+ return addOrdering(new NodeDepth(selector(table)));
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.query.QueryBuilder.OrderByOperandBuilder#path(java.lang.String)
+ */
+ public OrderByBuilder path( String table ) {
+ return addOrdering(new NodePath(selector(table)));
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.query.QueryBuilder.OrderByOperandBuilder#nodeName(java.lang.String)
+ */
+ public OrderByBuilder nodeName( String table ) {
+ return addOrdering(new NodeName(selector(table)));
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.query.QueryBuilder.OrderByOperandBuilder#nodeLocalName(java.lang.String)
+ */
+ public OrderByBuilder nodeLocalName( String table ) {
+ return addOrdering(new NodeLocalName(selector(table)));
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.query.QueryBuilder.OrderByOperandBuilder#lowerCaseOf()
+ */
+ public OrderByOperandBuilder lowerCaseOf() {
+ return new SingleOrderByOperandBuilder(builder, order) {
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.query.QueryBuilder.SingleOrderByOperandBuilder#addOrdering(org.jboss.dna.graph.query.model.DynamicOperand)
+ */
+ @Override
+ protected OrderByBuilder addOrdering( DynamicOperand operand ) {
+ return super.addOrdering(new LowerCase(operand));
+ }
+ };
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.query.QueryBuilder.OrderByOperandBuilder#upperCaseOf()
+ */
+ public OrderByOperandBuilder upperCaseOf() {
+ return new SingleOrderByOperandBuilder(builder, order) {
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.query.QueryBuilder.SingleOrderByOperandBuilder#addOrdering(org.jboss.dna.graph.query.model.DynamicOperand)
+ */
+ @Override
+ protected OrderByBuilder addOrdering( DynamicOperand operand ) {
+ return super.addOrdering(new UpperCase(operand));
+ }
+ };
+ }
+ }
+
+ /**
* Class used to specify a join clause of a query.
*
* @see QueryBuilder#join(String)
@@ -932,7 +1195,6 @@
* @return the interface for completing the criteria specification; never null
*/
public DynamicOperandBuilder lowerCaseOf();
-
}
public class ConstraintBuilder implements DynamicOperandBuilder {
@@ -975,9 +1237,12 @@
* Complete the specification of a constraint clause, and return the builder for the parent constraint clause.
*
* @return the constraint builder that was used to create this parenthetical constraint clause builder; never null
+ * @throws IllegalStateException if there was not an {@link #openParen() open parenthesis} to close
*/
public ConstraintBuilder closeParen() {
- assert parent != null;
+ if (parent == null) {
+ throw new IllegalStateException(GraphI18n.unexpectedClosingParenthesis.text());
+ }
buildLogicalConstraint();
return parent.setConstraint(constraint);
}
@@ -1125,6 +1390,10 @@
return setConstraint(new FullTextSearch(selector(table), propertyName, searchExpression));
}
+ protected ComparisonBuilder comparisonBuilder( DynamicOperand operand ) {
+ return new ComparisonBuilder(this, operand);
+ }
+
/**
* {@inheritDoc}
*
@@ -1132,7 +1401,7 @@
*/
public ComparisonBuilder length( String table,
String property ) {
- return new ComparisonBuilder(this, new Length(new PropertyValue(selector(table), property)));
+ return comparisonBuilder(new Length(new PropertyValue(selector(table), property)));
}
/**
@@ -1142,7 +1411,7 @@
*/
public ComparisonBuilder propertyValue( String table,
String property ) {
- return new ComparisonBuilder(this, new PropertyValue(selector(table), property));
+ return comparisonBuilder(new PropertyValue(selector(table), property));
}
/**
@@ -1151,7 +1420,7 @@
* @see org.jboss.dna.graph.query.QueryBuilder.DynamicOperandBuilder#fullTextSearchScore(String)
*/
public ComparisonBuilder fullTextSearchScore( String table ) {
- return new ComparisonBuilder(this, new FullTextSearchScore(selector(table)));
+ return comparisonBuilder(new FullTextSearchScore(selector(table)));
}
/**
@@ -1160,7 +1429,7 @@
* @see org.jboss.dna.graph.query.QueryBuilder.DynamicOperandBuilder#depth(java.lang.String)
*/
public ComparisonBuilder depth( String table ) {
- return new ComparisonBuilder(this, new NodeDepth(selector(table)));
+ return comparisonBuilder(new NodeDepth(selector(table)));
}
/**
@@ -1169,7 +1438,7 @@
* @see org.jboss.dna.graph.query.QueryBuilder.DynamicOperandBuilder#path(java.lang.String)
*/
public ComparisonBuilder path( String table ) {
- return new ComparisonBuilder(this, new NodePath(selector(table)));
+ return comparisonBuilder(new NodePath(selector(table)));
}
/**
@@ -1178,7 +1447,7 @@
* @see org.jboss.dna.graph.query.QueryBuilder.DynamicOperandBuilder#nodeLocalName(String)
*/
public ComparisonBuilder nodeLocalName( String table ) {
- return new ComparisonBuilder(this, new NodeLocalName(selector(table)));
+ return comparisonBuilder(new NodeLocalName(selector(table)));
}
/**
@@ -1187,7 +1456,7 @@
* @see org.jboss.dna.graph.query.QueryBuilder.DynamicOperandBuilder#nodeName(String)
*/
public ComparisonBuilder nodeName( String table ) {
- return new ComparisonBuilder(this, new NodeName(selector(table)));
+ return comparisonBuilder(new NodeName(selector(table)));
}
/**
@@ -1365,7 +1634,8 @@
*/
@Override
public ConstraintBuilder as( String type ) {
- return upperBoundary.comparisonBuilder.isBetween(upperBoundary.lowerBound, typeSystem.getTypeFactory(type).create(value));
+ return upperBoundary.comparisonBuilder.isBetween(upperBoundary.lowerBound, typeSystem.getTypeFactory(type)
+ .create(value));
}
}
@@ -2172,6 +2442,124 @@
}
}
+ public class ArithmeticBuilder {
+ protected final ArithmeticBuilder parent;
+ protected final ArithmeticOperator operator;
+ protected DynamicOperand left;
+ protected final ComparisonBuilder comparisonBuilder;
+
+ protected ArithmeticBuilder( ArithmeticOperator operator,
+ ComparisonBuilder comparisonBuilder,
+ DynamicOperand left,
+ ArithmeticBuilder parent ) {
+ this.operator = operator;
+ this.left = left;
+ this.comparisonBuilder = comparisonBuilder;
+ this.parent = parent; // may be null
+ }
+
+ /**
+ * Constrains the nodes in the the supplied table such that they must have a property value whose length matches the
+ * criteria.
+ *
+ * @param table the name of the table; may not be null and must refer to a valid name or alias of a table appearing in the
+ * FROM clause
+ * @param property the name of the property; may not be null and must refer to a valid property name
+ * @return the interface for completing the value portion of the criteria specification; never null
+ */
+ public ComparisonBuilder length( String table,
+ String property ) {
+ return comparisonBuilder(new Length(new PropertyValue(selector(table), property)));
+ }
+
+ /**
+ * Constrains the nodes in the the supplied table such that they must have a matching value for the named property.
+ *
+ * @param table the name of the table; may not be null and must refer to a valid name or alias of a table appearing in the
+ * FROM clause
+ * @param property the name of the property; may not be null and must refer to a valid property name
+ * @return the interface for completing the value portion of the criteria specification; never null
+ */
+ public ComparisonBuilder propertyValue( String table,
+ String property ) {
+ return comparisonBuilder(new PropertyValue(selector(table), property));
+ }
+
+ /**
+ * Constrains the nodes in the the supplied table such that they must satisfy the supplied full-text search on the nodes'
+ * property values.
+ *
+ * @param table the name of the table; may not be null and must refer to a valid name or alias of a table appearing in the
+ * FROM clause
+ * @return the interface for completing the value portion of the criteria specification; never null
+ */
+ public ComparisonBuilder fullTextSearchScore( String table ) {
+ return comparisonBuilder(new FullTextSearchScore(selector(table)));
+ }
+
+ /**
+ * Constrains the nodes in the the supplied table based upon criteria on the node's depth.
+ *
+ * @param table the name of the table; may not be null and must refer to a valid name or alias of a table appearing in the
+ * FROM clause
+ * @return the interface for completing the value portion of the criteria specification; never null
+ */
+ public ComparisonBuilder depth( String table ) {
+ return comparisonBuilder(new NodeDepth(selector(table)));
+ }
+
+ // /**
+ // * Simulate the use of an open parenthesis in the constraint. The resulting builder should be used to define the
+ // * constraint within the parenthesis, and should always be terminated with a {@link #closeParen()}.
+ // *
+ // * @return the constraint builder that should be used to define the portion of the constraint within the parenthesis;
+ // * never null
+ // * @see #closeParen()
+ // */
+ // public ArithmeticBuilder openParen() {
+ // return new ArithmeticBuilder(operator, comparisonBuilder, left, this);
+ // }
+ //
+ // /**
+ // * Complete the specification of a constraint clause, and return the builder for the parent constraint clause.
+ // *
+ // * @return the constraint builder that was used to create this parenthetical constraint clause builder; never null
+ // * @throws IllegalStateException if there was not an {@link #openParen() open parenthesis} to close
+ // */
+ // public ComparisonBuilder closeParen() {
+ // if (parent == null) {
+ // throw new IllegalStateException(GraphI18n.unexpectedClosingParenthesis.text());
+ // }
+ // buildLogicalConstraint();
+ // return parent.setLeft(left).comparisonBuilder;
+ // }
+ // protected ArithmeticBuilder setLeft( DynamicOperand left ) {
+ // this.left = left;
+ // return this;
+ // }
+
+ protected ComparisonBuilder comparisonBuilder( DynamicOperand right ) {
+ DynamicOperand leftOperand = null;
+ // If the left operand is an arithmetic operand, then we need to check the operator precedence ...
+ if (left instanceof ArithmeticOperand) {
+ ArithmeticOperand leftArith = (ArithmeticOperand)left;
+ ArithmeticOperator operator = leftArith.getOperator();
+ if (this.operator.precedes(operator)) {
+ // Need to do create an operand with leftArith.right and right
+ DynamicOperand inner = new ArithmeticOperand(leftArith.getRight(), this.operator, right);
+ leftOperand = new ArithmeticOperand(leftArith.getLeft(), operator, inner);
+ } else {
+ // the left preceds this, so we can add the new operand on top ...
+ leftOperand = new ArithmeticOperand(leftArith, operator, right);
+ }
+ } else {
+ // The left isn't an arith ...
+ leftOperand = new ArithmeticOperand(left, operator, right);
+ }
+ return new ComparisonBuilder(comparisonBuilder.constraintBuilder, leftOperand);
+ }
+ }
+
/**
* An interface used to set the right-hand side of a constraint.
*/
@@ -2197,6 +2585,26 @@
}
/**
+ * Create a comparison object based upon the addition of the previously-constructed {@link DynamicOperand} and the next
+ * DynamicOperand to be created with the supplied builder.
+ *
+ * @return the builder that should be used to create the right-hand-side of the operation; never null
+ */
+ public ArithmeticBuilder plus() {
+ return new ArithmeticBuilder(ArithmeticOperator.ADD, this, left, null);
+ }
+
+ /**
+ * Create a comparison object based upon the subtraction of the next {@link DynamicOperand} (created using the builder
+ * returned from this method) from the the previously-constructed DynamicOperand to be created with the supplied builder.
+ *
+ * @return the builder that should be used to create the right-hand-side of the operation; never null
+ */
+ public ArithmeticBuilder minus() {
+ return new ArithmeticBuilder(ArithmeticOperator.SUBTRACT, this, left, null);
+ }
+
+ /**
* Define the operator that will be used in the comparison, returning an interface that can be used to define the
* right-hand-side of the comparison.
*
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/QueryResults.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/QueryResults.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/QueryResults.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -71,6 +71,13 @@
public int getRowCount();
/**
+ * Get a description of the query plan, if requested.
+ *
+ * @return the query plan, or null if the plan was not requested
+ */
+ public String getPlan();
+
+ /**
* Get the problems encountered during execution.
*
* @return the problems; never null but possibly empty
Copied: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/ArithmeticOperand.java (from rev 1535, trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/PropertyValue.java)
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/ArithmeticOperand.java (rev 0)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/ArithmeticOperand.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -0,0 +1,133 @@
+/*
+ * 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.query.model;
+
+import net.jcip.annotations.Immutable;
+import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.common.util.HashCode;
+
+/**
+ * A dynamic operand that represents a (binary) arithmetic operation upon one or more other operands, used in {@link Comparison}
+ * and {@link Ordering} components.
+ */
+@Immutable
+public class ArithmeticOperand extends DynamicOperand {
+ private static final long serialVersionUID = 1L;
+
+ private final ArithmeticOperator operator;
+ private final DynamicOperand left;
+ private final DynamicOperand right;
+ private final int hc;
+
+ /**
+ * Create a arithmetic dynamic operand that operates upon the supplied operand(s).
+ *
+ * @param left the left-hand-side operand
+ * @param operator the arithmetic operator; may not be null
+ * @param right the right-hand-side operand
+ * @throws IllegalArgumentException if any of the arguments is null
+ */
+ public ArithmeticOperand( DynamicOperand left,
+ ArithmeticOperator operator,
+ DynamicOperand right ) {
+ super(left, right);
+ CheckArg.isNotNull(operator, "operator");
+ this.operator = operator;
+ this.left = left;
+ this.right = right;
+ this.hc = HashCode.compute(left, operator, right);
+ }
+
+ /**
+ * Get the operator for this binary operand.
+ *
+ * @return the operator; never null
+ */
+ public ArithmeticOperator getOperator() {
+ return operator;
+ }
+
+ /**
+ * Get the left-hand operand.
+ *
+ * @return the left-hand operator; never null
+ */
+ public DynamicOperand getLeft() {
+ return left;
+ }
+
+ /**
+ * Get the right-hand operand.
+ *
+ * @return the right-hand operator; never null
+ */
+ public DynamicOperand getRight() {
+ return right;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return Visitors.readable(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return hc;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof ArithmeticOperand) {
+ ArithmeticOperand that = (ArithmeticOperand)obj;
+ return this.getOperator() == that.getOperator() && this.getLeft().equals(that.getLeft())
+ && this.getRight().equals(that.getRight());
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.query.model.Visitable#accept(org.jboss.dna.graph.query.model.Visitor)
+ */
+ public void accept( Visitor visitor ) {
+ visitor.visit(this);
+ }
+}
Added: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/ArithmeticOperator.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/ArithmeticOperator.java (rev 0)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/ArithmeticOperator.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -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.graph.query.model;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import org.jboss.dna.common.util.CheckArg;
+
+/**
+ * The arithmetic operators.
+ */
+public enum ArithmeticOperator {
+
+ ADD("+", Arity.BINARY, 20),
+ SUBTRACT("-", Arity.BINARY, 19),
+ MULTIPLY("*", Arity.BINARY, 18),
+ DIVIDE("/", Arity.BINARY, 17);
+
+ public static enum Arity {
+ UNARY,
+ BINARY;
+ }
+
+ private static final Map<String, ArithmeticOperator> OPERATORS_BY_SYMBOL;
+ static {
+ Map<String, ArithmeticOperator> opsBySymbol = new HashMap<String, ArithmeticOperator>();
+ for (ArithmeticOperator operator : ArithmeticOperator.values()) {
+ opsBySymbol.put(operator.getSymbol(), operator);
+ }
+ OPERATORS_BY_SYMBOL = Collections.unmodifiableMap(opsBySymbol);
+ }
+
+ private final String symbol;
+ private final Arity arity;
+ private final int precedence;
+
+ private ArithmeticOperator( String symbol,
+ Arity arity,
+ int precedence ) {
+ this.symbol = symbol;
+ this.arity = arity;
+ this.precedence = precedence;
+ }
+
+ /**
+ * Get the symbol for this operator
+ *
+ * @return the symbolic representation; never null
+ */
+ public String getSymbol() {
+ return symbol;
+ }
+
+ /**
+ * Get the 'arity' of the operator.
+ *
+ * @return the number of parameters required
+ * @see #isUnary()
+ * @see #isBinary()
+ */
+ public Arity getArity() {
+ return arity;
+ }
+
+ /**
+ * Return whether this is an unary operator.
+ *
+ * @return true if this operator is unary, or false otherwise
+ * @see #getArity()
+ * @see #isBinary()
+ */
+ public boolean isUnary() {
+ return arity == Arity.UNARY;
+ }
+
+ /**
+ * Return whether this is an binary operator.
+ *
+ * @return true if this operator is binary, or false otherwise
+ * @see #getArity()
+ * @see #isUnary()
+ */
+ public boolean isBinary() {
+ return arity == Arity.BINARY;
+ }
+
+ /**
+ * Determine whether this operator has a higher precedence than the supplied operator.
+ *
+ * @param operator the other operator; may not be null
+ * @return true if this operator has a higher precedence, or false otherwise
+ */
+ public boolean precedes( ArithmeticOperator operator ) {
+ return this.precedence > operator.precedence;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Enum#toString()
+ */
+ @Override
+ public String toString() {
+ return symbol;
+ }
+
+ /**
+ * Attempt to find the Operator given a symbol. The matching is done independent of case.
+ *
+ * @param symbol the symbol
+ * @return the Operator having the supplied symbol, or null if there is no Operator with the supplied symbol
+ * @throws IllegalArgumentException if the symbol is null
+ */
+ public static ArithmeticOperator forSymbol( String symbol ) {
+ CheckArg.isNotNull(symbol, "symbol");
+ return OPERATORS_BY_SYMBOL.get(symbol.toUpperCase());
+ }
+}
Property changes on: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/ArithmeticOperator.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/DynamicOperand.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/DynamicOperand.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/DynamicOperand.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -23,7 +23,13 @@
*/
package org.jboss.dna.graph.query.model;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.Set;
import net.jcip.annotations.Immutable;
+import org.jboss.dna.common.util.CheckArg;
/**
* A dynamic operand used in a {@link Comparison} constraint.
@@ -32,10 +38,87 @@
public abstract class DynamicOperand implements LanguageObject {
private static final long serialVersionUID = 1L;
+ private final Set<SelectorName> selectorNames;
+
/**
- * Get the selector symbol to which this operand applies.
+ * Create a arithmetic dynamic operand that operates upon the supplied selector name(s).
*
- * @return the selector name; never null
+ * @param selectorNames the selector names
+ * @throws IllegalArgumentException if the selector names array is null or empty, or if any of the values are null
*/
- public abstract SelectorName getSelectorName();
+ protected DynamicOperand( SelectorName... selectorNames ) {
+ CheckArg.isNotNull(selectorNames, "selectorNames");
+ if (selectorNames.length == 1) {
+ CheckArg.isNotNull(selectorNames, "selectorNames[0]");
+ this.selectorNames = Collections.singleton(selectorNames[0]);
+ } else {
+ CheckArg.isNotNull(selectorNames, "selectorNames[0]");
+ this.selectorNames = Collections.unmodifiableSet(new LinkedHashSet<SelectorName>(Arrays.asList(selectorNames)));
+ int i = 0;
+ for (SelectorName name : this.selectorNames) {
+ CheckArg.isNotNull(name, "selectorNames[" + i++ + "]");
+ }
+ }
+ }
+
+ /**
+ * Create a arithmetic dynamic operand that operates upon the supplied selector name(s).
+ *
+ * @param selectorNames the selector names
+ * @throws IllegalArgumentException if the name list is null or empty, or if any of the values are null
+ */
+ protected DynamicOperand( Collection<SelectorName> selectorNames ) {
+ CheckArg.isNotNull(selectorNames, "selectorName");
+ this.selectorNames = Collections.unmodifiableSet(new LinkedHashSet<SelectorName>(selectorNames));
+ }
+
+ /**
+ * Create a arithmetic dynamic operand that operates upon the selector names given by the supplied dynamic operand(s).
+ *
+ * @param operand the operand defining the selector names
+ * @throws IllegalArgumentException if the operand is null
+ */
+ protected DynamicOperand( DynamicOperand operand ) {
+ CheckArg.isNotNull(operand, "operand");
+ this.selectorNames = operand.getSelectorNames(); // immutable, so we can reference it directly
+ }
+
+ /**
+ * Create a arithmetic dynamic operand that operates upon the selector names given by the supplied dynamic operand(s).
+ *
+ * @param operands the operands defining the selector names
+ * @throws IllegalArgumentException if the operand is null
+ */
+ protected DynamicOperand( Iterable<? extends DynamicOperand> operands ) {
+ CheckArg.isNotNull(operands, "operands");
+ Set<SelectorName> names = new LinkedHashSet<SelectorName>();
+ for (DynamicOperand operand : operands) {
+ names.addAll(operand.getSelectorNames());
+ }
+ this.selectorNames = Collections.unmodifiableSet(names);
+ }
+
+ /**
+ * Create a arithmetic dynamic operand that operates upon the selector names given by the supplied dynamic operand(s).
+ *
+ * @param operands the operands defining the selector names
+ * @throws IllegalArgumentException if the operand is null
+ */
+ protected DynamicOperand( DynamicOperand... operands ) {
+ CheckArg.isNotNull(operands, "operands");
+ Set<SelectorName> names = new LinkedHashSet<SelectorName>();
+ for (DynamicOperand operand : operands) {
+ names.addAll(operand.getSelectorNames());
+ }
+ this.selectorNames = Collections.unmodifiableSet(names);
+ }
+
+ /**
+ * Get the selector symbols to which this operand applies.
+ *
+ * @return the immutable ordered set of non-null selector names used by this operand; never null and never empty
+ */
+ public Set<SelectorName> getSelectorNames() {
+ return selectorNames;
+ }
}
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/FullTextSearchScore.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/FullTextSearchScore.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/FullTextSearchScore.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -24,36 +24,31 @@
package org.jboss.dna.graph.query.model;
import net.jcip.annotations.Immutable;
-import org.jboss.dna.common.util.CheckArg;
/**
* A dynamic operand that evaluates to the full-text search score of a node given by a selector, used in a {@link Comparison}
- * constraint.
+ * constraint and {@link Ordering}s.
*/
@Immutable
public class FullTextSearchScore extends DynamicOperand {
private static final long serialVersionUID = 1L;
- private final SelectorName selectorName;
-
/**
* Create a dynamic operand that evaluates to the full-text search score of the node identified by the selector.
*
* @param selectorName the name of the selector
*/
public FullTextSearchScore( SelectorName selectorName ) {
- CheckArg.isNotNull(selectorName, "selectorName");
- this.selectorName = selectorName;
+ super(selectorName);
}
/**
- * {@inheritDoc}
+ * Get the selector symbol upon which this operand applies.
*
- * @see org.jboss.dna.graph.query.model.DynamicOperand#getSelectorName()
+ * @return the one selector names used by this operand; never null
*/
- @Override
public SelectorName getSelectorName() {
- return selectorName;
+ return getSelectorNames().iterator().next();
}
/**
@@ -73,7 +68,7 @@
*/
@Override
public int hashCode() {
- return getSelectorName().hashCode();
+ return getSelectorNames().hashCode();
}
/**
@@ -86,7 +81,7 @@
if (obj == this) return true;
if (obj instanceof FullTextSearchScore) {
FullTextSearchScore that = (FullTextSearchScore)obj;
- if (!this.selectorName.equals(that.selectorName)) return false;
+ if (!this.getSelectorNames().equals(that.getSelectorNames())) return false;
return true;
}
return false;
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Length.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Length.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Length.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -24,7 +24,6 @@
package org.jboss.dna.graph.query.model;
import net.jcip.annotations.Immutable;
-import org.jboss.dna.common.util.CheckArg;
/**
* A dynamic operand that evaluates to the length of the supplied propety values, used in a {@link Comparison} constraint.
@@ -41,27 +40,26 @@
* @param propertyValue the property value operand
*/
public Length( PropertyValue propertyValue ) {
- CheckArg.isNotNull(propertyValue, "propertyValue");
+ super(propertyValue);
this.propertyValue = propertyValue;
}
/**
- * {@inheritDoc}
+ * Get the property value whose length is being constrained.
*
- * @see org.jboss.dna.graph.query.model.DynamicOperand#getSelectorName()
+ * @return the property value being constrained; never null
*/
- @Override
- public SelectorName getSelectorName() {
- return propertyValue.getSelectorName();
+ public final PropertyValue getPropertyValue() {
+ return propertyValue;
}
/**
- * Get the property value whose length is being constrained.
+ * Get the selector symbol upon which this operand applies.
*
- * @return the property value being constrained; never null
+ * @return the one selector names used by this operand; never null
*/
- public final PropertyValue getPropertyValue() {
- return propertyValue;
+ public SelectorName getSelectorName() {
+ return getSelectorNames().iterator().next();
}
/**
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/LowerCase.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/LowerCase.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/LowerCase.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -24,7 +24,6 @@
package org.jboss.dna.graph.query.model;
import net.jcip.annotations.Immutable;
-import org.jboss.dna.common.util.CheckArg;
/**
* A dynamic operand that evaluates to the lower-case representation of the supplied operand, used in a {@link Comparison}
@@ -42,7 +41,7 @@
* @param operand the operand that is to be lower-cased
*/
public LowerCase( DynamicOperand operand ) {
- CheckArg.isNotNull(operand, "operand");
+ super(operand);
this.operand = operand;
}
@@ -56,13 +55,12 @@
}
/**
- * {@inheritDoc}
+ * Get the selector symbol upon which this operand applies.
*
- * @see org.jboss.dna.graph.query.model.DynamicOperand#getSelectorName()
+ * @return the one selector names used by this operand; never null
*/
- @Override
public SelectorName getSelectorName() {
- return operand.getSelectorName();
+ return getSelectorNames().iterator().next();
}
/**
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodeDepth.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodeDepth.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodeDepth.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -24,7 +24,6 @@
package org.jboss.dna.graph.query.model;
import net.jcip.annotations.Immutable;
-import org.jboss.dna.common.util.CheckArg;
/**
* A dynamic operand that evaluates to the depth of a node given by a selector, used in a {@link Comparison} constraint.
@@ -33,8 +32,6 @@
public class NodeDepth extends DynamicOperand {
private static final long serialVersionUID = 1L;
- private final SelectorName selectorName;
-
/**
* Create a dynamic operand that evaluates to the depth of the node identified by the selector.
*
@@ -42,18 +39,16 @@
* @throws IllegalArgumentException if the selector name or property name are null
*/
public NodeDepth( SelectorName selectorName ) {
- CheckArg.isNotNull(selectorName, "selectorName");
- this.selectorName = selectorName;
+ super(selectorName);
}
/**
- * {@inheritDoc}
+ * Get the selector symbol upon which this operand applies.
*
- * @see org.jboss.dna.graph.query.model.DynamicOperand#getSelectorName()
+ * @return the one selector names used by this operand; never null
*/
- @Override
- public final SelectorName getSelectorName() {
- return selectorName;
+ public SelectorName getSelectorName() {
+ return getSelectorNames().iterator().next();
}
/**
@@ -73,7 +68,7 @@
*/
@Override
public int hashCode() {
- return getSelectorName().hashCode();
+ return getSelectorNames().hashCode();
}
/**
@@ -86,7 +81,7 @@
if (obj == this) return true;
if (obj instanceof NodeDepth) {
NodeDepth that = (NodeDepth)obj;
- return this.selectorName.equals(that.selectorName);
+ return this.getSelectorNames().equals(that.getSelectorNames());
}
return false;
}
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodeLocalName.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodeLocalName.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodeLocalName.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -24,7 +24,6 @@
package org.jboss.dna.graph.query.model;
import net.jcip.annotations.Immutable;
-import org.jboss.dna.common.util.CheckArg;
/**
* A dynamic operand that evaluates to the local name of a node given by a selector, used in a {@link Comparison} constraint.
@@ -33,26 +32,22 @@
public class NodeLocalName extends DynamicOperand {
private static final long serialVersionUID = 1L;
- private final SelectorName selectorName;
-
/**
* Create a dynamic operand that evaluates to the local name of the node identified by the selector.
*
* @param selectorName the name of the selector
*/
public NodeLocalName( SelectorName selectorName ) {
- CheckArg.isNotNull(selectorName, "selectorName");
- this.selectorName = selectorName;
+ super(selectorName);
}
/**
- * {@inheritDoc}
+ * Get the selector symbol upon which this operand applies.
*
- * @see org.jboss.dna.graph.query.model.DynamicOperand#getSelectorName()
+ * @return the one selector names used by this operand; never null
*/
- @Override
- public final SelectorName getSelectorName() {
- return selectorName;
+ public SelectorName getSelectorName() {
+ return getSelectorNames().iterator().next();
}
/**
@@ -72,7 +67,7 @@
*/
@Override
public int hashCode() {
- return getSelectorName().hashCode();
+ return getSelectorNames().hashCode();
}
/**
@@ -85,7 +80,7 @@
if (obj == this) return true;
if (obj instanceof NodeLocalName) {
NodeLocalName that = (NodeLocalName)obj;
- return this.selectorName.equals(that.selectorName);
+ return this.getSelectorNames().equals(that.getSelectorNames());
}
return false;
}
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodeName.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodeName.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodeName.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -24,7 +24,6 @@
package org.jboss.dna.graph.query.model;
import net.jcip.annotations.Immutable;
-import org.jboss.dna.common.util.CheckArg;
/**
* A dynamic operand that evaluates to the qualified name of a node given by a selector, used in a {@link Comparison} constraint.
@@ -33,26 +32,22 @@
public class NodeName extends DynamicOperand {
private static final long serialVersionUID = 1L;
- private final SelectorName selectorName;
-
/**
* Create a dynamic operand that evaluates to the qualified name of the node identified by the selector.
*
* @param selectorName the name of the selector
*/
public NodeName( SelectorName selectorName ) {
- CheckArg.isNotNull(selectorName, "selectorName");
- this.selectorName = selectorName;
+ super(selectorName);
}
/**
- * {@inheritDoc}
+ * Get the selector symbol upon which this operand applies.
*
- * @see org.jboss.dna.graph.query.model.DynamicOperand#getSelectorName()
+ * @return the one selector names used by this operand; never null
*/
- @Override
- public final SelectorName getSelectorName() {
- return selectorName;
+ public SelectorName getSelectorName() {
+ return getSelectorNames().iterator().next();
}
/**
@@ -72,7 +67,7 @@
*/
@Override
public int hashCode() {
- return getSelectorName().hashCode();
+ return getSelectorNames().hashCode();
}
/**
@@ -85,7 +80,7 @@
if (obj == this) return true;
if (obj instanceof NodeName) {
NodeName that = (NodeName)obj;
- return this.selectorName.equals(that.selectorName);
+ return this.getSelectorNames().equals(that.getSelectorNames());
}
return false;
}
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodePath.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodePath.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodePath.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -24,7 +24,6 @@
package org.jboss.dna.graph.query.model;
import net.jcip.annotations.Immutable;
-import org.jboss.dna.common.util.CheckArg;
/**
* A dynamic operand that evaluates to the path of a node given by a selector, used in a {@link Comparison} constraint.
@@ -33,8 +32,6 @@
public class NodePath extends DynamicOperand {
private static final long serialVersionUID = 1L;
- private final SelectorName selectorName;
-
/**
* Create a dynamic operand that evaluates to the path of the node identified by the selector.
*
@@ -42,18 +39,16 @@
* @throws IllegalArgumentException if the selector name or property name are null
*/
public NodePath( SelectorName selectorName ) {
- CheckArg.isNotNull(selectorName, "selectorName");
- this.selectorName = selectorName;
+ super(selectorName);
}
/**
- * {@inheritDoc}
+ * Get the selector symbol upon which this operand applies.
*
- * @see org.jboss.dna.graph.query.model.DynamicOperand#getSelectorName()
+ * @return the one selector names used by this operand; never null
*/
- @Override
- public final SelectorName getSelectorName() {
- return selectorName;
+ public SelectorName getSelectorName() {
+ return getSelectorNames().iterator().next();
}
/**
@@ -73,7 +68,7 @@
*/
@Override
public int hashCode() {
- return getSelectorName().hashCode();
+ return getSelectorNames().hashCode();
}
/**
@@ -86,7 +81,7 @@
if (obj == this) return true;
if (obj instanceof NodePath) {
NodePath that = (NodePath)obj;
- return this.selectorName.equals(that.selectorName);
+ return this.getSelectorNames().equals(that.getSelectorNames());
}
return false;
}
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/PropertyValue.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/PropertyValue.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/PropertyValue.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -34,7 +34,6 @@
public class PropertyValue extends DynamicOperand {
private static final long serialVersionUID = 1L;
- private final SelectorName selectorName;
private final String propertyName;
private final int hc;
@@ -47,21 +46,19 @@
*/
public PropertyValue( SelectorName selectorName,
String propertyName ) {
- CheckArg.isNotNull(selectorName, "selectorName");
+ super(selectorName);
CheckArg.isNotNull(propertyName, "propertyName");
- this.selectorName = selectorName;
this.propertyName = propertyName;
- this.hc = HashCode.compute(this.selectorName, this.propertyName);
+ this.hc = HashCode.compute(selectorName, this.propertyName);
}
/**
- * {@inheritDoc}
+ * Get the selector symbol upon which this operand applies.
*
- * @see org.jboss.dna.graph.query.model.DynamicOperand#getSelectorName()
+ * @return the one selector names used by this operand; never null
*/
- @Override
- public final SelectorName getSelectorName() {
- return selectorName;
+ public SelectorName getSelectorName() {
+ return getSelectorNames().iterator().next();
}
/**
@@ -104,7 +101,7 @@
if (obj instanceof PropertyValue) {
PropertyValue that = (PropertyValue)obj;
if (this.hc != that.hc) return false;
- return this.selectorName.equals(that.selectorName) && this.propertyName.equals(that.propertyName);
+ return this.getSelectorNames().equals(that.getSelectorNames()) && this.propertyName.equals(that.propertyName);
}
return false;
}
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/UpperCase.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/UpperCase.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/UpperCase.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -24,7 +24,6 @@
package org.jboss.dna.graph.query.model;
import net.jcip.annotations.Immutable;
-import org.jboss.dna.common.util.CheckArg;
/**
* A dynamic operand that evaluates to the upper-case representation of the supplied operand, used in a {@link Comparison}
@@ -42,18 +41,17 @@
* @param operand the operand that is to be lower-cased
*/
public UpperCase( DynamicOperand operand ) {
- CheckArg.isNotNull(operand, "operand");
+ super(operand);
this.operand = operand;
}
/**
- * {@inheritDoc}
+ * Get the selector symbol upon which this operand applies.
*
- * @see org.jboss.dna.graph.query.model.DynamicOperand#getSelectorName()
+ * @return the one selector names used by this operand; never null
*/
- @Override
public SelectorName getSelectorName() {
- return operand.getSelectorName();
+ return getSelectorNames().iterator().next();
}
/**
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Visitor.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Visitor.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Visitor.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -94,6 +94,8 @@
void visit( SetQuery obj );
+ void visit( ArithmeticOperand obj );
+
void visit( UpperCase obj );
}
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Visitors.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Visitors.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Visitors.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -138,6 +138,11 @@
}
@Override
+ public void visit( FullTextSearchScore fullTextSearchScore ) {
+ symbols.add(fullTextSearchScore.getSelectorName());
+ }
+
+ @Override
public void visit( Length length ) {
symbols.add(length.getSelectorName());
}
@@ -227,6 +232,14 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.graph.query.model.Visitor#visit(org.jboss.dna.graph.query.model.ArithmeticOperand)
+ */
+ public void visit( ArithmeticOperand obj ) {
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see org.jboss.dna.graph.query.model.Visitor#visit(org.jboss.dna.graph.query.model.Between)
*/
public void visit( Between obj ) {
@@ -569,6 +582,18 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.graph.query.model.Visitor#visit(org.jboss.dna.graph.query.model.ArithmeticOperand)
+ */
+ public void visit( ArithmeticOperand arithmeticOperation ) {
+ strategy.visit(arithmeticOperation);
+ enqueue(arithmeticOperation.getLeft());
+ enqueue(arithmeticOperation.getRight());
+ visitNext();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see org.jboss.dna.graph.query.model.Visitor#visit(org.jboss.dna.graph.query.model.Between)
*/
public void visit( Between between ) {
@@ -1013,6 +1038,21 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.graph.query.model.Visitor#visit(org.jboss.dna.graph.query.model.ArithmeticOperand)
+ */
+ public void visit( ArithmeticOperand arithmeticOperand ) {
+ append('(');
+ arithmeticOperand.getLeft().accept(this);
+ append(' ');
+ append(arithmeticOperand.getOperator().getSymbol());
+ append(' ');
+ arithmeticOperand.getRight().accept(this);
+ append(')');
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see org.jboss.dna.graph.query.model.Visitor#visit(org.jboss.dna.graph.query.model.Between)
*/
public void visit( Between between ) {
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/parse/SqlQueryParser.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/parse/SqlQueryParser.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/parse/SqlQueryParser.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -40,6 +40,8 @@
import org.jboss.dna.graph.GraphI18n;
import org.jboss.dna.graph.property.ValueFormatException;
import org.jboss.dna.graph.query.model.And;
+import org.jboss.dna.graph.query.model.ArithmeticOperand;
+import org.jboss.dna.graph.query.model.ArithmeticOperator;
import org.jboss.dna.graph.query.model.Between;
import org.jboss.dna.graph.query.model.BindVariableName;
import org.jboss.dna.graph.query.model.ChildNode;
@@ -106,6 +108,9 @@
* <code><dynamicOperand> [NOT] IN (<staticOperand> {, <staticOperand>})</code>"</li>
* <li>Support for the BETWEEN clause: "<code><dynamicOperand> [NOT] BETWEEN <lowerBoundStaticOperand> [EXCLUSIVE] AND
* <upperBoundStaticOperand> [EXCLUSIVE]</code>"</i>
+ * <li>Support for arithmetic operations ('+', '-', '*', '/') between dynamic operands used in <code>WHERE</code> criteria and <code>ORDER BY</code>
+ * clauses: "<code>WHERE <dynamicOperand> + <dynamicOperand> ...</code>" or "<code>ORDER BY (<dynamicOperand> + <dynamicOperand>) [ASC]</code>".
+ * Note that standard operator precedence is used, but grouping by (potentially nested) parentheses is also supported.</i>
* </ul>
* </p>
* <h3>SQL grammar</h3>
@@ -346,7 +351,8 @@
*
* <pre>
* DynamicOperand ::= PropertyValue | Length | NodeName | NodeLocalName | NodePath | NodeDepth |
- * FullTextSearchScore | LowerCase | UpperCase
+ * FullTextSearchScore | LowerCase | UpperCase | Arithmetic |
+ * '(' DynamicOperand ')'
* </pre>
* <h5>Property value</h5>
* <pre>
@@ -396,6 +402,10 @@
* <pre>
* UpperCase ::= 'UPPER(' DynamicOperand ')'
* </pre>
+ * <h5>Arithmetic</h5>
+ * <pre>
+ * Arithmetic ::= DynamicOperand ('+'|'-'|'*'|'/') DynamicOperand
+ * </pre>
*
* <h4>Ordering</h4>
*
@@ -1036,7 +1046,10 @@
Source source ) {
DynamicOperand result = null;
Position pos = tokens.nextPosition();
- if (tokens.canConsume("LENGTH", "(")) {
+ if (tokens.canConsume('(')) {
+ result = parseDynamicOperand(tokens, typeSystem, source);
+ tokens.consume(")");
+ } else if (tokens.canConsume("LENGTH", "(")) {
result = new Length(parsePropertyValue(tokens, typeSystem, source));
tokens.consume(")");
} else if (tokens.canConsume("LOWER", "(")) {
@@ -1098,6 +1111,44 @@
} else {
result = parsePropertyValue(tokens, typeSystem, source);
}
+
+ // Is this operand followed by an arithmetic operation ...
+ ArithmeticOperator arithmeticOperator = null;
+ if (tokens.canConsume('+')) {
+ arithmeticOperator = ArithmeticOperator.ADD;
+ } else if (tokens.canConsume('-')) {
+ arithmeticOperator = ArithmeticOperator.SUBTRACT;
+ } else if (tokens.canConsume('*')) {
+ arithmeticOperator = ArithmeticOperator.MULTIPLY;
+ } else if (tokens.canConsume('/')) {
+ arithmeticOperator = ArithmeticOperator.DIVIDE;
+ }
+ if (arithmeticOperator != null) {
+ if (tokens.matches('(')) {
+ // Don't use precendence, but instead use the next DynamicOperand as the RHS ...
+ DynamicOperand right = parseDynamicOperand(tokens, typeSystem, source);
+ result = new ArithmeticOperand(result, arithmeticOperator, right);
+ } else {
+ // There is no parenthesis, so use operator precedence ...
+ DynamicOperand right = parseDynamicOperand(tokens, typeSystem, source);
+ if (right instanceof ArithmeticOperand) {
+ // But the RHS is an arithmetic operand, so we need to use operator precedence ...
+ ArithmeticOperand arithRhs = (ArithmeticOperand)right;
+ ArithmeticOperator rhsOperator = arithRhs.getOperator();
+ if (arithmeticOperator.precedes(rhsOperator)) {
+ // This operand's operator does take precedence, so this must be computed before working with the RHS ...
+ DynamicOperand newRhs = arithRhs.getRight();
+ DynamicOperand newLhs = new ArithmeticOperand(result, arithmeticOperator, arithRhs.getLeft());
+ result = new ArithmeticOperand(newLhs, rhsOperator, newRhs);
+ } else {
+ result = new ArithmeticOperand(result, arithmeticOperator, right);
+ }
+ } else {
+ // The RHS is just another DynamicOperand ...
+ result = new ArithmeticOperand(result, arithmeticOperator, right);
+ }
+ }
+ }
return result;
}
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/plan/CanonicalPlanner.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/plan/CanonicalPlanner.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/plan/CanonicalPlanner.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -336,6 +336,9 @@
context.getHints().hasSort = true;
sortNode.setProperty(Property.SORT_ORDER_BY, orderings);
+ for (Ordering ordering : orderings) {
+ sortNode.addSelectors(Visitors.getSelectorsReferencedBy(ordering));
+ }
sortNode.addLastChild(plan);
return sortNode;
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/plan/PlanHints.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/plan/PlanHints.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/plan/PlanHints.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -25,6 +25,7 @@
import java.io.Serializable;
import net.jcip.annotations.NotThreadSafe;
+import org.jboss.dna.graph.query.QueryResults;
@NotThreadSafe
public final class PlanHints implements Serializable {
@@ -61,6 +62,9 @@
/** Flag indicates that the plan has at least one view somewhere */
public boolean hasView = false;
+ /** Flag indicates whether the query plan should be included in the {@link QueryResults} */
+ public boolean showPlan = false;
+
public PlanHints() {
}
@@ -75,6 +79,7 @@
sb.append(", hasLimit=").append(hasLimit);
sb.append(", hasOptionalJoin=").append(hasOptionalJoin);
sb.append(", hasFullTextSearch=").append(hasFullTextSearch);
+ sb.append(", showPlan=").append(showPlan);
sb.append('}');
return sb.toString();
}
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/plan/PlanUtil.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/plan/PlanUtil.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/plan/PlanUtil.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -27,12 +27,15 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jboss.dna.graph.query.QueryContext;
import org.jboss.dna.graph.query.model.And;
+import org.jboss.dna.graph.query.model.ArithmeticOperand;
+import org.jboss.dna.graph.query.model.ArithmeticOperator;
import org.jboss.dna.graph.query.model.Between;
import org.jboss.dna.graph.query.model.ChildNode;
import org.jboss.dna.graph.query.model.ChildNodeJoinCondition;
@@ -558,6 +561,20 @@
// Nothing to do here, as the selector names are fixed elsewhere
break;
case SORT:
+ // The selector names and Ordering objects needs to be changed ...
+ List<Ordering> orderings = node.getPropertyAsList(Property.SORT_ORDER_BY, Ordering.class);
+ List<Ordering> newOrderings = new ArrayList<Ordering>(orderings.size());
+ node.getSelectors().clear();
+ for (Ordering ordering : orderings) {
+ DynamicOperand operand = ordering.getOperand();
+ DynamicOperand newOperand = replaceViewReferences(context, operand, mappings, node);
+ if (newOperand != operand) {
+ ordering = new Ordering(newOperand, ordering.getOrder());
+ }
+ node.addSelectors(Visitors.getSelectorsReferencedBy(ordering));
+ newOrderings.add(ordering);
+ }
+ node.setProperty(Property.SORT_ORDER_BY, newOrderings);
break;
case GROUP:
// Don't yet use GROUP BY
@@ -678,11 +695,29 @@
DynamicOperand operand,
ColumnMapping mapping,
PlanNode node ) {
+ if (operand instanceof ArithmeticOperand) {
+ ArithmeticOperand arith = (ArithmeticOperand)operand;
+ DynamicOperand newLeft = replaceViewReferences(context, arith.getLeft(), mapping, node);
+ DynamicOperand newRight = replaceViewReferences(context, arith.getRight(), mapping, node);
+ return new ArithmeticOperand(newLeft, arith.getOperator(), newRight);
+ }
if (operand instanceof FullTextSearchScore) {
FullTextSearchScore score = (FullTextSearchScore)operand;
if (!mapping.getOriginalName().equals(score.getSelectorName())) return score;
- if (!mapping.isMappedToSingleSelector()) return score;
- return new FullTextSearchScore(mapping.getSingleMappedSelectorName());
+ if (mapping.isMappedToSingleSelector()) {
+ return new FullTextSearchScore(mapping.getSingleMappedSelectorName());
+ }
+ // There are multiple mappings, so we have to create a composite score ...
+ DynamicOperand composite = null;
+ for (SelectorName name : mapping.getMappedSelectorNames()) {
+ FullTextSearchScore mappedScore = new FullTextSearchScore(name);
+ if (composite == null) {
+ composite = mappedScore;
+ } else {
+ composite = new ArithmeticOperand(composite, ArithmeticOperator.ADD, mappedScore);
+ }
+ }
+ return composite;
}
if (operand instanceof Length) {
Length operation = (Length)operand;
@@ -857,7 +892,7 @@
public static class ColumnMapping {
private final SelectorName originalName;
private final Map<String, Column> mappedColumnsByOriginalColumnName = new HashMap<String, Column>();
- private final Set<SelectorName> mappedSelectorNames = new HashSet<SelectorName>();
+ private final Set<SelectorName> mappedSelectorNames = new LinkedHashSet<SelectorName>(); // maintains insertion order
public ColumnMapping( SelectorName originalName ) {
this.originalName = originalName;
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/process/ProcessingComponent.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/process/ProcessingComponent.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/process/ProcessingComponent.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -32,6 +32,7 @@
import org.jboss.dna.graph.property.Path;
import org.jboss.dna.graph.query.QueryContext;
import org.jboss.dna.graph.query.QueryResults.Columns;
+import org.jboss.dna.graph.query.model.ArithmeticOperand;
import org.jboss.dna.graph.query.model.DynamicOperand;
import org.jboss.dna.graph.query.model.FullTextSearchScore;
import org.jboss.dna.graph.query.model.Length;
@@ -318,6 +319,132 @@
}
};
}
+ if (operand instanceof ArithmeticOperand) {
+ ArithmeticOperand arith = (ArithmeticOperand)operand;
+ final DynamicOperation leftOp = createDynamicOperation(typeSystem, schemata, columns, arith.getLeft());
+ final DynamicOperation rightOp = createDynamicOperation(typeSystem, schemata, columns, arith.getRight());
+ // compute the expected (common) type ...
+ String leftType = leftOp.getExpectedType();
+ String rightType = rightOp.getExpectedType();
+ final String commonType = typeSystem.getCompatibleType(leftType, rightType);
+ if (typeSystem.getDoubleFactory().getTypeName().equals(commonType)) {
+ final TypeFactory<Double> commonTypeFactory = typeSystem.getDoubleFactory();
+ switch (arith.getOperator()) {
+ case ADD:
+ return new DynamicOperation() {
+ public String getExpectedType() {
+ return commonType;
+ }
+
+ public Object evaluate( Object[] tuple ) {
+ Double right = commonTypeFactory.create(rightOp.evaluate(tuple));
+ Double left = commonTypeFactory.create(leftOp.evaluate(tuple));
+ if (right == null) return left;
+ if (left == null) return right;
+ return left.doubleValue() / right.doubleValue();
+ }
+ };
+ case SUBTRACT:
+ return new DynamicOperation() {
+ public String getExpectedType() {
+ return commonType;
+ }
+
+ public Object evaluate( Object[] tuple ) {
+ Double right = commonTypeFactory.create(rightOp.evaluate(tuple));
+ Double left = commonTypeFactory.create(leftOp.evaluate(tuple));
+ if (right == null) return left;
+ if (left == null) left = 0.0d;
+ return left.doubleValue() * right.doubleValue();
+ }
+ };
+ case MULTIPLY:
+ return new DynamicOperation() {
+ public String getExpectedType() {
+ return commonType;
+ }
+
+ public Object evaluate( Object[] tuple ) {
+ Double right = commonTypeFactory.create(rightOp.evaluate(tuple));
+ Double left = commonTypeFactory.create(leftOp.evaluate(tuple));
+ if (right == null || left == null) return null;
+ return left.doubleValue() * right.doubleValue();
+ }
+ };
+ case DIVIDE:
+ return new DynamicOperation() {
+ public String getExpectedType() {
+ return commonType;
+ }
+
+ public Object evaluate( Object[] tuple ) {
+ Double right = commonTypeFactory.create(rightOp.evaluate(tuple));
+ Double left = commonTypeFactory.create(leftOp.evaluate(tuple));
+ if (right == null || left == null) return null;
+ return left.doubleValue() / right.doubleValue();
+ }
+ };
+ }
+ } else if (typeSystem.getLongFactory().getTypeName().equals(commonType)) {
+ final TypeFactory<Long> commonTypeFactory = typeSystem.getLongFactory();
+ switch (arith.getOperator()) {
+ case ADD:
+ return new DynamicOperation() {
+ public String getExpectedType() {
+ return commonType;
+ }
+
+ public Object evaluate( Object[] tuple ) {
+ Long right = commonTypeFactory.create(rightOp.evaluate(tuple));
+ Long left = commonTypeFactory.create(leftOp.evaluate(tuple));
+ if (right == null) return left;
+ if (left == null) return right;
+ return left.longValue() / right.longValue();
+ }
+ };
+ case SUBTRACT:
+ return new DynamicOperation() {
+ public String getExpectedType() {
+ return commonType;
+ }
+
+ public Object evaluate( Object[] tuple ) {
+ Long right = commonTypeFactory.create(rightOp.evaluate(tuple));
+ Long left = commonTypeFactory.create(leftOp.evaluate(tuple));
+ if (right == null) return left;
+ if (left == null) left = 0L;
+ return left.longValue() * right.longValue();
+ }
+ };
+ case MULTIPLY:
+ return new DynamicOperation() {
+ public String getExpectedType() {
+ return commonType;
+ }
+
+ public Object evaluate( Object[] tuple ) {
+ Long right = commonTypeFactory.create(rightOp.evaluate(tuple));
+ Long left = commonTypeFactory.create(leftOp.evaluate(tuple));
+ if (right == null || left == null) return null;
+ return left.longValue() * right.longValue();
+ }
+ };
+ case DIVIDE:
+ return new DynamicOperation() {
+ public String getExpectedType() {
+ return commonType;
+ }
+
+ public Object evaluate( Object[] tuple ) {
+ Long right = commonTypeFactory.create(rightOp.evaluate(tuple));
+ Long left = commonTypeFactory.create(leftOp.evaluate(tuple));
+ if (right == null || left == null) return null;
+ return left.longValue() / right.longValue();
+ }
+ };
+ }
+ }
+ }
assert false;
return null;
}
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/process/QueryProcessor.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/process/QueryProcessor.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/process/QueryProcessor.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -104,7 +104,8 @@
statistics = statistics.withExecutionTime(System.nanoTime() - nanos);
}
assert tuples != null;
- return new org.jboss.dna.graph.query.process.QueryResults(columns, statistics, tuples, context.getProblems());
+ final String planDesc = context.getHints().showPlan ? plan.getString() : null;
+ return new org.jboss.dna.graph.query.process.QueryResults(columns, statistics, tuples, context.getProblems(), planDesc);
}
/**
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/process/QueryResults.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/process/QueryResults.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/process/QueryResults.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -49,6 +49,7 @@
private final Columns columns;
private final List<Object[]> tuples;
private final Statistics statistics;
+ private final String plan;
/**
* Create a results object for the supplied context, command, and result columns and with the supplied tuples.
@@ -57,17 +58,20 @@
* @param statistics the statistics for this query; may not be null
* @param tuples the tuples
* @param problems the problems; may be null if there are no problems
+ * @param plan the text representation of the query plan, if the hints asked for it
*/
public QueryResults( Columns columns,
Statistics statistics,
List<Object[]> tuples,
- Problems problems ) {
+ Problems problems,
+ String plan ) {
assert columns != null;
assert statistics != null;
this.problems = problems != null ? problems : NO_PROBLEMS;
this.columns = columns;
this.tuples = tuples;
this.statistics = statistics;
+ this.plan = plan;
}
/**
@@ -80,7 +84,7 @@
public QueryResults( Columns columns,
Statistics statistics,
List<Object[]> tuples ) {
- this(columns, statistics, tuples, NO_PROBLEMS);
+ this(columns, statistics, tuples, NO_PROBLEMS, null);
}
/**
@@ -93,7 +97,7 @@
public QueryResults( Columns columns,
Statistics statistics,
Problems problems ) {
- this(columns, statistics, Collections.<Object[]>emptyList(), problems);
+ this(columns, statistics, Collections.<Object[]>emptyList(), problems, null);
}
/**
@@ -104,7 +108,7 @@
*/
public QueryResults( Columns columns,
Statistics statistics ) {
- this(columns, statistics, Collections.<Object[]>emptyList(), null);
+ this(columns, statistics, Collections.<Object[]>emptyList(), null, null);
}
/**
@@ -146,6 +150,15 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.graph.query.QueryResults#getPlan()
+ */
+ public String getPlan() {
+ return plan;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see org.jboss.dna.graph.query.QueryResults#getProblems()
*/
public Problems getProblems() {
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/process/SortValuesComponent.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/process/SortValuesComponent.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/process/SortValuesComponent.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -119,8 +119,8 @@
return new Comparator<Object[]>() {
public int compare( Object[] tuple1,
Object[] tuple2 ) {
- Object value1 = operation.evaluate(tuple1);
- Object value2 = operation.evaluate(tuple2);
+ Object value1 = typeFactory.create(operation.evaluate(tuple1));
+ Object value2 = typeFactory.create(operation.evaluate(tuple2));
return 0 - typeComparator.compare(value1, value2);
}
};
@@ -128,8 +128,8 @@
return new Comparator<Object[]>() {
public int compare( Object[] tuple1,
Object[] tuple2 ) {
- Object value1 = operation.evaluate(tuple1);
- Object value2 = operation.evaluate(tuple2);
+ Object value1 = typeFactory.create(operation.evaluate(tuple1));
+ Object value2 = typeFactory.create(operation.evaluate(tuple2));
return typeComparator.compare(value1, value2);
}
};
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/validate/Validator.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/validate/Validator.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/validate/Validator.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -26,14 +26,17 @@
import java.util.HashMap;
import java.util.Map;
import org.jboss.dna.common.collection.Problems;
+import org.jboss.dna.common.i18n.I18n;
import org.jboss.dna.graph.GraphI18n;
import org.jboss.dna.graph.query.QueryContext;
import org.jboss.dna.graph.query.model.AllNodes;
+import org.jboss.dna.graph.query.model.ArithmeticOperand;
import org.jboss.dna.graph.query.model.ChildNode;
import org.jboss.dna.graph.query.model.ChildNodeJoinCondition;
import org.jboss.dna.graph.query.model.Column;
import org.jboss.dna.graph.query.model.DescendantNode;
import org.jboss.dna.graph.query.model.DescendantNodeJoinCondition;
+import org.jboss.dna.graph.query.model.DynamicOperand;
import org.jboss.dna.graph.query.model.EquiJoinCondition;
import org.jboss.dna.graph.query.model.FullTextSearch;
import org.jboss.dna.graph.query.model.FullTextSearchScore;
@@ -49,6 +52,7 @@
import org.jboss.dna.graph.query.model.SameNode;
import org.jboss.dna.graph.query.model.SameNodeJoinCondition;
import org.jboss.dna.graph.query.model.SelectorName;
+import org.jboss.dna.graph.query.model.TypeSystem;
import org.jboss.dna.graph.query.model.Visitor;
import org.jboss.dna.graph.query.model.Visitors.AbstractVisitor;
import org.jboss.dna.graph.query.validate.Schemata.Table;
@@ -92,6 +96,53 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.graph.query.model.Visitors.AbstractVisitor#visit(org.jboss.dna.graph.query.model.ArithmeticOperand)
+ */
+ @Override
+ public void visit( ArithmeticOperand obj ) {
+ verifyArithmeticOperand(obj.getLeft());
+ verifyArithmeticOperand(obj.getRight());
+ }
+
+ protected void verifyArithmeticOperand( DynamicOperand operand ) {
+ // The left and right operands must have LONG or DOUBLE types ...
+ if (operand instanceof NodeDepth) {
+ // good to go
+ } else if (operand instanceof Length) {
+ // good to go
+ } else if (operand instanceof ArithmeticOperand) {
+ // good to go
+ } else if (operand instanceof FullTextSearchScore) {
+ // good to go
+ } else if (operand instanceof PropertyValue) {
+ PropertyValue value = (PropertyValue)operand;
+ SelectorName selector = value.getSelectorName();
+ String propertyName = value.getPropertyName();
+ Schemata.Column column = verify(selector, propertyName);
+ if (column != null) {
+ // Check the type ...
+ String columnType = column.getPropertyType();
+ TypeSystem types = context.getTypeSystem();
+ String longType = types.getLongFactory().getTypeName();
+ String doubleType = types.getDoubleFactory().getTypeName();
+ if (longType.equals(types.getCompatibleType(columnType, longType))) {
+ // Then the column type is long or can be converted to long ...
+ } else if (doubleType.equals(types.getCompatibleType(columnType, doubleType))) {
+ // Then the column type is double or can be converted to double ...
+ } else {
+ I18n msg = GraphI18n.columnTypeCannotBeUsedInArithmeticOperation;
+ problems.addError(msg, selector, propertyName, columnType);
+ }
+ }
+ } else {
+ I18n msg = GraphI18n.dynamicOperandCannotBeUsedInArithmeticOperation;
+ problems.addError(msg, operand);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see org.jboss.dna.graph.query.model.Visitors.AbstractVisitor#visit(org.jboss.dna.graph.query.model.ChildNode)
*/
@Override
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 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-graph/src/main/resources/org/jboss/dna/graph/GraphI18n.properties 2010-01-06 23:48:32 UTC (rev 1536)
@@ -131,6 +131,8 @@
columnDoesNotExistInQuery = Column '{0}' does not exist in query
columnIsNotFullTextSearchable = Column '{0}' on the table '{1}' does not support full-text searching
tableIsNotFullTextSearchable = Table '{0}' has no columns that support full-text searching
+columnTypeCannotBeUsedInArithmeticOperation = Column '{0}' on table '{1}' has a type of '{2}' and cannot be used in an arithmetic operation
+dynamicOperandCannotBeUsedInArithmeticOperation = '{0}' does not evaluate to a long or double and cannot be used in an arithmetic operation
selectorDoesNotExistInQuery = Selector '{0}' does not exist in query
propertyOnSelectorIsNotUsedInQuery = Property '{0}' on selector '{1}' is not used in query
errorResolvingNodesFromLocationsUsingSourceAndWorkspace = Error resolving nodes from locations using '{1}' workspace in '{0}'
@@ -155,6 +157,7 @@
expectingLiteralAndUnableToParseAsLong = Expecting literal and unable to parse '{0}' at line {1}, column {2} as a long
expectingLiteralAndUnableToParseAsDouble = Expecting literal and unable to parse '{0}' at line {1}, column {2} as a double
expectingLiteralAndUnableToParseAsDate = Expecting literal and unable to parse '{0}' at line {1}, column {2} as a date
+unexpectedClosingParenthesis = Unexpected closing parenthesis without a matching opening parenthesis
# Search
interruptedWhileClosingChannel = Thread was interrupted while closing request processing channel for source "{0}"
Modified: trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/QueryBuilderTest.java
===================================================================
--- trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/QueryBuilderTest.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/QueryBuilderTest.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -466,6 +466,40 @@
}
@Test
+ public void shouldBuildQueryWithCriteriaUsingPlus() {
+ query = builder.selectStar()
+ .from("table AS nodes")
+ .where()
+ .depth("nodes")
+ .plus()
+ .depth("nodes")
+ .plus()
+ .depth("nodes")
+ .isEqualTo(3)
+ .end()
+ .query();
+ assertThatSql(query, is("SELECT * FROM table AS nodes " + //
+ "WHERE ((DEPTH(nodes) + DEPTH(nodes)) + DEPTH(nodes)) = 3"));
+ }
+
+ @Test
+ public void shouldBuildQueryWithCriteriaUsingPlusAndMinus() {
+ query = builder.selectStar()
+ .from("table AS nodes")
+ .where()
+ .depth("nodes")
+ .minus()
+ .depth("nodes")
+ .plus()
+ .fullTextSearchScore("nodes")
+ .isEqualTo(3)
+ .end()
+ .query();
+ assertThatSql(query, is("SELECT * FROM table AS nodes " + //
+ "WHERE (DEPTH(nodes) - (DEPTH(nodes) + SCORE(nodes))) = 3"));
+ }
+
+ @Test
public void shouldBuildQueryWithCriteriaUsingLengthEqualTo() {
query = builder.selectStar()
.from("table AS nodes")
@@ -1369,7 +1403,7 @@
}
@Test
- public void shouldBuilderQueryWithSetCriteria() {
+ public void shouldBuildQueryWithSetCriteria() {
query = builder.selectStar()
.from("table AS nodes")
.where()
@@ -1380,4 +1414,18 @@
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
"WHERE NAME(nodes) IN ('value1','value2','value3')"));
}
+
+ @Test
+ public void shouldBuildQueryWithOneOrderByClause() {
+ query = builder.selectStar()
+ .from("table AS nodes")
+ .orderBy()
+ .ascending()
+ .fullTextSearchScore("nodes")
+ .then()
+ .descending()
+ .length("nodes", "column")
+ .end()
+ .query();
+ }
}
Modified: trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/RuleBasedOptimizerTest.java
===================================================================
--- trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/RuleBasedOptimizerTest.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/RuleBasedOptimizerTest.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -34,13 +34,19 @@
import org.jboss.dna.graph.GraphI18n;
import org.jboss.dna.graph.query.AbstractQueryTest;
import org.jboss.dna.graph.query.QueryContext;
+import org.jboss.dna.graph.query.model.ArithmeticOperand;
+import org.jboss.dna.graph.query.model.ArithmeticOperator;
import org.jboss.dna.graph.query.model.Column;
import org.jboss.dna.graph.query.model.Comparison;
+import org.jboss.dna.graph.query.model.DynamicOperand;
import org.jboss.dna.graph.query.model.EquiJoinCondition;
import org.jboss.dna.graph.query.model.FullTextSearch;
+import org.jboss.dna.graph.query.model.FullTextSearchScore;
import org.jboss.dna.graph.query.model.JoinType;
import org.jboss.dna.graph.query.model.Literal;
import org.jboss.dna.graph.query.model.Operator;
+import org.jboss.dna.graph.query.model.Order;
+import org.jboss.dna.graph.query.model.Ordering;
import org.jboss.dna.graph.query.model.PropertyValue;
import org.jboss.dna.graph.query.model.QueryCommand;
import org.jboss.dna.graph.query.model.SelectorName;
@@ -507,6 +513,88 @@
assertThat(node.isSameAs(access), is(true));
}
+ @Test
+ public void shouldOptimizePlanForQueryWithOrderByClause() {
+ node = optimize("SELECT v2.c11 AS c1 FROM v2 WHERE v2.c11 = 'x' AND v2.c12 = 'y' ORDER BY v2.c11, v2.c12 DESC");
+
+ // Create the expected plan ...
+ PlanNode sort = new PlanNode(Type.SORT, selector("t1"));
+ sort.setProperty(Property.SORT_ORDER_BY, orderings(ascending("t1", "c11"), descending("t1", "c12")));
+ PlanNode project = new PlanNode(Type.PROJECT, sort, selector("t1"));
+ project.setProperty(Property.PROJECT_COLUMNS, columns(column("t1", "c11", "c1")));
+ PlanNode join = new PlanNode(Type.JOIN, project, selector("t2"), selector("t1"));
+ join.setProperty(Property.JOIN_ALGORITHM, JoinAlgorithm.NESTED_LOOP);
+ join.setProperty(Property.JOIN_TYPE, JoinType.INNER);
+ join.setProperty(Property.JOIN_CONDITION, new EquiJoinCondition(selector("t1"), "c11", selector("t2"), "c21"));
+
+ PlanNode leftAccess = new PlanNode(Type.ACCESS, join, selector("t1"));
+ PlanNode leftProject = new PlanNode(Type.PROJECT, leftAccess, selector("t1"));
+ leftProject.setProperty(Property.PROJECT_COLUMNS, columns(column("t1", "c11")));
+ PlanNode leftSelect1 = new PlanNode(Type.SELECT, leftProject, selector("t1"));
+ leftSelect1.setProperty(Property.SELECT_CRITERIA, new Comparison(new PropertyValue(selector("t1"), "c11"),
+ Operator.EQUAL_TO, new Literal("x")));
+ PlanNode leftSelect2 = new PlanNode(Type.SELECT, leftSelect1, selector("t1"));
+ leftSelect2.setProperty(Property.SELECT_CRITERIA, new Comparison(new PropertyValue(selector("t1"), "c12"),
+ Operator.EQUAL_TO, new Literal("y")));
+ PlanNode leftSource = new PlanNode(Type.SOURCE, leftSelect2, selector("t1"));
+ leftSource.setProperty(Property.SOURCE_NAME, selector("t1"));
+ leftSource.setProperty(Property.SOURCE_COLUMNS, context.getSchemata().getTable(selector("t1")).getColumns());
+
+ PlanNode rightAccess = new PlanNode(Type.ACCESS, join, selector("t2"));
+ PlanNode rightProject = new PlanNode(Type.PROJECT, rightAccess, selector("t2"));
+ rightProject.setProperty(Property.PROJECT_COLUMNS, columns(column("t2", "c21")));
+ PlanNode rightSelect1 = new PlanNode(Type.SELECT, rightProject, selector("t2"));
+ rightSelect1.setProperty(Property.SELECT_CRITERIA, new Comparison(new PropertyValue(selector("t2"), "c21"),
+ Operator.EQUAL_TO, new Literal("x")));
+ PlanNode rightSource = new PlanNode(Type.SOURCE, rightSelect1, selector("t2"));
+ rightSource.setProperty(Property.SOURCE_NAME, selector("t2"));
+ rightSource.setProperty(Property.SOURCE_COLUMNS, context.getSchemata().getTable(selector("t2")).getColumns());
+
+ // Compare the expected and actual plan ...
+ assertThat(node.isSameAs(sort), is(true));
+ }
+
+ @Test
+ public void shouldOptimizePlanForQueryWithOrderByClauseThatUsesScoreFunction() {
+ node = optimize("SELECT v2.c11 AS c1 FROM v2 WHERE v2.c11 = 'x' AND v2.c12 = 'y' ORDER BY SCORE(v2) ASC");
+
+ // Create the expected plan ...
+ PlanNode sort = new PlanNode(Type.SORT, selector("t1"), selector("t2"));
+ sort.setProperty(Property.SORT_ORDER_BY, orderings(ascendingScore("t1", "t2")));
+ PlanNode project = new PlanNode(Type.PROJECT, sort, selector("t1"));
+ project.setProperty(Property.PROJECT_COLUMNS, columns(column("t1", "c11", "c1")));
+ PlanNode join = new PlanNode(Type.JOIN, project, selector("t2"), selector("t1"));
+ join.setProperty(Property.JOIN_ALGORITHM, JoinAlgorithm.NESTED_LOOP);
+ join.setProperty(Property.JOIN_TYPE, JoinType.INNER);
+ join.setProperty(Property.JOIN_CONDITION, new EquiJoinCondition(selector("t1"), "c11", selector("t2"), "c21"));
+
+ PlanNode leftAccess = new PlanNode(Type.ACCESS, join, selector("t1"));
+ PlanNode leftProject = new PlanNode(Type.PROJECT, leftAccess, selector("t1"));
+ leftProject.setProperty(Property.PROJECT_COLUMNS, columns(column("t1", "c11")));
+ PlanNode leftSelect1 = new PlanNode(Type.SELECT, leftProject, selector("t1"));
+ leftSelect1.setProperty(Property.SELECT_CRITERIA, new Comparison(new PropertyValue(selector("t1"), "c11"),
+ Operator.EQUAL_TO, new Literal("x")));
+ PlanNode leftSelect2 = new PlanNode(Type.SELECT, leftSelect1, selector("t1"));
+ leftSelect2.setProperty(Property.SELECT_CRITERIA, new Comparison(new PropertyValue(selector("t1"), "c12"),
+ Operator.EQUAL_TO, new Literal("y")));
+ PlanNode leftSource = new PlanNode(Type.SOURCE, leftSelect2, selector("t1"));
+ leftSource.setProperty(Property.SOURCE_NAME, selector("t1"));
+ leftSource.setProperty(Property.SOURCE_COLUMNS, context.getSchemata().getTable(selector("t1")).getColumns());
+
+ PlanNode rightAccess = new PlanNode(Type.ACCESS, join, selector("t2"));
+ PlanNode rightProject = new PlanNode(Type.PROJECT, rightAccess, selector("t2"));
+ rightProject.setProperty(Property.PROJECT_COLUMNS, columns(column("t2", "c21")));
+ PlanNode rightSelect1 = new PlanNode(Type.SELECT, rightProject, selector("t2"));
+ rightSelect1.setProperty(Property.SELECT_CRITERIA, new Comparison(new PropertyValue(selector("t2"), "c21"),
+ Operator.EQUAL_TO, new Literal("x")));
+ PlanNode rightSource = new PlanNode(Type.SOURCE, rightSelect1, selector("t2"));
+ rightSource.setProperty(Property.SOURCE_NAME, selector("t2"));
+ rightSource.setProperty(Property.SOURCE_COLUMNS, context.getSchemata().getTable(selector("t2")).getColumns());
+
+ // Compare the expected and actual plan ...
+ assertThat(node.isSameAs(sort), is(true));
+ }
+
// ----------------------------------------------------------------------------------------------------------------
// Utility methods ...
// ----------------------------------------------------------------------------------------------------------------
@@ -515,6 +603,39 @@
return Arrays.asList(columns);
}
+ protected List<Ordering> orderings( Ordering... orderings ) {
+ return Arrays.asList(orderings);
+ }
+
+ protected Ordering ascending( String table,
+ String columnName ) {
+ return new Ordering(new PropertyValue(new SelectorName(table), columnName), Order.ASCENDING);
+ }
+
+ protected Ordering descending( String table,
+ String columnName ) {
+ return new Ordering(new PropertyValue(new SelectorName(table), columnName), Order.DESCENDING);
+ }
+
+ protected Ordering ascendingScore( String... tableNames ) {
+ return new Ordering(score(tableNames), Order.ASCENDING);
+ }
+
+ protected Ordering descendingScore( String... tableNames ) {
+ return new Ordering(score(tableNames), Order.DESCENDING);
+ }
+
+ protected DynamicOperand score( String... tableNames ) {
+ DynamicOperand operand = null;
+ for (String tableName : tableNames) {
+ DynamicOperand right = new FullTextSearchScore(new SelectorName(tableName));
+ if (operand == null) operand = right;
+ else operand = new ArithmeticOperand(operand, ArithmeticOperator.ADD, right);
+ }
+ assert operand != null;
+ return operand;
+ }
+
protected Column column( String table,
String columnName ) {
return new Column(new SelectorName(table), columnName, columnName);
Modified: trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/plan/CanonicalPlannerTest.java
===================================================================
--- trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/plan/CanonicalPlannerTest.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/plan/CanonicalPlannerTest.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -60,6 +60,7 @@
private Schemata schemata;
private ImmutableSchemata.Builder schemataBuilder;
private QueryContext queryContext;
+ private boolean print;
@Before
public void beforeEach() {
@@ -69,8 +70,13 @@
builder = new QueryBuilder(typeSystem);
problems = new SimpleProblems();
schemataBuilder = ImmutableSchemata.createBuilder(typeSystem);
+ print = false;
}
+ protected void print( PlanNode plan ) {
+ if (print) System.out.println(plan);
+ }
+
protected SelectorName selector( String name ) {
return new SelectorName(name);
}
@@ -132,7 +138,7 @@
PlanNode source = plan.getFirstChild();
assertSourceNode(source, "__ALLNODES__", null, "column1", "column2", "column3");
assertThat(source.getChildCount(), is(0));
- System.out.println(plan);
+ print(plan);
}
@Test
@@ -159,7 +165,7 @@
query = builder.selectStar().from("someTable").query();
queryContext = new QueryContext(schemata, typeSystem, hints, problems);
plan = planner.createPlan(queryContext, query);
- System.out.println(plan);
+ print(plan);
assertThat(problems.hasErrors(), is(false));
assertThat(problems.isEmpty(), is(true));
assertProjectNode(plan, "column1", "column2", "column3");
@@ -188,7 +194,7 @@
queryContext = new QueryContext(schemata, typeSystem, hints, problems);
plan = planner.createPlan(queryContext, query);
assertThat(problems.hasErrors(), is(false));
- System.out.println(plan);
+ print(plan);
assertThat(plan.getType(), is(PlanNode.Type.PROJECT));
assertThat(plan.getSelectors(), is(selectors("t1")));
}
@@ -200,7 +206,7 @@
queryContext = new QueryContext(schemata, typeSystem, hints, problems);
plan = planner.createPlan(queryContext, query);
assertThat(problems.hasErrors(), is(false));
- System.out.println(plan);
+ print(plan);
assertThat(plan.getType(), is(PlanNode.Type.PROJECT));
assertThat(plan.getSelectors(), is(selectors("t1")));
}
@@ -267,4 +273,48 @@
assertThat(problems.hasErrors(), is(true));
}
+ @Test
+ public void shouldProducePlanWhenOrderByClauseIsUsed() {
+ schemata = schemataBuilder.addTable("dna:someTable", "column1", "column2", "column3").build();
+ query = builder.selectStar()
+ .from("dna:someTable AS t1")
+ .where()
+ .path("t1")
+ .isEqualTo(1L)
+ .end()
+ .orderBy()
+ .ascending()
+ .propertyValue("t1", "column1")
+ .end()
+ .query();
+ queryContext = new QueryContext(schemata, typeSystem, hints, problems);
+ plan = planner.createPlan(queryContext, query);
+ assertThat(problems.hasErrors(), is(false));
+ print(plan);
+ assertThat(plan.getType(), is(PlanNode.Type.SORT));
+ assertThat(plan.getSelectors(), is(selectors("t1")));
+ }
+
+ @Test
+ public void shouldProducePlanWhenOrderByClauseWithScoreIsUsed() {
+ schemata = schemataBuilder.addTable("dna:someTable", "column1", "column2", "column3").build();
+ query = builder.selectStar()
+ .from("dna:someTable AS t1")
+ .where()
+ .path("t1")
+ .isEqualTo(1L)
+ .end()
+ .orderBy()
+ .ascending()
+ .fullTextSearchScore("t1")
+ .end()
+ .query();
+ queryContext = new QueryContext(schemata, typeSystem, hints, problems);
+ plan = planner.createPlan(queryContext, query);
+ assertThat(problems.hasErrors(), is(false));
+ print(plan);
+ assertThat(plan.getType(), is(PlanNode.Type.SORT));
+ assertThat(plan.getSelectors(), is(selectors("t1")));
+ }
+
}
Modified: trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/process/QueryResultColumnsTest.java
===================================================================
--- trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/process/QueryResultColumnsTest.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/process/QueryResultColumnsTest.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -92,7 +92,7 @@
@Test
public void shouldReturnSameTuplesListPassedIntoConstructor() {
- results = new QueryResults(columns, statistics, tuples, context.getProblems());
+ results = new QueryResults(columns, statistics, tuples, context.getProblems(), null);
assertThat(results.getTuples(), is(sameInstance(tuples)));
}
@@ -105,14 +105,14 @@
@Test
public void shouldHaveNoTuplesIfConstructedWithEmptyTuplesList() {
tuples.clear();
- results = new QueryResults(columns, statistics, tuples, context.getProblems());
+ results = new QueryResults(columns, statistics, tuples, context.getProblems(), null);
assertThat(results.getTuples().isEmpty(), is(true));
assertThat(results.getCursor().hasNext(), is(false));
}
@Test
public void shouldReturnMutableTuplesList() {
- results = new QueryResults(columns, statistics, tuples, context.getProblems());
+ results = new QueryResults(columns, statistics, tuples, context.getProblems(), null);
assertThat(results.getTuples().isEmpty(), is(false));
results.getTuples().clear();
assertThat(results.getTuples().isEmpty(), is(true));
@@ -121,7 +121,7 @@
@Test
public void shouldReturnCursorThatAccessesTuples() {
- results = new QueryResults(columns, statistics, tuples, context.getProblems());
+ results = new QueryResults(columns, statistics, tuples, context.getProblems(), null);
Cursor cursor = results.getCursor();
Iterator<Object[]> expectedIter = tuples.iterator();
int rowNumber = 0;
@@ -155,7 +155,7 @@
@Test( expected = IllegalStateException.class )
public void shouldRequireNextOnCursorToBeCalledBeforeGettingValueUsingColumnIndex() {
- results = new QueryResults(columns, statistics, tuples, context.getProblems());
+ results = new QueryResults(columns, statistics, tuples, context.getProblems(), null);
Cursor cursor = results.getCursor();
assertThat(cursor.hasNext(), is(true));
cursor.getValue(0);
@@ -163,7 +163,7 @@
@Test( expected = IllegalStateException.class )
public void shouldRequireNextOnCursorToBeCalledBeforeGettingValueUsingColumnName() {
- results = new QueryResults(columns, statistics, tuples, context.getProblems());
+ results = new QueryResults(columns, statistics, tuples, context.getProblems(), null);
Cursor cursor = results.getCursor();
assertThat(cursor.hasNext(), is(true));
cursor.getValue("colA");
@@ -171,14 +171,14 @@
@Test
public void shouldPrintToStringAllResults() {
- results = new QueryResults(columns, statistics, tuples, context.getProblems());
+ results = new QueryResults(columns, statistics, tuples, context.getProblems(), null);
List<String> lines = StringUtil.splitLines(results.toString());
assertThat(lines.size(), is(tuples.size() + 4)); // = delim + header + delim + (...lines...) + delim
}
@Test
public void shouldPrintToStringBuilderAllResults() {
- results = new QueryResults(columns, statistics, tuples, context.getProblems());
+ results = new QueryResults(columns, statistics, tuples, context.getProblems(), null);
StringBuilder sb = new StringBuilder();
results.toString(typeSystem, sb);
List<String> lines = StringUtil.splitLines(sb.toString());
@@ -188,7 +188,7 @@
@Test
public void shouldPrintToStringBuilderAllResultsEvenWhenNoTuples() {
tuples.clear();
- results = new QueryResults(columns, statistics, tuples, context.getProblems());
+ results = new QueryResults(columns, statistics, tuples, context.getProblems(), null);
StringBuilder sb = new StringBuilder();
results.toString(typeSystem, sb);
List<String> lines = StringUtil.splitLines(sb.toString());
@@ -197,7 +197,7 @@
@Test
public void shouldPrintToStringBuilderOnlyFirstLinesOfResults() {
- results = new QueryResults(columns, statistics, tuples, context.getProblems());
+ results = new QueryResults(columns, statistics, tuples, context.getProblems(), null);
StringBuilder sb = new StringBuilder();
results.toString(typeSystem, sb, 1);
List<String> lines = StringUtil.splitLines(sb.toString());
@@ -207,7 +207,7 @@
@Test
public void shouldPrintToStringBuilderOnlyFirstLinesOfResultsEvenWhenNoTuples() {
tuples.clear();
- results = new QueryResults(columns, statistics, tuples, context.getProblems());
+ results = new QueryResults(columns, statistics, tuples, context.getProblems(), null);
StringBuilder sb = new StringBuilder();
results.toString(typeSystem, sb, 3);
List<String> lines = StringUtil.splitLines(sb.toString());
@@ -217,7 +217,7 @@
@Test
public void shouldPrintToStringBuilderAllResultsWhenMaxRowParameterIsLargerThanNumberOfTuples() {
tuples.clear();
- results = new QueryResults(columns, statistics, tuples, context.getProblems());
+ results = new QueryResults(columns, statistics, tuples, context.getProblems(), null);
StringBuilder sb = new StringBuilder();
results.toString(typeSystem, sb, 3);
List<String> lines = StringUtil.splitLines(sb.toString());
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrQueryManager.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrQueryManager.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrQueryManager.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -46,8 +46,12 @@
import javax.jcr.query.RowIterator;
import net.jcip.annotations.Immutable;
import net.jcip.annotations.NotThreadSafe;
+import org.jboss.dna.common.collection.Problem;
+import org.jboss.dna.common.collection.Problems;
+import org.jboss.dna.common.collection.Problem.Status;
import org.jboss.dna.common.text.ParsingException;
import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.common.util.StringUtil;
import org.jboss.dna.graph.Location;
import org.jboss.dna.graph.property.NamespaceRegistry;
import org.jboss.dna.graph.property.Path;
@@ -119,6 +123,7 @@
throw new InvalidQueryException(JcrI18n.queryCannotBeParsedUsingLanguage.text(language, expression));
}
PlanHints hints = new PlanHints();
+ hints.showPlan = true;
// If using XPath, we need to add a few hints ...
if (Query.XPATH.equals(language)) {
hints.hasFullTextSearch = true; // requires 'jcr:score' to exist
@@ -260,6 +265,18 @@
return queryNode;
}
+
+ protected void checkForProblems( Problems problems ) throws RepositoryException {
+ if (problems.hasErrors()) {
+ // Build a message with the problems ...
+ StringBuilder msg = new StringBuilder();
+ for (Problem problem : problems) {
+ if (problem.getStatus() != Status.ERROR) continue;
+ msg.append(problem.getMessageString()).append("\n");
+ }
+ throw new RepositoryException(msg.toString());
+ }
+ }
}
/**
@@ -297,7 +314,12 @@
this.variables = null;
}
- protected QueryCommand getCommand() {
+ /**
+ * Get the underlying and immutable Abstract Query Model representation of this query.
+ *
+ * @return the AQM representation; never null
+ */
+ public QueryCommand getAbstractQueryModel() {
return query;
}
@@ -314,12 +336,23 @@
schemata,
hints,
variables);
+ checkForProblems(result.getProblems());
if (Query.XPATH.equals(language)) {
return new XPathQueryResult(session, result);
}
return new JcrQueryResult(session, result);
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return language + " -> " + statement + "\n" + StringUtil.createString(' ', Math.min(language.length() - 3, 0))
+ + "AQM -> " + query;
+ }
}
@NotThreadSafe
@@ -354,8 +387,19 @@
statement,
MAXIMUM_RESULTS_FOR_FULL_TEXT_SEARCH_QUERIES,
0);
+ checkForProblems(result.getProblems());
return new JcrQueryResult(session, result);
}
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return language + " -> " + statement;
+ }
}
protected static final String JCR_SCORE_COLUMN_NAME = "jcr:score";
@@ -430,6 +474,15 @@
}
/**
+ * Get a description of the query plan, if requested.
+ *
+ * @return the query plan, or null if the plan was not requested
+ */
+ public String getPlan() {
+ return results.getPlan();
+ }
+
+ /**
* {@inheritDoc}
*
* @see java.lang.Object#toString()
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPath.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPath.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPath.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -26,10 +26,12 @@
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import org.jboss.dna.common.collection.ReadOnlyIterator;
import org.jboss.dna.common.util.CheckArg;
import org.jboss.dna.common.util.HashCode;
import org.jboss.dna.common.util.ObjectUtil;
import org.jboss.dna.graph.query.model.Operator;
+import org.jboss.dna.graph.query.model.Order;
/**
* Abstract syntax components of an XPath query. The supported grammar is defined by JCR 1.0, and is a subset of what is allowed
@@ -642,11 +644,14 @@
public static class PathExpression extends Component implements Iterable<StepExpression> {
private final List<StepExpression> steps;
private final boolean relative;
+ private final OrderBy orderBy;
public PathExpression( boolean relative,
- List<StepExpression> steps ) {
+ List<StepExpression> steps,
+ OrderBy orderBy ) {
this.steps = steps;
this.relative = relative;
+ this.orderBy = orderBy;
}
/**
@@ -657,6 +662,15 @@
}
/**
+ * Get the order-by clause.
+ *
+ * @return the order-by clause, or null if there is no such clause
+ */
+ public OrderBy getOrderBy() {
+ return orderBy;
+ }
+
+ /**
* @return steps
*/
public List<StepExpression> getSteps() {
@@ -669,12 +683,12 @@
public PathExpression withoutLast() {
assert !steps.isEmpty();
- return new PathExpression(relative, steps.subList(0, steps.size() - 1));
+ return new PathExpression(relative, steps.subList(0, steps.size() - 1), orderBy);
}
public PathExpression withoutFirst() {
assert !steps.isEmpty();
- return new PathExpression(relative, steps.subList(1, steps.size()));
+ return new PathExpression(relative, steps.subList(1, steps.size()), orderBy);
}
/**
@@ -701,7 +715,10 @@
if (obj == this) return true;
if (obj instanceof PathExpression) {
PathExpression that = (PathExpression)obj;
- return this.relative == that.relative && this.steps.equals(that.steps);
+ if (this.relative != that.relative) return false;
+ if (this.orderBy != null && !this.orderBy.equals(that.orderBy)) return false;
+ if (this.orderBy == null && that.orderBy != null) return false;
+ return this.steps.equals(that.steps);
}
return false;
}
@@ -1382,4 +1399,166 @@
return "schema-attribute(" + attributeDeclarationName + ")";
}
}
+
+ public static class OrderBy extends Component implements Iterable<OrderBySpec> {
+ private final List<OrderBySpec> orderBySpecifications;
+
+ public OrderBy( List<OrderBySpec> orderBySpecifications ) {
+ this.orderBySpecifications = orderBySpecifications;
+ }
+
+ /**
+ *@return the list of order-by specifications; never null
+ */
+ public List<OrderBySpec> getOrderBySpecifications() {
+ return orderBySpecifications;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.jcr.xpath.XPath.Component#collapse()
+ */
+ @Override
+ public Component collapse() {
+ return super.collapse();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Iterable#iterator()
+ */
+ public Iterator<OrderBySpec> iterator() {
+ return new ReadOnlyIterator<OrderBySpec>(orderBySpecifications.iterator());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof OrderBy) {
+ OrderBy that = (OrderBy)obj;
+ return this.orderBySpecifications.equals(that.orderBySpecifications);
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("order-by(");
+ boolean first = true;
+ for (OrderBySpec spec : orderBySpecifications) {
+ if (first) first = false;
+ else sb.append(',');
+ sb.append(spec);
+ }
+ sb.append(')');
+ return sb.toString();
+ }
+ }
+
+ public static class OrderBySpec {
+ private final Order order;
+ private final FunctionCall scoreFunction;
+ private final NameTest attributeName;
+
+ public OrderBySpec( Order order,
+ FunctionCall scoreFunction ) {
+ assert order != null;
+ assert scoreFunction != null;
+ this.order = order;
+ this.scoreFunction = scoreFunction;
+ this.attributeName = null;
+ }
+
+ public OrderBySpec( Order order,
+ NameTest attributeName ) {
+ assert order != null;
+ assert attributeName != null;
+ this.order = order;
+ this.scoreFunction = null;
+ this.attributeName = attributeName;
+ }
+
+ /**
+ * Get the attribute name for this order specification.
+ *
+ * @return the attribute name, or null if the order is defined by the {@link #getScoreFunction() score function}
+ */
+ public NameTest getAttributeName() {
+ return attributeName;
+ }
+
+ /**
+ * Get the score function for this order specification.
+ *
+ * @return the score function with its parameters, or null if the order is defined by the {@link #getAttributeName()
+ * attribute name}
+ */
+ public FunctionCall getScoreFunction() {
+ return scoreFunction;
+ }
+
+ /**
+ * The order for this specification
+ *
+ * @return the order; never null
+ */
+ public Order getOrder() {
+ return order;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof OrderBySpec) {
+ OrderBySpec that = (OrderBySpec)obj;
+ if (this.order != that.order) return false;
+ if (this.attributeName != null && !this.attributeName.equals(that.attributeName)) return false;
+ if (this.scoreFunction != null && !this.scoreFunction.equals(that.scoreFunction)) return false;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ if (scoreFunction != null) {
+ sb.append(scoreFunction.toString());
+ } else {
+ sb.append('@').append(attributeName.toString());
+ }
+ switch (order) {
+ case ASCENDING:
+ sb.append(" ascending");
+ break;
+ case DESCENDING:
+ sb.append(" descending");
+ break;
+ }
+ return sb.toString();
+ }
+ }
}
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPathParser.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPathParser.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPathParser.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -37,6 +37,7 @@
import org.jboss.dna.graph.GraphI18n;
import org.jboss.dna.graph.property.ValueFormatException;
import org.jboss.dna.graph.query.model.Operator;
+import org.jboss.dna.graph.query.model.Order;
import org.jboss.dna.graph.query.model.TypeSystem;
import org.jboss.dna.jcr.xpath.XPath.Add;
import org.jboss.dna.jcr.xpath.XPath.And;
@@ -63,6 +64,8 @@
import org.jboss.dna.jcr.xpath.XPath.NodeComparisonOperator;
import org.jboss.dna.jcr.xpath.XPath.NodeTest;
import org.jboss.dna.jcr.xpath.XPath.Or;
+import org.jboss.dna.jcr.xpath.XPath.OrderBy;
+import org.jboss.dna.jcr.xpath.XPath.OrderBySpec;
import org.jboss.dna.jcr.xpath.XPath.ParenthesizedExpression;
import org.jboss.dna.jcr.xpath.XPath.PathExpression;
import org.jboss.dna.jcr.xpath.XPath.ProcessingInstructionTest;
@@ -281,7 +284,8 @@
}
relative = false;
}
- PathExpression result = new PathExpression(relative, parseRelativePathExpr(tokens).getSteps());
+ PathExpression relativeExpr = parseRelativePathExpr(tokens);
+ PathExpression result = new PathExpression(relative, relativeExpr.getSteps(), relativeExpr.getOrderBy());
if (prependDependentOrSelf) {
result.getSteps().add(0, new DescendantOrSelf());
}
@@ -299,7 +303,8 @@
steps.add(parseStepExpr(tokens));
}
}
- return new PathExpression(true, steps);
+ OrderBy orderBy = parseOrderBy(tokens); // may be null
+ return new PathExpression(true, steps, orderBy);
}
protected StepExpression parseStepExpr( TokenStream tokens ) {
@@ -658,6 +663,37 @@
protected void parseSequenceType( TokenStream tokens ) {
}
+ protected OrderBy parseOrderBy( TokenStream tokens ) {
+ if (tokens.canConsume("order", "by")) {
+ List<OrderBySpec> specs = new ArrayList<OrderBySpec>();
+ do {
+ OrderBySpec spec = parseOrderBySpec(tokens);
+ specs.add(spec);
+ } while (tokens.canConsume(','));
+ if (!specs.isEmpty()) return new OrderBy(specs);
+ }
+ return null;
+ }
+
+ protected OrderBySpec parseOrderBySpec( TokenStream tokens ) {
+ if (tokens.canConsume('@')) {
+ NameTest attributeName = parseQName(tokens);
+ Order order = Order.ASCENDING;
+ if (tokens.canConsume("ascending")) order = Order.ASCENDING;
+ else if (tokens.canConsume("descending")) order = Order.DESCENDING;
+ return new OrderBySpec(order, attributeName);
+ }
+ if (tokens.matches("jcr", ":", "score", "(")) {
+ FunctionCall scoreFunction = parseFunctionCall(tokens);
+ Order order = Order.ASCENDING;
+ if (tokens.canConsume("ascending")) order = Order.ASCENDING;
+ else if (tokens.canConsume("descending")) order = Order.DESCENDING;
+ return new OrderBySpec(order, scoreFunction);
+ }
+ throw new ParsingException(tokens.nextPosition(),
+ "Expected either 'jcr:score(tableName)' or '@<propertyName>' but found " + tokens.consume());
+ }
+
/**
* Remove any leading and trailing single-quotes or double-quotes from the supplied text.
*
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPathToQueryTranslator.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPathToQueryTranslator.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPathToQueryTranslator.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -33,7 +33,11 @@
import org.jboss.dna.graph.property.PropertyType;
import org.jboss.dna.graph.query.QueryBuilder;
import org.jboss.dna.graph.query.QueryBuilder.ConstraintBuilder;
+import org.jboss.dna.graph.query.QueryBuilder.OrderByBuilder;
+import org.jboss.dna.graph.query.QueryBuilder.OrderByOperandBuilder;
+import org.jboss.dna.graph.query.model.AllNodes;
import org.jboss.dna.graph.query.model.Operator;
+import org.jboss.dna.graph.query.model.Query;
import org.jboss.dna.graph.query.model.QueryCommand;
import org.jboss.dna.graph.query.model.TypeSystem;
import org.jboss.dna.graph.query.parse.InvalidQueryException;
@@ -54,6 +58,8 @@
import org.jboss.dna.jcr.xpath.XPath.NameTest;
import org.jboss.dna.jcr.xpath.XPath.NodeTest;
import org.jboss.dna.jcr.xpath.XPath.Or;
+import org.jboss.dna.jcr.xpath.XPath.OrderBy;
+import org.jboss.dna.jcr.xpath.XPath.OrderBySpec;
import org.jboss.dna.jcr.xpath.XPath.ParenthesizedExpression;
import org.jboss.dna.jcr.xpath.XPath.PathExpression;
import org.jboss.dna.jcr.xpath.XPath.StepExpression;
@@ -221,6 +227,55 @@
translateSource(tableName, path, where);
}
where.end();
+
+ // Process the order-by clause ...
+ OrderBy orderBy = pathExpression.getOrderBy();
+ if (orderBy != null) {
+ OrderByBuilder orderByBuilder = builder.orderBy();
+ for (OrderBySpec spec : orderBy) {
+ OrderByOperandBuilder operandBuilder = null;
+ switch (spec.getOrder()) {
+ case ASCENDING:
+ operandBuilder = orderByBuilder.ascending();
+ break;
+ case DESCENDING:
+ operandBuilder = orderByBuilder.descending();
+ break;
+ }
+ assert operandBuilder != null;
+ if (spec.getAttributeName() != null) {
+ // This order by is defined by an attribute ...
+ NameTest attribute = spec.getAttributeName();
+ assert !attribute.isWildcard();
+ operandBuilder.propertyValue(tableName, attribute.toString());
+ builder.select(tableName + "." + attribute.toString());
+ } else {
+ // This order-by is defined by a "jcr:score" function ...
+ FunctionCall scoreFunction = spec.getScoreFunction();
+ assert scoreFunction != null;
+ List<Component> args = scoreFunction.getParameters();
+ String nameOfTableToScore = tableName;
+ if (!args.isEmpty()) {
+ if (args.size() == 1 && args.get(0) instanceof NameTest) {
+ // Just the table name ...
+ NameTest tableNameTest = (NameTest)args.get(0);
+ nameOfTableToScore = tableNameTest.toString();
+ }
+ }
+ operandBuilder.fullTextSearchScore(nameOfTableToScore);
+ }
+ }
+ orderByBuilder.end();
+ }
+ // Try building this query, because we need to check the # of columns selected and the # of sources ...
+ Query query = (Query)builder.query();
+ if (query.getColumns().isEmpty() && query.getSource() instanceof AllNodes) {
+ // This is basically 'SELECT * FROM __ALLNODES__", which means that no type was explicitly specified and
+ // nothing was selected from that type. According to JCR 1.0 Section 6.6.3.1, this equates to
+ // 'SELECT * FROM [nt:base]', and since there is just one property on nt:base (but many on __ALLNODES__)
+ // this really equates to 'SELECT [jcr:primaryType] FROM __ALLNODES__'.
+ builder.select("jcr:primaryType");
+ }
}
/**
@@ -301,17 +356,17 @@
if (path.size() == 0) {
// This is a query against the root node ...
String alias = newAlias();
- builder.from("nt:base AS " + alias);
+ builder.fromAllNodesAs(alias);
where.path(alias).isEqualTo("/");
return alias;
}
String alias = newAlias();
if (tableName != null) {
// This is after some element(...) steps, so we need to join ...
- builder.join("nt:base AS " + alias);
+ builder.joinAllNodesAs(alias);
} else {
// This is the only part of the query ...
- builder.from("nt:base AS " + alias);
+ builder.fromAllNodesAs(alias);
}
tableName = alias;
if (path.size() == 1 && path.get(0).collapse() instanceof NameTest) {
@@ -326,7 +381,7 @@
}
} else {
// Must be just a bunch of descendant-or-self, axis and filter steps ...
- translatePathExpressionConstraint(new PathExpression(true, path), where, alias);
+ translatePathExpressionConstraint(new PathExpression(true, path, null), where, alias);
}
return tableName;
}
@@ -338,7 +393,7 @@
NameTest typeName = elementTest.getTypeName();
if (typeName.isWildcard()) {
tableName = newAlias();
- builder.from("nt:base AS " + tableName);
+ builder.fromAllNodesAs(tableName);
} else {
if (typeName.getLocalTest() == null) {
throw new InvalidQueryException(
@@ -414,7 +469,7 @@
// This adds the criteria that the child node exists ...
NameTest childName = (NameTest)predicate;
String alias = newAlias();
- builder.join("nt:base AS " + alias).onChildNode(tableName, alias);
+ builder.joinAllNodesAs(alias).onChildNode(tableName, alias);
if (!childName.isWildcard()) where.nodeName(alias).isEqualTo(nameFrom(childName));
tableName = alias;
} else if (predicate instanceof Comparison) {
@@ -532,7 +587,7 @@
} else if (param1 instanceof NameTest) {
// refers to child node, so we need to add a join ...
String alias = newAlias();
- builder.join("nt:base AS " + alias).onChildNode(tableName, alias);
+ builder.joinAllNodesAs(alias).onChildNode(tableName, alias);
// Now add the criteria ...
where.search(alias, value);
tableName = alias;
@@ -570,31 +625,32 @@
// Requires that the descendant node with the relative path does exist ...
PathExpression pathExpr = (PathExpression)predicate;
List<StepExpression> steps = pathExpr.getSteps();
+ OrderBy orderBy = pathExpr.getOrderBy();
assert steps.size() > 1; // 1 or 0 would have been collapsed ...
Component firstStep = steps.get(0).collapse();
if (firstStep instanceof ContextItem) {
// Remove the context and retry ...
- return translatePredicate(new PathExpression(true, steps.subList(1, steps.size())), tableName, where);
+ return translatePredicate(new PathExpression(true, steps.subList(1, steps.size()), orderBy), tableName, where);
}
if (firstStep instanceof NameTest) {
// Special case where this is similar to '[a/@id]'
NameTest childName = (NameTest)firstStep;
String alias = newAlias();
- builder.join("nt:base AS " + alias).onChildNode(tableName, alias);
+ builder.joinAllNodesAs(alias).onChildNode(tableName, alias);
if (!childName.isWildcard()) {
where.nodeName(alias).isEqualTo(nameFrom(childName));
}
- return translatePredicate(new PathExpression(true, steps.subList(1, steps.size())), alias, where);
+ return translatePredicate(new PathExpression(true, steps.subList(1, steps.size()), orderBy), alias, where);
}
if (firstStep instanceof DescendantOrSelf) {
// Special case where this is similar to '[a/@id]'
String alias = newAlias();
- builder.join("nt:base AS " + alias).onDescendant(tableName, alias);
- return translatePredicate(new PathExpression(true, steps.subList(1, steps.size())), alias, where);
+ builder.joinAllNodesAs(alias).onDescendant(tableName, alias);
+ return translatePredicate(new PathExpression(true, steps.subList(1, steps.size()), orderBy), alias, where);
}
// Add the join ...
String alias = newAlias();
- builder.join("nt:base AS " + alias).onDescendant(tableName, alias);
+ builder.joinAllNodesAs(alias).onDescendant(tableName, alias);
// Now add the criteria ...
translatePathExpressionConstraint(pathExpr, where, alias);
} else {
Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrQueryManagerTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrQueryManagerTest.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrQueryManagerTest.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -44,7 +44,7 @@
import org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource;
import org.jboss.dna.graph.property.Name;
import org.jboss.dna.graph.property.Path.Segment;
-import org.jboss.dna.jcr.JcrQueryManager.JcrQuery;
+import org.jboss.dna.jcr.JcrQueryManager.JcrQueryResult;
import org.jboss.dna.jcr.JcrRepository.Option;
import org.jboss.dna.jcr.JcrRepository.QueryLanguage;
import org.junit.After;
@@ -179,8 +179,8 @@
assertThat(result, is(notNullValue()));
if (print) {
System.out.println();
- System.out.println(query.getLanguage() + ": " + query.getStatement());
- System.out.println(" --> : " + ((JcrQuery)query).getCommand());
+ System.out.println(query);
+ System.out.println(" plan -> " + ((JcrQueryResult)result).getPlan());
System.out.println(result);
}
assertThat(result.getNodes().getSize(), is(numberOfResults));
@@ -267,6 +267,30 @@
}
@Test
+ public void shouldBeAbleToExecuteXPathQueryToFindAllUnstructuredNodesOrderedByPropertyValue() throws RepositoryException {
+ Query query = session.getWorkspace()
+ .getQueryManager()
+ .createQuery("//element(*,nt:unstructured) order by @jcr:primaryType", Query.XPATH);
+ assertThat(query, is(notNullValue()));
+ QueryResult result = query.execute();
+ print = true;
+ assertResults(query, result, 21);
+ assertThat(result, is(notNullValue()));
+ assertResultsHaveColumns(result, "jcr:primaryType", "jcr:path", "jcr:score");
+ }
+
+ @Test
+ public void shouldBeAbleToExecuteXPathQueryToFindAllUnstructuredNodesOrderedByScore() throws RepositoryException {
+ Query query = session.getWorkspace().getQueryManager().createQuery("//element(*,nt:unstructured) order by jcr:score()",
+ Query.XPATH);
+ assertThat(query, is(notNullValue()));
+ QueryResult result = query.execute();
+ assertResults(query, result, 21);
+ assertThat(result, is(notNullValue()));
+ assertResultsHaveColumns(result, "jcr:primaryType", "jcr:path", "jcr:score");
+ }
+
+ @Test
public void shouldBeAbleToExecuteXPathQueryToFindSameNameSiblingsByIndex() throws RepositoryException {
Query query = session.getWorkspace().getQueryManager().createQuery("/jcr:root/Other/NodeA", Query.XPATH);
assertThat(query, is(notNullValue()));
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 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrTckTest.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -147,8 +147,6 @@
private static class LevelOneFeatureTests extends TestSuite {
protected LevelOneFeatureTests() {
super("JCR Level 1 API Tests");
- // We currently don't pass the tests in those suites that are commented out
- // See https://jira.jboss.org/jira/browse/DNA-285
addTestSuite(org.apache.jackrabbit.test.api.RootNodeTest.class);
addTestSuite(org.apache.jackrabbit.test.api.NodeReadMethodsTest.class);
Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/xpath/XPathParserTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/xpath/XPathParserTest.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/xpath/XPathParserTest.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -36,6 +36,7 @@
import org.jboss.dna.common.text.TokenStream.Tokenizer;
import org.jboss.dna.graph.ExecutionContext;
import org.jboss.dna.graph.query.model.Operator;
+import org.jboss.dna.graph.query.model.Order;
import org.jboss.dna.graph.query.model.TypeSystem;
import org.jboss.dna.jcr.xpath.XPath.And;
import org.jboss.dna.jcr.xpath.XPath.AnyKindTest;
@@ -55,6 +56,8 @@
import org.jboss.dna.jcr.xpath.XPath.NameTest;
import org.jboss.dna.jcr.xpath.XPath.NodeTest;
import org.jboss.dna.jcr.xpath.XPath.Or;
+import org.jboss.dna.jcr.xpath.XPath.OrderBy;
+import org.jboss.dna.jcr.xpath.XPath.OrderBySpec;
import org.jboss.dna.jcr.xpath.XPath.ParenthesizedExpression;
import org.jboss.dna.jcr.xpath.XPath.PathExpression;
import org.jboss.dna.jcr.xpath.XPath.SchemaAttributeTest;
@@ -137,6 +140,22 @@
literal("1"))));
}
+ @Test
+ public void shouldParseXPathExpressionWithOrderBy() {
+ assertParsable("//element(*, my:type) order by @a1,@a2", pathExpr(orderBy(asc(nameTest("a1")), asc(nameTest("a2"))),
+ descendantOrSelf(),
+ axisStep(element(wildcard(), nameTest("my", "type")))));
+ assertParsable("//element(*, my:type) order by @p:a1, @a2",
+ pathExpr(orderBy(asc(nameTest("p", "a1")), asc(nameTest("a2"))),
+ descendantOrSelf(),
+ axisStep(element(wildcard(), nameTest("my", "type")))));
+ assertParsable("/jcr:root/element(name, my:type) order by @p:a1", pathExpr(orderBy(asc(nameTest("p", "a1"))),
+ axisStep(nameTest("jcr", "root")),
+ axisStep(element(nameTest("name"),
+ nameTest("my", "type")))));
+ assertParsable("/jcr:root order by @p:a1", pathExpr(orderBy(asc(nameTest("p", "a1"))), axisStep(nameTest("jcr", "root"))));
+ }
+
@Ignore
@Test
public void shouldParseXPathExpressionsThatCombineSeparateExpressions() {
@@ -851,9 +870,69 @@
}
// ----------------------------------------------------------------------------------------------------------------
+ // order-by
+ // ----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void shouldParseOrderByOneAttributeNameClause() {
+ assertThat(parser.parseOrderBy(tokenize("order by @a1")), is(orderBy(asc(nameTest("a1")))));
+ assertThat(parser.parseOrderBy(tokenize("order by @a1 ascending")), is(orderBy(asc(nameTest("a1")))));
+ assertThat(parser.parseOrderBy(tokenize("order by @a1 descending")), is(orderBy(desc(nameTest("a1")))));
+ assertThat(parser.parseOrderBy(tokenize("order by @pre:a1")), is(orderBy(asc(nameTest("pre", "a1")))));
+ assertThat(parser.parseOrderBy(tokenize("order by @pre:a1 ascending")), is(orderBy(asc(nameTest("pre", "a1")))));
+ assertThat(parser.parseOrderBy(tokenize("order by @pre:a1 descending")), is(orderBy(desc(nameTest("pre", "a1")))));
+ }
+
+ @Test
+ public void shouldParseOrderByMultipleAttributeNameClauses() {
+ assertThat(parser.parseOrderBy(tokenize("order by @a1,@a2")), is(orderBy(asc(nameTest("a1")), asc(nameTest("a2")))));
+ assertThat(parser.parseOrderBy(tokenize("order by @a1 ascending , @a2 ascending")), is(orderBy(asc(nameTest("a1")),
+ asc(nameTest("a2")))));
+ assertThat(parser.parseOrderBy(tokenize("order by @a1 descending, @a2 ascending")), is(orderBy(desc(nameTest("a1")),
+ asc(nameTest("a2")))));
+ assertThat(parser.parseOrderBy(tokenize("order by @a1 ascending , @a2 descending")), is(orderBy(asc(nameTest("a1")),
+ desc(nameTest("a2")))));
+ assertThat(parser.parseOrderBy(tokenize("order by @a1 descending, @a2 descending")), is(orderBy(desc(nameTest("a1")),
+ desc(nameTest("a2")))));
+ assertThat(parser.parseOrderBy(tokenize("order by @pre:a1, @pre:a2")), is(orderBy(asc(nameTest("pre", "a1")),
+ asc(nameTest("pre", "a2")))));
+ assertThat(parser.parseOrderBy(tokenize("order by @a1 ascending, @pre:a2 ascending")), is(orderBy(asc(nameTest("a1")),
+ asc(nameTest("pre",
+ "a2")))));
+ assertThat(parser.parseOrderBy(tokenize("order by @a1 descending, @pre:a2 ascending")), is(orderBy(desc(nameTest("a1")),
+ asc(nameTest("pre",
+ "a2")))));
+ assertThat(parser.parseOrderBy(tokenize("order by @a1 ascending, @pre:a2 descending")), is(orderBy(asc(nameTest("a1")),
+ desc(nameTest("pre",
+ "a2")))));
+ assertThat(parser.parseOrderBy(tokenize("order by @a1 descending, @pre:a2 descending")),
+ is(orderBy(desc(nameTest("a1")), desc(nameTest("pre", "a2")))));
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
// utility methods
// ----------------------------------------------------------------------------------------------------------------
+ protected XPath.OrderBy orderBy( OrderBySpec... specs ) {
+ return new XPath.OrderBy(Arrays.asList(specs));
+ }
+
+ protected OrderBySpec asc( FunctionCall scoreFunction ) {
+ return new OrderBySpec(Order.ASCENDING, scoreFunction);
+ }
+
+ protected OrderBySpec desc( FunctionCall scoreFunction ) {
+ return new OrderBySpec(Order.DESCENDING, scoreFunction);
+ }
+
+ protected OrderBySpec asc( NameTest attributeName ) {
+ return new OrderBySpec(Order.ASCENDING, attributeName);
+ }
+
+ protected OrderBySpec desc( NameTest attributeName ) {
+ return new OrderBySpec(Order.DESCENDING, attributeName);
+ }
+
protected TokenStream tokenize( String xpath ) {
Tokenizer tokenizer = new XPathParser.XPathTokenizer(false); // skip comments
return new TokenStream(xpath, tokenizer, true).start(); // case sensitive!!
@@ -878,17 +957,32 @@
}
protected PathExpression pathExpr( List<StepExpression> steps ) {
- return new PathExpression(false, steps);
+ return new PathExpression(false, steps, null);
}
+ protected PathExpression pathExpr( List<StepExpression> steps,
+ OrderBy orderBy ) {
+ return new PathExpression(false, steps, orderBy);
+ }
+
+ protected PathExpression pathExpr( OrderBy orderBy,
+ StepExpression... steps ) {
+ return pathExpr(Arrays.asList(steps), orderBy);
+ }
+
protected PathExpression relativePathExpr( StepExpression... steps ) {
return relativePathExpr(Arrays.asList(steps));
}
protected PathExpression relativePathExpr( List<StepExpression> steps ) {
- return new PathExpression(true, steps);
+ return new PathExpression(true, steps, null);
}
+ protected PathExpression relativePathExpr( List<StepExpression> steps,
+ OrderBy orderBy ) {
+ return new PathExpression(true, steps, orderBy);
+ }
+
protected Literal literal( String value ) {
return new Literal(value);
}
Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/xpath/XPathToQueryTranslatorTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/xpath/XPathToQueryTranslatorTest.java 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/xpath/XPathToQueryTranslatorTest.java 2010-01-06 23:48:32 UTC (rev 1536)
@@ -65,85 +65,96 @@
@Test
public void shouldTranslateFromXPathOfAnyNode() {
- assertThat(xpath("//element(*)"), isSql("SELECT * FROM [nt:base] AS nodeSet1"));
- assertThat(xpath("/jcr:root//element(*)"), isSql("SELECT * FROM [nt:base] AS nodeSet1"));
- assertThat(xpath("//*"), isSql("SELECT * FROM [nt:base] AS nodeSet1"));
- assertThat(xpath("/jcr:root//*"), isSql("SELECT * FROM [nt:base] AS nodeSet1"));
- assertThat(xpath("//."), isSql("SELECT * FROM [nt:base] AS nodeSet1"));
- assertThat(xpath("/jcr:root//."), isSql("SELECT * FROM [nt:base] AS nodeSet1"));
+ assertThat(xpath("//element(*)"), isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1"));
+ assertThat(xpath("/jcr:root//element(*)"), isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1"));
+ assertThat(xpath("//*"), isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1"));
+ assertThat(xpath("/jcr:root//*"), isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1"));
+ assertThat(xpath("//."), isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1"));
+ assertThat(xpath("/jcr:root//."), isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1"));
}
@Test
public void shouldTranslateFromXPathContainingExplicitRootPath() {
- assertThat(xpath("/jcr:root"), isSql("SELECT * FROM [nt:base] AS nodeSet1 WHERE PATH(nodeSet1) = '/'"));
+ assertThat(xpath("/jcr:root"),
+ isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/'"));
}
@Test
public void shouldTranslateFromXPathContainingExplicitPath() {
- assertThat(xpath("/jcr:root/a"), isSql("SELECT * FROM [nt:base] AS nodeSet1 WHERE PATH(nodeSet1) = '/a'"));
- assertThat(xpath("/jcr:root/a/b"), isSql("SELECT * FROM [nt:base] AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b'"));
- assertThat(xpath("/jcr:root/a/b/c"), isSql("SELECT * FROM [nt:base] AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b/c'"));
- assertThat(xpath("/jcr:root/a/b/c/d"), isSql("SELECT * FROM [nt:base] AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b/c/d'"));
+ assertThat(xpath("/jcr:root/a"),
+ isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/a'"));
+ assertThat(xpath("/jcr:root/a/b"),
+ isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b'"));
+ assertThat(xpath("/jcr:root/a/b/c"),
+ isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b/c'"));
+ assertThat(xpath("/jcr:root/a/b/c/d"),
+ isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b/c/d'"));
}
@Test
public void shouldTranslateFromXPathContainingExplicitPathWithChildNumbers() {
- assertThat(xpath("/jcr:root/a[2]/b"), isSql("SELECT * FROM [nt:base] AS nodeSet1 WHERE PATH(nodeSet1) = '/a[2]/b'"));
- assertThat(xpath("/jcr:root/a/b[3]"), isSql("SELECT * FROM [nt:base] AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b[3]'"));
- assertThat(xpath("/jcr:root/a[2]/b[3]"), isSql("SELECT * FROM [nt:base] AS nodeSet1 WHERE PATH(nodeSet1) = '/a[2]/b[3]'"));
+ assertThat(xpath("/jcr:root/a[2]/b"),
+ isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/a[2]/b'"));
+ assertThat(xpath("/jcr:root/a/b[3]"),
+ isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b[3]'"));
+ assertThat(xpath("/jcr:root/a[2]/b[3]"),
+ isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/a[2]/b[3]'"));
}
@Test
public void shouldTranslateFromXPathContainingExplicitPathWithWildcardChildNumbers() {
- assertThat(xpath("/jcr:root/a[*]/b"), isSql("SELECT * FROM [nt:base] AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b'"));
- assertThat(xpath("/jcr:root/a/b[*]"), isSql("SELECT * FROM [nt:base] AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b'"));
- assertThat(xpath("/jcr:root/a[*]/b[*]"), isSql("SELECT * FROM [nt:base] AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b'"));
+ assertThat(xpath("/jcr:root/a[*]/b"),
+ isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b'"));
+ assertThat(xpath("/jcr:root/a/b[*]"),
+ isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b'"));
+ assertThat(xpath("/jcr:root/a[*]/b[*]"),
+ isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b'"));
}
@Test
public void shouldTranslateFromXPathContainingPathWithDescendantOrSelf() {
assertThat(xpath("/jcr:root/a/b//c"),
- isSql("SELECT * FROM [nt:base] AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b/c' OR PATH(nodeSet1) LIKE '/a/b/%/c'"));
+ isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b/c' OR PATH(nodeSet1) LIKE '/a/b/%/c'"));
assertThat(xpath("/jcr:root/a/b[2]//c"),
- isSql("SELECT * FROM [nt:base] AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b[2]/c' OR PATH(nodeSet1) LIKE '/a/b[2]/%/c'"));
+ isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b[2]/c' OR PATH(nodeSet1) LIKE '/a/b[2]/%/c'"));
assertThat(xpath("/jcr:root/a/b//c[4]"),
- isSql("SELECT * FROM [nt:base] AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b/c[4]' OR PATH(nodeSet1) LIKE '/a/b/%/c[4]'"));
+ isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b/c[4]' OR PATH(nodeSet1) LIKE '/a/b/%/c[4]'"));
assertThat(xpath("/jcr:root/a/b[2]//c[4]"),
- isSql("SELECT * FROM [nt:base] AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b[2]/c[4]' OR PATH(nodeSet1) LIKE '/a/b[2]/%/c[4]'"));
+ isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b[2]/c[4]' OR PATH(nodeSet1) LIKE '/a/b[2]/%/c[4]'"));
}
@Test
public void shouldTranslateFromXPathContainingPathWithMultipleDescendantOrSelf() {
assertThat(xpath("/jcr:root/a/b//c//d"),
- isSql("SELECT * FROM [nt:base] AS nodeSet1 WHERE (((PATH(nodeSet1) = '/a/b/c/d' OR PATH(nodeSet1) LIKE '/a/b/%/c/d') OR PATH(nodeSet1) LIKE '/a/b/c/%/d') OR PATH(nodeSet1) LIKE '/a/b/%/c/%/d')"));
+ isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1 WHERE (((PATH(nodeSet1) = '/a/b/c/d' OR PATH(nodeSet1) LIKE '/a/b/%/c/d') OR PATH(nodeSet1) LIKE '/a/b/c/%/d') OR PATH(nodeSet1) LIKE '/a/b/%/c/%/d')"));
}
@Test
public void shouldTranslateFromXPathContainingPredicatesUsingRelativePaths() {
assertThat(xpath("//element(*,my:type)[a/@id]"),
- isSql("SELECT * FROM [my:type] JOIN [nt:base] as nodeSet1 ON ISCHILDNODE(nodeSet1,[my:type]) WHERE NAME(nodeSet1) = 'a' AND nodeSet1.id IS NOT NULL"));
+ isSql("SELECT * FROM [my:type] JOIN __ALLNODES__ as nodeSet1 ON ISCHILDNODE(nodeSet1,[my:type]) WHERE NAME(nodeSet1) = 'a' AND nodeSet1.id IS NOT NULL"));
assertThat(xpath("//element(*,my:type)[a/b/@id]"),
- isSql("SELECT * FROM [my:type] JOIN [nt:base] as nodeSet1 ON ISCHILDNODE(nodeSet1,[my:type]) JOIN [nt:base] as nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE (NAME(nodeSet1) = 'a' AND NAME(nodeSet2) = 'b') AND nodeSet2.id IS NOT NULL"));
+ isSql("SELECT * FROM [my:type] JOIN __ALLNODES__ as nodeSet1 ON ISCHILDNODE(nodeSet1,[my:type]) JOIN __ALLNODES__ as nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE (NAME(nodeSet1) = 'a' AND NAME(nodeSet2) = 'b') AND nodeSet2.id IS NOT NULL"));
assertThat(xpath("//element(*,my:type)[a/b/((@id and @name) or not(@address))]"),
- isSql("SELECT * FROM [my:type] JOIN [nt:base] as nodeSet1 ON ISCHILDNODE(nodeSet1,[my:type]) JOIN [nt:base] as nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE (NAME(nodeSet1) = 'a' AND NAME(nodeSet2) = 'b') AND ((nodeSet2.id IS NOT NULL and nodeSet2.name IS NOT NULL) OR (NOT(nodeSet2.address IS NOT NULL)))"));
+ isSql("SELECT * FROM [my:type] JOIN __ALLNODES__ as nodeSet1 ON ISCHILDNODE(nodeSet1,[my:type]) JOIN __ALLNODES__ as nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE (NAME(nodeSet1) = 'a' AND NAME(nodeSet2) = 'b') AND ((nodeSet2.id IS NOT NULL and nodeSet2.name IS NOT NULL) OR (NOT(nodeSet2.address IS NOT NULL)))"));
assertThat(xpath("//element(*,my:type)[./a/b/((@id and @name) or not(@address))]"),
- isSql("SELECT * FROM [my:type] JOIN [nt:base] as nodeSet1 ON ISCHILDNODE(nodeSet1,[my:type]) JOIN [nt:base] as nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE (NAME(nodeSet1) = 'a' AND NAME(nodeSet2) = 'b') AND ((nodeSet2.id IS NOT NULL and nodeSet2.name IS NOT NULL) OR (NOT(nodeSet2.address IS NOT NULL)))"));
+ isSql("SELECT * FROM [my:type] JOIN __ALLNODES__ as nodeSet1 ON ISCHILDNODE(nodeSet1,[my:type]) JOIN __ALLNODES__ as nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE (NAME(nodeSet1) = 'a' AND NAME(nodeSet2) = 'b') AND ((nodeSet2.id IS NOT NULL and nodeSet2.name IS NOT NULL) OR (NOT(nodeSet2.address IS NOT NULL)))"));
assertThat(xpath("//element(*,my:type)[a/b/((@id and @name) or not(jcr:contains(@desc,'rock star')))]"),
- isSql("SELECT * FROM [my:type] JOIN [nt:base] as nodeSet1 ON ISCHILDNODE(nodeSet1,[my:type]) JOIN [nt:base] as nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE (NAME(nodeSet1) = 'a' AND NAME(nodeSet2) = 'b') AND ((nodeSet2.id IS NOT NULL and nodeSet2.name IS NOT NULL) OR (NOT(CONTAINS(nodeSet2.desc,'rock star'))))"));
+ isSql("SELECT * FROM [my:type] JOIN __ALLNODES__ as nodeSet1 ON ISCHILDNODE(nodeSet1,[my:type]) JOIN __ALLNODES__ as nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE (NAME(nodeSet1) = 'a' AND NAME(nodeSet2) = 'b') AND ((nodeSet2.id IS NOT NULL and nodeSet2.name IS NOT NULL) OR (NOT(CONTAINS(nodeSet2.desc,'rock star'))))"));
assertThat(xpath("//element(*,my:type)[*/@id]"),
- isSql("SELECT * FROM [my:type] JOIN [nt:base] as nodeSet1 ON ISCHILDNODE(nodeSet1,[my:type]) WHERE nodeSet1.id IS NOT NULL"));
+ isSql("SELECT * FROM [my:type] JOIN __ALLNODES__ as nodeSet1 ON ISCHILDNODE(nodeSet1,[my:type]) WHERE nodeSet1.id IS NOT NULL"));
assertThat(xpath("//element(*,my:type)[*/*/@id]"),
- isSql("SELECT * FROM [my:type] JOIN [nt:base] as nodeSet1 ON ISCHILDNODE(nodeSet1,[my:type]) JOIN [nt:base] as nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE nodeSet2.id IS NOT NULL"));
+ isSql("SELECT * FROM [my:type] JOIN __ALLNODES__ as nodeSet1 ON ISCHILDNODE(nodeSet1,[my:type]) JOIN __ALLNODES__ as nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE nodeSet2.id IS NOT NULL"));
assertThat(xpath("//element(*,my:type)[./*/*/@id]"),
- isSql("SELECT * FROM [my:type] JOIN [nt:base] as nodeSet1 ON ISCHILDNODE(nodeSet1,[my:type]) JOIN [nt:base] as nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE nodeSet2.id IS NOT NULL"));
+ isSql("SELECT * FROM [my:type] JOIN __ALLNODES__ as nodeSet1 ON ISCHILDNODE(nodeSet1,[my:type]) JOIN __ALLNODES__ as nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE nodeSet2.id IS NOT NULL"));
assertThat(xpath("//element(*,my:type)[.//@id]"),
- isSql("SELECT * FROM [my:type] JOIN [nt:base] as nodeSet1 ON ISDESCENDANTNODE(nodeSet1,[my:type]) WHERE nodeSet1.id IS NOT NULL"));
+ isSql("SELECT * FROM [my:type] JOIN __ALLNODES__ as nodeSet1 ON ISDESCENDANTNODE(nodeSet1,[my:type]) WHERE nodeSet1.id IS NOT NULL"));
}
@Test
public void shouldTranslateFromXPathContainingPredicatesIdentifyingPropertiesThatMustHaveValues() {
assertThat(xpath("/jcr:root/testroot/serializationNode[@jcr:primaryType]"),
- isSql("SELECT * FROM [nt:base] AS nodeSet1 WHERE PATH(nodeSet1) = '/testroot/serializationNode' AND nodeSet1.[jcr:primaryType] IS NOT NULL"));
+ isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/testroot/serializationNode' AND nodeSet1.[jcr:primaryType] IS NOT NULL"));
assertThat(xpath("//element(*,my:type)[@id]"), isSql("SELECT * FROM [my:type] WHERE id IS NOT NULL"));
assertThat(xpath("//element(*,my:type)[@id][@name]"),
isSql("SELECT * FROM [my:type] WHERE id IS NOT NULL AND name IS NOT NULL"));
@@ -192,8 +203,8 @@
assertThat(xpath("//element(*,my:type)/(@id union @name)"), isSql("SELECT id, name FROM [my:type]"));
assertThat(xpath("//element(*,my:type)/(@id union @name union @x:address)"),
isSql("SELECT id, name, [x:address] FROM [my:type]"));
- assertThat(xpath("//(@id|@name)"), isSql("SELECT nodeSet1.id, nodeSet1.name FROM [nt:base] AS nodeSet1"));
- assertThat(xpath("//./(@id|@name)"), isSql("SELECT nodeSet1.id, nodeSet1.name FROM [nt:base] AS nodeSet1"));
+ assertThat(xpath("//(@id|@name)"), isSql("SELECT nodeSet1.id, nodeSet1.name FROM __ALLNODES__ AS nodeSet1"));
+ assertThat(xpath("//./(@id|@name)"), isSql("SELECT nodeSet1.id, nodeSet1.name FROM __ALLNODES__ AS nodeSet1"));
}
@Test
@@ -208,53 +219,67 @@
@Test
public void shouldTranslateFromXPathOfAnyNodeWithName() {
- assertThat(xpath("//element(nodeName,*)"), isSql("SELECT * FROM [nt:base] AS nodeSet1 WHERE NAME(nodeSet1) = 'nodeName'"));
+ assertThat(xpath("//element(nodeName,*)"),
+ isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1 WHERE NAME(nodeSet1) = 'nodeName'"));
- assertThat(xpath("//element(nodeName,*)"), isSql("SELECT * FROM [nt:base] AS nodeSet1 WHERE NAME(nodeSet1) = 'nodeName'"));
+ assertThat(xpath("//element(nodeName,*)"),
+ isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1 WHERE NAME(nodeSet1) = 'nodeName'"));
- assertThat(xpath("//nodeName"), isSql("SELECT * FROM [nt:base] AS nodeSet1 WHERE NAME(nodeSet1) = 'nodeName'"));
+ assertThat(xpath("//nodeName"),
+ isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1 WHERE NAME(nodeSet1) = 'nodeName'"));
assertThat(xpath("/jcr:root//element(nodeName,*)"),
- isSql("SELECT * FROM [nt:base] AS nodeSet1 WHERE NAME(nodeSet1) = 'nodeName'"));
+ isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1 WHERE NAME(nodeSet1) = 'nodeName'"));
- assertThat(xpath("/jcr:root//nodeName"), isSql("SELECT * FROM [nt:base] AS nodeSet1 WHERE NAME(nodeSet1) = 'nodeName'"));
+ assertThat(xpath("/jcr:root//nodeName"),
+ isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1 WHERE NAME(nodeSet1) = 'nodeName'"));
}
@Test
public void shouldTranslateFromXPathOfNodeWithNameUnderRoot() {
assertThat(xpath("/jcr:root/element(nodeName,*)"),
- isSql("SELECT * FROM [nt:base] AS nodeSet1 WHERE NAME(nodeSet1) = 'nodeName' AND DEPTH(nodeSet1) = CAST(1 AS LONG)"));
+ isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1 WHERE NAME(nodeSet1) = 'nodeName' AND DEPTH(nodeSet1) = CAST(1 AS LONG)"));
- assertThat(xpath("/jcr:root/nodeName"), isSql("SELECT * FROM [nt:base] AS nodeSet1 WHERE PATH(nodeSet1) = '/nodeName'"));
+ assertThat(xpath("/jcr:root/nodeName"),
+ isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/nodeName'"));
- assertThat(xpath("nodeName"), isSql("SELECT * FROM [nt:base] AS nodeSet1 WHERE PATH(nodeSet1) = '/nodeName'"));
+ assertThat(xpath("nodeName"),
+ isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/nodeName'"));
}
@Test
public void shouldTranslateFromXPathOfAnyNodeUsingPredicate() {
assertThat(xpath("//.[jcr:contains(.,'bar')]"),
- isSql("SELECT * FROM [nt:base] AS nodeSet1 WHERE CONTAINS(nodeSet1.*,'bar')"));
+ isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1 WHERE CONTAINS(nodeSet1.*,'bar')"));
assertThat(xpath("//.[jcr:contains(a,'bar')]"),
- isSql("SELECT * FROM [nt:base] AS nodeSet1 JOIN [nt:base] AS nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE CONTAINS(nodeSet2.*,'bar')"));
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 JOIN __ALLNODES__ AS nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE CONTAINS(nodeSet2.*,'bar')"));
assertThat(xpath("//*[jcr:contains(.,'bar')]"),
- isSql("SELECT * FROM [nt:base] AS nodeSet1 WHERE CONTAINS(nodeSet1.*,'bar')"));
+ isSql("SELECT nodeSet1.[jcr:primaryType] FROM __ALLNODES__ AS nodeSet1 WHERE CONTAINS(nodeSet1.*,'bar')"));
assertThat(xpath("//*[jcr:contains(a,'bar')]"),
- isSql("SELECT * FROM [nt:base] AS nodeSet1 JOIN [nt:base] AS nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE CONTAINS(nodeSet2.*,'bar')"));
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 JOIN __ALLNODES__ AS nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE CONTAINS(nodeSet2.*,'bar')"));
assertThat(xpath("//*[jcr:contains(a/@b,'bar')]"),
- isSql("SELECT * FROM [nt:base] AS nodeSet1 JOIN [nt:base] AS nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE NAME(nodeSet2) = 'a' AND CONTAINS(nodeSet2.b,'bar')"));
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 JOIN __ALLNODES__ AS nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE NAME(nodeSet2) = 'a' AND CONTAINS(nodeSet2.b,'bar')"));
assertThat(xpath("//*[jcr:contains(a/*/@b,'bar')]"),
- isSql("SELECT * FROM [nt:base] AS nodeSet1 JOIN [nt:base] AS nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) JOIN [nt:base] AS nodeSet3 ON ISCHILDNODE(nodeSet3,nodeSet2) WHERE NAME(nodeSet2) = 'a' AND CONTAINS(nodeSet3.b,'bar')"));
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 JOIN __ALLNODES__ AS nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) JOIN __ALLNODES__ AS nodeSet3 ON ISCHILDNODE(nodeSet3,nodeSet2) WHERE NAME(nodeSet2) = 'a' AND CONTAINS(nodeSet3.b,'bar')"));
assertThat(xpath("/jcr:root//element(*)[jcr:contains(a/@b,'bar')]"),
- isSql("SELECT * FROM [nt:base] AS nodeSet1 JOIN [nt:base] AS nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE NAME(nodeSet2) = 'a' AND CONTAINS(nodeSet2.b,'bar')"));
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 JOIN __ALLNODES__ AS nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE NAME(nodeSet2) = 'a' AND CONTAINS(nodeSet2.b,'bar')"));
assertThat(xpath("/jcr:root//element(*)[jcr:contains(a/*/@b,'bar')]"),
- isSql("SELECT * FROM [nt:base] AS nodeSet1 JOIN [nt:base] AS nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) JOIN [nt:base] AS nodeSet3 ON ISCHILDNODE(nodeSet3,nodeSet2) WHERE NAME(nodeSet2) = 'a' AND CONTAINS(nodeSet3.b,'bar')"));
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 JOIN __ALLNODES__ AS nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) JOIN __ALLNODES__ AS nodeSet3 ON ISCHILDNODE(nodeSet3,nodeSet2) WHERE NAME(nodeSet2) = 'a' AND CONTAINS(nodeSet3.b,'bar')"));
assertThat(xpath("/jcr:root//*[jcr:contains(a/@b,'bar')]"),
- isSql("SELECT * FROM [nt:base] AS nodeSet1 JOIN [nt:base] AS nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE NAME(nodeSet2) = 'a' AND CONTAINS(nodeSet2.b,'bar')"));
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 JOIN __ALLNODES__ AS nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE NAME(nodeSet2) = 'a' AND CONTAINS(nodeSet2.b,'bar')"));
assertThat(xpath("/jcr:root//*[jcr:contains(a/*/@b,'bar')]"),
- isSql("SELECT * FROM [nt:base] AS nodeSet1 JOIN [nt:base] AS nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) JOIN [nt:base] AS nodeSet3 ON ISCHILDNODE(nodeSet3,nodeSet2) WHERE NAME(nodeSet2) = 'a' AND CONTAINS(nodeSet3.b,'bar')"));
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 JOIN __ALLNODES__ AS nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) JOIN __ALLNODES__ AS nodeSet3 ON ISCHILDNODE(nodeSet3,nodeSet2) WHERE NAME(nodeSet2) = 'a' AND CONTAINS(nodeSet3.b,'bar')"));
}
@Test
+ public void shouldTranslateFromXPathUsingOrderBy() {
+ assertThat(xpath("//element(*,*) order by @title"),
+ isSql("SELECT nodeSet1.title FROM __ALLNODES__ AS nodeSet1 ORDER BY nodeSet1.title"));
+ assertThat(xpath("/jcr:root/testroot/*[@prop1] order by @prop1 ascending"),
+ isSql("SELECT nodeSet1.prop1 FROM __ALLNODES__ as nodeSet1 WHERE PATH(nodeSet1) = '/testroot' AND nodeSet1.prop1 IS NOT NULL ORDER BY nodeSet1.prop1"));
+ }
+
+ @Test
public void shouldParseXPathExpressions() {
xpath("/jcr:root/a/b/c");
xpath("/jcr:root/a/b/c[*]");
Modified: trunk/dna-jcr/src/test/resources/tck/repositoryForTckTests.xml
===================================================================
--- trunk/dna-jcr/src/test/resources/tck/repositoryForTckTests.xml 2010-01-06 22:13:11 UTC (rev 1535)
+++ trunk/dna-jcr/src/test/resources/tck/repositoryForTckTests.xml 2010-01-06 23:48:32 UTC (rev 1536)
@@ -55,7 +55,14 @@
<nt:unstructured jcr:name="node1" prop1="<foo&foo>">
<nt:unstructured jcr:name="jcr:xmltext" jcr:xmlcharacters="This is the text for node1[2]!" />
</nt:unstructured>
- <nt:unstructured jcr:name="node1" prop1="<foo&foo>">
+ <nt:unstructured jcr:name="node1" prop1="prop1 value for node1[3]">
<nt:unstructured jcr:name="jcr:xmltext" jcr:xmlcharacters="This is the text for node1[3]!" />
</nt:unstructured>
+ <!--
+ XPathOrderByTest requires multiple nodes of type 'nt:unstructured' with distinct 'prop1' values
+ -->
+ <nt:unstructured jcr:name="nodeForOrderBy" prop1="propValue3"/>
+ <nt:unstructured jcr:name="anotherNodeForOrderBy" prop1="propValue1">
+ <nt:unstructured jcr:name="aNestedNodeForOrderBy" prop1="propValue2"/>
+ </nt:unstructured>
</testroot>
\ No newline at end of file
14 years, 5 months
DNA SVN: r1535 - in trunk/extensions/dna-connector-svn/src: test/java/org/jboss/dna/connector/svn and 1 other directory.
by dna-commits@lists.jboss.org
Author: bcarothers
Date: 2010-01-06 17:13:11 -0500 (Wed, 06 Jan 2010)
New Revision: 1535
Modified:
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepository.java
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepositorySource.java
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnIntegrationTest.java
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositorySourceTest.java
Log:
Corrected Eclipse warnings
Modified: trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepository.java
===================================================================
--- trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepository.java 2010-01-06 18:43:36 UTC (rev 1534)
+++ trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepository.java 2010-01-06 22:13:11 UTC (rev 1535)
@@ -59,10 +59,10 @@
public class SvnRepository extends WritablePathRepository {
- private static final String DEFAULT_MIME_TYPE = "application/octet-stream";
- private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
+ protected static final String DEFAULT_MIME_TYPE = "application/octet-stream";
+ protected static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
- private final SvnRepositorySource source;
+ protected final SvnRepositorySource source;
static {
// for DAV (over http and https)
Modified: trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepositorySource.java
===================================================================
--- trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepositorySource.java 2010-01-06 18:43:36 UTC (rev 1534)
+++ trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepositorySource.java 2010-01-06 22:13:11 UTC (rev 1535)
@@ -289,6 +289,11 @@
return false;
}
+ @Override
+ public int hashCode() {
+ return getName().hashCode();
+ }
+
/**
* {@inheritDoc}
*
Modified: trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnIntegrationTest.java
===================================================================
--- trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnIntegrationTest.java 2010-01-06 18:43:36 UTC (rev 1534)
+++ trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnIntegrationTest.java 2010-01-06 22:13:11 UTC (rev 1535)
@@ -69,6 +69,7 @@
return null;
}
+ @SuppressWarnings( "synthetic-access" )
public ExecutionContext getExecutionContext() {
return context;
}
Modified: trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositorySourceTest.java
===================================================================
--- trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositorySourceTest.java 2010-01-06 18:43:36 UTC (rev 1534)
+++ trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositorySourceTest.java 2010-01-06 22:13:11 UTC (rev 1535)
@@ -35,14 +35,12 @@
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
-import java.util.UUID;
import java.util.concurrent.TimeUnit;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.RefAddr;
import javax.naming.Reference;
import javax.naming.spi.ObjectFactory;
-import org.jboss.dna.connector.svn.SvnRepositorySource;
import org.jboss.dna.graph.ExecutionContext;
import org.jboss.dna.graph.Subgraph;
import org.jboss.dna.graph.cache.BasicCachePolicy;
@@ -65,11 +63,9 @@
private SvnRepositorySource source;
private RepositoryConnection connection;
private String validName;
- private String validUuidPropertyName;
private static String url;
private String username;
private String password;
- private UUID validRootNodeUuid;
private final ExecutionContext context = new ExecutionContext();
@BeforeClass
@@ -93,6 +89,7 @@
return null;
}
+ @SuppressWarnings( "synthetic-access" )
public ExecutionContext getExecutionContext() {
return context;
}
@@ -220,23 +217,21 @@
public void shouldCreateJndiReferenceAndRecreatedObjectFromReference() throws Exception {
BasicCachePolicy cachePolicy = new BasicCachePolicy();
cachePolicy.setTimeToLive(1000L, TimeUnit.MILLISECONDS);
- convertToAndFromJndiReference(validName, validRootNodeUuid, url, username, password, validUuidPropertyName, 100);
+ convertToAndFromJndiReference(validName, url, username, password, 100);
}
@Test
public void shouldCreateJndiReferenceAndRecreatedObjectFromReferenceWithNullProperties() throws Exception {
BasicCachePolicy cachePolicy = new BasicCachePolicy();
cachePolicy.setTimeToLive(1000L, TimeUnit.MILLISECONDS);
- convertToAndFromJndiReference("some source", null, "url1", null, null, null, 100);
- convertToAndFromJndiReference(null, null, "url2", null, null, null, 100);
+ convertToAndFromJndiReference("some source", "url1", null, null, 100);
+ convertToAndFromJndiReference(null, "url2", null, null, 100);
}
private void convertToAndFromJndiReference( String sourceName,
- UUID rootNodeUuid,
String url,
String username,
String password,
- String uuidPropertyName,
int retryLimit ) throws Exception {
source.setRetryLimit(retryLimit);
source.setName(sourceName);
14 years, 5 months
DNA SVN: r1534 - in trunk: extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn and 1 other directories.
by dna-commits@lists.jboss.org
Author: bcarothers
Date: 2010-01-06 13:43:36 -0500 (Wed, 06 Jan 2010)
New Revision: 1534
Modified:
trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/svn/SvnAndJcrIntegrationTest.java
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepository.java
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepositorySource.java
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnIntegrationTest.java
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositoryConnectorNoCreateWorkspaceTest.java
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositoryConnectorNotWritableTest.java
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositoryConnectorWritableTest.java
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositorySourceTest.java
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRespositoryConnectorReadableTest.java
Log:
DNA-624 Canonicalize Property Names/Behavior in SVN Connector
Applied patch that changes the name of setDirectoryOfDefaultWorkspace to setDefaultWorkspaceName and changes the behavior of the workspace names as described in the issue description.
Modified: trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/svn/SvnAndJcrIntegrationTest.java
===================================================================
--- trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/svn/SvnAndJcrIntegrationTest.java 2010-01-06 01:14:23 UTC (rev 1533)
+++ trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/svn/SvnAndJcrIntegrationTest.java 2010-01-06 18:43:36 UTC (rev 1534)
@@ -51,7 +51,7 @@
@Before
public void beforeEach() throws Exception {
final String repositoryUrl = "http://anonsvn.jboss.org/repos/dna/";
- final String[] predefinedWorkspaceNames = {repositoryUrl + "trunk", repositoryUrl + "tags", repositoryUrl + "branches"};
+ final String[] predefinedWorkspaceNames = {"trunk", "tags", "branches"};
final String svnRepositorySource = "svnRepositorySource";
final String repositoryName = "svnRepository";
final JcrConfiguration configuration = new JcrConfiguration();
@@ -61,7 +61,8 @@
.setProperty("username", "anonymous")
.setProperty("repositoryRootUrl", repositoryUrl)
.setProperty("predefinedWorkspaceNames", predefinedWorkspaceNames)
- .setProperty("directoryForDefaultWorkspace", predefinedWorkspaceNames[0])
+.setProperty("defaultWorkspaceName",
+ predefinedWorkspaceNames[0])
.setProperty("creatingWorkspacesAllowed", false);
configuration.repository(repositoryName).setSource(svnRepositorySource).setOption(Option.QUERY_EXECUTION_ENABLED, "false");
Modified: trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepository.java
===================================================================
--- trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepository.java 2010-01-06 01:14:23 UTC (rev 1533)
+++ trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepository.java 2010-01-06 18:43:36 UTC (rev 1534)
@@ -50,13 +50,11 @@
import org.tmatesoft.svn.core.SVNNodeKind;
import org.tmatesoft.svn.core.SVNProperties;
import org.tmatesoft.svn.core.SVNProperty;
-import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
import org.tmatesoft.svn.core.io.SVNRepository;
-import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.wc.SVNWCUtil;
public class SvnRepository extends WritablePathRepository {
@@ -89,7 +87,7 @@
doCreateWorkspace(context, workspaceName);
}
- String defaultWorkspaceName = source.getDirectoryForDefaultWorkspace();
+ String defaultWorkspaceName = source.getDefaultWorkspaceName();
if (defaultWorkspaceName != null && !workspaces.containsKey(defaultWorkspaceName)) {
doCreateWorkspace(context, defaultWorkspaceName);
}
@@ -161,15 +159,11 @@
UUID rootNodeUuid ) {
super(name, rootNodeUuid);
- try {
- workspaceRoot = SVNRepositoryFactory.create(SVNURL.parseURIDecoded(name));
+ workspaceRoot = getWorkspaceDirectory(name);
- ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(source.getUsername(),
- source.getPassword());
- workspaceRoot.setAuthenticationManager(authManager);
- } catch (SVNException ex) {
- throw new IllegalStateException(ex);
- }
+ ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(source.getUsername(),
+ source.getPassword());
+ workspaceRoot.setAuthenticationManager(authManager);
}
public Path getLowestExistingPath( Path path ) {
@@ -845,7 +839,10 @@
}
protected SVNRepository getWorkspaceDirectory( String workspaceName ) {
- if (workspaceName == null) workspaceName = source.getDirectoryForDefaultWorkspace();
+ if (workspaceName == null) workspaceName = source.getDefaultWorkspaceName();
+
+ workspaceName = source.getRepositoryRootUrl() + workspaceName;
+
SVNRepository repository = null;
SVNRepository repos = SvnRepositoryUtil.createRepository(workspaceName, source.getUsername(), source.getPassword());
if (SvnRepositoryUtil.isDirectory(repos, "")) {
Modified: trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepositorySource.java
===================================================================
--- trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepositorySource.java 2010-01-06 01:14:23 UTC (rev 1533)
+++ trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepositorySource.java 2010-01-06 18:43:36 UTC (rev 1534)
@@ -168,30 +168,28 @@
}
/**
- * Get the file system path to the existing directory that should be used for the default workspace. If the default is
- * specified as a null String or is not a valid and resolvable path, this source will consider the default to be the current
- * working directory of this virtual machine, as defined by the <code>new File(".")</code>.
+ * Get the path to the existing directory that should be used for the default workspace. This path should be relative to the
+ * {@link #getRepositoryRootUrl() repository root URL}. If the default is specified as a null String or is not a valid and
+ * resolvable path, this source will consider the default to be the current working directory of this virtual machine, as
+ * defined by the <code>new File(".")</code>.
*
* @return the file system path to the directory representing the default workspace, or null if the default should be the
* current working directory
*/
- public String getDirectoryForDefaultWorkspace() {
- return defaultWorkspace;
- }
-
public String getDefaultWorkspaceName() {
return defaultWorkspace;
}
/**
- * Set the file system path to the existing directory that should be used for the default workspace. If the default is
- * specified as a null String or is not a valid and resolvable path, this source will consider the default to be the current
- * working directory of this virtual machine, as defined by the <code>new File(".")</code>.
+ * Set the file system path to the existing directory that should be used for the default workspace. This path should be
+ * relative to the {@link #getRepositoryRootUrl() repository root URL}. If the default is specified as a null String or is not
+ * a valid and resolvable path, this source will consider the default to be the current working directory of this virtual
+ * machine, as defined by the <code>new File(".")</code>.
*
* @param pathToDirectoryForDefaultWorkspace the valid and resolvable file system path to the directory representing the
* default workspace, or null if the current working directory should be used as the default workspace
*/
- public synchronized void setDirectoryForDefaultWorkspace( String pathToDirectoryForDefaultWorkspace ) {
+ public synchronized void setDefaultWorkspaceName( String pathToDirectoryForDefaultWorkspace ) {
this.defaultWorkspace = pathToDirectoryForDefaultWorkspace;
}
@@ -315,7 +313,7 @@
}
ref.add(new StringRefAddr(RETRY_LIMIT, Integer.toString(getRetryLimit())));
ref.add(new StringRefAddr(ROOT_NODE_UUID, rootNodeUuid.toString()));
- ref.add(new StringRefAddr(DEFAULT_WORKSPACE, getDirectoryForDefaultWorkspace()));
+ ref.add(new StringRefAddr(DEFAULT_WORKSPACE, getDefaultWorkspaceName()));
ref.add(new StringRefAddr(ALLOW_CREATING_WORKSPACES, Boolean.toString(isCreatingWorkspacesAllowed())));
String[] workspaceNames = getPredefinedWorkspaceNames();
if (workspaceNames != null && workspaceNames.length != 0) {
@@ -362,7 +360,7 @@
if (password != null) source.setPassword(password);
if (retryLimit != null) source.setRetryLimit(Integer.parseInt(retryLimit));
if (rootNodeUuid != null) source.setRootNodeUuid(rootNodeUuid);
- if (defaultWorkspace != null) source.setDirectoryForDefaultWorkspace(defaultWorkspace);
+ if (defaultWorkspace != null) source.setDefaultWorkspaceName(defaultWorkspace);
if (createWorkspaces != null) source.setCreatingWorkspacesAllowed(Boolean.parseBoolean(createWorkspaces));
if (workspaceNames != null && workspaceNames.length != 0) source.setPredefinedWorkspaceNames(workspaceNames);
return source;
Modified: trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnIntegrationTest.java
===================================================================
--- trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnIntegrationTest.java 2010-01-06 01:14:23 UTC (rev 1533)
+++ trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnIntegrationTest.java 2010-01-06 18:43:36 UTC (rev 1534)
@@ -27,7 +27,6 @@
import static org.hamcrest.core.IsNull.notNullValue;
import static org.junit.Assert.assertThat;
import java.util.Map;
-import org.jboss.dna.connector.svn.SvnRepositorySource;
import org.jboss.dna.graph.ExecutionContext;
import org.jboss.dna.graph.Graph;
import org.jboss.dna.graph.Location;
@@ -53,7 +52,7 @@
@Before
public void beforeEach() {
repositoryUrl = "http://anonsvn.jboss.org/repos/dna/";
- predefinedWorkspaceNames = new String[] {repositoryUrl + "trunk", repositoryUrl + "tags", repositoryUrl + "branches"};
+ predefinedWorkspaceNames = new String[] {"trunk", "tags", "branches"};
context = new ExecutionContext();
source = new SvnRepositorySource();
source.setName("svn repository source");
@@ -62,7 +61,7 @@
source.setPassword("");
source.setCreatingWorkspacesAllowed(true);
source.setPredefinedWorkspaceNames(predefinedWorkspaceNames);
- source.setDirectoryForDefaultWorkspace(predefinedWorkspaceNames[0]);
+ source.setDefaultWorkspaceName(predefinedWorkspaceNames[0]);
source.setCreatingWorkspacesAllowed(false);
source.initialize(new RepositoryContext() {
Modified: trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositoryConnectorNoCreateWorkspaceTest.java
===================================================================
--- trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositoryConnectorNoCreateWorkspaceTest.java 2010-01-06 01:14:23 UTC (rev 1533)
+++ trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositoryConnectorNoCreateWorkspaceTest.java 2010-01-06 18:43:36 UTC (rev 1534)
@@ -1,6 +1,5 @@
package org.jboss.dna.connector.svn;
-import org.jboss.dna.connector.svn.SvnRepositorySource;
import org.jboss.dna.graph.Graph;
import org.jboss.dna.graph.connector.RepositorySource;
import org.jboss.dna.graph.connector.test.WorkspaceConnectorTest;
@@ -23,14 +22,14 @@
*/
@Override
protected RepositorySource setUpSource() throws Exception {
- String[] predefinedWorkspaceNames = new String[] {url + "trunk", url + "tags"};
+ String[] predefinedWorkspaceNames = new String[] {"trunk", "tags"};
SvnRepositorySource source = new SvnRepositorySource();
source.setName("Test Repository");
source.setUsername("sp");
source.setPassword("");
source.setRepositoryRootUrl(url);
source.setPredefinedWorkspaceNames(predefinedWorkspaceNames);
- source.setDirectoryForDefaultWorkspace(predefinedWorkspaceNames[0]);
+ source.setDefaultWorkspaceName(predefinedWorkspaceNames[0]);
source.setCreatingWorkspacesAllowed(false);
return source;
Modified: trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositoryConnectorNotWritableTest.java
===================================================================
--- trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositoryConnectorNotWritableTest.java 2010-01-06 01:14:23 UTC (rev 1533)
+++ trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositoryConnectorNotWritableTest.java 2010-01-06 18:43:36 UTC (rev 1534)
@@ -1,6 +1,5 @@
package org.jboss.dna.connector.svn;
-import org.jboss.dna.connector.svn.SvnRepositorySource;
import org.jboss.dna.graph.Graph;
import org.jboss.dna.graph.connector.RepositorySource;
import org.jboss.dna.graph.connector.test.NotWritableConnectorTest;
@@ -23,14 +22,14 @@
*/
@Override
protected RepositorySource setUpSource() throws Exception {
- String[] predefinedWorkspaceNames = new String[]{url+"trunk", url+"tags"};
+ String[] predefinedWorkspaceNames = new String[] {"trunk", "tags"};
SvnRepositorySource source = new SvnRepositorySource();
source.setName("Test Repository");
source.setUsername("sp");
source.setPassword("");
source.setRepositoryRootUrl(url);
source.setPredefinedWorkspaceNames(predefinedWorkspaceNames);
- source.setDirectoryForDefaultWorkspace(predefinedWorkspaceNames[0]);
+ source.setDefaultWorkspaceName(predefinedWorkspaceNames[0]);
source.setCreatingWorkspacesAllowed(false);
return source;
Modified: trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositoryConnectorWritableTest.java
===================================================================
--- trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositoryConnectorWritableTest.java 2010-01-06 01:14:23 UTC (rev 1533)
+++ trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositoryConnectorWritableTest.java 2010-01-06 18:43:36 UTC (rev 1534)
@@ -27,7 +27,6 @@
import static org.hamcrest.core.IsNull.notNullValue;
import static org.junit.Assert.assertThat;
import java.io.ByteArrayOutputStream;
-import org.jboss.dna.connector.svn.SvnRepositorySource;
import org.jboss.dna.graph.DnaLexicon;
import org.jboss.dna.graph.Graph;
import org.jboss.dna.graph.JcrLexicon;
@@ -63,14 +62,14 @@
@Override
protected RepositorySource setUpSource() throws Exception {
url = SvnConnectorTestUtil.createURL("src/test/resources/dummy_svn_repos", "target/copy_of dummy_svn_repos");
- String[] predefinedWorkspaceNames = new String[] {url + "trunk", url + "tags"};
+ String[] predefinedWorkspaceNames = new String[] {"trunk", "tags"};
SvnRepositorySource source = new SvnRepositorySource();
source.setName("Test Repository");
source.setUsername("sp");
source.setPassword("");
source.setRepositoryRootUrl(url);
source.setPredefinedWorkspaceNames(predefinedWorkspaceNames);
- source.setDirectoryForDefaultWorkspace(predefinedWorkspaceNames[0]);
+ source.setDefaultWorkspaceName(predefinedWorkspaceNames[0]);
source.setCreatingWorkspacesAllowed(Boolean.TRUE);
source.setUpdatesAllowed(true);
Modified: trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositorySourceTest.java
===================================================================
--- trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositorySourceTest.java 2010-01-06 01:14:23 UTC (rev 1533)
+++ trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositorySourceTest.java 2010-01-06 18:43:36 UTC (rev 1534)
@@ -265,7 +265,7 @@
assertThat((String)refAttributes.remove(SvnRepositorySource.ALLOW_CREATING_WORKSPACES),
is(Boolean.toString(source.isCreatingWorkspacesAllowed())));
assertThat((String)refAttributes.remove(SvnRepositorySource.DEFAULT_WORKSPACE),
- is(source.getDirectoryForDefaultWorkspace()));
+ is(source.getDefaultWorkspaceName()));
refAttributes.remove(SvnRepositorySource.PREDEFINED_WORKSPACE_NAMES);
assertThat(refAttributes.isEmpty(), is(true));
Modified: trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRespositoryConnectorReadableTest.java
===================================================================
--- trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRespositoryConnectorReadableTest.java 2010-01-06 01:14:23 UTC (rev 1533)
+++ trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRespositoryConnectorReadableTest.java 2010-01-06 18:43:36 UTC (rev 1534)
@@ -27,7 +27,6 @@
import static org.hamcrest.core.IsNull.notNullValue;
import static org.junit.Assert.assertThat;
import java.util.List;
-import org.jboss.dna.connector.svn.SvnRepositorySource;
import org.jboss.dna.graph.Graph;
import org.jboss.dna.graph.JcrLexicon;
import org.jboss.dna.graph.JcrNtLexicon;
@@ -59,14 +58,14 @@
*/
@Override
protected RepositorySource setUpSource() throws Exception {
- String[] predefinedWorkspaceNames = new String[]{url + "trunk", url + "tags"};
+ String[] predefinedWorkspaceNames = new String[] {"trunk", "tags"};
SvnRepositorySource source = new SvnRepositorySource();
source.setName("Test Repository");
source.setUsername("sp");
source.setPassword("");
source.setRepositoryRootUrl(url);
source.setPredefinedWorkspaceNames(predefinedWorkspaceNames);
- source.setDirectoryForDefaultWorkspace(predefinedWorkspaceNames[0]);
+ source.setDefaultWorkspaceName(predefinedWorkspaceNames[0]);
source.setCreatingWorkspacesAllowed(false);
return source;
14 years, 5 months
DNA SVN: r1533 - trunk/dna-jcr/src/test/java/org/jboss/dna/jcr.
by dna-commits@lists.jboss.org
Author: bcarothers
Date: 2010-01-05 20:14:23 -0500 (Tue, 05 Jan 2010)
New Revision: 1533
Modified:
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/DnaRepositoryStub.java
Log:
Modified this file to log all runtime exceptions, including ones coming from jcrEngine.start().
Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/DnaRepositoryStub.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/DnaRepositoryStub.java 2010-01-06 00:36:37 UTC (rev 1532)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/DnaRepositoryStub.java 2010-01-06 01:14:23 UTC (rev 1533)
@@ -23,7 +23,6 @@
*/
package org.jboss.dna.jcr;
-import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import org.apache.jackrabbit.test.RepositoryStub;
@@ -33,7 +32,6 @@
import org.jboss.dna.graph.Graph;
import org.jboss.dna.graph.property.Path;
import org.jboss.security.config.IDTrustConfiguration;
-import org.xml.sax.SAXException;
/**
* Concrete implementation of {@link RepositoryStub} based on DNA-specific configuration.
@@ -42,12 +40,11 @@
public static final String DNA_SKIP_IMPORT = "javax.jcr.tck.dnaSkipImport";
public static final String DNA_NODE_TYPE_PATH = "javax.jcr.tck.dnaNodeTypePath";
-
+
private static final String REPOSITORY_SOURCE_NAME = "Test Repository Source";
private static String currentConfigurationName = "default";
-
private Properties configProps;
private String repositoryConfigurationName;
private JcrRepository repository;
@@ -93,30 +90,21 @@
configuration.repository(REPOSITORY_SOURCE_NAME).addNodeTypes(getClass().getResourceAsStream(nodeTypePath));
}
- } catch (SAXException se) {
- se.printStackTrace();
- throw new IllegalStateException(se);
- } catch (IOException ioe) {
- ioe.printStackTrace();
- throw new IllegalStateException(ioe);
- }
+ JcrEngine engine = configuration.build();
+ engine.start();
- JcrEngine engine = configuration.build();
- engine.start();
+ Problems problems = engine.getProblems();
+ // Print all of the problems from the engine configuration ...
+ for (Problem problem : problems) {
+ System.err.println(problem);
+ }
+ if (problems.hasErrors()) {
+ throw new IllegalStateException("Problems starting JCR repository");
+ }
- Problems problems = engine.getProblems();
- // Print all of the problems from the engine configuration ...
- for (Problem problem : problems) {
- System.err.println(problem);
- }
- if (problems.hasErrors()) {
- throw new IllegalStateException("Problems starting JCR repository");
- }
+ ExecutionContext executionContext = engine.getExecutionContext();
+ executionContext.getNamespaceRegistry().register(TestLexicon.Namespace.PREFIX, TestLexicon.Namespace.URI);
- ExecutionContext executionContext = engine.getExecutionContext();
- executionContext.getNamespaceRegistry().register(TestLexicon.Namespace.PREFIX, TestLexicon.Namespace.URI);
-
- try {
repository = engine.getRepository(REPOSITORY_SOURCE_NAME);
// This needs to check configProps directly to avoid an infinite loop
14 years, 5 months