Permalink
Browse files

quick fixes, moved Interval into its own class, made IntervalSet immu…

…table, figured out better way to have alternate ID expressions.

Signed-off-by: gburgett <gordon.burgett@gmail.com>
  • Loading branch information...
1 parent 73023ec commit f8c191303a6b7327c1538b9c1d26176870b5fd7e @gburgett committed Jan 16, 2013
@@ -39,5 +39,5 @@
* @param clazz
* @return
*/
- public XPathExpression<?> idSelector(Class<?> clazz);
+ public XPathExpression<Object> idSelector(Class<?> clazz);
}
@@ -57,19 +57,19 @@ public ConversionService extend(ConversionService service) {
return new JAXBConversionService(service);
}
- private Map<Class<?>, XPathExpression<?>> idSelectorCache = new ConcurrentHashMap<>();
+ private Map<Class<?>, XPathExpression<Object>> idSelectorCache = new ConcurrentHashMap<>();
@Override
- public XPathExpression<?> idSelector(Class<?> clazz) {
- XPathExpression<?> ret = idSelectorCache.get(clazz);
+ public XPathExpression<Object> idSelector(Class<?> clazz) {
+ XPathExpression<Object> ret = idSelectorCache.get(clazz);
if(ret == null){
ret = makeIdSelector(clazz);
idSelectorCache.put(clazz, ret);
}
return ret;
}
- private XPathExpression<?> makeIdSelector(Class<?> clazz){
+ private XPathExpression<Object> makeIdSelector(Class<?> clazz){
IdAccessor accessor = IdAccessor.forClass(clazz);
if(!accessor.hasId()){
@@ -108,6 +108,9 @@ public ConversionService extend(ConversionService service) {
ret.append(accessor.getIdPropertyName());
}
}
+ else{
+ ret.append(accessor.getIdPropertyName());
+ }
}
if(ns == null){
@@ -23,6 +23,7 @@
import org.gburgett.xflat.query.XpathQuery;
import org.gburgett.xflat.query.XpathUpdate;
import org.jdom2.Element;
+import org.jdom2.xpath.XPathExpression;
/**
* A table implementation that converts objects to elements
@@ -36,9 +37,14 @@ public void setConversionService(ConversionService conversionService) {
this.conversionService = conversionService;
}
- private IdAccessor accessor;
+ private final IdAccessor accessor;
- private Map<T, String> idMap;
+ private final Map<T, String> idMap;
+
+ private XPathExpression<Object> alternateIdExpression;
+ void setAlternateIdExpression(XPathExpression<Object> expression){
+ this.alternateIdExpression = expression;
+ }
ConvertingTable(Class<T> type, String name){
super(type, name);
@@ -48,6 +54,10 @@ public void setConversionService(ConversionService conversionService) {
//we need to keep a reference to the ID in a weak cache
idMap = Collections.synchronizedMap(new WeakHashMap<T, String>());
}
+ else{
+ idMap = null;
+ }
+
}
//<editor-fold desc="helpers">
@@ -220,6 +230,8 @@ private Element findOneElement(XpathQuery query){
}
private Cursor<Element> queryTable(final XpathQuery query){
+ query.setAlternateIdExpression(alternateIdExpression);
+
return this.doWithEngine(new EngineAction<Cursor<Element>>(){
@Override
public Cursor<Element> act(Engine engine) {
@@ -230,6 +242,8 @@ private Element findOneElement(XpathQuery query){
@Override
public Cursor<T> find(final XpathQuery query) {
+ query.setAlternateIdExpression(alternateIdExpression);
+
return this.doWithEngine(new EngineAction<Cursor<T>>(){
@Override
public Cursor<T> act(Engine engine) {
@@ -367,6 +381,8 @@ public Boolean act(Engine engine) {
@Override
public int update(final XpathQuery query, final XpathUpdate update) {
+ query.setAlternateIdExpression(alternateIdExpression);
+
return this.doWithEngine(new EngineAction<Integer>(){
@Override
public Integer act(Engine engine) {
@@ -393,6 +409,8 @@ public Object act(Engine engine) {
@Override
public int deleteAll(final XpathQuery query) {
+ query.setAlternateIdExpression(alternateIdExpression);
+
return this.doWithEngine(new EngineAction<Integer>(){
@Override
public Integer act(Engine engine) {
@@ -4,18 +4,15 @@
*/
package org.gburgett.xflat.db;
-import org.gburgett.xflat.DatabaseConfig;
import org.gburgett.xflat.TableConfig;
import java.io.File;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.gburgett.xflat.XflatException;
-import org.gburgett.xflat.convert.ConversionException;
-import org.gburgett.xflat.db.EngineState;
+import org.gburgett.xflat.convert.PojoConverter;
import org.gburgett.xflat.db.EngineBase.SpinDownEvent;
import org.gburgett.xflat.db.EngineBase.SpinDownEventHandler;
-import org.jdom2.Document;
import org.jdom2.Element;
/**
@@ -98,7 +95,12 @@ public TableBase getTable(Class<?> clazz){
}
ConvertingTable<T> ret = new ConvertingTable<>(clazz, this.name);
+
ret.setConversionService(this.db.getConversionService());
+ PojoConverter converter = this.db.getPojoConverter();
+ if(converter != null){
+ ret.setAlternateIdExpression(converter.idSelector(clazz));
+ }
return ret;
}
@@ -426,9 +426,14 @@ public void extendConversionService(PojoConverter extender){
return (Table<T>)ret;
}
- private AtomicBoolean pojoConverter = new AtomicBoolean(false);
+ private AtomicBoolean pojoConverterLoaded = new AtomicBoolean(false);
+ private volatile PojoConverter pojoConverter;
+ public PojoConverter getPojoConverter(){
+ return pojoConverter;
+ }
+
private void loadPojoConverter() throws ClassNotFoundException, InstantiationException, IllegalAccessException{
- if(!pojoConverter.compareAndSet(false, true)){
+ if(!pojoConverterLoaded.compareAndSet(false, true)){
return;
}
Class<?> converter;
@@ -439,9 +444,9 @@ private void loadPojoConverter() throws ClassNotFoundException, InstantiationExc
return;
}
- PojoConverter obj = (PojoConverter)converter.newInstance();
+ this.pojoConverter = (PojoConverter)converter.newInstance();
- this.extendConversionService(obj);
+ this.extendConversionService(this.pojoConverter);
}
public enum DatabaseState{
@@ -0,0 +1,158 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.gburgett.xflat.query;
+
+import java.util.Comparator;
+import java.util.Objects;
+
+/**
+ * Represents one interval within an interval set. The interval
+ * is represented by two values, the begin and the end,
+ * which can be inclusive or exclusive.
+ * @param <U>
+ */
+public class Interval<U> {
+ final U begin;
+ final U end;
+
+ boolean endInclusive;
+ boolean beginInclusive;
+
+ /**
+ * Gets the begin value of this interval. A null value means negative infinity.
+ * @return
+ */
+ public U getBegin() {
+ return begin;
+ }
+
+ /**
+ * Gets the end value of this interval. A null value means positive infinity.
+ * @return
+ */
+ public U getEnd() {
+ return end;
+ }
+
+ /**
+ * Gets whether the interval is inclusive of the beginning.
+ * True means inclusive, false means exclusive.
+ * @return
+ */
+ public boolean getBeginInclusive() {
+ //Too late I realized it would have been better to do this having the booleans mean inclusive.
+ //Unfortunately too much work to undo it now, fortunately I hadn't written any public facing
+ //stuff based on that paradigm yet.
+ return this.beginInclusive;
+ }
+
+
+ /**
+ * Gets whether the interval is inclusive of the end.
+ * True means inclusive, false means exclusive.
+ * @return
+ */
+ public boolean getEndInclusive() {
+ return this.endInclusive;
+ }
+
+ public Interval(U begin, boolean beginInclusive, U end, boolean endInclusive) {
+ this.begin = begin;
+ this.end = end;
+ this.beginInclusive = beginInclusive;
+ this.endInclusive = endInclusive;
+ }
+
+ /**
+ * Returns true iff the given value is contained by this Interval, according
+ * to the given comparator.
+ * @param value The value to test.
+ * @param comparator The comparator used to compare values.
+ * @return true if the value is contained by the Interval, false otherwise.
+ */
+ public boolean contains(U value, Comparator<U> comparator) {
+ int lower = comparator.compare(value, begin);
+ if (lower < 0) {
+ return false;
+ }
+ if (lower == 0) {
+ return this.beginInclusive;
+ }
+ int upper = comparator.compare(value, end);
+ if (upper > 0) {
+ return false;
+ }
+ if (upper == 0) {
+ return this.endInclusive;
+ }
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 3;
+ hash = 67 * hash + Objects.hashCode(this.begin);
+ hash = 67 * hash + Objects.hashCode(this.end);
+ hash = 67 * hash + (this.beginInclusive ? 1 : 0);
+ hash = 67 * hash + (this.endInclusive ? 1 : 0);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final Interval<U> other = (Interval<U>) obj;
+ if (!Objects.equals(this.begin, other.begin)) {
+ return false;
+ }
+ if (!Objects.equals(this.end, other.end)) {
+ return false;
+ }
+ if (this.beginInclusive != other.beginInclusive) {
+ return false;
+ }
+ if (this.endInclusive != other.endInclusive) {
+ return false;
+ }
+ return true;
+ }
+
+ public void toString(StringBuilder sb) {
+ if (beginInclusive) {
+ sb.append('[');
+ } else {
+ sb.append('(');
+ }
+ if (begin != null) {
+ sb.append(begin);
+ } else {
+ sb.append("-∞");
+ }
+ sb.append(", ");
+ if (end != null) {
+ sb.append(end);
+ } else {
+ sb.append("");
+ }
+ if (endInclusive) {
+ sb.append(']');
+ } else {
+ sb.append(')');
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ toString(sb);
+ return sb.toString();
+ }
+
+}
Oops, something went wrong.

0 comments on commit f8c1913

Please sign in to comment.