com.datastax.data.dataset.DataSet Maven / Gradle / Ivy
The newest version!
package com.datastax.data.dataset;
import com.datastax.data.dataset.event.TableChangeEvent;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.*;
import java.math.BigDecimal;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
public class DataSet {
public enum OutputControl { ALL_ROWS, MODIFIED_ONLY };
private static final Logger LOG = Logger.getLogger(DataSet.class.getName());
protected static final String DEFAULT_NAME_PREFIX = "DataSource";
private static final NameGenerator NAMEGEN = new NameGenerator(DEFAULT_NAME_PREFIX);
private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
private String name;
private Map tables = new HashMap();
private Map relations = new HashMap();
private Map values = new HashMap();
private Parser parser;
private NameChangeListener nameChangeListener = new NameChangeListener();
public DataSet() {
setName(NAMEGEN.generateName(this));
}
public DataSet(String name) {
setName(name);
}
public void setName(String name) {
if (this.name != name) {
assert DataSetUtils.isValidName(name);
String oldName = this.name;
this.name = name;
pcs.firePropertyChange("name", oldName, name);
}
}
public String getName() {
return name;
}
public DataTable createTable() {
return createTable(null);
}
public DataTable createTable(String name) {
DataTable table = new DataTable(this, name);
table.addPropertyChangeListener("name", nameChangeListener);
tables.put(table.getName(), table);
return table;
}
public DataRelationTable createRelationTable() {
return createRelationTable(null);
}
public DataRelationTable createRelationTable(String name) {
DataRelationTable table = new DataRelationTable(this, name);
table.addPropertyChangeListener("name", nameChangeListener);
tables.put(table.getName(), table);
return table;
}
public DataRelation createRelation() {
return createRelation(null);
}
public DataRelation createRelation(String name) {
DataRelation relation = new DataRelation(this, name);
relation.addPropertyChangeListener("name", nameChangeListener);
relations.put(relation.getName(), relation);
return relation;
}
public DataValue createValue() {
return createValue(null);
}
public DataValue createValue(String name) {
DataValue value = new DataValue(this, name);
value.addPropertyChangeListener("name", nameChangeListener);
values.put(value.getName(), value);
return value;
}
public void dropTable(DataTable table) {
dropTable(table.getName());
}
public void dropTable(String tableName) {
DataTable table = tables.remove(tableName);
if (table != null) {
table.removeFromDataSet();
table.removePropertyChangeListener("name", nameChangeListener);
for (DataRelation r : relations.values()) {
DataColumn col = r.getChildColumn();
if (col != null && col.getTable() == table) {
r.setChildColumn(null);
}
col = r.getParentColumn();
if (col != null && col.getTable() == table) {
r.setParentColumn(null);
}
}
for (DataTable t : tables.values()) {
if (t instanceof DataRelationTable) {
DataRelationTable drt = (DataRelationTable)t;
if (drt.getParentTable() == table) {
drt.setParentTable(null);
}
if (drt.getParentSelector() != null && drt.getParentSelector().getTable() == table) {
drt.setParentSelector(null);
}
}
}
}
}
public void dropRelationTable(DataRelationTable table) {
dropTable(table.getName());
}
public void dropRelationTable(String tableName) {
dropTable(tableName);
}
public void dropRelation(DataRelation relation) {
dropRelation(relation.getName());
}
public void dropRelation(String relationName) {
DataRelation relation = relations.remove(relationName);
if (relation != null) {
relation.removeFromDataSet();
relation.removePropertyChangeListener("name", nameChangeListener);
for (DataTable t : tables.values()) {
if (t instanceof DataRelationTable) {
DataRelationTable drt = (DataRelationTable)t;
if (drt.getRelation() == relation) {
drt.setRelation(null);
}
}
}
}
}
public void dropValue(DataValue value) {
dropValue(value.getName());
}
public void dropValue(String valueName) {
DataValue value = values.remove(valueName);
if (value != null) {
value.removeFromDataSet();
value.removePropertyChangeListener("name", nameChangeListener);
}
}
protected boolean hasElement(String name) {
boolean b = relations.containsKey(name);
if (!b) {
b = tables.containsKey(name);
}
if (!b) {
b = values.containsKey(name);
}
return b;
}
public Object getElement(String path) {
if (path == null) {
return null;
}
if (path.contains(".")) {
String[] steps = path.split("\\.");
assert steps.length == 2;
DataTable table = tables.get(steps[0]);
DataColumn col = table.getColumn(steps[1]);
if (col != null) {
return col;
} else {
return table.getSelector(steps[1]);
}
} else {
if (relations.containsKey(path)) {
return relations.get(path);
} else if (tables.containsKey(path)) {
return tables.get(path);
} else if (values.containsKey(path)) {
return values.get(path);
}
}
return null;
}
public List getRows(String path) {
if (path == null || path.trim().equals("")) {
return Collections.EMPTY_LIST;
}
path = path.trim();
String[] steps = path.split("\\.");
List workingSet = null;
for (String step : steps) {
String name = null;
String selectorName = null;
if (step.contains("[")) {
name = step.substring(0, step.indexOf('['));
selectorName = step.substring(step.indexOf('[')+1, step.indexOf(']'));
}
if (workingSet == null) {
DataTable table = tables.get(name);
if (table == null) {
assert false;
}
workingSet = table.getRows();
if (selectorName != null) {
}
} else {
DataRelation relation = relations.get(name);
if (relation == null) {
assert false;
}
workingSet = relation.getRows((DataRow[])workingSet.toArray(new DataRow[workingSet.size()]));
if (selectorName != null) {
}
}
}
return Collections.unmodifiableList(workingSet);
}
public List filterRows(List rows, DataSelector ds) {
List indices = ds.getRowIndices();
List results = new ArrayList(indices.size());
for (int index : indices) {
results.add(rows.get(index));
}
return results;
}
public List getColumns(String path) {
String[] parts = path.split("\\.");
assert parts.length == 1 || parts.length == 2;
DataTable table = tables.get(parts[0]);
if (table == null) {
DataRelation relation = relations.get(parts[0]);
if (relation == null) {
return new ArrayList();
} else {
table = relation.getChildColumn().getTable();
}
}
if (parts.length == 1) {
return table.getColumns();
} else {
List results = new ArrayList();
results.add(table.getColumn(parts[1]));
return Collections.unmodifiableList(results);
}
}
public DataTable getTable(String tableName) {
return tables.get(tableName);
}
public List getTables() {
List tableList = new ArrayList();
for(DataTable table : tables.values()) {
tableList.add(table);
}
return tableList;
}
public DataRelationTable getRelationTable(String name) {
return (DataRelationTable)tables.get(name);
}
public DataValue getValue(String valueName) {
return values.get(valueName);
}
public List getValues() {
List values = new ArrayList();
for (DataValue v : this.values.values()) {
values.add(v);
}
return values;
}
public DataRelation getRelation(String relationName) {
return relations.get(relationName);
}
public List getRelations() {
List relations = new ArrayList();
for (DataRelation r : this.relations.values()) {
relations.add(r);
}
return relations;
}
public void load() {
for (DataTable table : tables.values()) {
if (!(table instanceof DataRelationTable)) {
table.load();
}
}
}
public void loadAndWait() {
for (DataTable table : tables.values()) {
if (!(table instanceof DataRelationTable)) {
table.loadAndWait();
}
}
}
public void refresh() {
for (DataTable table : tables.values()) {
if (!(table instanceof DataRelationTable)) {
table.refresh();
}
}
}
public void refreshAndWait() {
for (DataTable table : tables.values()) {
if (!(table instanceof DataRelationTable)) {
table.refreshAndWait();
}
}
}
public void clear() {
for (DataTable table : tables.values()) {
if (!(table instanceof DataRelationTable)) {
table.clear();
}
}
}
public void save() {
for (DataTable table : tables.values()) {
if (!(table instanceof DataRelationTable)) {
table.save();
}
}
}
public void saveAndWait() {
for (DataTable table : tables.values()) {
if (!(table instanceof DataRelationTable)) {
table.saveAndWait();
}
}
}
Parser getParser() {
if (parser == null || parser.isInUse()) {
parser = new Parser(this);
}
return parser;
}
public static DataSet createFromSchema(String schema) {
return DataSetUtils.createFromXmlSchema(schema);
}
public String getSchema() {
return DataSetUtils.getXmlSchema(this);
}
public static DataSet createFromSchema(File f) throws FileNotFoundException {
return DataSetUtils.createFromXmlSchema(f);
}
public static DataSet createFromSchema(InputStream is) {
return DataSetUtils.createFromXmlSchema(is);
}
public void readXml(File f) {
String xml = "";
try {
FileInputStream fis = new FileInputStream(f);
readXml(fis);
fis.close();
} catch (Exception e) {
LOG.log(Level.SEVERE, "Failed to read xml from file {0}. {1}", new Object[]{f, e.getStackTrace()});
}
}
public void readXml(InputStream is) {
String xml = "";
try {
StringBuilder builder = new StringBuilder();
byte[] bytes = new byte[4096];
int length = -1;
while ((length = is.read(bytes)) != -1) {
builder.append(new String(bytes, 0, length));
}
xml = builder.toString();
readXml(xml);
} catch (Exception e) {
LOG.log(Level.SEVERE, "Failed to read xml from input stream.", e);
}
}
public void readXml(String xml) {
try {
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document dom = db.parse(new ByteArrayInputStream(xml.getBytes()));
XPath xpath = XPathFactory.newInstance().newXPath();
String path = null;
for (DataTable table : tables.values()) {
if (!(table instanceof DataRelationTable)) {
table.fireDataTableChanged(TableChangeEvent.newLoadStartEvent(table));
table.clear();
if ( !table.isAppendRowSupported()) {
LOG.fine("Table '" + table.getName() + "' does " +
"not support append row; skipping (regardless of " +
"input).");
continue;
}
LOG.finer("loading table " + table.getName());
path = "/" + name + "/" + table.getName();
NodeList nodes = (NodeList)xpath.evaluate(path, dom, XPathConstants.NODESET);
LOG.finer(" found " + nodes.getLength() + " rows for path " + path);
for (int i=0; i\n");
builder.append("<");
builder.append(name);
builder.append(">\n");
for (DataTable table : tables.values()) {
if (!(table instanceof DataRelationTable)) {
for (DataRow row : table.rows) {
if ( flags == OutputControl.MODIFIED_ONLY && row.getStatus() == DataRow.DataRowStatus.UNCHANGED ) {
continue;
}
builder.append("\t<");
builder.append(table.getName());
builder.append(">\n");
for (DataColumn col : table.columns.values()) {
builder.append("\t\t<");
builder.append(col.getName());
builder.append(">");
String val = row.getValue(col) == null ? "" : row.getValue(col).toString();
val = val.replaceAll("&", "&");
val = val.replaceAll("<", "<");
val = val.replaceAll(">", ">");
val = val.replaceAll("'", "'");
val = val.replaceAll("\"", """);
builder.append(val);
builder.append("");
builder.append(col.getName());
builder.append(">\n");
}
builder.append("\t");
builder.append(table.getName());
builder.append(">\n");
}
}
}
builder.append("");
builder.append(name);
builder.append(">");
return builder.toString();
}
public String toString() {
StringBuilder buffer = new StringBuilder();
buffer.append("DataSource: ").append(name).append("\n");
for (DataTable table : tables.values()) {
if (table instanceof DataRelationTable) {
buffer.append("\tDataRelationTable: ").append(table.getName()).append("\n");
} else {
buffer.append("\tDataTable: ").append(table.getName()).append("\n");
}
for (DataColumn col : table.getColumns()) {
buffer.append("\t\tDataColumn: ").append(col.getName()).append("\n");
}
}
for (DataRelation relation : relations.values()) {
buffer.append("\tRelation: ").append(relation.getName()).append("\n");
DataColumn parentColumn = relation.getParentColumn();
buffer.append("\t\tParentColumn: ").append(parentColumn == null ? "" : parentColumn.getTable().getName()).append(".").append(parentColumn == null ? "" : parentColumn.getName()).append("\n");
DataColumn childColumn = relation.getChildColumn();
buffer.append("\t\tChildColumn: ").append(childColumn == null ? "" : childColumn.getTable().getName()).append(".").append(childColumn == null ? "" : childColumn.getName()).append("\n");
}
buffer.append(getSchema());
return buffer.toString();
}
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
try {
DataSet ds = DataSetUtils.createFromXmlSchema(new File("/usr/local/src/databinding/src/test/org/data/dataset/contact.ds"));
} catch (Exception e) {
e.printStackTrace();
}
long stopTime = System.currentTimeMillis();
System.out.println((stopTime - startTime));
}
private final class NameChangeListener implements PropertyChangeListener {
public void propertyChange(PropertyChangeEvent evt) {
Object source = evt.getSource();
if (source instanceof DataTable) {
DataTable table = (DataTable)source;
tables.remove(evt.getOldValue());
tables.put((String)evt.getNewValue(), table);
} else if (source instanceof DataRelation) {
DataRelation relation = (DataRelation)source;
relations.remove(evt.getOldValue());
relations.put((String)evt.getNewValue(), relation);
} else if (source instanceof DataValue) {
DataValue value = (DataValue)source;
values.remove(evt.getOldValue());
values.put((String)evt.getNewValue(), value);
}
}
}
}