package timeflow.data.db;
import java.net.URL;
import java.util.*;
import timeflow.data.db.filter.*;
import timeflow.data.time.*;
public class ArrayDB implements ActDB {
private Schema schema;
private List<Act> data=new ArrayList<Act>();
private Field[] fields;
private String source="[unknown]";
private String description="";
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
@Override
public void setAlias(Field field, String name) {
schema.addAlias(field,name);
}
public ArrayDB(String[] fieldNames, Class[] types, String source)
{
this.schema=new Schema();
this.source=source;
int n=fieldNames.length;
fields=new Field[n];
for (int i=0; i<n; i++)
{
fields[i]=schema.add(fieldNames[i], types[i]);
fields[i].index=i;
}
}
public Field[] getFieldArray()
{
return fields;
}
@Override
public Field addField(String name, Class type) {
int n=fields.length;
// make new Field.
Field field=new Field(name, type);
field.index=n;
// make new array of fields.
Field[] moreFields=new Field[n+1];
System.arraycopy(fields, 0, moreFields, 0, n);
moreFields[n]=field;
this.fields=moreFields;
// go through all the data items and expand their arrays, too.
for (Act d: data)
{
IndexedAct item=(IndexedAct)d;
Object[] old=item.data;
item.data=new Object[n+1];
System.arraycopy(old,0,item.data,0,n);
}
//System.out.println("Field added: "+field);
schema.add(field);
return field;
}
public Field getField(String name)
{
return schema.getField(name);
}
@Override
public ActList all() {
return select(null);
}
@Override
public Act createAct() {
IndexedAct act=new IndexedAct(this, fields.length);
data.add(act);
return act;
}
@Override
public void delete(Act act) {
data.remove(act);
}
@Override
public void deleteField(Field deadField) {
System.out.println("Deleting: "+deadField);
schema.delete(deadField);
int n=fields.length;
int m=deadField.index;
// make new array of fields.
Field[] fewerFields=new Field[n-1];
removeItem(fields, fewerFields, m);
fields=fewerFields;
// go through all the data items and contract their arrays, too.
for (Act d: data)
{
IndexedAct item=(IndexedAct)d;
Object[] old=item.data;
item.data=new Object[n-1];
removeItem(old,item.data,m);
}
// change field indices
for (int i=0; i<fields.length; i++)
{
System.out.println("fields["+i+"]="+fields[i]);
if (fields[i].index>deadField.index)
fields[i].index--;
}
}
private static void removeItem(Object[] a, Object[] b, int m)
{
int n=a.length;
if (m>0)
System.arraycopy(a,0,b,0,m);
if (m<n-1)
System.arraycopy(a,m+1, b, m,n-m-1);
}
@Override
public List<Field> getFields(Class type) {
return schema.getFields(type);
}
@Override
public ActList select(ActFilter filter) {
ActList set=new ActList(this);
for (Act a: data)
if (filter==null || filter.accept(a))
set.add(a);
return set;
}
@Override
public List<Field> getFields() {
return schema.getFields();
}
@Override
public Act get(int i) {
return data.get(i);
}
@Override
public int size() {
return data.size();
}
@Override
public Iterator<Act> iterator() {
return data.iterator();
}
@Override
public List<String> getFieldKeys() {
return schema.getKeys();
}
@Override
public void setNewFieldOrder(List<Field> newOrder) {
schema.setNewFieldOrder(newOrder);
}
class IndexedAct implements Act {
Object[] data;
ActDB db;
IndexedAct(ActDB db, int numFields)
{
this.db=db;
data=new Object[numFields];
}
@Override
public String getString(Field field) {
return (String)data[field.index];
}
public void setText(Field field, String text)
{
data[field.index]=text;
}
@Override
public String[] getTextList(Field field) {
return (String[])data[field.index];
}
public void setTextList(Field field, String[] list){
data[field.index]=list;
}
@Override
public double getValue(Field field) {
Double d=(Double)data[field.index];
return d==null ? Double.NaN : d.doubleValue();
}
public void setValue(Field field, double value)
{
data[field.index]=value;
}
@Override
public Object get(Field field) {
return data[field.index];
}
@Override
public ActDB getDB() {
return db;
}
@Override
public void set(Field field, Object value) {
data[field.index]=value;
}
@Override
public RoughTime getTime(Field field) {
return (RoughTime)data[field.index];
}
@Override
public void setTime(Field field, RoughTime time) {
data[field.index]=time;
}
@Override
public URL getURL(Field field) {
return (URL)data[field.index];
}
@Override
public void setURL(Field field, URL url) {
data[field.index]=url;
}
}
@Override
public void renameField(Field field, String name) {
schema.renameField(field, name);
}
}