Skip to content

Commit

Permalink
quick fixes, moved Interval into its own class, made IntervalSet immu…
Browse files Browse the repository at this point in the history
…table, figured out better way to have alternate ID expressions.

Signed-off-by: gburgett <gordon.burgett@gmail.com>
  • Loading branch information
gburgett committed Jan 16, 2013
1 parent 73023ec commit f8c1913
Show file tree
Hide file tree
Showing 8 changed files with 334 additions and 249 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,5 @@ public interface PojoConverter {
* @param clazz
* @return
*/
public XPathExpression<?> idSelector(Class<?> clazz);
public XPathExpression<Object> idSelector(Class<?> clazz);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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()){
Expand Down Expand Up @@ -108,6 +108,9 @@ private XPathExpression<?> makeIdSelector(Class<?> clazz){
ret.append(accessor.getIdPropertyName());
}
}
else{
ret.append(accessor.getIdPropertyName());
}
}

if(ns == null){
Expand Down
22 changes: 20 additions & 2 deletions java/XFlat/src/org/gburgett/xflat/db/ConvertingTable.java
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
Expand All @@ -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">
Expand Down Expand Up @@ -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) {
Expand All @@ -230,6 +242,8 @@ public Cursor<Element> act(Engine engine) {

@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) {
Expand Down Expand Up @@ -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) {
Expand All @@ -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) {
Expand Down
10 changes: 6 additions & 4 deletions java/XFlat/src/org/gburgett/xflat/db/TableMetadata.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand Down Expand Up @@ -98,7 +95,12 @@ private <T> TableBase makeTableForClass(Class<T> 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;
}

Expand Down
13 changes: 9 additions & 4 deletions java/XFlat/src/org/gburgett/xflat/db/XFlatDatabase.java
Original file line number Diff line number Diff line change
Expand Up @@ -426,9 +426,14 @@ public <T> Table<T> getTable(Class<T> type, String name){
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;
Expand All @@ -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{
Expand Down
158 changes: 158 additions & 0 deletions java/XFlat/src/org/gburgett/xflat/query/Interval.java
Original file line number Diff line number Diff line change
@@ -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();
}

}
Loading

0 comments on commit f8c1913

Please sign in to comment.