You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rya.apache.org by ca...@apache.org on 2017/08/23 15:47:08 UTC

[3/3] incubator-rya git commit: RYA-292 Added owl:intersectionOf inference. Closes #206.

RYA-292 Added owl:intersectionOf inference. Closes #206.


Project: http://git-wip-us.apache.org/repos/asf/incubator-rya/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rya/commit/e9488ff6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rya/tree/e9488ff6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rya/diff/e9488ff6

Branch: refs/heads/master
Commit: e9488ff69f1a88300060c4010956403605cabd66
Parents: 1efa100
Author: eric.white <Er...@parsons.com>
Authored: Wed Aug 2 17:52:10 2017 -0400
Committer: Caleb Meier <ca...@parsons.com>
Committed: Wed Aug 23 08:45:57 2017 -0700

----------------------------------------------------------------------
 .../api/RdfCloudTripleStoreConfiguration.java   | 155 ++--
 .../api/persist/utils/RyaDaoQueryWrapper.java   | 185 ++++
 .../src/main/java/MongoRyaDirectExample.java    | 538 ++++++-----
 .../RdfCloudTripleStoreConnection.java          |  33 +-
 .../evaluation/FilterRangeVisitor.java          |  63 +-
 .../evaluation/PushJoinDownVisitor.java         |  24 +-
 .../evaluation/ReorderJoinVisitor.java          |  24 +-
 .../evaluation/SeparateFilterJoinsVisitor.java  |  31 +-
 .../inference/InferenceEngine.java              | 883 ++++++++++++-------
 .../inference/InferenceEngineException.java     |  12 +-
 .../inference/IntersectionOfVisitor.java        | 210 +++++
 .../rdftriplestore/inference/InverseURI.java    |  94 +-
 .../inference/PropertyChainVisitor.java         | 114 ++-
 .../inference/SubClassOfVisitor.java            |  33 +-
 .../inference/SubPropertyOfVisitor.java         |  37 +-
 .../inference/TransitivePropertyVisitor.java    |  22 +-
 .../utils/FixedStatementPattern.java            |  23 +-
 .../inference/InferenceEngineTest.java          | 225 +++--
 .../rdftriplestore/inference/InferenceIT.java   | 105 ++-
 .../inference/IntersectionOfVisitorTest.java    | 235 +++++
 20 files changed, 2068 insertions(+), 978 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/e9488ff6/common/rya.api/src/main/java/org/apache/rya/api/RdfCloudTripleStoreConfiguration.java
----------------------------------------------------------------------
diff --git a/common/rya.api/src/main/java/org/apache/rya/api/RdfCloudTripleStoreConfiguration.java b/common/rya.api/src/main/java/org/apache/rya/api/RdfCloudTripleStoreConfiguration.java
index c72b85a..ee91e6b 100644
--- a/common/rya.api/src/main/java/org/apache/rya/api/RdfCloudTripleStoreConfiguration.java
+++ b/common/rya.api/src/main/java/org/apache/rya/api/RdfCloudTripleStoreConfiguration.java
@@ -26,12 +26,11 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
+import org.apache.hadoop.conf.Configuration;
 import org.apache.rya.api.domain.RyaURI;
 import org.apache.rya.api.layout.TableLayoutStrategy;
 import org.apache.rya.api.layout.TablePrefixLayoutStrategy;
 import org.apache.rya.api.persist.RdfEvalStatsDAO;
-
-import org.apache.hadoop.conf.Configuration;
 import org.openrdf.query.algebra.evaluation.QueryOptimizer;
 
 import com.google.common.base.Joiner;
