com.datastax.data.dataset.DataColumn Maven / Gradle / Ivy
The newest version!
package com.datastax.data.dataset;
import com.datastax.data.dataset.event.DataTableEventAdapter;
import com.datastax.data.dataset.event.RowChangeEvent;
import com.datastax.data.dataset.event.TableChangeEvent;
import net.sf.jga.fn.UnaryFunctor;
import net.sf.jga.parser.ParseException;
import net.sf.jga.parser.UnaryFunctorRef;
import net.sf.jga.parser.UncheckedParseException;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
public class DataColumn {
private static final Logger LOG = Logger.getLogger(DataColumn.class.getName());
protected static final String DEFAULT_NAME_PREFIX = "DataColumn";
private static final NameGenerator NAMEGEN = new NameGenerator(DEFAULT_NAME_PREFIX);
private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
private DataTable table;
private String name = NAMEGEN.generateName(this);
private Class type = Object.class;
private boolean readOnly = false;
private boolean required = false;
private Object defaultValue;
private boolean keyColumn;
private String expression;
private UnaryFunctor expImpl;
protected DataColumn(DataTable table) {
assert table != null;
this.table = table;
}
public DataTable getTable() {
return table;
}
void removeFromTable() {
table = null;
if (expImpl != null) {
Parser.unregister(expImpl, listener, sources);
}
}
public String getName() {
return name;
}
public void setName(String name) {
if (this.name != name) {
assert DataSetUtils.isValidName(name);
assert !table.columns.containsKey(name) && !table.selectors.containsKey(name);
String oldName = this.name;
this.name = name;
pcs.firePropertyChange("name", oldName, name);
}
}
public Class getType() {
if (expression != null && expression.length() > 0 && expImpl == null)
expImpl = parseExpression();
return type;
}
public void setType(Class type) {
if (this.type != type) {
Class oldType = this.type;
this.type = type == null ? Object.class : type;
pcs.firePropertyChange("type", oldType, type);
}
}
public boolean isReadOnly() {
return readOnly;
}
public void setReadOnly(boolean readOnly) {
if (this.readOnly != readOnly) {
boolean oldValue = this.readOnly;
this.readOnly = readOnly;
pcs.firePropertyChange("readOnly", oldValue, readOnly);
}
}
public boolean isRequired() {
return required || keyColumn;
}
public void setRequired(boolean required) {
if (this.required != required) {
boolean oldValue = this.required;
this.required = required;
pcs.firePropertyChange("required", oldValue, required);
}
}
public Object getDefaultValue() {
return defaultValue;
}
public void setDefaultValue(Object defaultValue) {
if (this.defaultValue != defaultValue) {
Object oldVal = this.defaultValue;
this.defaultValue = defaultValue;
pcs.firePropertyChange("defaultValue", oldVal, defaultValue);
}
}
public boolean isKeyColumn() {
return keyColumn;
}
public void setKeyColumn(boolean value) {
if (value != keyColumn) {
boolean oldVal = keyColumn;
keyColumn = value;
pcs.firePropertyChange("keyColumn", oldVal, value);
if (!oldVal && value && !required) {
pcs.firePropertyChange("required", required, true);
} else if (oldVal && !value && !required) {
pcs.firePropertyChange("required", true, required);
}
}
}
public String getExpression() {
return expression;
}
public void setExpression(String expression) {
if (expression == null) {
expression = "";
}
if ( !(expression.equals(this.expression))) {
String oldExpression = this.expression;
this.expression = expression;
pcs.firePropertyChange("expression", oldExpression, expression);
if (expImpl != null) {
Parser.unregister(expImpl, listener, sources);
expImpl = null;
}
}
}
public Object getValueForRow(DataRow row) {
if (expImpl == null) {
if (expression == null || expression.equals("")) {
expImpl = null;
} else {
expImpl = parseExpression();
}
}
return expImpl == null ? null : expImpl.fn(row);
}
public String toString() {
if (table == null)
return "Column "+getName()+" [dropped]";
return "Column "+getTable().getName()+"."+getName();
}
private Parser getParser() { return getTable().getDataSet().getParser(); }
private boolean isParsing = false;
synchronized private UnaryFunctor parseExpression() {
LOG.log(Level.FINE, "Attempting to create the expression implementation");
if (isParsing) {
throw new UncheckedParseException("Circular Reference Exception");
}
try {
isParsing = true;
Parser parser = getParser();
UnaryFunctorRef ref = parser.parseComputedColumn(getTable(),this,expression);
UnaryFunctor uf = ref.getFunctor();
sources = Parser.register(uf, this, listener);
setType(ref.getReturnType());
return uf;
}
catch (ParseException pe) {
if (pe.getCause() instanceof UncheckedParseException)
throw (UncheckedParseException) pe.getCause();
LOG.log(Level.FINE, "The expression [{0}] is not valid. {1}",
new Object[]{expression, pe});
type = Void.TYPE;
return null;
}
finally {
isParsing = false;
}
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
pcs.addPropertyChangeListener(listener);
}
public void addPropertyChangeListener(String property, PropertyChangeListener listener) {
pcs.addPropertyChangeListener(property, listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
pcs.removePropertyChangeListener(listener);
}
public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
pcs.removePropertyChangeListener(propertyName, listener);
}
private Set sources = new HashSet();
boolean dependsOn(Object element){
if (element == this)
return true;
for(Object obj : sources) {
if (obj == element)
return true;
if (obj instanceof DataColumn) {
if (((DataColumn) obj).dependsOn(element))
return true;
}
if (obj instanceof DataValue) {
if (((DataValue) obj).dependsOn(element))
return true;
}
}
return false;
}
DataTableEventAdapter listener = new DataTableEventAdapter() {
public void propertyChange(PropertyChangeEvent evt) {
super.propertyChange(evt);
getTable().fireDataTableChanged(
TableChangeEvent.newColumnChangedEvent(getTable(),DataColumn.this));
}
public void cellChanged(RowChangeEvent evt) {
DataRow row = (DataRow) evt.getSource();
DataColumn col = evt.getColumnAffected();
if (sources.contains(col)) {
row.fireDataRowChanged(RowChangeEvent.newCellChangedEvent(row,
DataColumn.this, null, evt.getPriorRowStatus()));
}
}
};
}