/*
* ARX: Powerful Data Anonymization
* Copyright 2012 - 2017 Fabian Prasser, Florian Kohlmayer and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.deidentifier.arx;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.deidentifier.arx.DataType.ARXDate;
import org.deidentifier.arx.DataType.ARXDecimal;
import de.linearbits.objectselector.IAccessor;
import de.linearbits.objectselector.Selector;
import de.linearbits.objectselector.SelectorBuilder;
import de.linearbits.objectselector.datatypes.DataType;
/**
* A selector for tuples.
*
* @author Fabian Prasser
* @author Florian Kohlmayer
*/
public class DataSelector {
/**
* An accessor for data elements.
*
* @author Fabian Prasser
*/
private class DataAccessor implements IAccessor<Integer>{
/** The data handle. */
private final DataHandle handle;
/** The data definition. */
private final DataDefinition definition;
/** The data types. */
private final Map<String, DataType<?>> types;
/** The indices. */
private final Map<String, Integer> indices;
/**
* Creates a new instance.
*
* @param data
*/
protected DataAccessor(Data data){
this.handle = data.getHandle();
this.definition = data.getDefinition();
this.types = getTypes();
this.indices = getIndices();
}
@Override
public boolean exists(String arg0) {
return indices.containsKey(arg0);
}
@Override
public DataType<?> getType(String arg0) {
return types.get(arg0);
}
@Override
public Object getValue(Integer arg0, String arg1) {
int column = indices.get(arg1);
DataType<?> type = types.get(arg1);
String value = handle.getValue(arg0, column);
return type.fromString(value);
}
@Override
public boolean isDataTypesSupported() {
return true;
}
@Override
public boolean isExistanceSupported() {
return true;
}
/**
* Returns the indices.
*
* @return
*/
private Map<String, Integer> getIndices() {
Map<String, Integer> result = new HashMap<String, Integer>();
for (int i=0; i<handle.getNumColumns(); i++){
result.put(handle.getAttributeName(i), i);
}
return result;
}
/**
* Returns the data types.
*
* @return
*/
private Map<String, DataType<?>> getTypes() {
Map<String, DataType<?>> result = new HashMap<String, DataType<?>>();
for (int i=0; i<handle.getNumColumns(); i++){
String attribute = handle.getAttributeName(i);
org.deidentifier.arx.DataType<?> type = definition.getDataType(attribute);
if (type instanceof org.deidentifier.arx.DataType.ARXDecimal){
String format = ((ARXDecimal)type).getFormat();
result.put(attribute, DataType.NUMERIC(format));
} else if (type instanceof org.deidentifier.arx.DataType.ARXInteger) {
result.put(attribute, DataType.NUMERIC);
} else if (type instanceof org.deidentifier.arx.DataType.ARXString) {
result.put(attribute, DataType.STRING);
} else if (type instanceof org.deidentifier.arx.DataType.ARXDate){
String format = ((ARXDate)type).getFormat();
result.put(attribute, DataType.DATE(format));
} else {
result.put(attribute, DataType.STRING);
}
}
return result;
}
}
/**
*
*
* @param data
* @return
*/
public static DataSelector create(Data data){
return new DataSelector(data);
}
/**
*
*
* @param data
* @param query
* @return
* @throws ParseException
*/
public static DataSelector create(Data data, String query) throws ParseException{
return new DataSelector(data, query);
}
/** The builder. */
private final SelectorBuilder<Integer> builder;
/** The selector. */
private Selector<Integer> selector = null;
/**
*
*
* @param data
*/
private DataSelector(Data data){
this.builder = new SelectorBuilder<Integer>(new DataAccessor(data));
}
/**
*
*
* @param data
* @param query
* @throws ParseException
*/
private DataSelector(Data data, String query) throws ParseException {
this.builder = new SelectorBuilder<Integer>(new DataAccessor(data), query);
}
/**
*
*
* @return
*/
public DataSelector and(){
this.builder.and();
return this;
}
/**
*
*
* @return
*/
public DataSelector begin(){
this.builder.begin();
return this;
}
/**
*
*
* @throws ParseException
*/
public void build() throws ParseException{
this.selector = this.builder.build();
}
/**
*
*
* @return
*/
public DataSelector end(){
this.builder.end();
return this;
}
/**
*
*
* @param val
* @return
*/
public DataSelector equals(final Date val){
this.builder.equals(val);
return this;
}
/**
*
*
* @param val
* @return
*/
public DataSelector equals(final double val){
this.builder.equals(val);
return this;
}
/**
*
*
* @param val
* @return
*/
public DataSelector equals(final String val){
this.builder.equals(val);
return this;
}
/**
*
*
* @param name
* @return
*/
public DataSelector field(String name){
this.builder.field(name);
return this;
}
/**
*
*
* @param val
* @return
*/
public DataSelector geq(final Date val){
this.builder.geq(val);
return this;
}
/**
*
*
* @param val
* @return
*/
public DataSelector geq(final double val){
this.builder.geq(val);
return this;
}
/**
*
*
* @param val
* @return
*/
public DataSelector geq(final String val){
this.builder.geq(val);
return this;
}
/**
*
*
* @param val
* @return
*/
public DataSelector greater(final Date val){
this.builder.greater(val);
return this;
}
/**
*
*
* @param val
* @return
*/
public DataSelector greater(final double val){
this.builder.greater(val);
return this;
}
/**
*
*
* @param val
* @return
*/
public DataSelector greater(final String val){
this.builder.greater(val);
return this;
}
/**
* Determines whether the given row is selected by the expression.
*
* @param row
* @return
*/
public boolean isSelected(int row){
if (selector == null) {
try {
build();
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
return selector.isSelected(row);
}
/* **************************************
* Datetime
* **************************************/
/**
*
*
* @param val
* @return
*/
public DataSelector leq(final Date val){
this.builder.leq(val);
return this;
}
/*
* NUMERIC
*/
/**
*
*
* @param val
* @return
*/
public DataSelector leq(final double val){
this.builder.leq(val);
return this;
}
/* **************************************
* STRING
* **************************************/
/**
*
*
* @param val
* @return
*/
public DataSelector leq(final String val){
this.builder.leq(val);
return this;
}
/**
*
*
* @param val
* @return
*/
public DataSelector less(final Date val){
this.builder.less(val);
return this;
}
/**
*
*
* @param val
* @return
*/
public DataSelector less(final double val){
this.builder.less(val);
return this;
}
/**
*
*
* @param val
* @return
*/
public DataSelector less(final String val){
this.builder.less(val);
return this;
}
/**
*
*
* @return
*/
public DataSelector or(){
this.builder.or();
return this;
}
}