@@ -59,7 +58,7 @@ public abstract class RdfCloudTripleStoreConfiguration extends Configuration {
     public static final String CONF_LIMIT = "query.limit";
     public static final String CONF_QUERYPLAN_FLAG = "query.printqueryplan";
     public static final String CONF_QUERY_AUTH = "query.auth";
-	public static final String CONF_RESULT_FORMAT = "query.resultformat";
+    public static final String CONF_RESULT_FORMAT = "query.resultformat";
     public static final String CONF_CV = "conf.cv";
     public static final String CONF_TBL_SPO = "tbl.spo";
     public static final String CONF_TBL_PO = "tbl.po";
@@ -73,6 +72,7 @@ public abstract class RdfCloudTripleStoreConfiguration extends Configuration {
     public static final String CONF_STATEMENT_METADATA_PROPERTIES = "statement.metadata.properites";
     public static final String CONF_USE_STATEMENT_METADATA = "use.statement.metadata";
     public static final String STATS_PUSH_EMPTY_RDFTYPE_DOWN = "conf.stats.rdftype.down";
+    public static final String INFER_INCLUDE_INTERSECTION_OF = "infer.include.intersectionof";
     public static final String INFER_INCLUDE_INVERSEOF = "infer.include.inverseof";
     public static final String INFER_INCLUDE_SUBCLASSOF = "infer.include.subclassof";
     public static final String INFER_INCLUDE_SUBPROPOF = "infer.include.subpropof";
@@ -92,7 +92,7 @@ public abstract class RdfCloudTripleStoreConfiguration extends Configuration {
     public RdfCloudTripleStoreConfiguration() {
     }
 
-    public RdfCloudTripleStoreConfiguration(Configuration other) {
+    public RdfCloudTripleStoreConfiguration(final Configuration other) {
         super(other);
         if (other instanceof RdfCloudTripleStoreConfiguration) {
             setTableLayoutStrategy(((RdfCloudTripleStoreConfiguration) other).getTableLayoutStrategy());
@@ -100,13 +100,13 @@ public abstract class RdfCloudTripleStoreConfiguration extends Configuration {
     }
 
     @Override
-	public abstract RdfCloudTripleStoreConfiguration clone();
+    public abstract RdfCloudTripleStoreConfiguration clone();
 
     public TableLayoutStrategy getTableLayoutStrategy() {
         return tableLayoutStrategy;
     }
 
-    public void setTableLayoutStrategy(TableLayoutStrategy tableLayoutStrategy) {
+    public void setTableLayoutStrategy(final TableLayoutStrategy tableLayoutStrategy) {
         if (tableLayoutStrategy != null) {
             this.tableLayoutStrategy = tableLayoutStrategy;
         } else {
@@ -120,28 +120,28 @@ public abstract class RdfCloudTripleStoreConfiguration extends Configuration {
     }
 
     public Long getTtl() {
-        String val = get(CONF_TTL);
+        final String val = get(CONF_TTL);
         if (val != null) {
             return Long.valueOf(val);
         }
         return null;
     }
 
-    public void setTtl(Long ttl) {
+    public void setTtl(final Long ttl) {
         Preconditions.checkNotNull(ttl);
         Preconditions.checkArgument(ttl >= 0, "ttl must be non negative");
         set(CONF_TTL, ttl.toString());
     }
 
     public Long getStartTime() {
-        String val = get(CONF_STARTTIME);
+        final String val = get(CONF_STARTTIME);
         if (val != null) {
             return Long.valueOf(val);
         }
         return null;
     }
 
-    public void setStartTime(Long startTime) {
+    public void setStartTime(final Long startTime) {
         Preconditions.checkNotNull(startTime);
         Preconditions.checkArgument(startTime >= 0, "startTime must be non negative");
         set(CONF_STARTTIME, startTime.toString());
@@ -151,7 +151,7 @@ public abstract class RdfCloudTripleStoreConfiguration extends Configuration {
         return getInt(CONF_NUM_THREADS, 2);
     }
 
-    public void setNumThreads(Integer numThreads) {
+    public void setNumThreads(final Integer numThreads) {
         Preconditions.checkNotNull(numThreads);
         Preconditions.checkArgument(numThreads > 0, "numThreads must be greater than 0");
         setInt(CONF_NUM_THREADS, numThreads);
@@ -161,7 +161,7 @@ public abstract class RdfCloudTripleStoreConfiguration extends Configuration {
         return getBoolean(CONF_PERFORMANT, true);
     }
 
-    public void setPerformant(Boolean val) {
+    public void setPerformant(final Boolean val) {
         Preconditions.checkNotNull(val);
         setBoolean(CONF_PERFORMANT, val);
     }
@@ -170,7 +170,7 @@ public abstract class RdfCloudTripleStoreConfiguration extends Configuration {
         return getBoolean(CONF_INFER, false);
     }
 
-    public void setInfer(Boolean val) {
+    public void setInfer(final Boolean val) {
         Preconditions.checkNotNull(val);
         setBoolean(CONF_INFER, val);
     }
@@ -179,7 +179,7 @@ public abstract class RdfCloudTripleStoreConfiguration extends Configuration {
         return getBoolean(CONF_USE_STATS, false);
     }
 
-    public void setUseStats(Boolean val) {
+    public void setUseStats(final Boolean val) {
         Preconditions.checkNotNull(val);
         setBoolean(CONF_USE_STATS, val);
     }
@@ -188,7 +188,7 @@ public abstract class RdfCloudTripleStoreConfiguration extends Configuration {
         return getBoolean(CONF_USE_SELECTIVITY, false);
     }
 
-    public void setUseSelectivity(Boolean val) {
+    public void setUseSelectivity(final Boolean val) {
         Preconditions.checkNotNull(val);
         setBoolean(CONF_USE_SELECTIVITY, val);
     }
@@ -197,7 +197,7 @@ public abstract class RdfCloudTripleStoreConfiguration extends Configuration {
         return getBoolean(CONF_PREFIX_ROW_WITH_HASH, false);
     }
 
-    public void setPrefixRowsWithHash(Boolean val) {
+    public void setPrefixRowsWithHash(final Boolean val) {
         Preconditions.checkNotNull(val);
         setBoolean(CONF_PREFIX_ROW_WITH_HASH, val);
     }
@@ -206,49 +206,49 @@ public abstract class RdfCloudTripleStoreConfiguration extends Configuration {
         return get(CONF_TBL_PREFIX, RdfCloudTripleStoreConstants.TBL_PRFX_DEF);
     }
 
-    public void setTablePrefix(String tablePrefix) {
+    public void setTablePrefix(final String tablePrefix) {
         Preconditions.checkNotNull(tablePrefix);
         set(CONF_TBL_PREFIX, tablePrefix);
         setTableLayoutStrategy(new TablePrefixLayoutStrategy(tablePrefix)); //TODO: Should we change the layout strategy
     }
 
     public Integer getBatchSize() {
-        String val = get(CONF_BATCH_SIZE);
+        final String val = get(CONF_BATCH_SIZE);
         if (val != null) {
             return Integer.valueOf(val);
         }
         return null;
     }
 
-    public void setBatchSize(Long batchSize) {
+    public void setBatchSize(final Long batchSize) {
         Preconditions.checkNotNull(batchSize);
         Preconditions.checkArgument(batchSize > 0, "Batch Size must be greater than 0");
         setLong(CONF_BATCH_SIZE, batchSize);
     }
 
     public Long getOffset() {
-        String val = get(CONF_OFFSET);
+        final String val = get(CONF_OFFSET);
         if (val != null) {
             return Long.valueOf(val);
         }
         return null;
     }
 
-    public void setOffset(Long offset) {
+    public void setOffset(final Long offset) {
         Preconditions.checkNotNull(offset);
         Preconditions.checkArgument(offset >= 0, "offset must be positive");
         setLong(CONF_OFFSET, offset);
     }
 
     public Long getLimit() {
-        String val = get(CONF_LIMIT);
+        final String val = get(CONF_LIMIT);
         if (val != null) {
             return Long.valueOf(val);
         }
         return null;
     }
 
-    public void setLimit(Long limit) {
+    public void setLimit(final Long limit) {
         Preconditions.checkNotNull(limit);
         Preconditions.checkArgument(limit >= 0, "limit must be positive");
         setLong(CONF_LIMIT, limit);
@@ -259,7 +259,7 @@ public abstract class RdfCloudTripleStoreConfiguration extends Configuration {
         return getBoolean(CONF_QUERYPLAN_FLAG, false);
     }
 
-    public void setDisplayQueryPlan(Boolean val) {
+    public void setDisplayQueryPlan(final Boolean val) {
         Preconditions.checkNotNull(val);
         setBoolean(CONF_QUERYPLAN_FLAG, val);
     }
@@ -269,7 +269,7 @@ public abstract class RdfCloudTripleStoreConfiguration extends Configuration {
      * @deprecated
      */
     @Deprecated
-	public String getAuth() {
+    public String getAuth() {
         return Joiner.on(",").join(getAuths());
     }
 
@@ -278,7 +278,7 @@ public abstract class RdfCloudTripleStoreConfiguration extends Configuration {
      * @deprecated
      */
     @Deprecated
-	public void setAuth(String auth) {
+    public void setAuth(final String auth) {
         Preconditions.checkNotNull(auth);
         setStrings(CONF_QUERY_AUTH, auth);
     }
@@ -287,25 +287,25 @@ public abstract class RdfCloudTripleStoreConfiguration extends Configuration {
         return getStrings(CONF_QUERY_AUTH, EMPTY_STR_ARR);
     }
 
-    public void setAuths(String... auths) {
+    public void setAuths(final String... auths) {
         Preconditions.checkNotNull(auths);
         setStrings(CONF_QUERY_AUTH, auths);
     }
 
-	public String getEmit() {
-		return get(CONF_RESULT_FORMAT);
+    public String getEmit() {
+        return get(CONF_RESULT_FORMAT);
     }
 
-    public void setEmit(String emit) {
-		Preconditions.checkNotNull(emit);
-		set(CONF_RESULT_FORMAT, emit);
+    public void setEmit(final String emit) {
+        Preconditions.checkNotNull(emit);
+        set(CONF_RESULT_FORMAT, emit);
     }
 
     public String getCv() {
         return get(CONF_CV);
     }
 
-    public void setCv(String cv) {
+    public void setCv(final String cv) {
         Preconditions.checkNotNull(cv);
         set(CONF_CV, cv);
     }
@@ -315,7 +315,7 @@ public abstract class RdfCloudTripleStoreConfiguration extends Configuration {
         return getBoolean(CONF_USE_COMPOSITE, true);
     }
 
-    public void setCompositeCardinality(Boolean val) {
+    public void setCompositeCardinality(final Boolean val) {
         Preconditions.checkNotNull(val);
         setBoolean(CONF_USE_COMPOSITE, val);
     }
@@ -325,16 +325,35 @@ public abstract class RdfCloudTripleStoreConfiguration extends Configuration {
         return getBoolean(STATS_PUSH_EMPTY_RDFTYPE_DOWN, true);
     }
 
-    public void setStatsPushEmptyRdftypeDown(Boolean val) {
+    public void setStatsPushEmptyRdftypeDown(final Boolean val) {
         Preconditions.checkNotNull(val);
         setBoolean(STATS_PUSH_EMPTY_RDFTYPE_DOWN, val);
     }
 
+    /**
+     * @return {@code true} if owl:intersectionOf inferencing is enabled.
+     * {@code false} otherwise. Defaults to {@code true} if nothing is
+     * specified.
+     */
+    public Boolean isInferIntersectionOf() {
+        return getBoolean(INFER_INCLUDE_INTERSECTION_OF, true);
+    }
+
+    /**
+     * Sets whether owl:intersectionOf inferencing is enabled or disabled.
+     * @param value {@code true} if owl:intersectionOf inferencing is enabled.
+     * {@code false} otherwise.
+     */
+    public void setInferIntersectionOf(final Boolean value) {
+        Preconditions.checkNotNull(value);
+        setBoolean(INFER_INCLUDE_INTERSECTION_OF, value);
+    }
+
     public Boolean isInferInverseOf() {
         return getBoolean(INFER_INCLUDE_INVERSEOF, true);
     }
 
-    public void setInferInverseOf(Boolean val) {
+    public void setInferInverseOf(final Boolean val) {
         Preconditions.checkNotNull(val);
         setBoolean(INFER_INCLUDE_INVERSEOF, val);
     }
@@ -343,7 +362,7 @@ public abstract class RdfCloudTripleStoreConfiguration extends Configuration {
         return getBoolean(INFER_INCLUDE_SUBCLASSOF, true);
     }
 
-    public void setInferSubClassOf(Boolean val) {
+    public void setInferSubClassOf(final Boolean val) {
         Preconditions.checkNotNull(val);
         setBoolean(INFER_INCLUDE_SUBCLASSOF, val);
     }
@@ -352,7 +371,7 @@ public abstract class RdfCloudTripleStoreConfiguration extends Configuration {
         return getBoolean(INFER_INCLUDE_SUBPROPOF, true);
     }
 
-    public void setInferSubPropertyOf(Boolean val) {
+    public void setInferSubPropertyOf(final Boolean val) {
         Preconditions.checkNotNull(val);
         setBoolean(INFER_INCLUDE_SUBPROPOF, val);
     }
@@ -361,7 +380,7 @@ public abstract class RdfCloudTripleStoreConfiguration extends Configuration {
         return getBoolean(INFER_INCLUDE_SYMMPROP, true);
     }
 
-    public void setInferSymmetricProperty(Boolean val) {
+    public void setInferSymmetricProperty(final Boolean val) {
         Preconditions.checkNotNull(val);
         setBoolean(INFER_INCLUDE_SYMMPROP, val);
     }
@@ -370,12 +389,12 @@ public abstract class RdfCloudTripleStoreConfiguration extends Configuration {
         return getBoolean(INFER_INCLUDE_TRANSITIVEPROP, true);
     }
 
-    public void setInferTransitiveProperty(Boolean val) {
+    public void setInferTransitiveProperty(final Boolean val) {
         Preconditions.checkNotNull(val);
         setBoolean(INFER_INCLUDE_TRANSITIVEPROP, val);
     }
 
-    public void setRdfEvalStatsDaoClass(Class<? extends RdfEvalStatsDAO> rdfEvalStatsDaoClass) {
+    public void setRdfEvalStatsDaoClass(final Class<? extends RdfEvalStatsDAO> rdfEvalStatsDaoClass) {
         Preconditions.checkNotNull(rdfEvalStatsDaoClass);
         setClass(RDF_EVAL_STATS_DAO_CLASS, rdfEvalStatsDaoClass, RdfEvalStatsDAO.class);
     }
@@ -385,50 +404,50 @@ public abstract class RdfCloudTripleStoreConfiguration extends Configuration {
     }
 
 
-    public void setPcjTables(List<String> indexTables) {
+    public void setPcjTables(final List<String> indexTables) {
         Preconditions.checkNotNull(indexTables);
         setStrings(CONF_PCJ_TABLES, indexTables.toArray(new String[]{}));
     }
 
 
     public List<String> getPcjTables() {
-        List<String> pcjTables = Lists.newArrayList();
-        String[] tables = getStrings(CONF_PCJ_TABLES);
+        final List<String> pcjTables = Lists.newArrayList();
+        final String[] tables = getStrings(CONF_PCJ_TABLES);
         if(tables == null) {
             return pcjTables;
         }
-        for(String table: tables) {
+        for(final String table: tables) {
             Preconditions.checkNotNull(table);
             pcjTables.add(table);
         }
         return pcjTables;
     }
-    
-    public void setUseStatementMetadata(boolean useMetadata) {
+
+    public void setUseStatementMetadata(final boolean useMetadata) {
         setBoolean(CONF_USE_STATEMENT_METADATA, useMetadata);
     }
-    
+
     public boolean getUseStatementMetadata() {
         return getBoolean(CONF_USE_STATEMENT_METADATA, false);
     }
-    
-    public void setStatementMetadataProperties(Set<RyaURI> metadataProperties) {
-        
-        String[] propArray = new String[metadataProperties.size()];
+
+    public void setStatementMetadataProperties(final Set<RyaURI> metadataProperties) {
+
+        final String[] propArray = new String[metadataProperties.size()];
         int i = 0;
-        for(RyaURI uri: metadataProperties) {
+        for(final RyaURI uri: metadataProperties) {
             propArray[i] = uri.getData();
             i++;
         }
         setStrings(CONF_STATEMENT_METADATA_PROPERTIES, propArray);
     }
-    
-    
+
+
     public Set<RyaURI> getStatementMetadataProperties() {
-        Set<RyaURI> uriSet = new HashSet<>();
-        String[] uriStrings = getStrings(CONF_STATEMENT_METADATA_PROPERTIES);
+        final Set<RyaURI> uriSet = new HashSet<>();
+        final String[] uriStrings = getStrings(CONF_STATEMENT_METADATA_PROPERTIES);
         if (uriStrings != null) {
-            for (String s : uriStrings) {
+            for (final String s : uriStrings) {
                 uriSet.add(new RyaURI(s));
             }
         }
@@ -436,13 +455,13 @@ public abstract class RdfCloudTripleStoreConfiguration extends Configuration {
     }
 
 
-    public void setPcjOptimizer(Class<? extends QueryOptimizer> optimizer) {
+    public void setPcjOptimizer(final Class<? extends QueryOptimizer> optimizer) {
         Preconditions.checkNotNull(optimizer);
         setClass(CONF_PCJ_OPTIMIZER, optimizer, QueryOptimizer.class);
     }
 
     public Class<QueryOptimizer> getPcjOptimizer() {
-        Class<? extends QueryOptimizer> opt = getClass(CONF_PCJ_OPTIMIZER, null, QueryOptimizer.class);
+        final Class<? extends QueryOptimizer> opt = getClass(CONF_PCJ_OPTIMIZER, null, QueryOptimizer.class);
         if (opt != null) {
             Preconditions.checkArgument(QueryOptimizer.class.isAssignableFrom(opt));
             return (Class<QueryOptimizer>) opt;
@@ -452,10 +471,10 @@ public abstract class RdfCloudTripleStoreConfiguration extends Configuration {
     }
 
 
-    public void setOptimizers(List<Class<? extends QueryOptimizer>> optimizers) {
+    public void setOptimizers(final List<Class<? extends QueryOptimizer>> optimizers) {
         Preconditions.checkNotNull(optimizers);
-        List<String> strs = Lists.newArrayList();
-        for (Class ai : optimizers){
+        final List<String> strs = Lists.newArrayList();
+        for (final Class ai : optimizers){
             Preconditions.checkNotNull(ai);
             strs.add(ai.getName());
         }
@@ -464,8 +483,8 @@ public abstract class RdfCloudTripleStoreConfiguration extends Configuration {
     }
 
     public List<Class<QueryOptimizer>> getOptimizers() {
-        List<Class<QueryOptimizer>> opts = Lists.newArrayList();
-        for (Class<?> clazz : getClasses(CONF_OPTIMIZERS)){
+        final List<Class<QueryOptimizer>> opts = Lists.newArrayList();
+        for (final Class<?> clazz : getClasses(CONF_OPTIMIZERS)){
             Preconditions.checkArgument(QueryOptimizer.class.isAssignableFrom(clazz));
             opts.add((Class<QueryOptimizer>) clazz);
         }
@@ -479,7 +498,7 @@ public abstract class RdfCloudTripleStoreConfiguration extends Configuration {
         return get(REGEX_SUBJECT);
     }
 
-    public void setRegexSubject(String regexSubject) {
+    public void setRegexSubject(final String regexSubject) {
         Preconditions.checkNotNull(regexSubject);
         set(REGEX_SUBJECT, regexSubject);
     }
@@ -488,7 +507,7 @@ public abstract class RdfCloudTripleStoreConfiguration extends Configuration {
         return get(REGEX_PREDICATE);
     }
 
-    public void setRegexPredicate(String regex) {
+    public void setRegexPredicate(final String regex) {
         Preconditions.checkNotNull(regex);
         set(REGEX_PREDICATE, regex);
     }
@@ -497,7 +516,7 @@ public abstract class RdfCloudTripleStoreConfiguration extends Configuration {
         return get(REGEX_OBJECT);
     }
 
-    public void setRegexObject(String regex) {
+    public void setRegexObject(final String regex) {
         Preconditions.checkNotNull(regex);
         set(REGEX_OBJECT, regex);
     }

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/e9488ff6/common/rya.api/src/main/java/org/apache/rya/api/persist/utils/RyaDaoQueryWrapper.java
----------------------------------------------------------------------
diff --git a/common/rya.api/src/main/java/org/apache/rya/api/persist/utils/RyaDaoQueryWrapper.java b/common/rya.api/src/main/java/org/apache/rya/api/persist/utils/RyaDaoQueryWrapper.java
new file mode 100644
index 0000000..af7af8a
--- /dev/null
+++ b/common/rya.api/src/main/java/org/apache/rya/api/persist/utils/RyaDaoQueryWrapper.java
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.rya.api.persist.utils;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.apache.rya.api.RdfCloudTripleStoreConfiguration;
+import org.apache.rya.api.domain.RyaStatement;
+import org.apache.rya.api.persist.RyaDAO;
+import org.apache.rya.api.resolver.RyaToRdfConversions;
+import org.openrdf.model.Resource;
+import org.openrdf.model.Statement;
+import org.openrdf.model.URI;
+import org.openrdf.model.Value;
+import org.openrdf.query.QueryEvaluationException;
+import org.openrdf.rio.RDFHandler;
+
+import info.aduna.iteration.CloseableIteration;
+
+/**
+ * Wraps Rya DAO queries into a simpler interface that just passes in the
+ * statement to query for and a handler for dealing with each statement in the
+ * query result. This handles iterating over the query, throwing any exceptions,
+ * and closing the query iterator when done. The same wrapper can be re-used
+ * for multiple queries.
+ */
+public class RyaDaoQueryWrapper {
+    private final RyaDAO<?> ryaDao;
+    private final RdfCloudTripleStoreConfiguration conf;
+
+    /**
+     * Creates a new instance of {@link RyaDaoQueryWrapper}.
+     * @param ryaDao the {@link RyaDAO}. (not {@code null})
+     * @param conf the {@link RdfCloudTripleStoreConfiguration}.
+     * (not {@code null})
+     */
+    public RyaDaoQueryWrapper(final RyaDAO<?> ryaDao, final RdfCloudTripleStoreConfiguration conf) {
+        this.ryaDao = checkNotNull(ryaDao);
+        this.conf = checkNotNull(conf);
+    }
+
+    /**
+     * Creates a new instance of {@link RyaDaoQueryWrapper}.
+     * @param ryaDao the {@link RyaDAO}. (not {@code null})
+     */
+    public RyaDaoQueryWrapper(final RyaDAO<?> ryaDao) {
+        this(checkNotNull(ryaDao), ryaDao.getConf());
+    }
+
+    /**
+     * Handles all results of a query. Closes the query iterator when done.
+     * @param subject the subject {@link Resource} to query for.
+     * @param predicate the predicate {@link URI} to query for.
+     * @param object the object {@link Value} to query for.
+     * @param rdfStatementHandler the {@link RDFHandler} to use for handling
+     * each statement returned. (not {@code null})
+     * @param contexts the context {@link Resource}s to query for.
+     * @throws QueryEvaluationException
+     */
+    public void queryAll(final Resource subject, final URI predicate, final Value object, final RDFHandler rdfStatementHandler, final Resource... contexts) throws QueryEvaluationException {
+        checkNotNull(rdfStatementHandler);
+        final CloseableIteration<Statement, QueryEvaluationException> iter = RyaDAOHelper.query(ryaDao, subject, predicate, object, conf, contexts);
+        try {
+            while (iter.hasNext()) {
+                final Statement statement = iter.next();
+                try {
+                    rdfStatementHandler.handleStatement(statement);
+                } catch (final Exception e) {
+                    throw new QueryEvaluationException("Error handling statement.", e);
+                }
+            }
+        } finally {
+            if (iter != null) {
+                iter.close();
+            }
+        }
+    }
+
+    /**
+     * Handles all results of a query. Closes the query iterator when done.
+     * @param statement the {@link Statement} to query for. (not {@code null})
+     * @param rdfStatementHandler the {@link RDFHandler} to use for handling
+     * each statement returned. (not {@code null})
+     * @throws QueryEvaluationException
+     */
+    public void queryAll(final Statement statement, final RDFHandler rdfStatementHandler) throws QueryEvaluationException {
+        final Resource subject = statement.getSubject();
+        final URI predicate = statement.getPredicate();
+        final Value object = statement.getObject();
+        final Resource context = statement.getContext();
+        queryAll(subject, predicate, object, rdfStatementHandler, context);
+    }
+
+    /**
+     * Handles all results of a query. Closes the query iterator when done.
+     * @param ryaStatement the {@link RyaStatement} to query for.
+     * (not {@code null})
+     * @param rdfStatementHandler the {@link RDFHandler} to use for handling
+     * each statement returned. (not {@code null})
+     * @throws QueryEvaluationException
+     */
+    public void queryAll(final RyaStatement ryaStatement, final RDFHandler rdfStatementHandler) throws QueryEvaluationException {
+        checkNotNull(ryaStatement);
+        final Statement statement = RyaToRdfConversions.convertStatement(ryaStatement);
+        queryAll(statement, rdfStatementHandler);
+    }
+
+    /**
+     * Handles only the first result of a query. Closes the query iterator when
+     * done.
+     * @param subject the subject {@link Resource} to query for.
+     * @param predicate the predicate {@link URI} to query for.
+     * @param object the object {@link Value} to query for.
+     * @param rdfStatementHandler the {@link RDFHandler} to use for handling the
+     * first statement returned. (not {@code null})
+     * @param contexts the context {@link Resource}s to query for.
+     * @throws QueryEvaluationException
+     */
+    public void queryFirst(final Resource subject, final URI predicate, final Value object, final RDFHandler rdfStatementHandler, final Resource... contexts) throws QueryEvaluationException {
+        checkNotNull(rdfStatementHandler);
+        final CloseableIteration<Statement, QueryEvaluationException> iter = RyaDAOHelper.query(ryaDao, subject, predicate, object, conf, contexts);
+        try {
+            if (iter.hasNext()) {
+                final Statement statement = iter.next();
+                try {
+                    rdfStatementHandler.handleStatement(statement);
+                } catch (final Exception e) {
+                    throw new QueryEvaluationException("Error handling statement.", e);
+                }
+            }
+        } finally {
+            if (iter != null) {
+                iter.close();
+            }
+        }
+    }
+
+    /**
+     * Handles only the first result of a query. Closes the query iterator when
+     * done.
+     * @param statement the {@link Statement} to query for. (not {@code null})
+     * @param rdfStatementHandler the {@link RDFHandler} to use for handling the
+     * first statement returned. (not {@code null})
+     * @throws QueryEvaluationException
+     */
+    public void queryFirst(final Statement statement, final RDFHandler rdfStatementHandler) throws QueryEvaluationException {
+        checkNotNull(statement);
+        final Resource subject = statement.getSubject();
+        final URI predicate = statement.getPredicate();
+        final Value object = statement.getObject();
+        final Resource context = statement.getContext();
+        queryFirst(subject, predicate, object, rdfStatementHandler, context);
+    }
+
+    /**
+     * Handles only the first result of a query. Closes the query iterator when
+     * done.
+     * @param ryaStatement the {@link RyaStatement} to query for.
+     * (not {@code null})
+     * @param rdfStatementHandler the {@link RDFHandler} to use for handling the
+     * first statement returned. (not {@code null})
+     * @throws QueryEvaluationException
+     */
+    public void queryFirst(final RyaStatement ryaStatement, final RDFHandler rdfStatementHandler) throws QueryEvaluationException {
+        checkNotNull(ryaStatement);
+        final Statement statement = RyaToRdfConversions.convertStatement(ryaStatement);
+        queryFirst(statement, rdfStatementHandler);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/e9488ff6/extras/indexingExample/src/main/java/MongoRyaDirectExample.java
----------------------------------------------------------------------
diff --git a/extras/indexingExample/src/main/java/MongoRyaDirectExample.java b/extras/indexingExample/src/main/java/MongoRyaDirectExample.java
index 1294a44..342916a 100644
--- a/extras/indexingExample/src/main/java/MongoRyaDirectExample.java
+++ b/extras/indexingExample/src/main/java/MongoRyaDirectExample.java
@@ -6,9 +6,9 @@
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
- * 
+ *
  *   http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -22,7 +22,20 @@ import java.util.List;
 
 import org.apache.commons.lang.Validate;
 import org.apache.hadoop.conf.Configuration;
+import org.apache.log4j.ConsoleAppender;
+import org.apache.log4j.Level;
+import org.apache.log4j.LogManager;
 import org.apache.log4j.Logger;
+import org.apache.log4j.PatternLayout;
+import org.apache.rya.indexing.accumulo.ConfigUtils;
+import org.apache.rya.indexing.mongodb.MongoIndexingConfiguration;
+import org.apache.rya.indexing.mongodb.MongoIndexingConfiguration.MongoDBIndexingConfigBuilder;
+import org.apache.rya.mongodb.MockMongoFactory;
+import org.apache.rya.mongodb.MongoConnectorFactory;
+import org.apache.rya.rdftriplestore.RdfCloudTripleStore;
+import org.apache.rya.rdftriplestore.inference.InferenceEngineException;
+import org.apache.rya.sail.config.RyaSailFactory;
+import org.apache.zookeeper.ClientCnxn;
 import org.openrdf.model.Namespace;
 import org.openrdf.model.URI;
 import org.openrdf.model.ValueFactory;
@@ -48,21 +61,13 @@ import org.openrdf.sail.Sail;
 import com.mongodb.MongoClient;
 import com.mongodb.ServerAddress;
 
-import org.apache.rya.api.RdfCloudTripleStoreConfiguration;
-import org.apache.rya.indexing.GeoConstants;
-import org.apache.rya.indexing.accumulo.ConfigUtils;
-import org.apache.rya.indexing.mongodb.MongoIndexingConfiguration;
-import org.apache.rya.indexing.mongodb.MongoIndexingConfiguration.MongoDBIndexingConfigBuilder;
-import org.apache.rya.mongodb.MockMongoFactory;
-import org.apache.rya.mongodb.MongoConnectorFactory;
-import org.apache.rya.mongodb.MongoDBRdfConfiguration;
-import org.apache.rya.rdftriplestore.RdfCloudTripleStore;
-import org.apache.rya.rdftriplestore.inference.InferenceEngineException;
-import org.apache.rya.sail.config.RyaSailFactory;
+import info.aduna.iteration.Iterations;
 
 public class MongoRyaDirectExample {
     private static final Logger log = Logger.getLogger(MongoRyaDirectExample.class);
 
+    private static final boolean IS_DETAILED_LOGGING_ENABLED = false;
+
     //
     // Connection configuration parameters
     //
@@ -75,19 +80,33 @@ public class MongoRyaDirectExample {
     private static final String MONGO_INSTANCE_URL = "localhost";
     private static final String MONGO_INSTANCE_PORT = "27017";
 
-    public static void main(String[] args) throws Exception {
-        Configuration conf = getConf();
+    public static void setupLogging() {
+        final Logger rootLogger = LogManager.getRootLogger();
+        rootLogger.setLevel(Level.OFF);
+        final ConsoleAppender ca = (ConsoleAppender) rootLogger.getAppender("stdout");
+        ca.setLayout(new PatternLayout("%d{MMM dd yyyy HH:mm:ss} %5p [%t] (%F:%L) - %m%n"));
+        rootLogger.setLevel(Level.INFO);
+        // Filter out noisy messages from the following classes.
+        Logger.getLogger(ClientCnxn.class).setLevel(Level.OFF);
+        Logger.getLogger(MockMongoFactory.class).setLevel(Level.OFF);
+    }
+
+    public static void main(final String[] args) throws Exception {
+        if (IS_DETAILED_LOGGING_ENABLED) {
+            setupLogging();
+        }
+        final Configuration conf = getConf();
         conf.setBoolean(ConfigUtils.DISPLAY_QUERY_PLAN, PRINT_QUERIES);
-  
+
         SailRepository repository = null;
         SailRepositoryConnection conn = null;
         try {
             log.info("Connecting to Indexing Sail Repository.");
-            Sail sail = RyaSailFactory.getInstance(conf);
+            final Sail sail = RyaSailFactory.getInstance(conf);
             repository = new SailRepository(sail);
             conn = repository.getConnection();
 
-            long start = System.currentTimeMillis();
+            final long start = System.currentTimeMillis();
             log.info("Running SPARQL Example: Add and Delete");
             testAddAndDelete(conn);
             testAddAndDeleteNoContext(conn);
@@ -96,10 +115,11 @@ public class MongoRyaDirectExample {
             testAddAndFreeTextSearchWithPCJ(conn);
            //  to test out inference, set inference to true in the conf
             if (USE_INFER){
-            	testInfer(conn, sail);
-            	testPropertyChainInference(conn, sail);
-            	testPropertyChainInferenceAltRepresentation(conn, sail);
-            	testAllValuesFromInference(conn, sail);
+                testInfer(conn, sail);
+                testPropertyChainInference(conn, sail);
+                testPropertyChainInferenceAltRepresentation(conn, sail);
+                testAllValuesFromInference(conn, sail);
+                testIntersectionOfInference(conn, sail);
             }
 
             log.info("TIME: " + (System.currentTimeMillis() - start) / 1000.);
@@ -169,30 +189,30 @@ public class MongoRyaDirectExample {
 //        Validate.isTrue(tupleHandler.getCount() == 0);
 //    }
 
-    private static void closeQuietly(SailRepository repository) {
+    private static void closeQuietly(final SailRepository repository) {
         if (repository != null) {
             try {
                 repository.shutDown();
-            } catch (RepositoryException e) {
+            } catch (final RepositoryException e) {
                 // quietly absorb this exception
             }
         }
     }
 
-    private static void closeQuietly(SailRepositoryConnection conn) {
+    private static void closeQuietly(final SailRepositoryConnection conn) {
         if (conn != null) {
             try {
                 conn.close();
-            } catch (RepositoryException e) {
+            } catch (final RepositoryException e) {
                 // quietly absorb this exception
             }
         }
     }
 
-    private static void testAddAndFreeTextSearchWithPCJ(SailRepositoryConnection conn) throws Exception {
+    private static void testAddAndFreeTextSearchWithPCJ(final SailRepositoryConnection conn) throws Exception {
         // add data to the repository using the SailRepository add methods
-        ValueFactory f = conn.getValueFactory();
-        URI person = f.createURI("http://example.org/ontology/Person");
+        final ValueFactory f = conn.getValueFactory();
+        final URI person = f.createURI("http://example.org/ontology/Person");
 
         String uuid;
 
@@ -272,184 +292,237 @@ public class MongoRyaDirectExample {
     private static MockMongoFactory mock = null;
     private static Configuration getConf() throws IOException {
 
-    	MongoDBIndexingConfigBuilder builder = MongoIndexingConfiguration.builder()
-    		.setUseMockMongo(USE_MOCK).setUseInference(USE_INFER).setAuths("U");
+        MongoDBIndexingConfigBuilder builder = MongoIndexingConfiguration.builder()
+            .setUseMockMongo(USE_MOCK).setUseInference(USE_INFER).setAuths("U");
 
         if (USE_MOCK) {
             mock = MockMongoFactory.newFactory();
-            MongoClient c = mock.newMongoClient();
-            ServerAddress address = c.getAddress();
-            String url = address.getHost();
-            String port = Integer.toString(address.getPort());
+            final MongoClient c = mock.newMongoClient();
+            final ServerAddress address = c.getAddress();
+            final String url = address.getHost();
+            final String port = Integer.toString(address.getPort());
             c.close();
             builder.setMongoHost(url).setMongoPort(port);
         } else {
             // User name and password must be filled in:
-        	builder = builder.setMongoUser("fill this in")
-        					 .setMongoPassword("fill this in")
-        					 .setMongoHost(MONGO_INSTANCE_URL)
-        					 .setMongoPort(MONGO_INSTANCE_PORT);
+            builder = builder.setMongoUser("fill this in")
+                             .setMongoPassword("fill this in")
+                             .setMongoHost(MONGO_INSTANCE_URL)
+                             .setMongoPort(MONGO_INSTANCE_PORT);
         }
-        
+
         return builder.setMongoDBName(MONGO_DB)
                .setMongoCollectionPrefix(MONGO_COLL_PREFIX)
                .setUseMongoFreetextIndex(true)
                .setMongoFreeTextPredicates(RDFS.LABEL.stringValue()).build();
-        
+
     }
 
 
-    public static void testAddAndDelete(SailRepositoryConnection conn) throws MalformedQueryException, RepositoryException,
+    public static void testAddAndDelete(final SailRepositoryConnection conn) throws MalformedQueryException, RepositoryException,
     UpdateExecutionException, QueryEvaluationException, TupleQueryResultHandlerException {
 
-    	// Add data
-    	String query = "INSERT DATA\n"//
-    			+ "{ GRAPH <http://updated/test> {\n"//
-    			+ "  <http://acme.com/people/Mike> " //
-    			+ "       <http://acme.com/actions/likes> \"A new book\" ;\n"//
-    			+ "       <http://acme.com/actions/likes> \"Avocados\" .\n" + "} }";
+        // Add data
+        String query = "INSERT DATA\n"//
+                + "{ GRAPH <http://updated/test> {\n"//
+                + "  <http://acme.com/people/Mike> " //
+                + "       <http://acme.com/actions/likes> \"A new book\" ;\n"//
+                + "       <http://acme.com/actions/likes> \"Avocados\" .\n" + "} }";
 
-    	log.info("Performing Query");
+        log.info("Performing Query");
 
-    	Update update = conn.prepareUpdate(QueryLanguage.SPARQL, query);
-    	update.execute();
+        Update update = conn.prepareUpdate(QueryLanguage.SPARQL, query);
+        update.execute();
 
-    	query = "select ?p ?o { GRAPH <http://updated/test> {<http://acme.com/people/Mike> ?p ?o . }}";
-    	CountingResultHandler resultHandler = new CountingResultHandler();
-    	TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, query);
-    	tupleQuery.evaluate(resultHandler);
-    	log.info("Result count : " + resultHandler.getCount());
+        query = "select ?p ?o { GRAPH <http://updated/test> {<http://acme.com/people/Mike> ?p ?o . }}";
+        final CountingResultHandler resultHandler = new CountingResultHandler();
+        TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, query);
+        tupleQuery.evaluate(resultHandler);
+        log.info("Result count : " + resultHandler.getCount());
 
-    	Validate.isTrue(resultHandler.getCount() == 2);
+        Validate.isTrue(resultHandler.getCount() == 2);
 
-    	resultHandler.resetCount();
+        resultHandler.resetCount();
 
-    	// Delete Data
-    	query = "DELETE DATA\n" //
-    			+ "{ GRAPH <http://updated/test> {\n"
-    			+ "  <http://acme.com/people/Mike> <http://acme.com/actions/likes> \"A new book\" ;\n"
-    			+ "   <http://acme.com/actions/likes> \"Avocados\" .\n" + "}}";
+        // Delete Data
+        query = "DELETE DATA\n" //
+                + "{ GRAPH <http://updated/test> {\n"
+                + "  <http://acme.com/people/Mike> <http://acme.com/actions/likes> \"A new book\" ;\n"
+                + "   <http://acme.com/actions/likes> \"Avocados\" .\n" + "}}";
 
-    	update = conn.prepareUpdate(QueryLanguage.SPARQL, query);
-    	update.execute();
+        update = conn.prepareUpdate(QueryLanguage.SPARQL, query);
+        update.execute();
 
-    	query = "select ?p ?o { GRAPH <http://updated/test> {<http://acme.com/people/Mike> ?p ?o . }}";
-    	tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, query);
-    	tupleQuery.evaluate(resultHandler);
-    	log.info("Result count : " + resultHandler.getCount());
+        query = "select ?p ?o { GRAPH <http://updated/test> {<http://acme.com/people/Mike> ?p ?o . }}";
+        tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, query);
+        tupleQuery.evaluate(resultHandler);
+        log.info("Result count : " + resultHandler.getCount());
 
-    	Validate.isTrue(resultHandler.getCount() == 0);
+        Validate.isTrue(resultHandler.getCount() == 0);
     }
 
-    
-    public static void testPropertyChainInferenceAltRepresentation(SailRepositoryConnection conn, Sail sail) throws MalformedQueryException, RepositoryException,
+
+    public static void testPropertyChainInferenceAltRepresentation(final SailRepositoryConnection conn, final Sail sail) throws MalformedQueryException, RepositoryException,
     UpdateExecutionException, QueryEvaluationException, TupleQueryResultHandlerException, InferenceEngineException {
 
-    	// Add data
-    	String query = "INSERT DATA\n"//
-    			+ "{ GRAPH <http://updated/test> {\n"//
-    			+ "  <urn:jenGreatGranMother> <urn:Motherof> <urn:jenGranMother> . "
-    			+ "  <urn:jenGranMother> <urn:isChildOf> <urn:jenGreatGranMother> . "
-    			+ "  <urn:jenGranMother> <urn:Motherof> <urn:jenMother> . " 
-    			+ "  <urn:jenMother> <urn:isChildOf> <urn:jenGranMother> . "
-    			+ " <urn:jenMother> <urn:Motherof> <urn:jen> . "
-    			+ "  <urn:jen> <urn:isChildOf> <urn:jenMother> . "
-    			+ " <urn:jen> <urn:Motherof> <urn:jenDaughter> .  }}";
-
-    	log.info("Performing Query");
-
-    	Update update = conn.prepareUpdate(QueryLanguage.SPARQL, query);
-    	update.execute();
-
-    	query = "select ?p { GRAPH <http://updated/test> {?s <urn:Motherof>/<urn:Motherof> ?p}}";
-    	CountingResultHandler resultHandler = new CountingResultHandler();
-    	TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, query);
-    	tupleQuery.evaluate(resultHandler);
-    	log.info("Result count : " + resultHandler.getCount());
-
-
-    	// try adding a property chain and querying for it
-    	query = "INSERT DATA\n"//
-    			+ "{ GRAPH <http://updated/test> {\n"//
-    			+ "  <urn:greatMother> owl:propertyChainAxiom <urn:12342>  . " + 
-    			" <urn:12342> <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> _:node1atjakcvbx15023 . " + 
-    			" _:node1atjakcvbx15023 <http://www.w3.org/2002/07/owl#inverseOf> <urn:isChildOf> . " + 
-    			" <urn:12342> <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:node1atjakcvbx15123 . " + 
-       			" _:node1atjakcvbx15123 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> . " + 
-    			" _:node1atjakcvbx15123 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> <urn:MotherOf> .  }}";
-    	update = conn.prepareUpdate(QueryLanguage.SPARQL, query);
-    	update.execute();
-    	((RdfCloudTripleStore) sail).getInferenceEngine().refreshGraph();
-
-    	resultHandler.resetCount();
-    	query = "select ?x { GRAPH <http://updated/test> {<urn:jenGreatGranMother> <urn:greatMother> ?x}}";
-    	resultHandler = new CountingResultHandler();
-    	tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, query);
-    	tupleQuery.evaluate(resultHandler);
-    	log.info("Result count : " + resultHandler.getCount());
+        // Add data
+        String query = "INSERT DATA\n"//
+                + "{ GRAPH <http://updated/test> {\n"//
+                + "  <urn:jenGreatGranMother> <urn:Motherof> <urn:jenGranMother> . "
+                + "  <urn:jenGranMother> <urn:isChildOf> <urn:jenGreatGranMother> . "
+                + "  <urn:jenGranMother> <urn:Motherof> <urn:jenMother> . "
+                + "  <urn:jenMother> <urn:isChildOf> <urn:jenGranMother> . "
+                + " <urn:jenMother> <urn:Motherof> <urn:jen> . "
+                + "  <urn:jen> <urn:isChildOf> <urn:jenMother> . "
+                + " <urn:jen> <urn:Motherof> <urn:jenDaughter> .  }}";
+
+        log.info("Performing Query");
+
+        Update update = conn.prepareUpdate(QueryLanguage.SPARQL, query);
+        update.execute();
+
+        query = "select ?p { GRAPH <http://updated/test> {?s <urn:Motherof>/<urn:Motherof> ?p}}";
+        CountingResultHandler resultHandler = new CountingResultHandler();
+        TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, query);
+        tupleQuery.evaluate(resultHandler);
+        log.info("Result count : " + resultHandler.getCount());
+
+
+        // try adding a property chain and querying for it
+        query = "INSERT DATA\n"//
+                + "{ GRAPH <http://updated/test> {\n"//
+                + "  <urn:greatMother> owl:propertyChainAxiom <urn:12342>  . " +
+                " <urn:12342> <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> _:node1atjakcvbx15023 . " +
+                " _:node1atjakcvbx15023 <http://www.w3.org/2002/07/owl#inverseOf> <urn:isChildOf> . " +
+                " <urn:12342> <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:node1atjakcvbx15123 . " +
+                   " _:node1atjakcvbx15123 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> . " +
+                " _:node1atjakcvbx15123 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> <urn:MotherOf> .  }}";
+        update = conn.prepareUpdate(QueryLanguage.SPARQL, query);
+        update.execute();
+        ((RdfCloudTripleStore) sail).getInferenceEngine().refreshGraph();
+
+        resultHandler.resetCount();
+        query = "select ?x { GRAPH <http://updated/test> {<urn:jenGreatGranMother> <urn:greatMother> ?x}}";
+        resultHandler = new CountingResultHandler();
+        tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, query);
+        tupleQuery.evaluate(resultHandler);
+        log.info("Result count : " + resultHandler.getCount());
 
     }
-    
-    public static void testPropertyChainInference(SailRepositoryConnection conn, Sail sail) throws MalformedQueryException, RepositoryException,
+
+    public static void testPropertyChainInference(final SailRepositoryConnection conn, final Sail sail) throws MalformedQueryException, RepositoryException,
     UpdateExecutionException, QueryEvaluationException, TupleQueryResultHandlerException, InferenceEngineException {
 
-    	// Add data
-    	String query = "INSERT DATA\n"//
-    			+ "{ GRAPH <http://updated/test> {\n"//
-    			+ "  <urn:paulGreatGrandfather> <urn:father> <urn:paulGrandfather> . "
-    			+ "  <urn:paulGrandfather> <urn:father> <urn:paulFather> . " + 
-    			" <urn:paulFather> <urn:father> <urn:paul> . " + 
-    			" <urn:paul> <urn:father> <urn:paulSon> .  }}";
-
-    	log.info("Performing Query");
-
-    	Update update = conn.prepareUpdate(QueryLanguage.SPARQL, query);
-    	update.execute();
-
-    	query = "select ?p { GRAPH <http://updated/test> {<urn:paulGreatGrandfather> <urn:father>/<urn:father> ?p}}";
-    	CountingResultHandler resultHandler = new CountingResultHandler();
-    	TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, query);
-    	tupleQuery.evaluate(resultHandler);
-    	log.info("Result count : " + resultHandler.getCount());
-
-
-    	// try adding a property chain and querying for it
-    	query = "INSERT DATA\n"//
-    			+ "{ GRAPH <http://updated/test> {\n"//
-    			+ "  <urn:greatGrandfather> owl:propertyChainAxiom <urn:1234>  . " + 
-    			" <urn:1234> <http://www.w3.org/2000/10/swap/list#length> 3 . " + 
-    			" <urn:1234> <http://www.w3.org/2000/10/swap/list#index> (0 <urn:father>) . " + 
-    			" <urn:1234> <http://www.w3.org/2000/10/swap/list#index> (1 <urn:father>) . " + 
-    			" <urn:1234> <http://www.w3.org/2000/10/swap/list#index> (2 <urn:father>) .  }}";
-    	update = conn.prepareUpdate(QueryLanguage.SPARQL, query);
-    	update.execute();
-    	query = "INSERT DATA\n"//
-    			+ "{ GRAPH <http://updated/test> {\n"//
-    			+ "  <urn:grandfather> owl:propertyChainAxiom <urn:12344>  . " + 
-    			" <urn:12344> <http://www.w3.org/2000/10/swap/list#length> 2 . " + 
-    			" <urn:12344> <http://www.w3.org/2000/10/swap/list#index> (0 <urn:father>) . " + 
-    			" <urn:12344> <http://www.w3.org/2000/10/swap/list#index> (1 <urn:father>) .  }}";
-    	update = conn.prepareUpdate(QueryLanguage.SPARQL, query);
-    	update.execute();
-    	((RdfCloudTripleStore) sail).getInferenceEngine().refreshGraph();
-
-    	resultHandler.resetCount();
-    	query = "select ?p { GRAPH <http://updated/test> {<urn:paulGreatGrandfather> <urn:greatGrandfather> ?p}}";
-    	resultHandler = new CountingResultHandler();
-    	tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, query);
-    	tupleQuery.evaluate(resultHandler);
-    	log.info("Result count : " + resultHandler.getCount());
-
-    	resultHandler.resetCount();
-    	query = "select ?s ?p { GRAPH <http://updated/test> {?s <urn:grandfather> ?p}}";
-    	resultHandler = new CountingResultHandler();
-    	tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, query);
-    	tupleQuery.evaluate(resultHandler);
-    	log.info("Result count : " + resultHandler.getCount());
+        // Add data
+        String query = "INSERT DATA\n"//
+                + "{ GRAPH <http://updated/test> {\n"//
+                + "  <urn:paulGreatGrandfather> <urn:father> <urn:paulGrandfather> . "
+                + "  <urn:paulGrandfather> <urn:father> <urn:paulFather> . " +
+                " <urn:paulFather> <urn:father> <urn:paul> . " +
+                " <urn:paul> <urn:father> <urn:paulSon> .  }}";
+
+        log.info("Performing Query");
+
+        Update update = conn.prepareUpdate(QueryLanguage.SPARQL, query);
+        update.execute();
+
+        query = "select ?p { GRAPH <http://updated/test> {<urn:paulGreatGrandfather> <urn:father>/<urn:father> ?p}}";
+        CountingResultHandler resultHandler = new CountingResultHandler();
+        TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, query);
+        tupleQuery.evaluate(resultHandler);
+        log.info("Result count : " + resultHandler.getCount());
+
+
+        // try adding a property chain and querying for it
+        query = "INSERT DATA\n"//
+                + "{ GRAPH <http://updated/test> {\n"//
+                + "  <urn:greatGrandfather> owl:propertyChainAxiom <urn:1234>  . " +
+                " <urn:1234> <http://www.w3.org/2000/10/swap/list#length> 3 . " +
+                " <urn:1234> <http://www.w3.org/2000/10/swap/list#index> (0 <urn:father>) . " +
+                " <urn:1234> <http://www.w3.org/2000/10/swap/list#index> (1 <urn:father>) . " +
+                " <urn:1234> <http://www.w3.org/2000/10/swap/list#index> (2 <urn:father>) .  }}";
+        update = conn.prepareUpdate(QueryLanguage.SPARQL, query);
+        update.execute();
+        query = "INSERT DATA\n"//
+                + "{ GRAPH <http://updated/test> {\n"//
+                + "  <urn:grandfather> owl:propertyChainAxiom <urn:12344>  . " +
+                " <urn:12344> <http://www.w3.org/2000/10/swap/list#length> 2 . " +
+                " <urn:12344> <http://www.w3.org/2000/10/swap/list#index> (0 <urn:father>) . " +
+                " <urn:12344> <http://www.w3.org/2000/10/swap/list#index> (1 <urn:father>) .  }}";
+        update = conn.prepareUpdate(QueryLanguage.SPARQL, query);
+        update.execute();
+        ((RdfCloudTripleStore) sail).getInferenceEngine().refreshGraph();
+
+        resultHandler.resetCount();
+        query = "select ?p { GRAPH <http://updated/test> {<urn:paulGreatGrandfather> <urn:greatGrandfather> ?p}}";
+        resultHandler = new CountingResultHandler();
+        tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, query);
+        tupleQuery.evaluate(resultHandler);
+        log.info("Result count : " + resultHandler.getCount());
+
+        resultHandler.resetCount();
+        query = "select ?s ?p { GRAPH <http://updated/test> {?s <urn:grandfather> ?p}}";
+        resultHandler = new CountingResultHandler();
+        tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, query);
+        tupleQuery.evaluate(resultHandler);
+        log.info("Result count : " + resultHandler.getCount());
 
     }
 
-    public static void testAllValuesFromInference(SailRepositoryConnection conn, Sail sail) throws MalformedQueryException, RepositoryException,
+    public static void testIntersectionOfInference(final SailRepositoryConnection conn, final Sail sail) throws MalformedQueryException, RepositoryException, UpdateExecutionException, QueryEvaluationException, TupleQueryResultHandlerException, InferenceEngineException {
+        log.info("Adding Data");
+        final String instances = "INSERT DATA\n"
+                + "{ GRAPH <http://updated/test> {\n"
+                + "  <urn:Susan> a <urn:Mother> . \n"
+                + "  <urn:Mary> a <urn:Woman> . \n"
+                + "  <urn:Mary> a <urn:Parent> . \n"
+                + "}}";
+        Update update = conn.prepareUpdate(QueryLanguage.SPARQL, instances);
+        update.execute();
+        final String inferQuery = "select distinct ?x { GRAPH <http://updated/test> { ?x a <urn:Mother> }}";
+        final String explicitQuery = "select distinct ?x { GRAPH <http://updated/test> {\n"
+                + "  { ?x a <urn:Mother> }\n"
+                + "  UNION {\n"
+                + "    ?x a <urn:Woman> .\n"
+                + "    ?x a <urn:Parent> .\n"
+                + "  }\n"
+                + "}}";
+        log.info("Running Explicit Query");
+        CountingResultHandler resultHandler = new CountingResultHandler();
+        TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, explicitQuery);
+        tupleQuery.evaluate(resultHandler);
+        log.info("Result count : " + resultHandler.getCount());
+        Validate.isTrue(resultHandler.getCount() == 2);
+        log.info("Running Inference-dependant Query");
+        resultHandler.resetCount();
+        tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, inferQuery);
+        tupleQuery.evaluate(resultHandler);
+        log.info("Result count : " + resultHandler.getCount());
+        Validate.isTrue(resultHandler.getCount() == 1);
+        log.info("Adding owl:intersectionOf Schema");
+        // ONTOLOGY - :Mother intersectionOf[:Woman, :Parent]
+        final String ontology = "INSERT DATA\n"
+                + "{ GRAPH <http://updated/test> {\n"
+                + "  <urn:Mother> owl:intersectionOf _:bnode1 . \n"
+                + "  _:bnode1 rdf:first <urn:Woman> . \n"
+                + "  _:bnode1 rdf:rest _:bnode2 . \n"
+                + "  _:bnode2 rdf:first <urn:Parent> . \n"
+                + "  _:bnode2 rdf:rest rdf:nil . \n"
+               + "}}";
+        update = conn.prepareUpdate(QueryLanguage.SPARQL, ontology);
+        update.execute();
+        log.info("Refreshing InferenceEngine");
+        ((RdfCloudTripleStore) sail).getInferenceEngine().refreshGraph();
+        log.info("Re-running Inference-dependant Query");
+        resultHandler.resetCount();
+        resultHandler = new CountingResultHandler();
+        tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, inferQuery);
+        tupleQuery.evaluate(resultHandler);
+        log.info("Result count : " + resultHandler.getCount());
+        Validate.isTrue(resultHandler.getCount() == 2);
+    }
+
+    public static void testAllValuesFromInference(final SailRepositoryConnection conn, final Sail sail) throws MalformedQueryException, RepositoryException,
     UpdateExecutionException, QueryEvaluationException, TupleQueryResultHandlerException, InferenceEngineException {
         log.info("Adding Data");
         String insert = "INSERT DATA\n"
@@ -469,7 +542,7 @@ public class MongoRyaDirectExample {
                 + "  }\n"
                 + "}}";
         log.info("Running Explicit Query");
-        CountingResultHandler resultHandler = new CountingResultHandler();
+        final CountingResultHandler resultHandler = new CountingResultHandler();
         TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, explicitQuery);
         tupleQuery.evaluate(resultHandler);
         log.info("Result count : " + resultHandler.getCount());
@@ -498,84 +571,85 @@ public class MongoRyaDirectExample {
         log.info("Result count : " + resultHandler.getCount());
         Validate.isTrue(resultHandler.getCount() == 2);
     }
-    
-    public static void testInfer(SailRepositoryConnection conn, Sail sail) throws MalformedQueryException, RepositoryException, 
+
+    public static void testInfer(final SailRepositoryConnection conn, final Sail sail) throws MalformedQueryException, RepositoryException,
     UpdateExecutionException, QueryEvaluationException, TupleQueryResultHandlerException, InferenceEngineException {
 
-    	// Add data
-    	String query = "INSERT DATA\n"//
-    			+ "{ \n"//
-    			+ " <http://acme.com/people/Mike> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <urn:type1>.  "
-    			+ " <urn:type1> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <urn:superclass>.  }";
+        // Add data
+        String query = "INSERT DATA\n"//
+                + "{ \n"//
+                + " <http://acme.com/people/Mike> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <urn:type1>.  "
+                + " <urn:type1> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <urn:superclass>.  }";
 
-    	log.info("Performing Query");
+        log.info("Performing Query");
 
-    	Update update = conn.prepareUpdate(QueryLanguage.SPARQL, query);
-    	update.execute();
-    	
-    	// refresh the graph for inferencing (otherwise there is a five minute wait)
-    	((RdfCloudTripleStore) sail).getInferenceEngine().refreshGraph();
+        final Update update = conn.prepareUpdate(QueryLanguage.SPARQL, query);
+        update.execute();
 
-    	query = "select ?s { ?s <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <urn:superclass> . }";
-    	CountingResultHandler resultHandler = new CountingResultHandler();
-    	TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, query);
-    	tupleQuery.evaluate(resultHandler);
-    	log.info("Result count : " + resultHandler.getCount());
+        // refresh the graph for inferencing (otherwise there is a five minute wait)
+        ((RdfCloudTripleStore) sail).getInferenceEngine().refreshGraph();
 
-    	Validate.isTrue(resultHandler.getCount() == 1);
+        query = "select ?s { ?s <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <urn:superclass> . }";
+        final CountingResultHandler resultHandler = new CountingResultHandler();
+        final TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, query);
+        tupleQuery.evaluate(resultHandler);
+        log.info("Result count : " + resultHandler.getCount());
+
+        Validate.isTrue(resultHandler.getCount() == 1);
 
-    	resultHandler.resetCount();
+        resultHandler.resetCount();
     }
-    public static void testAddNamespaces(SailRepositoryConnection conn) throws MalformedQueryException, RepositoryException,
+
+    public static void testAddNamespaces(final SailRepositoryConnection conn) throws MalformedQueryException, RepositoryException,
     UpdateExecutionException, QueryEvaluationException, TupleQueryResultHandlerException {
 
-    	conn.setNamespace("rya", "http://rya.com");
-    	RepositoryResult<Namespace> results = conn.getNamespaces();
-    	for (Namespace space : results.asList()){
-    		System.out.println(space.getName() + ", " + space.getPrefix());
-    	}
+        conn.setNamespace("rya", "http://rya.com");
+        final RepositoryResult<Namespace> results = conn.getNamespaces();
+        for (final Namespace space : Iterations.asList(results)){
+            System.out.println(space.getName() + ", " + space.getPrefix());
+        }
       }
 
-    public static void testAddAndDeleteNoContext(SailRepositoryConnection conn) throws MalformedQueryException, RepositoryException,
+    public static void testAddAndDeleteNoContext(final SailRepositoryConnection conn) throws MalformedQueryException, RepositoryException,
     UpdateExecutionException, QueryEvaluationException, TupleQueryResultHandlerException {
 
-    	// Add data
-    	String query = "INSERT DATA\n"//
-    			+ "{ \n"//
-    			+ "  <http://acme.com/people/Mike> " //
-    			+ "       <http://acme.com/actions/likes> \"A new book\" ;\n"//
-    			+ "       <http://acme.com/actions/likes> \"Avocados\" .\n" + " }";
+        // Add data
+        String query = "INSERT DATA\n"//
+                + "{ \n"//
+                + "  <http://acme.com/people/Mike> " //
+                + "       <http://acme.com/actions/likes> \"A new book\" ;\n"//
+                + "       <http://acme.com/actions/likes> \"Avocados\" .\n" + " }";
 
-    	log.info("Performing Query");
+        log.info("Performing Query");
 
-    	Update update = conn.prepareUpdate(QueryLanguage.SPARQL, query);
-    	update.execute();
+        Update update = conn.prepareUpdate(QueryLanguage.SPARQL, query);
+        update.execute();
 
-    	query = "select ?p ?o {<http://acme.com/people/Mike> ?p ?o . }";
-    	CountingResultHandler resultHandler = new CountingResultHandler();
-    	TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, query);
-    	tupleQuery.evaluate(resultHandler);
-    	log.info("Result count : " + resultHandler.getCount());
+        query = "select ?p ?o {<http://acme.com/people/Mike> ?p ?o . }";
+        final CountingResultHandler resultHandler = new CountingResultHandler();
+        TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, query);
+        tupleQuery.evaluate(resultHandler);
+        log.info("Result count : " + resultHandler.getCount());
 
-    	Validate.isTrue(resultHandler.getCount() == 2);
+        Validate.isTrue(resultHandler.getCount() == 2);
 
-    	resultHandler.resetCount();
+        resultHandler.resetCount();
 
-    	// Delete Data
-    	query = "DELETE DATA\n" //
-    			+ "{ \n"
-    			+ "  <http://acme.com/people/Mike> <http://acme.com/actions/likes> \"A new book\" ;\n"
-    			+ "   <http://acme.com/actions/likes> \"Avocados\" .\n" + "}";
+        // Delete Data
+        query = "DELETE DATA\n" //
+                + "{ \n"
+                + "  <http://acme.com/people/Mike> <http://acme.com/actions/likes> \"A new book\" ;\n"
+                + "   <http://acme.com/actions/likes> \"Avocados\" .\n" + "}";
 
-    	update = conn.prepareUpdate(QueryLanguage.SPARQL, query);
-    	update.execute();
+        update = conn.prepareUpdate(QueryLanguage.SPARQL, query);
+        update.execute();
 
-    	query = "select ?p ?o { {<http://acme.com/people/Mike> ?p ?o . }}";
-    	tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, query);
-    	tupleQuery.evaluate(resultHandler);
-    	log.info("Result count : " + resultHandler.getCount());
+        query = "select ?p ?o { {<http://acme.com/people/Mike> ?p ?o . }}";
+        tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, query);
+        tupleQuery.evaluate(resultHandler);
+        log.info("Result count : " + resultHandler.getCount());
 
-    	Validate.isTrue(resultHandler.getCount() == 0);
+        Validate.isTrue(resultHandler.getCount() == 0);
     }
 
     private static class CountingResultHandler implements TupleQueryResultHandler {
@@ -590,11 +664,11 @@ public class MongoRyaDirectExample {
         }
 
         @Override
-        public void startQueryResult(List<String> arg0) throws TupleQueryResultHandlerException {
+        public void startQueryResult(final List<String> arg0) throws TupleQueryResultHandlerException {
         }
 
         @Override
-        public void handleSolution(BindingSet arg0) throws TupleQueryResultHandlerException {
+        public void handleSolution(final BindingSet arg0) throws TupleQueryResultHandlerException {
             count++;
             System.out.println(arg0);
         }
@@ -604,15 +678,11 @@ public class MongoRyaDirectExample {
         }
 
         @Override
-        public void handleBoolean(boolean arg0) throws QueryResultHandlerException {
-          // TODO Auto-generated method stub
-          
+        public void handleBoolean(final boolean arg0) throws QueryResultHandlerException {
         }
 
         @Override
-        public void handleLinks(List<String> arg0) throws QueryResultHandlerException {
-          // TODO Auto-generated method stub
-          
+        public void handleLinks(final List<String> arg0) throws QueryResultHandlerException {
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/e9488ff6/sail/src/main/java/org/apache/rya/rdftriplestore/RdfCloudTripleStoreConnection.java
----------------------------------------------------------------------
diff --git a/sail/src/main/java/org/apache/rya/rdftriplestore/RdfCloudTripleStoreConnection.java b/sail/src/main/java/org/apache/rya/rdftriplestore/RdfCloudTripleStoreConnection.java
index ec93da8..a64c0ec 100644
--- a/sail/src/main/java/org/apache/rya/rdftriplestore/RdfCloudTripleStoreConnection.java
+++ b/sail/src/main/java/org/apache/rya/rdftriplestore/RdfCloudTripleStoreConnection.java
@@ -46,6 +46,7 @@ import org.apache.rya.api.persist.utils.RyaDAOHelper;
 import org.apache.rya.api.resolver.RdfToRyaConversions;
 import org.apache.rya.rdftriplestore.evaluation.FilterRangeVisitor;
 import org.apache.rya.rdftriplestore.evaluation.ParallelEvaluationStrategyImpl;
+import org.apache.rya.rdftriplestore.evaluation.QueryJoinOptimizer;
 import org.apache.rya.rdftriplestore.evaluation.QueryJoinSelectOptimizer;
 import org.apache.rya.rdftriplestore.evaluation.RdfCloudTripleStoreEvaluationStatistics;
 import org.apache.rya.rdftriplestore.evaluation.RdfCloudTripleStoreSelectivityEvaluationStatistics;
@@ -54,6 +55,7 @@ import org.apache.rya.rdftriplestore.inference.AllValuesFromVisitor;
 import org.apache.rya.rdftriplestore.inference.DomainRangeVisitor;
 import org.apache.rya.rdftriplestore.inference.HasValueVisitor;
 import org.apache.rya.rdftriplestore.inference.InferenceEngine;
+import org.apache.rya.rdftriplestore.inference.IntersectionOfVisitor;
 import org.apache.rya.rdftriplestore.inference.InverseOfVisitor;
 import org.apache.rya.rdftriplestore.inference.PropertyChainVisitor;
 import org.apache.rya.rdftriplestore.inference.SameAsVisitor;
@@ -103,7 +105,6 @@ import org.openrdf.sail.helpers.SailConnectionBase;
 import info.aduna.iteration.CloseableIteration;
 
 public class RdfCloudTripleStoreConnection extends SailConnectionBase {
-
     private final RdfCloudTripleStore store;
 
     private RdfEvalStatsDAO rdfEvalStatsDAO;
@@ -114,7 +115,7 @@ public class RdfCloudTripleStoreConnection extends SailConnectionBase {
     private final RdfCloudTripleStoreConfiguration conf;
 
 
-	private ProvenanceCollector provenanceCollector;
+    private ProvenanceCollector provenanceCollector;
 
     public RdfCloudTripleStoreConnection(final RdfCloudTripleStore sailBase, final RdfCloudTripleStoreConfiguration conf, final ValueFactory vf)
             throws SailException {
@@ -218,12 +219,11 @@ public class RdfCloudTripleStoreConnection extends SailConnectionBase {
         verifyIsOpen();
         logger.trace("Incoming query model:\n{}", tupleExpr.toString());
         if (provenanceCollector != null){
-        	try {
-				provenanceCollector.recordQuery(tupleExpr.toString());
-			} catch (final ProvenanceCollectionException e) {
-				// TODO silent fail
-				e.printStackTrace();
-			}
+            try {
+                provenanceCollector.recordQuery(tupleExpr.toString());
+            } catch (final ProvenanceCollectionException e) {
+                logger.trace("Provenance failed to record query.", e);
+            }
         }
         tupleExpr = tupleExpr.clone();
 
@@ -354,6 +354,7 @@ public class RdfCloudTripleStoreConnection extends SailConnectionBase {
                     tupleExpr.visit(new DomainRangeVisitor(queryConf, inferenceEngine));
                     tupleExpr.visit(new AllValuesFromVisitor(queryConf, inferenceEngine));
                     tupleExpr.visit(new HasValueVisitor(queryConf, inferenceEngine));
+                    tupleExpr.visit(new IntersectionOfVisitor(queryConf, inferenceEngine));
                     tupleExpr.visit(new PropertyChainVisitor(queryConf, inferenceEngine));
                     tupleExpr.visit(new TransitivePropertyVisitor(queryConf, inferenceEngine));
                     tupleExpr.visit(new SymmetricPropertyVisitor(queryConf, inferenceEngine));
@@ -362,7 +363,7 @@ public class RdfCloudTripleStoreConnection extends SailConnectionBase {
                     tupleExpr.visit(new SubClassOfVisitor(queryConf, inferenceEngine));
                     tupleExpr.visit(new SameAsVisitor(queryConf, inferenceEngine));
                 } catch (final Exception e) {
-                    e.printStackTrace();
+                    logger.error("Error encountered while visiting query node.", e);
                 }
             }
             if (queryConf.isPerformant()) {
@@ -388,13 +389,11 @@ public class RdfCloudTripleStoreConnection extends SailConnectionBase {
             if (stats != null) {
 
                 if (stats instanceof RdfCloudTripleStoreSelectivityEvaluationStatistics) {
-
-                    (new QueryJoinSelectOptimizer(stats,
-                            selectEvalDAO)).optimize(tupleExpr, dataset, bindings);
+                    final QueryJoinSelectOptimizer qjso = new QueryJoinSelectOptimizer(stats, selectEvalDAO);
+                    qjso.optimize(tupleExpr, dataset, bindings);
                 } else {
-
-                    (new org.apache.rya.rdftriplestore.evaluation.QueryJoinOptimizer(stats)).optimize(tupleExpr, dataset,
-                            bindings); // TODO: Make pluggable
+                    final QueryJoinOptimizer qjo = new QueryJoinOptimizer(stats);
+                    qjo.optimize(tupleExpr, dataset, bindings); // TODO: Make pluggable
                 }
             }
 
@@ -611,7 +610,7 @@ public class RdfCloudTripleStoreConnection extends SailConnectionBase {
         }
 
         @Override
-		public CloseableIteration<Statement, QueryEvaluationException> getStatements(
+        public CloseableIteration<Statement, QueryEvaluationException> getStatements(
                 final Resource subject, final URI predicate, final Value object,
                 final Resource... contexts) throws QueryEvaluationException {
             return RyaDAOHelper.query(ryaDAO, subject, predicate, object, conf, contexts);
@@ -625,7 +624,7 @@ public class RdfCloudTripleStoreConnection extends SailConnectionBase {
         }
 
         @Override
-		public ValueFactory getValueFactory() {
+        public ValueFactory getValueFactory() {
             return RdfCloudTripleStoreConstants.VALUE_FACTORY;
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/e9488ff6/sail/src/main/java/org/apache/rya/rdftriplestore/evaluation/FilterRangeVisitor.java
----------------------------------------------------------------------
diff --git a/sail/src/main/java/org/apache/rya/rdftriplestore/evaluation/FilterRangeVisitor.java b/sail/src/main/java/org/apache/rya/rdftriplestore/evaluation/FilterRangeVisitor.java
index db5ba78..27b799f 100644
--- a/sail/src/main/java/org/apache/rya/rdftriplestore/evaluation/FilterRangeVisitor.java
+++ b/sail/src/main/java/org/apache/rya/rdftriplestore/evaluation/FilterRangeVisitor.java
@@ -1,5 +1,11 @@
 package org.apache.rya.rdftriplestore.evaluation;
 
+import static org.apache.rya.api.RdfCloudTripleStoreConstants.RANGE;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -8,9 +14,9 @@ package org.apache.rya.rdftriplestore.evaluation;
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
- * 
+ *
  *   http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -27,47 +33,46 @@ import org.apache.rya.api.domain.RangeValue;
 import org.openrdf.model.Value;
 import org.openrdf.model.impl.BooleanLiteralImpl;
 import org.openrdf.query.QueryEvaluationException;
-import org.openrdf.query.algebra.*;
+import org.openrdf.query.algebra.Filter;
+import org.openrdf.query.algebra.FunctionCall;
+import org.openrdf.query.algebra.StatementPattern;
+import org.openrdf.query.algebra.ValueConstant;
+import org.openrdf.query.algebra.ValueExpr;
+import org.openrdf.query.algebra.Var;
 import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static org.apache.rya.api.RdfCloudTripleStoreConstants.RANGE;
-
 /**
  * Class FilterTimeIndexVisitor
  * Date: Apr 11, 2011
  * Time: 10:16:15 PM
  */
-public class FilterRangeVisitor extends QueryModelVisitorBase {
+public class FilterRangeVisitor extends QueryModelVisitorBase<Exception> {
 
-    private RdfCloudTripleStoreConfiguration conf;
-    private Map<Var, RangeValue> rangeValues = new HashMap<Var, RangeValue>();
+    private final RdfCloudTripleStoreConfiguration conf;
+    private final Map<Var, RangeValue> rangeValues = new HashMap<Var, RangeValue>();
 
-    public FilterRangeVisitor(RdfCloudTripleStoreConfiguration conf) {
+    public FilterRangeVisitor(final RdfCloudTripleStoreConfiguration conf) {
         this.conf = conf;
     }
 
     @Override
-    public void meet(Filter node) throws Exception {
+    public void meet(final Filter node) throws Exception {
         super.meet(node);
 
-        ValueExpr arg = node.getCondition();
+        final ValueExpr arg = node.getCondition();
         if (arg instanceof FunctionCall) {
-            FunctionCall fc = (FunctionCall) arg;
+            final FunctionCall fc = (FunctionCall) arg;
             if (RANGE.stringValue().equals(fc.getURI())) {
                 //range(?var, start, end)
-                List<ValueExpr> valueExprs = fc.getArgs();
+                final List<ValueExpr> valueExprs = fc.getArgs();
                 if (valueExprs.size() != 3) {
                     throw new QueryEvaluationException("org.apache:range must have 3 parameters: variable, start, end");
                 }
-                Var var = (Var) valueExprs.get(0);
-                ValueConstant startVc = (ValueConstant) valueExprs.get(1);
-                ValueConstant endVc = (ValueConstant) valueExprs.get(2);
-                Value start = startVc.getValue();
-                Value end = endVc.getValue();
+                final Var var = (Var) valueExprs.get(0);
+                final ValueConstant startVc = (ValueConstant) valueExprs.get(1);
+                final ValueConstant endVc = (ValueConstant) valueExprs.get(2);
+                final Value start = startVc.getValue();
+                final Value end = endVc.getValue();
                 rangeValues.put(var, new RangeValue(start, end));
                 node.setCondition(new ValueConstant(BooleanLiteralImpl.TRUE));
             }
@@ -75,15 +80,15 @@ public class FilterRangeVisitor extends QueryModelVisitorBase {
     }
 
     @Override
-    public void meet(StatementPattern node) throws Exception {
+    public void meet(final StatementPattern node) throws Exception {
         super.meet(node);
 
-        Var subjectVar = node.getSubjectVar();
-        RangeValue subjRange = rangeValues.get(subjectVar);
-        Var predVar = node.getPredicateVar();
-        RangeValue predRange = rangeValues.get(predVar);
-        Var objVar = node.getObjectVar();
-        RangeValue objRange = rangeValues.get(objVar);
+        final Var subjectVar = node.getSubjectVar();
+        final RangeValue subjRange = rangeValues.get(subjectVar);
+        final Var predVar = node.getPredicateVar();
+        final RangeValue predRange = rangeValues.get(predVar);
+        final Var objVar = node.getObjectVar();
+        final RangeValue objRange = rangeValues.get(objVar);
         if(subjRange != null) {
             subjectVar.setValue(new RangeURI(subjRange));//Assumes no blank nodes can be ranges
         }

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/e9488ff6/sail/src/main/java/org/apache/rya/rdftriplestore/evaluation/PushJoinDownVisitor.java
----------------------------------------------------------------------
diff --git a/sail/src/main/java/org/apache/rya/rdftriplestore/evaluation/PushJoinDownVisitor.java b/sail/src/main/java/org/apache/rya/rdftriplestore/evaluation/PushJoinDownVisitor.java
index ebf9737..ecf4c7b 100644
--- a/sail/src/main/java/org/apache/rya/rdftriplestore/evaluation/PushJoinDownVisitor.java
+++ b/sail/src/main/java/org/apache/rya/rdftriplestore/evaluation/PushJoinDownVisitor.java
@@ -8,9 +8,9 @@ package org.apache.rya.rdftriplestore.evaluation;
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
- * 
+ *
  *   http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -30,13 +30,13 @@ import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
  * Date: Apr 11, 2011
  * Time: 10:16:15 PM
  */
-public class PushJoinDownVisitor extends QueryModelVisitorBase {
+public class PushJoinDownVisitor extends QueryModelVisitorBase<Exception> {
     @Override
-    public void meet(Join node) throws Exception {
+    public void meet(final Join node) throws Exception {
         super.meet(node);
 
-        TupleExpr leftArg = node.getLeftArg();
-        TupleExpr rightArg = node.getRightArg();
+        final TupleExpr leftArg = node.getLeftArg();
+        final TupleExpr rightArg = node.getRightArg();
 
         /**
          * if join(join(1, 2), join(3,4))
@@ -44,12 +44,12 @@ public class PushJoinDownVisitor extends QueryModelVisitorBase {
          * join(join(join(1,2), 3), 4)
          */
         if (leftArg instanceof Join && rightArg instanceof Join) {
-            Join leftJoin = (Join) leftArg;
-            Join rightJoin = (Join) rightArg;
-            TupleExpr right_LeftArg = rightJoin.getLeftArg();
-            TupleExpr right_rightArg = rightJoin.getRightArg();
-            Join inner = new Join(leftJoin, right_LeftArg);
-            Join outer = new Join(inner, right_rightArg);
+            final Join leftJoin = (Join) leftArg;
+            final Join rightJoin = (Join) rightArg;
+            final TupleExpr right_LeftArg = rightJoin.getLeftArg();
+            final TupleExpr right_rightArg = rightJoin.getRightArg();
+            final Join inner = new Join(leftJoin, right_LeftArg);
+            final Join outer = new Join(inner, right_rightArg);
             node.replaceWith(outer);
         }
 

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/e9488ff6/sail/src/main/java/org/apache/rya/rdftriplestore/evaluation/ReorderJoinVisitor.java
----------------------------------------------------------------------
diff --git a/sail/src/main/java/org/apache/rya/rdftriplestore/evaluation/ReorderJoinVisitor.java b/sail/src/main/java/org/apache/rya/rdftriplestore/evaluation/ReorderJoinVisitor.java
index 9ff09b2..2ae159f 100644
--- a/sail/src/main/java/org/apache/rya/rdftriplestore/evaluation/ReorderJoinVisitor.java
+++ b/sail/src/main/java/org/apache/rya/rdftriplestore/evaluation/ReorderJoinVisitor.java
@@ -8,9 +8,9 @@ package org.apache.rya.rdftriplestore.evaluation;
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
- * 
+ *
  *   http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -31,13 +31,13 @@ import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
  * Date: Apr 11, 2011
  * Time: 10:16:15 PM
  */
-public class ReorderJoinVisitor extends QueryModelVisitorBase {
+public class ReorderJoinVisitor extends QueryModelVisitorBase<Exception> {
     @Override
-    public void meet(Join node) throws Exception {
+    public void meet(final Join node) throws Exception {
         super.meet(node);
-        
-        TupleExpr leftArg = node.getLeftArg();
-        TupleExpr rightArg = node.getRightArg();
+
+        final TupleExpr leftArg = node.getLeftArg();
+        final TupleExpr rightArg = node.getRightArg();
 
         /**
          * if join(stmtPattern1, join(stmtPattern2, anything)
@@ -45,10 +45,10 @@ public class ReorderJoinVisitor extends QueryModelVisitorBase {
          * join(join(stmtPattern1, stmtPattern2), anything)
          */
         if (leftArg instanceof StatementPattern && rightArg instanceof Join) {
-            Join rightJoin = (Join) rightArg;
+            final Join rightJoin = (Join) rightArg;
             //find the stmtPattern in the right side
-            TupleExpr right_LeftArg = rightJoin.getLeftArg();
-            TupleExpr right_rightArg = rightJoin.getRightArg();
+            final TupleExpr right_LeftArg = rightJoin.getLeftArg();
+            final TupleExpr right_rightArg = rightJoin.getRightArg();
             if (right_LeftArg instanceof StatementPattern || right_rightArg instanceof StatementPattern) {
                 StatementPattern stmtPattern = null;
                 TupleExpr anything = null;
@@ -60,8 +60,8 @@ public class ReorderJoinVisitor extends QueryModelVisitorBase {
                     anything = right_LeftArg;
                 }
 
-                Join inner = new Join(leftArg, stmtPattern);
-                Join outer = new Join(inner, anything);
+                final Join inner = new Join(leftArg, stmtPattern);
+                final Join outer = new Join(inner, anything);
                 node.replaceWith(outer);
             }
         }

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/e9488ff6/sail/src/main/java/org/apache/rya/rdftriplestore/evaluation/SeparateFilterJoinsVisitor.java
----------------------------------------------------------------------
diff --git a/sail/src/main/java/org/apache/rya/rdftriplestore/evaluation/SeparateFilterJoinsVisitor.java b/sail/src/main/java/org/apache/rya/rdftriplestore/evaluation/SeparateFilterJoinsVisitor.java
index fc16c15..8f24220 100644
--- a/sail/src/main/java/org/apache/rya/rdftriplestore/evaluation/SeparateFilterJoinsVisitor.java
+++ b/sail/src/main/java/org/apache/rya/rdftriplestore/evaluation/SeparateFilterJoinsVisitor.java
@@ -8,9 +8,9 @@ package org.apache.rya.rdftriplestore.evaluation;
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
- * 
+ *
  *   http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -18,10 +18,11 @@ package org.apache.rya.rdftriplestore.evaluation;
  * specific language governing permissions and limitations
  * under the License.
  */
-
-
-
-import org.openrdf.query.algebra.*;
+import org.openrdf.query.algebra.Filter;
+import org.openrdf.query.algebra.Join;
+import org.openrdf.query.algebra.StatementPattern;
+import org.openrdf.query.algebra.TupleExpr;
+import org.openrdf.query.algebra.ValueExpr;
 import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
 
 /**
@@ -30,24 +31,24 @@ import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
  * Date: Apr 11, 2011
  * Time: 10:16:15 PM
  */
-public class SeparateFilterJoinsVisitor extends QueryModelVisitorBase {
+public class SeparateFilterJoinsVisitor extends QueryModelVisitorBase<Exception> {
     @Override
-    public void meet(Filter node) throws Exception {
+    public void meet(final Filter node) throws Exception {
         super.meet(node);
 
-        ValueExpr condition = node.getCondition();
-        TupleExpr arg = node.getArg();
+        final ValueExpr condition = node.getCondition();
+        final TupleExpr arg = node.getArg();
         if (!(arg instanceof Join)) {
             return;
         }
 
-        Join join = (Join) arg;
-        TupleExpr leftArg = join.getLeftArg();
-        TupleExpr rightArg = join.getRightArg();
+        final Join join = (Join) arg;
+        final TupleExpr leftArg = join.getLeftArg();
+        final TupleExpr rightArg = join.getRightArg();
 
         if (leftArg instanceof StatementPattern && rightArg instanceof StatementPattern) {
-            Filter left = new Filter(leftArg, condition);
-            Filter right = new Filter(rightArg, condition);
+            final Filter left = new Filter(leftArg, condition);
+            final Filter right = new Filter(rightArg, condition);
             node.replaceWith(new Join(left, right));
         }