http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/domain/RyaStatement.java
----------------------------------------------------------------------
diff --git 
a/common/rya.api/src/main/java/org/apache/rya/api/domain/RyaStatement.java 
b/common/rya.api/src/main/java/org/apache/rya/api/domain/RyaStatement.java
new file mode 100644
index 0000000..18bde98
--- /dev/null
+++ b/common/rya.api/src/main/java/org/apache/rya/api/domain/RyaStatement.java
@@ -0,0 +1,252 @@
+package mvm.rya.api.domain;
+
+/*
+ * 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.
+ */
+
+
+
+import java.util.Arrays;
+
+/**
+ * Date: 7/17/12
+ * Time: 7:20 AM
+ */
+public class RyaStatement {
+    private RyaURI subject;
+    private RyaURI predicate;
+    private RyaType object;
+    private RyaURI context;
+    private String qualifer;
+    private byte[] columnVisibility;
+    private byte[] value;
+    private Long timestamp;
+
+    public RyaStatement() {
+    }
+
+    public RyaStatement(RyaURI subject, RyaURI predicate, RyaType object) {
+        this(subject, predicate, object, null);
+    }
+
+    public RyaStatement(RyaURI subject, RyaURI predicate, RyaType object, 
RyaURI context) {
+        this(subject, predicate, object, context, null);
+    }
+
+    public RyaStatement(RyaURI subject, RyaURI predicate, RyaType object, 
RyaURI context, String qualifier) {
+        this(subject, predicate, object, context, qualifier, null);
+    }
+
+    public RyaStatement(RyaURI subject, RyaURI predicate, RyaType object, 
RyaURI context, String qualifier, byte[] columnVisibility) {
+        this(subject, predicate, object, context, qualifier, columnVisibility, 
null);
+    }
+
+    public RyaStatement(RyaURI subject, RyaURI predicate, RyaType object, 
RyaURI context, String qualifier, byte[] columnVisibility, byte[] value) {
+        this(subject, predicate, object, context, qualifier, columnVisibility, 
value, null);
+    }
+
+    public RyaStatement(RyaURI subject, RyaURI predicate, RyaType object, 
RyaURI context, String qualifier, byte[] columnVisibility, byte[] value, Long 
timestamp) {
+        this.subject = subject;
+        this.predicate = predicate;
+        this.object = object;
+        this.context = context;
+        this.qualifer = qualifier;
+        this.columnVisibility = columnVisibility;
+        this.value = value;
+        this.timestamp = timestamp != null ? timestamp : 
System.currentTimeMillis();
+    }
+
+    public RyaURI getSubject() {
+        return subject;
+    }
+
+    public void setSubject(RyaURI subject) {
+        this.subject = subject;
+    }
+
+    public RyaURI getPredicate() {
+        return predicate;
+    }
+
+    public void setPredicate(RyaURI predicate) {
+        this.predicate = predicate;
+    }
+
+    public RyaType getObject() {
+        return object;
+    }
+
+    public void setObject(RyaType object) {
+        this.object = object;
+    }
+
+    public RyaURI getContext() {
+        return context;
+    }
+
+    public void setContext(RyaURI context) {
+        this.context = context;
+    }
+
+    public byte[] getColumnVisibility() {
+        return columnVisibility;
+    }
+
+    public void setColumnVisibility(byte[] columnVisibility) {
+        this.columnVisibility = columnVisibility;
+    }
+
+    public byte[] getValue() {
+        return value;
+    }
+
+    public void setValue(byte[] value) {
+        this.value = value;
+    }
+
+    public Long getTimestamp() {
+        return timestamp;
+    }
+
+    public void setTimestamp(Long timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        RyaStatement that = (RyaStatement) o;
+
+        if (!Arrays.equals(columnVisibility, that.columnVisibility)) return 
false;
+        if (context != null ? !context.equals(that.context) : that.context != 
null) return false;
+        if (object != null ? !object.equals(that.object) : that.object != 
null) return false;
+        if (predicate != null ? !predicate.equals(that.predicate) : 
that.predicate != null) return false;
+        if (qualifer != null ? !qualifer.equals(that.qualifer) : that.qualifer 
!= null) return false;
+        if (subject != null ? !subject.equals(that.subject) : that.subject != 
null) return false;
+        if (timestamp != null ? !timestamp.equals(that.timestamp) : 
that.timestamp != null) return false;
+        if (!Arrays.equals(value, that.value)) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = subject != null ? subject.hashCode() : 0;
+        result = 31 * result + (predicate != null ? predicate.hashCode() : 0);
+        result = 31 * result + (object != null ? object.hashCode() : 0);
+        result = 31 * result + (context != null ? context.hashCode() : 0);
+        result = 31 * result + (qualifer != null ? qualifer.hashCode() : 0);
+        result = 31 * result + (columnVisibility != null ? 
Arrays.hashCode(columnVisibility) : 0);
+        result = 31 * result + (value != null ? Arrays.hashCode(value) : 0);
+        result = 31 * result + (timestamp != null ? timestamp.hashCode() : 0);
+        return result;
+    }
+
+    public String getQualifer() {
+        return qualifer;
+    }
+
+    public void setQualifer(String qualifer) {
+        this.qualifer = qualifer;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("RyaStatement");
+        sb.append("{subject=").append(subject);
+        sb.append(", predicate=").append(predicate);
+        sb.append(", object=").append(object);
+        sb.append(", context=").append(context);
+        sb.append(", qualifier=").append(qualifer);
+        sb.append(", columnVisibility=").append(columnVisibility == null ? 
"null" : new String(columnVisibility));
+        sb.append(", value=").append(value == null ? "null" : new 
String(value));
+        sb.append(", timestamp=").append(timestamp);
+        sb.append('}');
+        return sb.toString();
+    }
+
+    public static RyaStatementBuilder builder() {
+        return new RyaStatementBuilder();
+    }
+
+    public static RyaStatementBuilder builder(RyaStatement ryaStatement) {
+        return new RyaStatementBuilder(ryaStatement);
+    }
+
+
+    //builder
+    public static class RyaStatementBuilder {
+
+        RyaStatement ryaStatement;
+
+        public RyaStatementBuilder() {
+            ryaStatement = new RyaStatement();
+        }
+
+        public RyaStatementBuilder(RyaStatement ryaStatement) {
+            this.ryaStatement = ryaStatement;
+        }
+
+        public RyaStatementBuilder setTimestamp(Long timestamp) {
+            ryaStatement.setTimestamp(timestamp);
+            return this;
+        }
+
+        public RyaStatementBuilder setValue(byte[] value) {
+            ryaStatement.setValue(value);
+            return this;
+        }
+
+        public RyaStatementBuilder setColumnVisibility(byte[] 
columnVisibility) {
+            ryaStatement.setColumnVisibility(columnVisibility);
+            return this;
+        }
+
+        public RyaStatementBuilder setQualifier(String str) {
+            ryaStatement.setQualifer(str);
+            return this;
+        }
+
+        public RyaStatementBuilder setContext(RyaURI ryaURI) {
+            ryaStatement.setContext(ryaURI);
+            return this;
+        }
+
+        public RyaStatementBuilder setSubject(RyaURI ryaURI) {
+            ryaStatement.setSubject(ryaURI);
+            return this;
+        }
+
+        public RyaStatementBuilder setPredicate(RyaURI ryaURI) {
+            ryaStatement.setPredicate(ryaURI);
+            return this;
+        }
+
+        public RyaStatementBuilder setObject(RyaType ryaType) {
+            ryaStatement.setObject(ryaType);
+            return this;
+        }
+
+        public RyaStatement build() {
+            return ryaStatement;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/domain/RyaType.java
----------------------------------------------------------------------
diff --git 
a/common/rya.api/src/main/java/org/apache/rya/api/domain/RyaType.java 
b/common/rya.api/src/main/java/org/apache/rya/api/domain/RyaType.java
new file mode 100644
index 0000000..7a35253
--- /dev/null
+++ b/common/rya.api/src/main/java/org/apache/rya/api/domain/RyaType.java
@@ -0,0 +1,135 @@
+package mvm.rya.api.domain;
+
+/*
+ * 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.
+ */
+
+
+
+
+import org.openrdf.model.URI;
+import org.openrdf.model.vocabulary.XMLSchema;
+
+/**
+ * Base Rya Type
+ * Date: 7/16/12
+ * Time: 11:45 AM
+ */
+public class RyaType implements Comparable {
+
+    private URI dataType;
+    private String data;
+
+    public RyaType() {
+        setDataType(XMLSchema.STRING);
+    }
+
+    public RyaType(String data) {
+        this(XMLSchema.STRING, data);
+    }
+
+
+    public RyaType(URI dataType, String data) {
+        setDataType(dataType);
+        setData(data);
+    }
+
+    /**
+     * TODO: Can we get away without using the openrdf URI
+     *
+     * @return
+     */
+    public URI getDataType() {
+        return dataType;
+    }
+
+    public String getData() {
+        return data;
+    }
+
+    public void setDataType(URI dataType) {
+        this.dataType = dataType;
+    }
+
+    public void setData(String data) {
+        this.data = data;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("RyaType");
+        sb.append("{dataType=").append(dataType);
+        sb.append(", data='").append(data).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+
+    /**
+     * Determine equality based on string representations of data and datatype.
+     * @param o The object to compare with
+     * @return true if the other object is also a RyaType and both data and 
datatype match.
+     */
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || !(o instanceof RyaType)) return false;
+        RyaType ryaType = (RyaType) o;
+        if (data != null ? !data.equals(ryaType.data) : ryaType.data != null) 
return false;
+        if (dataType != null ? !dataType.equals(ryaType.dataType) : 
ryaType.dataType != null) return false;
+        return true;
+    }
+
+    /**
+     * Generate a hash based on the string representations of both data and 
datatype.
+     * @return A hash consistent with equals.
+     */
+    @Override
+    public int hashCode() {
+        int result = dataType != null ? dataType.hashCode() : 0;
+        result = 31 * result + (data != null ? data.hashCode() : 0);
+        return result;
+    }
+
+    /**
+     * Define a natural ordering based on data and datatype.
+     * @param o The object to compare with
+     * @return 0 if both the data string and the datatype string 
representation match between the objects,
+     *          where matching is defined by string comparison or both being 
null;
+     *          Otherwise, an integer whose sign yields a consistent ordering.
+     */
+    @Override
+    public int compareTo(Object o) {
+        int result = -1;
+        if (o != null && o instanceof RyaType) {
+            result = 0;
+            RyaType other = (RyaType) o;
+            if (this.data != other.data) {
+                if (this.data == null) return 1;
+                if (other.data == null) return -1;
+                result = this.data.compareTo(other.data);
+            }
+            if (result == 0 && this.dataType != other.dataType) {
+                if (this.dataType == null) return 1;
+                if (other.dataType == null) return -1;
+                result = 
this.dataType.toString().compareTo(other.dataType.toString());
+            }
+        }
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/domain/RyaTypePrefix.java
----------------------------------------------------------------------
diff --git 
a/common/rya.api/src/main/java/org/apache/rya/api/domain/RyaTypePrefix.java 
b/common/rya.api/src/main/java/org/apache/rya/api/domain/RyaTypePrefix.java
new file mode 100644
index 0000000..d394417
--- /dev/null
+++ b/common/rya.api/src/main/java/org/apache/rya/api/domain/RyaTypePrefix.java
@@ -0,0 +1,59 @@
+package mvm.rya.api.domain;
+
+/*
+ * 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.
+ */
+
+
+
+import org.openrdf.model.URI;
+
+import static mvm.rya.api.RdfCloudTripleStoreConstants.DELIM;
+import static mvm.rya.api.RdfCloudTripleStoreConstants.LAST;
+
+/**
+ * Date: 7/24/12
+ * Time: 3:26 PM
+ */
+public class RyaTypePrefix extends RyaTypeRange {
+
+    public RyaTypePrefix(URI datatype, String prefix) {
+        super();
+        setPrefix(datatype, prefix);
+    }
+
+    public RyaTypePrefix(String prefix) {
+        super();
+        setPrefix(prefix);
+    }
+
+    public void setPrefix(String prefix) {
+        setStart(new RyaType(prefix + DELIM));
+        setStop(new RyaType(prefix + LAST));
+    }
+
+    public void setPrefix(URI datatype, String prefix) {
+        setStart(new RyaType(datatype, prefix + DELIM));
+        setStop(new RyaType(datatype, prefix + LAST));
+    }
+
+    public String getPrefix() {
+        String data = getStart().getData();
+        return data.substring(0, data.length() - 1);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/domain/RyaTypeRange.java
----------------------------------------------------------------------
diff --git 
a/common/rya.api/src/main/java/org/apache/rya/api/domain/RyaTypeRange.java 
b/common/rya.api/src/main/java/org/apache/rya/api/domain/RyaTypeRange.java
new file mode 100644
index 0000000..a744399
--- /dev/null
+++ b/common/rya.api/src/main/java/org/apache/rya/api/domain/RyaTypeRange.java
@@ -0,0 +1,99 @@
+package mvm.rya.api.domain;
+
+/*
+ * 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.
+ */
+
+
+
+import org.openrdf.model.URI;
+
+/**
+ * Date: 7/17/12
+ * Time: 9:53 AM
+ */
+public class RyaTypeRange extends RyaType implements RyaRange {
+    private RyaType start;
+    private RyaType stop;
+
+    public RyaTypeRange() {
+    }
+
+    public RyaTypeRange(RyaType start, RyaType stop) {
+        this.start = start;
+        this.stop = stop;
+    }
+
+    public RyaType getStart() {
+        return start;
+    }
+
+    public void setStart(RyaType start) {
+        this.start = start;
+    }
+
+    public RyaType getStop() {
+        return stop;
+    }
+
+    public void setStop(RyaType stop) {
+        this.stop = stop;
+    }
+
+    @Override
+    public URI getDataType() {
+        return start.getDataType();
+    }
+
+    @Override
+    public String getData() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("RyaTypeRange");
+        sb.append("{start=").append(start);
+        sb.append(", stop=").append(stop);
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        if (!super.equals(o)) return false;
+
+        RyaTypeRange that = (RyaTypeRange) o;
+
+        if (start != null ? !start.equals(that.start) : that.start != null) 
return false;
+        if (stop != null ? !stop.equals(that.stop) : that.stop != null) return 
false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = super.hashCode();
+        result = 31 * result + (start != null ? start.hashCode() : 0);
+        result = 31 * result + (stop != null ? stop.hashCode() : 0);
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/domain/RyaURI.java
----------------------------------------------------------------------
diff --git a/common/rya.api/src/main/java/org/apache/rya/api/domain/RyaURI.java 
b/common/rya.api/src/main/java/org/apache/rya/api/domain/RyaURI.java
new file mode 100644
index 0000000..aa174c5
--- /dev/null
+++ b/common/rya.api/src/main/java/org/apache/rya/api/domain/RyaURI.java
@@ -0,0 +1,63 @@
+package mvm.rya.api.domain;
+
+/*
+ * 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.
+ */
+
+
+
+import org.openrdf.model.URI;
+import org.openrdf.model.util.URIUtil;
+import org.openrdf.model.vocabulary.XMLSchema;
+
+
+/**
+ * Date: 7/16/12
+ * Time: 11:56 AM
+ */
+public class RyaURI extends RyaType {
+
+    public RyaURI() {
+        setDataType(XMLSchema.ANYURI);
+    }
+
+    public RyaURI(String data) {
+        super(XMLSchema.ANYURI, data);
+    }
+
+    public RyaURI(String namespace, String data) {
+        super(XMLSchema.ANYURI, namespace + data);
+    }
+
+    protected RyaURI(URI datatype, String data) {
+        super(datatype, data);
+    }
+
+    @Override
+    public void setData(String data) {
+        super.setData(data);
+        validate(data);
+    }
+
+    protected void validate(String data) {
+        if (data == null)
+            throw new IllegalArgumentException("Null not URI");
+        URIUtil.getLocalNameIndex(data);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/domain/RyaURIPrefix.java
----------------------------------------------------------------------
diff --git 
a/common/rya.api/src/main/java/org/apache/rya/api/domain/RyaURIPrefix.java 
b/common/rya.api/src/main/java/org/apache/rya/api/domain/RyaURIPrefix.java
new file mode 100644
index 0000000..f808607
--- /dev/null
+++ b/common/rya.api/src/main/java/org/apache/rya/api/domain/RyaURIPrefix.java
@@ -0,0 +1,47 @@
+package mvm.rya.api.domain;
+
+/*
+ * 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.
+ */
+
+
+
+import mvm.rya.api.RdfCloudTripleStoreConstants;
+
+/**
+ * Date: 7/24/12
+ * Time: 3:26 PM
+ */
+public class RyaURIPrefix extends RyaURIRange {
+    public static final String LAST = "\u00FF";
+
+    public RyaURIPrefix(String prefix) {
+        super();
+        setPrefix(prefix);
+    }
+
+    public void setPrefix(String prefix) {
+        setStart(new RyaURI(prefix + RdfCloudTripleStoreConstants.DELIM));
+        setStop(new RyaURI(prefix + LAST));
+    }
+
+    public String getPrefix() {
+        String data = getStart().getData();
+        return data.substring(0, data.length() - 1);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/domain/RyaURIRange.java
----------------------------------------------------------------------
diff --git 
a/common/rya.api/src/main/java/org/apache/rya/api/domain/RyaURIRange.java 
b/common/rya.api/src/main/java/org/apache/rya/api/domain/RyaURIRange.java
new file mode 100644
index 0000000..2c2b836
--- /dev/null
+++ b/common/rya.api/src/main/java/org/apache/rya/api/domain/RyaURIRange.java
@@ -0,0 +1,95 @@
+package mvm.rya.api.domain;
+
+/*
+ * 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.
+ */
+
+
+
+/**
+ * Date: 7/17/12
+ * Time: 9:59 AM
+ */
+public class RyaURIRange extends RyaURI implements RyaRange {
+    public static final RyaURI LAST_URI = new RyaURI(((char) 255) + ":#" + 
((char) 255));
+
+    private RyaURI start;
+    private RyaURI stop;
+
+    public RyaURIRange() {
+        super();
+    }
+
+    public RyaURIRange(RyaURI start, RyaURI stop) {
+        this.start = start;
+        this.stop = stop;
+    }
+
+    public RyaURI getStart() {
+        return start;
+    }
+
+    public void setStart(RyaURI start) {
+        this.start = start;
+    }
+
+    public RyaURI getStop() {
+        return stop;
+    }
+
+    public void setStop(RyaURI stop) {
+        this.stop = stop;
+    }
+
+    @Override
+    public String getData() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("RyaURIRange");
+        sb.append("{start=").append(start);
+        sb.append(", stop=").append(stop);
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        if (!super.equals(o)) return false;
+
+        RyaURIRange that = (RyaURIRange) o;
+
+        if (start != null ? !start.equals(that.start) : that.start != null) 
return false;
+        if (stop != null ? !stop.equals(that.stop) : that.stop != null) return 
false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = super.hashCode();
+        result = 31 * result + (start != null ? start.hashCode() : 0);
+        result = 31 * result + (stop != null ? stop.hashCode() : 0);
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/instance/ConfigurationFields.java
----------------------------------------------------------------------
diff --git 
a/common/rya.api/src/main/java/org/apache/rya/api/instance/ConfigurationFields.java
 
b/common/rya.api/src/main/java/org/apache/rya/api/instance/ConfigurationFields.java
new file mode 100644
index 0000000..25212f4
--- /dev/null
+++ 
b/common/rya.api/src/main/java/org/apache/rya/api/instance/ConfigurationFields.java
@@ -0,0 +1,35 @@
+package mvm.rya.api.instance;
+
+/*
+ * 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.
+ */
+
+/**
+ * The possible configuration fields used in a Rya application.
+ *
+ * Note: The fields used here are from ConfigUtils.java, but this project
+ * doesn't have scope.
+ * TODO: Refactor ConfigUtils so this class is not needed.
+ */
+class ConfigurationFields {
+    static final String USE_GEO = "sc.use_geo";
+    static final String USE_FREETEXT = "sc.use_freetext";
+    static final String USE_TEMPORAL = "sc.use_temporal";
+    static final String USE_ENTITY = "sc.use_entity";
+    static final String USE_PCJ = "sc.use_pcj";
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/instance/RyaDetails.java
----------------------------------------------------------------------
diff --git 
a/common/rya.api/src/main/java/org/apache/rya/api/instance/RyaDetails.java 
b/common/rya.api/src/main/java/org/apache/rya/api/instance/RyaDetails.java
new file mode 100644
index 0000000..565b545
--- /dev/null
+++ b/common/rya.api/src/main/java/org/apache/rya/api/instance/RyaDetails.java
@@ -0,0 +1,1031 @@
+package mvm.rya.api.instance;
+
+/*
+ * 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.
+ */
+
+import static java.util.Objects.requireNonNull;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Objects;
+
+import javax.annotation.Nullable;
+import javax.annotation.ParametersAreNonnullByDefault;
+import javax.annotation.concurrent.Immutable;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * Details about how a Rya instance's state.
+ */
+@Immutable
+@ParametersAreNonnullByDefault
+public class RyaDetails implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    // General metadata about the instance.
+    private final String instanceName;
+    private final String version;
+
+    // Secondary Index Details.
+    private final EntityCentricIndexDetails entityCentricDetails;
+    private final GeoIndexDetails geoDetails;
+    private final PCJIndexDetails pcjDetails;
+    private final TemporalIndexDetails temporalDetails;
+    private final FreeTextIndexDetails freeTextDetails;
+
+    // Statistics Details.
+    private final ProspectorDetails prospectorDetails;
+    private final JoinSelectivityDetails joinSelectivityDetails;
+
+    /**
+     * Private to prevent initialization through the constructor. To build
+     * instances of this class, use the {@link Builder}.
+     */
+    private RyaDetails(
+            final String instanceName,
+            final String version,
+            final EntityCentricIndexDetails entityCentricDetails,
+            final GeoIndexDetails geoDetails,
+            final PCJIndexDetails pcjDetails,
+            final TemporalIndexDetails temporalDetails,
+            final FreeTextIndexDetails freeTextDetails,
+            final ProspectorDetails prospectorDetails,
+            final JoinSelectivityDetails joinSelectivityDetails) {
+        this.instanceName = requireNonNull(instanceName);
+        this.version = requireNonNull(version);
+        this.entityCentricDetails = requireNonNull(entityCentricDetails);
+        this.geoDetails = requireNonNull(geoDetails);
+        this.pcjDetails = requireNonNull(pcjDetails);
+        this.temporalDetails = requireNonNull(temporalDetails);
+        this.freeTextDetails = requireNonNull(freeTextDetails);
+        this.prospectorDetails = requireNonNull(prospectorDetails);
+        this.joinSelectivityDetails = requireNonNull(joinSelectivityDetails);
+    }
+
+    /**
+     * @return The name that uniquely identifies the instance of Rya within
+     *   the system that hosts it.
+     */
+    public String getRyaInstanceName() {
+        return instanceName;
+    }
+
+    /**
+     * @return The version of Rya this instance uses.
+     */
+    public String getRyaVersion() {
+        return version;
+    }
+
+    /**
+     * @return Information about the instance's Entity Centric Index.
+     */
+    public EntityCentricIndexDetails getEntityCentricIndexDetails() {
+        return entityCentricDetails;
+    }
+
+    /**
+     * @return Information about the instance's Geospatial Index.
+     */
+    public GeoIndexDetails getGeoIndexDetails() {
+        return geoDetails;
+    }
+
+    /**
+     * @return Information about the instance's Precomputed Join Index.
+     */
+    public PCJIndexDetails getPCJIndexDetails() {
+        return pcjDetails;
+    }
+
+    /**
+     * @return Information about the instance's Temporal Index.
+     */
+    public TemporalIndexDetails getTemporalIndexDetails() {
+        return temporalDetails;
+    }
+
+    /**
+     * @return Information about the instance's Free Text Index.
+     */
+    public FreeTextIndexDetails getFreeTextIndexDetails() {
+        return freeTextDetails;
+    }
+
+    /**
+     * @return Information about the instance's Prospector Statistics.
+     */
+    public ProspectorDetails getProspectorDetails() {
+        return prospectorDetails;
+    }
+
+    /**
+     * @return Information about the instance's Join Selectivity Statistics.
+     */
+    public JoinSelectivityDetails getJoinSelectivityDetails() {
+        return joinSelectivityDetails;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+                instanceName,
+                version,
+                entityCentricDetails,
+                geoDetails,
+                pcjDetails,
+                temporalDetails,
+                freeTextDetails,
+                prospectorDetails,
+                joinSelectivityDetails);
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if(this == obj) {
+            return true;
+        }
+        if(obj instanceof RyaDetails) {
+            final RyaDetails details = (RyaDetails) obj;
+            return Objects.equals(instanceName, details.instanceName) &&
+                    Objects.equals(version, details.version) &&
+                    Objects.equals(entityCentricDetails, 
details.entityCentricDetails) &&
+                    Objects.equals(geoDetails, details.geoDetails) &&
+                    Objects.equals(pcjDetails, details.pcjDetails) &&
+                    Objects.equals(temporalDetails, details.temporalDetails) &&
+                    Objects.equals(freeTextDetails, details.freeTextDetails) &&
+                    Objects.equals(prospectorDetails, 
details.prospectorDetails) &&
+                    Objects.equals(joinSelectivityDetails, 
details.joinSelectivityDetails);
+        }
+        return false;
+    }
+
+    /**
+     * @return An empty instance of {@link Builder}.
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * @param detials - The builder will be initialized with this object's 
values. (not null)
+     * @return An instance of {@link Builder} that is initialized with a 
{@link RyaDetails}'s values.
+     */
+    public static Builder builder(final RyaDetails details) {
+        return new Builder(details);
+    }
+
+    /**
+     * Builds instances of {@link RyaDetails}.
+     */
+    @ParametersAreNonnullByDefault
+    public static class Builder {
+
+        // General metadata about the instance.
+        private String instanceName;
+        private String version;
+
+        // Secondary Index Details.
+        private EntityCentricIndexDetails entityCentricDetails;
+        private GeoIndexDetails geoDetails;
+        private PCJIndexDetails.Builder pcjIndexDetailsBuilder;
+        private TemporalIndexDetails temporalDetails;
+        private FreeTextIndexDetails freeTextDetails;
+
+        // Statistics Details.
+        private ProspectorDetails prospectorDetails;
+        private JoinSelectivityDetails joinSelectivityDetails;
+
+        /**
+         * Construcst an empty instance of {@link Builder}.
+         */
+        public Builder() { }
+
+        /**
+         * Constructs an instance of {@link Builder} that is initialized with
+         * a {@link RyaDetails}'s values.
+         *
+         * @param detials - The builder will be initialized with this object's 
values. (not null)
+         */
+        public Builder(final RyaDetails details) {
+            requireNonNull(details);
+            instanceName = details.instanceName;
+            version = details.version;
+            entityCentricDetails = details.entityCentricDetails;
+            geoDetails = details.geoDetails;
+            pcjIndexDetailsBuilder = PCJIndexDetails.builder( 
details.pcjDetails );
+            temporalDetails = details.temporalDetails;
+            freeTextDetails = details.freeTextDetails;
+            prospectorDetails = details.prospectorDetails;
+            joinSelectivityDetails = details.joinSelectivityDetails;
+        }
+
+        /**
+         * @param instanceName - The name that uniquely identifies the 
instance of Rya within
+         *   the system that hosts it.
+         * @return This {@link Builder} so that method invocations may be 
chained.
+         */
+        public Builder setRyaInstanceName(@Nullable final String instanceName) 
{
+            this.instanceName = instanceName;
+            return this;
+        }
+
+        /**
+         * @param version - The version of Rya this instance uses.
+         * @return This {@link Builder} so that method invocations may be 
chained.
+         */
+        public Builder setRyaVersion(@Nullable final String version) {
+            this.version = version;
+            return this;
+        }
+
+        /**
+         * @param entityCentricDetails - Information about the instance's 
Entity Centric Index.
+         * @return This {@link Builder} so that method invocations may be 
chained.
+         */
+        public Builder setEntityCentricIndexDetails(@Nullable final 
EntityCentricIndexDetails entityCentricDetails) {
+            this.entityCentricDetails = entityCentricDetails;
+            return this;
+        }
+
+        /**
+         *
+         * @param geoDetails - Information about the instance's Geospatial 
Index.
+         * @return This {@link Builder} so that method invocations may be 
chained.
+         */
+        public Builder setGeoIndexDetails(@Nullable final GeoIndexDetails 
geoDetails) {
+            this.geoDetails = geoDetails;
+            return this;
+        }
+
+        /**
+         * @param temporalDetails - Information about the instance's Temporal 
Index.
+         * @return This {@link Builder} so that method invocations may be 
chained.
+         */
+        public Builder setTemporalIndexDetails(@Nullable final 
TemporalIndexDetails temporalDetails) {
+            this.temporalDetails = temporalDetails;
+            return this;
+        }
+
+        /**
+         * @param freeTextDetails - Information about the instance's Free Text 
Index.
+         * @return This {@link Builder} so that method invocations may be 
chained.
+         */
+        public Builder setFreeTextDetails(@Nullable final FreeTextIndexDetails 
freeTextDetails) {
+            this.freeTextDetails = freeTextDetails;
+            return this;
+        }
+
+        /**
+         * @param pcjDetails - Information about the instance's Precomputed 
Join Index.
+         * @return This {@link Builder} so that method invocations may be 
chained.
+         */
+        public Builder setPCJIndexDetails(@Nullable final 
PCJIndexDetails.Builder pcjDetailsBuilder) {
+            this.pcjIndexDetailsBuilder = pcjDetailsBuilder;
+            return this;
+        }
+
+        /**
+         * @return Get the {@link PCJIndexDetails.Builder} used to build the
+         *   PCJ Index's details.
+         */
+        public @Nullable PCJIndexDetails.Builder getPCJIndexDetails() {
+            return pcjIndexDetailsBuilder;
+        }
+
+        /**
+         * @param prospectorDetails - Information about the instance's 
Prospector Statistics.
+         * @return This {@link Builder} so that method invocations may be 
chained.
+         */
+        public Builder setProspectorDetails(@Nullable final ProspectorDetails 
prospectorDetails) {
+            this.prospectorDetails = prospectorDetails;
+            return this;
+        }
+
+        /**
+         * @param joinSelectivityDetails - Information about the instance's 
Join Selectivity Statistics.
+         * @return This {@link Builder} so that method invocations may be 
chained.
+         */
+        public Builder setJoinSelectivityDetails(@Nullable final 
JoinSelectivityDetails joinSelectivityDetails) {
+            this.joinSelectivityDetails = joinSelectivityDetails;
+            return this;
+        }
+
+        /**
+         * @return An instance of {@link RyaDetails} built using this
+         *   builder's values.
+         */
+        public RyaDetails build() {
+            return new RyaDetails(
+                    instanceName,
+                    version,
+                    entityCentricDetails,
+                    geoDetails,
+                    pcjIndexDetailsBuilder.build(),
+                    temporalDetails,
+                    freeTextDetails,
+                    prospectorDetails,
+                    joinSelectivityDetails);
+        }
+    }
+
+    /**
+     * Details about a Rya instance's Geospatial Index.
+     */
+    @Immutable
+    @ParametersAreNonnullByDefault
+    public static class GeoIndexDetails implements Serializable {
+        private static final long serialVersionUID = 1L;
+
+        private final boolean enabled;
+
+        /**
+         * Constructs an instance of {@link GeoIndexDetails}.
+         *
+         * @param enabled - Whether or not a Geospatial Index will be 
maintained by the Rya instance.
+         */
+        public GeoIndexDetails(final boolean enabled) {
+            this.enabled = enabled;
+        }
+
+        /**
+         * @return Whether or not a Geospatial Index will be maintained by the 
Rya instance.
+         */
+        public boolean isEnabled() {
+            return enabled;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash( enabled );
+        }
+
+        @Override
+        public boolean equals(final Object obj) {
+            if(this == obj) {
+                return true;
+            }
+            if(obj instanceof GeoIndexDetails) {
+                final GeoIndexDetails details = (GeoIndexDetails) obj;
+                return enabled == details.enabled;
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Details about a Rya instance's Temporal Index.
+     */
+    @Immutable
+    @ParametersAreNonnullByDefault
+    public static class TemporalIndexDetails implements Serializable {
+        private static final long serialVersionUID = 1L;
+
+        private final boolean enabled;
+
+        /**
+         * Constructs an instance of {@link TemporalIndexDetails}.
+         *
+         * @param enabled - Whether or not a Temporal Index will be maintained 
by the Rya instance.
+         */
+        public TemporalIndexDetails(final boolean enabled) {
+            this.enabled = enabled;
+        }
+
+        /**
+         * @return Whether or not a Temporal Index will be maintained by the 
Rya instance.
+         */
+        public boolean isEnabled() {
+            return enabled;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash( enabled );
+        }
+
+        @Override
+        public boolean equals(final Object obj) {
+            if(this == obj) {
+                return true;
+            }
+            if(obj instanceof TemporalIndexDetails) {
+                final TemporalIndexDetails details = (TemporalIndexDetails) 
obj;
+                return enabled == details.enabled;
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Details about a Rya instance's Entity Centric Index.
+     */
+    @Immutable
+    @ParametersAreNonnullByDefault
+    public static class EntityCentricIndexDetails implements Serializable {
+        private static final long serialVersionUID = 1L;
+
+        private final boolean enabled;
+
+        /**
+         * Constructs an instance of {@link EntityCentricIndexDetails}.
+         *
+         * @param enabled - Whether or not a Entity Centric Index will be 
maintained by the Rya instance.
+         */
+        public EntityCentricIndexDetails(final boolean enabled) {
+            this.enabled = enabled;
+        }
+
+        /**
+         * @return Whether or not a Entity Centric Index will be maintained by 
the Rya instance.
+         */
+        public boolean isEnabled() {
+            return enabled;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash( enabled );
+        }
+
+        @Override
+        public boolean equals(final Object obj) {
+            if(this == obj) {
+                return true;
+            }
+            if(obj instanceof EntityCentricIndexDetails) {
+                final EntityCentricIndexDetails details = 
(EntityCentricIndexDetails) obj;
+                return enabled == details.enabled;
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Details about a Rya instance's Free Text Index.
+     */
+    @Immutable
+    @ParametersAreNonnullByDefault
+    public static class FreeTextIndexDetails implements Serializable {
+        private static final long serialVersionUID = 1L;
+
+        private final boolean enabled;
+
+        /**
+         * Constructs an instance of {@link FreeTextIndexDetails}.
+         *
+         * @param enabled - Whether or not a Free Text Index will be 
maintained by the Rya instance.
+         */
+        public FreeTextIndexDetails(final boolean enabled) {
+            this.enabled = enabled;
+        }
+
+        /**
+         * @return Whether or not a Free Text Index will be maintained by the 
Rya instance.
+         */
+        public boolean isEnabled() {
+            return enabled;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash( enabled );
+        }
+
+        @Override
+        public boolean equals(final Object obj) {
+            if(this == obj) {
+                return true;
+            }
+            if(obj instanceof FreeTextIndexDetails) {
+                final FreeTextIndexDetails details = (FreeTextIndexDetails) 
obj;
+                return enabled == details.enabled;
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Details about a Rya instance's PCJ Index.
+     */
+    @Immutable
+    @ParametersAreNonnullByDefault
+    public static class PCJIndexDetails implements Serializable {
+        private static final long serialVersionUID = 1L;
+
+        public final boolean enabled;
+        private final Optional<FluoDetails> fluoDetails;
+        private final ImmutableMap<String, PCJDetails> pcjDetails;
+
+        /**
+         * Private to prevent initialization through the constructor. To build
+         * instances of this class, use the {@link Builder}.
+         *
+         * @param enabled - Whether or not a Precomputed Join Index will be 
maintained by the Rya instance.
+         * @param fluoDetails - Details about a Fluo application that is used 
to
+         *   incrementally update PCJs if one has been installed for this RYA
+         *   instance. (not null)
+         * @param pcjDetails - Details about the PCJs that have been created
+         *   for this Rya instance. (not null)
+         */
+        private PCJIndexDetails(
+                final boolean enabled,
+                final Optional<FluoDetails> fluoDetails,
+                final ImmutableMap<String, PCJDetails> pcjDetails) {
+            this.enabled = enabled;
+            this.fluoDetails = requireNonNull(fluoDetails);
+            this.pcjDetails = requireNonNull(pcjDetails);
+        }
+
+        /**
+         * @return Whether or not a Precomputed Join Index will be maintained 
by the Rya instance.
+         */
+        public boolean isEnabled() {
+            return enabled;
+        }
+
+        /**
+         * @return Details about a Fluo application that is used to 
incrementally
+         *   update PCJs if one has been installed for this RYA instance.
+         */
+        public Optional<FluoDetails> getFluoDetails() {
+            return fluoDetails;
+        }
+
+        /**
+         * @return Details about the PCJs that have been created for this Rya 
instance.
+         *   The key is the PCJ ID and the value are the details for the ID.
+         */
+        public ImmutableMap<String, PCJDetails> getPCJDetails() {
+            return pcjDetails;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(enabled, fluoDetails, pcjDetails);
+        }
+
+        @Override
+        public boolean equals(final Object obj) {
+            if(this == obj) {
+                return true;
+            }
+            if(obj instanceof PCJIndexDetails) {
+                final PCJIndexDetails details = (PCJIndexDetails) obj;
+                return Objects.equals(enabled, details.enabled) &&
+                        Objects.equals(fluoDetails,  details.fluoDetails) &&
+                        Objects.equals(pcjDetails, details.pcjDetails);
+            }
+            return false;
+        }
+
+        /**
+         * @return A new instance of {@link Builder}.
+         */
+        public static Builder builder() {
+            return new Builder();
+        }
+
+        /**
+         * @param detials - The builder will be initialized with this object's 
values. (not null)
+         * @return An instance of {@link Builder} that is initialized with a 
{@link PCJIndexDetails}'s values.
+         */
+        public static Builder builder(final PCJIndexDetails pcjIndexDetails) {
+            return new Builder(pcjIndexDetails);
+        }
+
+        /**
+         * Builds instance of {@link PCJIndexDetails).
+         */
+        @ParametersAreNonnullByDefault
+        public static class Builder {
+
+            private Boolean enabled = null;
+            private FluoDetails fluoDetails = null;
+            private final Map<String, PCJDetails.Builder> pcjDetailsBuilders = 
new HashMap<>();
+
+            /**
+             * Constructs an empty instance of {@link Builder}.
+             */
+            public Builder() { }
+
+            /**
+             * Constructs an instance of {@link Builder} that is initialized 
with
+             * the values of a {@link PCJIndexDetails}.
+             *
+             * @param pcjIndexDetails - This objects values will be used to 
initialize
+             *   the builder. (not null)
+             */
+            public Builder(final PCJIndexDetails pcjIndexDetails) {
+                requireNonNull(pcjIndexDetails);
+                this.enabled = pcjIndexDetails.enabled;
+                this.fluoDetails = pcjIndexDetails.fluoDetails.orNull();
+
+                for(final PCJDetails pcjDetails : 
pcjIndexDetails.pcjDetails.values()) {
+                    pcjDetailsBuilders.put(pcjDetails.getId(), 
PCJDetails.builder(pcjDetails));
+                }
+            }
+
+            /**
+             * @param enabled - Whether or not a Precomputed Join Index will 
be maintained by the Rya instance.
+             * @return This {@link Builder} so that method invocations may be 
chained.
+             */
+            public Builder setEnabled(final Boolean enabled) {
+                this.enabled = enabled;
+                return this;
+            }
+
+            /**
+             * @param fluoDetails - Details about a Fluo application that is 
used
+             *   to incrementally update PCJs if one has been installed for 
this RYA instance.
+             * @return This {@link Builder} so that method invocations may be 
chained.
+             */
+            public Builder setFluoDetails(@Nullable final FluoDetails 
fluoDetails) {
+                this.fluoDetails = fluoDetails;
+                return this;
+            }
+
+            /**
+             * @param pcjDetails - Details about the PCJs that have been 
created for this Rya instance.
+             * @return This {@link Builder} so that method invocations may be 
chained.
+             */
+            public Builder addPCJDetails(@Nullable final PCJDetails.Builder 
pcjDetailsBuilder) {
+                if(pcjDetailsBuilder != null) {
+                    this.pcjDetailsBuilders.put(pcjDetailsBuilder.getId(), 
pcjDetailsBuilder);
+                }
+                return this;
+            }
+
+            /**
+             * @param pcjId - The PCJ ID of the {@link PCJDetails.Builder} to 
remove. (not null)
+             * @return This {@link Builder} so that method invocations may be 
chained.
+             */
+            public Builder removePCJDetails(@Nullable final String pcjId) {
+                requireNonNull(pcjId);
+                this.pcjDetailsBuilders.remove(pcjId);
+                return this;
+            }
+
+            /**
+             * @return Builds an instance of {@link PCJIndexDetails} using 
this builder's values.
+             */
+            public PCJIndexDetails build() {
+                final ImmutableMap.Builder<String, PCJDetails> pcjDetails = 
ImmutableMap.builder();
+                for(final Entry<String, PCJDetails.Builder> entry : 
pcjDetailsBuilders.entrySet()) {
+                    pcjDetails.put(entry.getKey(), entry.getValue().build());
+                }
+
+                return new PCJIndexDetails(
+                        enabled,
+                        Optional.fromNullable( fluoDetails ),
+                        pcjDetails.build());
+            }
+        }
+
+        /**
+         * Details about a Fluo Incremental PCJ application that has been 
installed
+         * as part of this Rya instance.
+         */
+        @Immutable
+        @ParametersAreNonnullByDefault
+        public static class FluoDetails implements Serializable {
+            private static final long serialVersionUID = 1L;
+
+            private final String updateAppName;
+
+            /**
+             * Constructs an instance of {@link FluoDetails}.
+             *
+             * @param updateAppName - The name of the Fluo application that is
+             *   updating this Rya instance's incremental PCJs. (not null)
+             */
+            public FluoDetails(final String updateAppName) {
+                this.updateAppName = requireNonNull(updateAppName);
+            }
+
+            /**
+             * @return The name of the Fluo application.
+             */
+            public String getUpdateAppName() {
+                return updateAppName;
+            }
+
+            @Override
+            public int hashCode() {
+                return Objects.hash(updateAppName);
+            }
+
+            @Override
+            public boolean equals(final Object obj) {
+                if(this == obj) {
+                    return true;
+                }
+                if(obj instanceof FluoDetails) {
+                    final FluoDetails details = (FluoDetails) obj;
+                    return Objects.equals(updateAppName, 
details.updateAppName);
+                }
+                return false;
+            }
+        }
+
+        /**
+         * Details about a specific PCJ that is being maintained within the 
Rya instance.
+         */
+        @Immutable
+        @ParametersAreNonnullByDefault
+        public static class PCJDetails implements Serializable {
+            private static final long serialVersionUID = 1L;
+
+            private final String id;
+            private final Optional<PCJUpdateStrategy> updateStrategy;
+            private final Optional<Date> lastUpdateTime;
+
+            /**
+             * Private to prevent initialization through the constructor. To 
build
+             * instances of this class, use the {@link Builder}.
+             *
+             * @param id - Uniquely identifies the PCJ within this instance of 
Rya. (not null)
+             * @param updateStrategy - Describes how the PCJ is being updated. 
(not null)
+             * @param lastUpdateTime - The last time the PCJ was updated. This 
information
+             *   may not be provided. (not null)
+             */
+            private PCJDetails(
+                    final String id,
+                    final Optional<PCJUpdateStrategy> updateStrategy,
+                    final Optional<Date> lastUpdateTime) {
+                this.id = requireNonNull(id);
+                this.updateStrategy = requireNonNull(updateStrategy);
+                this.lastUpdateTime = requireNonNull(lastUpdateTime);
+            }
+
+            /**
+             * @return Uniquely identifies the PCJ within this instance of Rya.
+             */
+            public String getId() {
+                return id;
+            }
+
+            /**
+             * @return Describes how the PCJ is being updated.
+             */
+            public Optional<PCJUpdateStrategy> getUpdateStrategy() {
+                return updateStrategy;
+            }
+
+            /**
+             * @return The last time the PCJ was updated. This information
+             *   may not be provided.
+             */
+            public Optional<Date> getLastUpdateTime() {
+                return lastUpdateTime;
+            }
+
+            @Override
+            public int hashCode() {
+                return Objects.hash(id, updateStrategy, lastUpdateTime);
+            }
+
+            @Override
+            public boolean equals(final Object obj) {
+                if(this == obj) {
+                    return true;
+                }
+                if(obj instanceof PCJDetails) {
+                    final PCJDetails details = (PCJDetails) obj;
+                    return Objects.equals(id, details.id) &&
+                            Objects.equals(updateStrategy, 
details.updateStrategy) &&
+                            Objects.equals(lastUpdateTime, 
details.lastUpdateTime);
+                }
+                return false;
+            }
+
+            /**
+             * @return A new instance of {@link Builder}.
+             */
+            public static Builder builder() {
+                return new Builder();
+            }
+
+            /**
+             * @param detials - The builder will be initialized with this 
object's values. (not null)
+             * @return An instance of {@link Builder} that is initialized with 
a {@link PCJDetails}' values.
+             */
+            public static Builder builder(final PCJDetails details) {
+                return new Builder(details);
+            }
+
+            /**
+             * Builds instance of {@link PCJDetails}.
+             */
+            @ParametersAreNonnullByDefault
+            public static class Builder {
+
+                private String id;
+                private PCJUpdateStrategy updateStrategy;
+                private Date lastUpdateTime;
+
+                /**
+                 * Constructs an instance of {@link Builder}.
+                 */
+                public Builder() { }
+
+                /**
+                 * Constructs an instance of {@link Builder} that is 
initialized with
+                 * the values of a {@link PCJDetails}.
+                 *
+                 * @param details - This object's values will be used to 
initialize the builder. (not null)
+                 */
+                public Builder(final PCJDetails details) {
+                    requireNonNull(details);
+                    this.id = details.id;
+                    this.updateStrategy = details.updateStrategy.orNull();
+                    this.lastUpdateTime = details.lastUpdateTime.orNull();
+                }
+
+                /**
+                 * @return Uniquely identifies the PCJ within this instance of 
Rya.
+                 */
+                public @Nullable String getId() {
+                    return id;
+                }
+
+                /**
+                 * @param id - Uniquely identifies the PCJ within this 
instance of Rya.
+                 * @return This {@link Builder} so that method invocations may 
be chained.
+                 */
+                public Builder setId(@Nullable final String id) {
+                    this.id = id;
+                    return this;
+                }
+
+                /**
+                 * @return Describes how the PCJ is being updated.
+                 */
+                public PCJUpdateStrategy getUpdateStrategy() {
+                    return updateStrategy;
+                }
+
+                /**
+                 * @param updateStrategy - Describes how the PCJ is being 
updated.
+                 * @return This {@link Builder} so that method invocations may 
be chained.
+                 */
+                public Builder setUpdateStrategy(@Nullable final 
PCJUpdateStrategy updateStrategy) {
+                    this.updateStrategy = updateStrategy;
+                    return this;
+                }
+
+                /**
+                 * @return The last time the PCJ was updated. This information 
may not be provided.
+                 */
+                public @Nullable Date getLastUpdateTime() {
+                    return lastUpdateTime;
+                }
+
+                /**
+                 * @param lastUpdateTime - The last time the PCJ was updated. 
This information
+                 *   may not be provided.
+                 * @return This {@link Builder} so that method invocations may 
be chained.
+                 */
+                public Builder setLastUpdateTime(@Nullable final Date 
lastUpdateTime) {
+                    this.lastUpdateTime = lastUpdateTime;
+                    return this;
+                }
+
+                /**
+                 * @return An instance of {@link PCJDetails} built using this 
builder's values.
+                 */
+                public PCJDetails build() {
+                    return new PCJDetails(
+                            id,
+                            Optional.fromNullable(updateStrategy),
+                            Optional.fromNullable(lastUpdateTime));
+                }
+            }
+
+            /**
+             * Describes the different strategies that may be used to update a 
PCJ index.
+             */
+            public static enum PCJUpdateStrategy {
+                /**
+                 * The PCJ is being updated by periodically rebuilding all of 
the results.
+                 */
+                BATCH,
+
+                /**
+                 * The PCJ is being updated frequently and incrementally as new
+                 * Statements are inserted into the Tya instance.
+                 */
+                INCREMENTAL;
+            }
+        }
+    }
+
+    /**
+     * Details about a Rya instance's Prospector statistics.
+     */
+    @Immutable
+    @ParametersAreNonnullByDefault
+    public static class ProspectorDetails implements Serializable {
+        private static final long serialVersionUID = 1L;
+
+        private final Optional<Date> lastUpdated;
+
+        /**
+         * Constructs an instance of {@link ProspectorDetails}.
+         *
+         * @param lastUpdated - The last time the Prospector statistics were 
updated for the Rya instance. (not null)
+         */
+        public ProspectorDetails(final Optional<Date> lastUpdated) {
+            this.lastUpdated = requireNonNull(lastUpdated);
+        }
+
+        /**
+         * @return The last time the Prospector statistics were updated for 
the Rya instance.
+         */
+        public Optional<Date> getLastUpdated() {
+            return lastUpdated;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash( lastUpdated );
+        }
+
+        @Override
+        public boolean equals(final Object obj) {
+            if(this == obj) {
+                return true;
+            }
+            if(obj instanceof ProspectorDetails) {
+                final ProspectorDetails details = (ProspectorDetails) obj;
+                return Objects.equals(lastUpdated, details.lastUpdated);
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Details about a Rya instance's Join Selectivity statistics.
+     */
+    @Immutable
+    @ParametersAreNonnullByDefault
+    public static class JoinSelectivityDetails implements Serializable {
+        private static final long serialVersionUID = 1L;
+
+        private final Optional<Date> lastUpdated;
+
+        /**
+         * Constructs an instance of {@link JoinSelectivityDetails}.
+         *
+         * @param lastUpdated - The last time the Join Selectivity statistics 
were updated for the Rya instance. (not null)
+         */
+        public JoinSelectivityDetails(final Optional<Date> lastUpdated) {
+            this.lastUpdated = requireNonNull(lastUpdated);
+        }
+
+        /**
+         * @return The last time the Join Selectivity statistics were updated 
for the Rya instance.
+         */
+        public Optional<Date> getLastUpdated() {
+            return lastUpdated;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash( lastUpdated );
+        }
+
+        @Override
+        public boolean equals(final Object obj) {
+            if(this == obj) {
+                return true;
+            }
+            if(obj instanceof JoinSelectivityDetails) {
+                final JoinSelectivityDetails details = 
(JoinSelectivityDetails) obj;
+                return Objects.equals(lastUpdated, details.lastUpdated);
+            }
+            return false;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/instance/RyaDetailsRepository.java
----------------------------------------------------------------------
diff --git 
a/common/rya.api/src/main/java/org/apache/rya/api/instance/RyaDetailsRepository.java
 
b/common/rya.api/src/main/java/org/apache/rya/api/instance/RyaDetailsRepository.java
new file mode 100644
index 0000000..d05c65a
--- /dev/null
+++ 
b/common/rya.api/src/main/java/org/apache/rya/api/instance/RyaDetailsRepository.java
@@ -0,0 +1,123 @@
+package mvm.rya.api.instance;
+
+/*
+ * 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.
+ */
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
+/**
+ * Provides access to the {@link RyaDetails} information that describes
+ * an instance of Rya.
+ */
+@ParametersAreNonnullByDefault
+public interface RyaDetailsRepository {
+
+    /**
+     * Check whether the details for this instance of Rya have been 
initialized or not.
+     *
+     * @return {@code true} if it has been initialized; otherwise {@code 
false}.
+     * @throws RyaDetailsRepositoryException Something caused this operation 
to fail.
+     */
+    public boolean isInitialized() throws RyaDetailsRepositoryException;
+
+    /**
+     * Initializes the {@link RyaDetails} that is stored for an instance of 
Rya.
+     *
+     * @param details - A Rya instance's details at installation time. (not 
null)
+     * @throws AlreadyInitializedException This repository has already been 
initialized.
+     * @throws RyaDetailsRepositoryException Something caused this operation 
to fail.
+     */
+    public void initialize(RyaDetails details) throws 
AlreadyInitializedException, RyaDetailsRepositoryException;
+
+    /**
+     * Get the {@link RyaDetails} that describe this instance of Rya.
+     *
+     * @return The details that describe this instance of Rya.
+     * @throws NotInitializedException The Rya instance's details have not 
been initialized yet.
+     * @throws RyaDetailsRepositoryException Something caused this operation 
to fail.
+     */
+    public RyaDetails getRyaInstanceDetails() throws NotInitializedException, 
RyaDetailsRepositoryException;
+
+    /**
+     * Update the {@link RyaDetails} that describe this instance of Rya.
+     *
+     * @param oldDetails - The copy of the details that have been updated. 
(not null)
+     * @param newDetails - The updated details. (not null)
+     * @throws NotInitializedException The Rya instance's details have not 
been initialized yet.
+     * @throws ConcurrentUpdateException An update couldn't be performed 
because
+     * the old state of the object no longer matches the current state.
+     * @throws RyaDetailsRepositoryException Something caused this operation 
to fail.
+     */
+    public void update(RyaDetails oldDetails, RyaDetails newDetails) throws 
NotInitializedException, ConcurrentUpdateException, 
RyaDetailsRepositoryException;
+
+    /**
+     * The root exception of all {@link RyaDetailsRepository} operations.
+     */
+    public static class RyaDetailsRepositoryException extends Exception {
+        private static final long serialVersionUID = 1L;
+
+        public RyaDetailsRepositoryException(final String message) {
+            super(message);
+        }
+
+        public RyaDetailsRepositoryException(final String message, final 
Throwable cause) {
+            super(message, cause);
+        }
+    }
+
+    /**
+     * You can not initialize a {@link RyaDetailsRepository} that has already
+     * been initialized.
+     */
+    public static class AlreadyInitializedException extends 
RyaDetailsRepositoryException {
+        private static final long serialVersionUID = 1L;
+
+        public AlreadyInitializedException(final String message) {
+            super(message);
+        }
+    }
+
+    /**
+     * Some methods of {@link RyaDetailsRepository} may only be invoked after
+     * it has been initialized.
+     */
+    public static class NotInitializedException extends 
RyaDetailsRepositoryException {
+        private static final long serialVersionUID = 1L;
+
+        public NotInitializedException(final String message) {
+            super(message);
+        }
+
+        public NotInitializedException(final String message, final Throwable 
cause) {
+            super(message, cause);
+        }
+    }
+
+    /**
+     * An update couldn't be performed because the old state of the object no
+     * longer matches the current state.
+     */
+    public static class ConcurrentUpdateException extends 
RyaDetailsRepositoryException {
+        private static final long serialVersionUID = 1L;
+
+        public ConcurrentUpdateException(final String message) {
+            super(message);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/instance/RyaDetailsToConfiguration.java
----------------------------------------------------------------------
diff --git 
a/common/rya.api/src/main/java/org/apache/rya/api/instance/RyaDetailsToConfiguration.java
 
b/common/rya.api/src/main/java/org/apache/rya/api/instance/RyaDetailsToConfiguration.java
new file mode 100644
index 0000000..8734adc
--- /dev/null
+++ 
b/common/rya.api/src/main/java/org/apache/rya/api/instance/RyaDetailsToConfiguration.java
@@ -0,0 +1,98 @@
+/**
+ * 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 mvm.rya.api.instance;
+
+import static java.util.Objects.requireNonNull;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.log4j.Logger;
+
+import com.google.common.base.Optional;
+
+/**
+ * Used to fetch {@link RyaDetails} from a {@link RyaDetailsRepository} and
+ * add them to the application's {@link Configuration}.
+ */
+@ParametersAreNonnullByDefault
+public class RyaDetailsToConfiguration {
+    private static final Logger log = 
Logger.getLogger(RyaDetailsToConfiguration.class);
+
+    /**
+     * Ensures the values in the {@link Configuration} do not conflict with 
the values in {@link RyaDetails}.
+     * If they do, the values in {@link RyaDetails} take precedent and the 
{@link Configuration} value will
+     * be overwritten.
+     *
+     * @param details - The {@link RyaDetails} to add to the {@link 
Configuration}. (not null)
+     * @param conf - The {@link Configuration} to add {@link RyaDetails} to. 
(not null)
+     */
+    public static void addRyaDetailsToConfiguration(final RyaDetails details, 
final Configuration conf) {
+        requireNonNull(details);
+        requireNonNull(conf);
+
+        checkAndSet(conf, ConfigurationFields.USE_ENTITY, 
details.getEntityCentricIndexDetails().isEnabled());
+        checkAndSet(conf, ConfigurationFields.USE_FREETEXT, 
details.getFreeTextIndexDetails().isEnabled());
+        checkAndSet(conf, ConfigurationFields.USE_GEO, 
details.getGeoIndexDetails().isEnabled());
+        checkAndSet(conf, ConfigurationFields.USE_TEMPORAL, 
details.getTemporalIndexDetails().isEnabled());
+        checkAndSet(conf, ConfigurationFields.USE_PCJ, 
details.getPCJIndexDetails().isEnabled());
+    }
+
+    /**
+     * Ensures a Rya Client will not try to use a secondary index that is not 
not supported by the Rya Instance
+     * it is connecting to.
+     * </p>
+     * If the configuration...
+     * <ul>
+     *   <li>provides an 'on' value for an index that is supported, then 
nothing changes.</li>
+     *   <li>provides an 'off' value for an index that is or is not supported, 
then nothing changes.</li>
+     *   <li>provides an 'on' value for an index that is not supported, then 
the index is turned
+     *       off and a warning is logged.</li>
+     *   <li>does not provide any value for an index, then it will be turned 
on if supported.</li>
+     * </ul>
+     *
+     * @param conf - The {@link Configuration} to potentially change. (not 
null)
+     * @param useIndexField - The field within {@code conf} that indicates if 
the client will utilize the index. (not null)
+     * @param indexSupported - {@code true} if the Rya Instance supports the 
index; otherwise {@code false}.
+     */
+    private static void checkAndSet(final Configuration conf, final String 
useIndexField, final boolean indexSupported) {
+        requireNonNull(conf);
+        requireNonNull(useIndexField);
+
+        final Optional<String> useIndexStr = Optional.fromNullable( 
conf.get(useIndexField) );
+
+        // If no value was provided, default to using the index if it is 
supported.
+        if(!useIndexStr.isPresent()) {
+            log.info("No Rya Client configuration was provided for the " + 
useIndexField +
+                    " index, so it is being defaulted to " + indexSupported);
+            conf.setBoolean(useIndexField, indexSupported);
+            return;
+        }
+
+        // If configured to use the index, but the Rya Instance does not 
support it, then turn it off.
+        final boolean useIndex = Boolean.parseBoolean( useIndexStr.get() );
+        if(useIndex && !indexSupported) {
+            log.warn("The Rya Client indicates it wants to use a secondary 
index that the Rya Instance does not support. " +
+                    "This is not allowed, so the index will be turned off. 
Index Configuration Field: " + useIndexField);
+            conf.setBoolean(useIndexField, false);
+        }
+
+        // Otherwise use whatever the Client wants to use.
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/instance/RyaDetailsUpdater.java
----------------------------------------------------------------------
diff --git 
a/common/rya.api/src/main/java/org/apache/rya/api/instance/RyaDetailsUpdater.java
 
b/common/rya.api/src/main/java/org/apache/rya/api/instance/RyaDetailsUpdater.java
new file mode 100644
index 0000000..9d5dae7
--- /dev/null
+++ 
b/common/rya.api/src/main/java/org/apache/rya/api/instance/RyaDetailsUpdater.java
@@ -0,0 +1,124 @@
+/**
+ * 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 mvm.rya.api.instance;
+
+import static java.util.Objects.requireNonNull;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import mvm.rya.api.instance.RyaDetailsRepository.ConcurrentUpdateException;
+import mvm.rya.api.instance.RyaDetailsRepository.RyaDetailsRepositoryException;
+import 
mvm.rya.api.instance.RyaDetailsUpdater.RyaDetailsMutator.CouldNotApplyMutationException;
+
+/**
+ * A utility that will attempt to commit a change to a Rya instance's details
+ * until it either takes or the mutation can no longer be applied. This can
+ * can be used in place of boilerplate code that handles the concurrent nature
+ * of details updates.
+ */
+@ParametersAreNonnullByDefault
+public class RyaDetailsUpdater {
+    private static final Logger log = 
LoggerFactory.getLogger(RyaDetailsUpdater.class);
+
+    /**
+     * Applies a mutation to a an instance of {@link RyaDetails}.
+     */
+    @ParametersAreNonnullByDefault
+    public static interface RyaDetailsMutator {
+
+        /**
+         * Applies a mutation to a {@link RyaDetails} object.
+         *
+         * @param originalDetails - The {@link RyaDetails} that were just 
fetched
+         *   from the {@link RyaDetailsRepository}.
+         * @return The updated details.
+         * @throws CouldNotApplyMutationException The mutation could not be 
applied
+         *   to the supplied {@link RyaDetails}. This can be used to break out 
of
+         *   the update loop when the details are in a state the mutation can 
not
+         *   be applied to.
+         */
+        public RyaDetails mutate(RyaDetails originalDetails) throws 
CouldNotApplyMutationException;
+
+        /**
+         * Indicates a mutation could not be applied to an instance of {@link 
RyaDetails}.
+         */
+        public static class CouldNotApplyMutationException extends Exception {
+            private static final long serialVersionUID = 1L;
+
+            /**
+             * Constructs a new exception with the specified detail message.  
The
+             * cause is not initialized, and may subsequently be initialized by
+             * a call to {@link #initCause(Throwable)}.
+             *
+             * @param   message   the detail message. The detail message is 
saved for
+             *          later retrieval by the {@link #getMessage()} method.
+             */
+            public CouldNotApplyMutationException(final String message) {
+                super(message);
+            }
+        }
+    }
+
+    private final RyaDetailsRepository repo;
+
+    /**
+     * Constructs an instance of {@link RyaDetailsUpdater}.
+     *
+     * @param repo - The repository that this updater will commit changes to. 
(not null)
+     */
+    public RyaDetailsUpdater(final RyaDetailsRepository repo) {
+        this.repo = requireNonNull(repo);
+    }
+
+    /**
+     * Updates an instance of {@link RyaDetails} by fetching the details from
+     * the {@link RyaDetailsRepository} that was supplied at construction time,
+     * applying the {@link RyaDetailsMutator} to them, and them committing the
+     * change. If the update failed because of a concurrent update problem, 
then
+     * it will try again. The updater will continue to do this until the 
changes
+     * take or another exception type is thrown.
+     *
+     * @param mutator - The mutator that will be used to apply a chagne to the
+     *   repository's {@link RyaDetails}.
+     * @throws RyaDetailsRepositoryException A repository side error caused
+     *   the update to fail. This could be a communications problem with the
+     *   store repository, uninitialized, etc.
+     * @throws CouldNotApplyMutationException An application side error caused
+     *   the update to fail. This is thrown by the mutator when the details
+     *   would be in an illegal state if the mutation were to be applied.
+     */
+    public void update(final RyaDetailsMutator mutator) throws 
RyaDetailsRepositoryException, CouldNotApplyMutationException {
+        requireNonNull(mutator);
+
+        boolean updated = false;
+        while(!updated) {
+            try {
+                final RyaDetails original = repo.getRyaInstanceDetails();
+                final RyaDetails mutated = mutator.mutate(original);
+                repo.update(original, mutated);
+                updated = true;
+            } catch(final ConcurrentUpdateException e) {
+                log.debug("Failed to update the details because another 
application changed them. Trying again.", e);
+            }
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/layout/TableLayoutStrategy.java
----------------------------------------------------------------------
diff --git 
a/common/rya.api/src/main/java/org/apache/rya/api/layout/TableLayoutStrategy.java
 
b/common/rya.api/src/main/java/org/apache/rya/api/layout/TableLayoutStrategy.java
new file mode 100644
index 0000000..61732d3
--- /dev/null
+++ 
b/common/rya.api/src/main/java/org/apache/rya/api/layout/TableLayoutStrategy.java
@@ -0,0 +1,40 @@
+package mvm.rya.api.layout;
+
+/*
+ * 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.
+ */
+
+
+
+/**
+ * Created by IntelliJ IDEA.
+ * Date: 4/25/12
+ * Time: 12:20 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public interface TableLayoutStrategy {
+    
+    public String getSpo();
+    public String getPo();
+    public String getOsp();
+    public String getNs();
+    public String getEval();
+    public String getProspects();
+    public String getSelectivity();
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/layout/TablePrefixLayoutStrategy.java
----------------------------------------------------------------------
diff --git 
a/common/rya.api/src/main/java/org/apache/rya/api/layout/TablePrefixLayoutStrategy.java
 
b/common/rya.api/src/main/java/org/apache/rya/api/layout/TablePrefixLayoutStrategy.java
new file mode 100644
index 0000000..0e995ab
--- /dev/null
+++ 
b/common/rya.api/src/main/java/org/apache/rya/api/layout/TablePrefixLayoutStrategy.java
@@ -0,0 +1,85 @@
+package mvm.rya.api.layout;
+
+/*
+ * 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.
+ */
+
+
+
+import mvm.rya.api.RdfCloudTripleStoreConstants;
+
+/**
+ * Created by IntelliJ IDEA.
+ * Date: 4/25/12
+ * Time: 12:20 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class TablePrefixLayoutStrategy implements TableLayoutStrategy{
+    private String tablePrefix = RdfCloudTripleStoreConstants.TBL_PRFX_DEF;
+
+    public TablePrefixLayoutStrategy() {
+    }
+
+    public TablePrefixLayoutStrategy(String tablePrefix) {
+        this.tablePrefix = tablePrefix;
+    }
+
+    @Override
+    public String getSpo() {
+        return tablePrefix + RdfCloudTripleStoreConstants.TBL_SPO_SUFFIX;
+    }
+
+    @Override
+    public String getPo() {
+        return tablePrefix + RdfCloudTripleStoreConstants.TBL_PO_SUFFIX;
+    }
+
+    @Override
+    public String getOsp() {
+        return tablePrefix + RdfCloudTripleStoreConstants.TBL_OSP_SUFFIX;
+    }
+
+    @Override
+    public String getNs() {
+        return tablePrefix + RdfCloudTripleStoreConstants.TBL_NS_SUFFIX;
+    }
+
+    @Override
+    public String getEval() {
+        return tablePrefix + RdfCloudTripleStoreConstants.TBL_EVAL_SUFFIX;
+    }
+
+    @Override
+    public String getProspects() {
+        return tablePrefix + RdfCloudTripleStoreConstants.TBL_STATS_SUFFIX;
+    }
+    
+    @Override
+    public String getSelectivity() {
+        return tablePrefix + RdfCloudTripleStoreConstants.TBL_SEL_SUFFIX;
+    }
+
+    
+    public String getTablePrefix() {
+        return tablePrefix;
+    }
+
+    public void setTablePrefix(String tablePrefix) {
+        this.tablePrefix = tablePrefix;
+    }
+}


Reply via email to