Make persistence layer independent from Village API.
This commit is contained in:
parent
e3061ffba2
commit
df3b4de13f
5 changed files with 362 additions and 236 deletions
|
@ -20,6 +20,8 @@ public final class DbColumn {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.relation = rel;
|
this.relation = rel;
|
||||||
|
if (relation != null)
|
||||||
|
relation.setColumnType (type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,4 +45,4 @@ public final class DbColumn {
|
||||||
return relation;
|
return relation;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,8 +58,11 @@ public final class DbMapping implements Updatable {
|
||||||
DbColumn[] columns = null;
|
DbColumn[] columns = null;
|
||||||
// Map of db columns by name
|
// Map of db columns by name
|
||||||
HashMap columnMap;
|
HashMap columnMap;
|
||||||
|
|
||||||
// pre-rendered select statement
|
// pre-rendered select statement
|
||||||
String select = null;
|
String selectString = null;
|
||||||
|
String insertString = null;
|
||||||
|
String updateString = null;
|
||||||
|
|
||||||
// db field used as primary key
|
// db field used as primary key
|
||||||
private String idField;
|
private String idField;
|
||||||
|
@ -194,7 +197,7 @@ public final class DbMapping implements Updatable {
|
||||||
// same with columns and select string
|
// same with columns and select string
|
||||||
columns = null;
|
columns = null;
|
||||||
columnMap.clear();
|
columnMap.clear();
|
||||||
select = null;
|
selectString = insertString = updateString = null;
|
||||||
|
|
||||||
|
|
||||||
if (extendsProto != null) {
|
if (extendsProto != null) {
|
||||||
|
@ -634,14 +637,40 @@ public final class DbMapping implements Updatable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public StringBuffer getSelect () throws SQLException, ClassNotFoundException {
|
public StringBuffer getSelect () throws SQLException, ClassNotFoundException {
|
||||||
String sel = select;
|
String sel = selectString;
|
||||||
if (sel != null)
|
if (sel != null)
|
||||||
return new StringBuffer (sel);
|
return new StringBuffer (sel);
|
||||||
StringBuffer s = new StringBuffer ("SELECT * FROM ");
|
StringBuffer s = new StringBuffer ("SELECT * FROM ");
|
||||||
s.append (getTableName ());
|
s.append (getTableName ());
|
||||||
s.append (" ");
|
s.append (" ");
|
||||||
// cache rendered string for later calls.
|
// cache rendered string for later calls.
|
||||||
select = s.toString();
|
selectString = s.toString();
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public StringBuffer getInsert () {
|
||||||
|
String ins = insertString;
|
||||||
|
if (ins != null)
|
||||||
|
return new StringBuffer (ins);
|
||||||
|
StringBuffer s = new StringBuffer ("INSERT INTO ");
|
||||||
|
s.append (getTableName ());
|
||||||
|
s.append (" ( ");
|
||||||
|
s.append (getIDField());
|
||||||
|
// cache rendered string for later calls.
|
||||||
|
insertString = s.toString();
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringBuffer getUpdate () {
|
||||||
|
String upd = updateString;
|
||||||
|
if (upd != null)
|
||||||
|
return new StringBuffer (upd);
|
||||||
|
StringBuffer s = new StringBuffer ("UPDATE ");
|
||||||
|
s.append (getTableName ());
|
||||||
|
s.append (" SET ");
|
||||||
|
// cache rendered string for later calls.
|
||||||
|
updateString = s.toString();
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1748,11 +1748,20 @@ public final class Node implements INode, Serializable {
|
||||||
if (propMap == null)
|
if (propMap == null)
|
||||||
return;
|
return;
|
||||||
try {
|
try {
|
||||||
Property p = (Property) propMap.remove (propname.toLowerCase ());
|
// if node is relational, leave a null property so that it is
|
||||||
|
// updated in the DB. Otherwise, remove the property.
|
||||||
|
Property p;
|
||||||
|
boolean relational = dbmap != null && dbmap.isRelational();
|
||||||
|
if (relational)
|
||||||
|
p = (Property) propMap.get (propname.toLowerCase ());
|
||||||
|
else
|
||||||
|
p = (Property) propMap.remove (propname.toLowerCase ());
|
||||||
if (p != null) {
|
if (p != null) {
|
||||||
checkWriteLock ();
|
checkWriteLock ();
|
||||||
if (p.getType() == Property.NODE)
|
if (p.getType() == Property.NODE)
|
||||||
p.unregisterNode ();
|
p.unregisterNode ();
|
||||||
|
if (relational)
|
||||||
|
p.setStringValue (null);
|
||||||
// Server.throwNodeEvent (new NodeEvent (this, NodeEvent.PROPERTIES_CHANGED));
|
// Server.throwNodeEvent (new NodeEvent (this, NodeEvent.PROPERTIES_CHANGED));
|
||||||
lastmodified = System.currentTimeMillis ();
|
lastmodified = System.currentTimeMillis ();
|
||||||
if (state == CLEAN)
|
if (state == CLEAN)
|
||||||
|
|
|
@ -9,7 +9,6 @@ import helma.framework.core.Application;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import com.workingdogs.village.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The NodeManager is responsible for fetching Nodes from the internal or
|
* The NodeManager is responsible for fetching Nodes from the internal or
|
||||||
|
@ -410,62 +409,117 @@ public final class NodeManager {
|
||||||
db.saveNode (txn, node.getID (), node);
|
db.saveNode (txn, node.getID (), node);
|
||||||
} else {
|
} else {
|
||||||
// app.logEvent ("inserting relational node: "+node.getID ());
|
// app.logEvent ("inserting relational node: "+node.getID ());
|
||||||
TableDataSet tds = null;
|
|
||||||
|
DbColumn[] columns = dbm.getColumns ();
|
||||||
|
|
||||||
|
StringBuffer b1 = dbm.getInsert ();
|
||||||
|
StringBuffer b2 = new StringBuffer (" ) VALUES ( ?");
|
||||||
|
|
||||||
|
String nameField = dbm.getNameField ();
|
||||||
|
String prototypeField = dbm.getPrototypeField ();
|
||||||
|
|
||||||
|
for (int i=0; i<columns.length; i++) {
|
||||||
|
Relation rel = columns[i].getRelation();
|
||||||
|
String name = columns[i].getName();
|
||||||
|
if ((rel != null && (rel.isPrimitive() || rel.isReference())) ||
|
||||||
|
name.equals (nameField) || name.equals (prototypeField))
|
||||||
|
{
|
||||||
|
b1.append (", "+columns[i].getName());
|
||||||
|
b2.append (", ?");
|
||||||
|
System.err.println ("ADDING COLUMN: "+columns[i].getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
b1.append (b2);
|
||||||
|
b1.append (" )");
|
||||||
|
|
||||||
|
Connection con = dbm.getConnection ();
|
||||||
|
PreparedStatement stmt = con.prepareStatement (b1.toString ());
|
||||||
try {
|
try {
|
||||||
tds = new TableDataSet (dbm.getConnection (), dbm.getSchema (), dbm.getKeyDef ());
|
|
||||||
Record rec = tds.addRecord ();
|
|
||||||
rec.setValue (dbm.getIDField (), node.getID ());
|
|
||||||
|
|
||||||
String nameField = dbm.getNameField ();
|
int stmtNumber = 1;
|
||||||
if (nameField != null)
|
stmt.setString (stmtNumber, node.getID());
|
||||||
rec.setValue (nameField, node.getName ());
|
|
||||||
|
|
||||||
for (Iterator i=dbm.getProp2DB().entrySet().iterator(); i.hasNext(); ) {
|
Hashtable propMap = node.getPropMap ();
|
||||||
Map.Entry e = (Map.Entry) i.next ();
|
for (int i=0; i<columns.length; i++) {
|
||||||
String propname = (String) e.getKey ();
|
Relation rel = columns[i].getRelation();
|
||||||
Relation rel = (Relation) e.getValue ();
|
Property p = null;
|
||||||
Property p = node.getProperty (propname);
|
if (rel != null && (rel.isPrimitive() || rel.isReference()))
|
||||||
|
p = (Property) propMap.get (rel.getPropName ());
|
||||||
|
String name = columns[i].getName ();
|
||||||
|
if (!(rel != null && (rel.isPrimitive() || rel.isReference())) && !name.equals (nameField) && !name.equals (prototypeField))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (p != null && rel != null) {
|
stmtNumber++;
|
||||||
switch (p.getType ()) {
|
if (p != null) {
|
||||||
case IProperty.STRING:
|
if (p.getValue() == null) {
|
||||||
rec.setValue (rel.getDbField(), p.getStringValue ());
|
stmt.setNull (stmtNumber, columns[i].getType ());
|
||||||
break;
|
} else {
|
||||||
case IProperty.BOOLEAN:
|
switch (columns[i].getType ()) {
|
||||||
rec.setValue (rel.getDbField(), p.getBooleanValue ());
|
|
||||||
break;
|
case Types.BIT:
|
||||||
case IProperty.DATE:
|
case Types.TINYINT:
|
||||||
Timestamp t = new Timestamp (p.getDateValue ().getTime ());
|
case Types.BIGINT:
|
||||||
rec.setValue (rel.getDbField(), t);
|
case Types.SMALLINT:
|
||||||
break;
|
case Types.INTEGER:
|
||||||
case IProperty.INTEGER:
|
stmt.setLong (stmtNumber, p.getIntegerValue());
|
||||||
rec.setValue (rel.getDbField(), p.getIntegerValue ());
|
break;
|
||||||
break;
|
|
||||||
case IProperty.FLOAT:
|
case Types.REAL:
|
||||||
rec.setValue (rel.getDbField(), p.getFloatValue ());
|
case Types.FLOAT:
|
||||||
break;
|
case Types.DOUBLE:
|
||||||
case IProperty.NODE:
|
case Types.NUMERIC:
|
||||||
if (rel.reftype == Relation.REFERENCE) {
|
case Types.DECIMAL:
|
||||||
// INode n = p.getNodeValue ();
|
stmt.setDouble (stmtNumber, p.getFloatValue());
|
||||||
// String foreignID = n == null ? null : n.getID ();
|
break;
|
||||||
rec.setValue (rel.getDbField(), p.getStringValue ());
|
|
||||||
}
|
case Types.LONGVARBINARY:
|
||||||
break;
|
case Types.VARBINARY:
|
||||||
|
case Types.BINARY:
|
||||||
|
case Types.BLOB:
|
||||||
|
stmt.setString (stmtNumber, p.getStringValue());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Types.LONGVARCHAR:
|
||||||
|
case Types.CHAR:
|
||||||
|
case Types.VARCHAR:
|
||||||
|
case Types.OTHER:
|
||||||
|
stmt.setString (stmtNumber, p.getStringValue());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Types.DATE:
|
||||||
|
case Types.TIME:
|
||||||
|
case Types.TIMESTAMP:
|
||||||
|
stmt.setTimestamp (stmtNumber, p.getTimestampValue());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Types.NULL:
|
||||||
|
stmt.setNull (stmtNumber, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
stmt.setString (stmtNumber, p.getStringValue());
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
p.dirty = false;
|
} else {
|
||||||
} else if (rel != null && rel.getDbField() != null) {
|
if (name.equals (nameField))
|
||||||
rec.setValueNull (rel.getDbField());
|
stmt.setString (stmtNumber, node.getName());
|
||||||
|
else if (name.equals (prototypeField))
|
||||||
|
stmt.setString (stmtNumber, node.getPrototype ());
|
||||||
|
else
|
||||||
|
stmt.setNull (stmtNumber, columns[i].getType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
stmt.executeUpdate ();
|
||||||
if (dbm.getPrototypeField () != null) {
|
|
||||||
rec.setValue (dbm.getPrototypeField (), node.getPrototype ());
|
|
||||||
}
|
} catch (Exception x) {
|
||||||
rec.markForInsert ();
|
x.printStackTrace ();
|
||||||
tds.save ();
|
throw x;
|
||||||
} finally {
|
} finally {
|
||||||
if (tds != null) try {
|
if (stmt != null) try {
|
||||||
tds.close ();
|
stmt.close ();
|
||||||
} catch (Exception ignore) {}
|
} catch (Exception ignore) {}
|
||||||
}
|
}
|
||||||
dbm.notifyDataChange ();
|
dbm.notifyDataChange ();
|
||||||
|
@ -489,82 +543,134 @@ public final class NodeManager {
|
||||||
db.saveNode (txn, node.getID (), node);
|
db.saveNode (txn, node.getID (), node);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
TableDataSet tds = null;
|
Hashtable propMap = node.getPropMap ();
|
||||||
|
Property[] props = new Property[propMap.size()];
|
||||||
|
propMap.values().toArray (props);
|
||||||
|
|
||||||
|
// make sure table meta info is loaded by dbmapping
|
||||||
|
dbm.getColumns ();
|
||||||
|
|
||||||
|
StringBuffer b = dbm.getUpdate ();
|
||||||
|
|
||||||
|
boolean comma = false;
|
||||||
|
for (int i=0; i<props.length; i++) {
|
||||||
|
// skip clean properties
|
||||||
|
if (props[i] == null || !props[i].dirty) {
|
||||||
|
// null out clean property so we don't consider it later
|
||||||
|
props[i] = null;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Relation rel = dbm.propertyToRelation (props[i].getName());
|
||||||
|
// skip readonly, virtual and collection relations
|
||||||
|
if (rel == null || rel.readonly || rel.virtual ||
|
||||||
|
(rel.reftype != Relation.REFERENCE && rel.reftype != Relation.PRIMITIVE))
|
||||||
|
{
|
||||||
|
// null out property so we don't consider it later
|
||||||
|
props[i] = null;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (comma)
|
||||||
|
b.append (", ");
|
||||||
|
else
|
||||||
|
comma = true;
|
||||||
|
b.append (rel.getDbField());
|
||||||
|
b.append (" = ?");
|
||||||
|
|
||||||
|
}
|
||||||
|
// if no columns were updated, return
|
||||||
|
if (!comma)
|
||||||
|
return;
|
||||||
|
|
||||||
|
b.append (" WHERE ");
|
||||||
|
b.append (dbm.getIDField ());
|
||||||
|
b.append (" = ");
|
||||||
|
if (dbm.needsQuotes (dbm.getIDField ())) {
|
||||||
|
b.append ("'");
|
||||||
|
b.append (escape(node.getID()));
|
||||||
|
b.append ("'");
|
||||||
|
} else {
|
||||||
|
b.append (node.getID());
|
||||||
|
}
|
||||||
|
|
||||||
|
Connection con = dbm.getConnection ();
|
||||||
|
PreparedStatement stmt = con.prepareStatement (b.toString ());
|
||||||
|
System.err.println (b.toString());
|
||||||
|
int stmtNumber = 0;
|
||||||
try {
|
try {
|
||||||
tds = new TableDataSet (dbm.getConnection (), dbm.getSchema (), dbm.getKeyDef ());
|
for (int i=0; i<props.length; i++) {
|
||||||
Record rec = tds.addRecord ();
|
Property p = props[i];
|
||||||
rec.setValue (dbm.getIDField (), node.getID ());
|
if (p == null)
|
||||||
|
|
||||||
int updated = 0;
|
|
||||||
|
|
||||||
for (Iterator i=dbm.getProp2DB().entrySet().iterator(); i.hasNext(); ) {
|
|
||||||
Map.Entry e = (Map.Entry) i.next ();
|
|
||||||
String propname = (String) e.getKey ();
|
|
||||||
Relation rel = (Relation) e.getValue ();
|
|
||||||
|
|
||||||
// skip properties that don't need to be updated before fetching them
|
|
||||||
if (rel != null && (rel.readonly || rel.virtual ||
|
|
||||||
(rel.reftype != Relation.REFERENCE && rel.reftype != Relation.PRIMITIVE)))
|
|
||||||
continue;
|
continue;
|
||||||
|
Relation rel = dbm.propertyToRelation (p.getName());
|
||||||
|
|
||||||
Property p = node.getProperty (propname);
|
stmtNumber++;
|
||||||
|
|
||||||
if (p != null && rel != null) {
|
if (p.getValue() == null) {
|
||||||
|
stmt.setNull (stmtNumber, rel.getColumnType ());
|
||||||
|
} else {
|
||||||
|
switch (rel.getColumnType ()) {
|
||||||
|
case Types.BIT:
|
||||||
|
case Types.TINYINT:
|
||||||
|
case Types.BIGINT:
|
||||||
|
case Types.SMALLINT:
|
||||||
|
case Types.INTEGER:
|
||||||
|
stmt.setLong (stmtNumber, p.getIntegerValue());
|
||||||
|
break;
|
||||||
|
|
||||||
if (p.dirty) {
|
case Types.REAL:
|
||||||
switch (p.getType ()) {
|
case Types.FLOAT:
|
||||||
case IProperty.STRING:
|
case Types.DOUBLE:
|
||||||
updated++;
|
case Types.NUMERIC:
|
||||||
rec.setValue (rel.getDbField(), p.getStringValue ());
|
case Types.DECIMAL:
|
||||||
break;
|
stmt.setDouble (stmtNumber, p.getFloatValue());
|
||||||
case IProperty.BOOLEAN:
|
break;
|
||||||
updated++;
|
|
||||||
rec.setValue (rel.getDbField(), p.getBooleanValue ());
|
case Types.LONGVARBINARY:
|
||||||
break;
|
case Types.VARBINARY:
|
||||||
case IProperty.DATE:
|
case Types.BINARY:
|
||||||
updated++;
|
case Types.BLOB:
|
||||||
Timestamp t = new Timestamp (p.getDateValue ().getTime ());
|
stmt.setString (stmtNumber, p.getStringValue());
|
||||||
rec.setValue (rel.getDbField(), t);
|
break;
|
||||||
break;
|
|
||||||
case IProperty.INTEGER:
|
case Types.LONGVARCHAR:
|
||||||
updated++;
|
case Types.CHAR:
|
||||||
rec.setValue (rel.getDbField(), p.getIntegerValue ());
|
case Types.VARCHAR:
|
||||||
break;
|
case Types.OTHER:
|
||||||
case IProperty.FLOAT:
|
stmt.setString (stmtNumber, p.getStringValue());
|
||||||
updated++;
|
break;
|
||||||
rec.setValue (rel.getDbField(), p.getFloatValue ());
|
|
||||||
break;
|
case Types.DATE:
|
||||||
case IProperty.NODE:
|
case Types.TIME:
|
||||||
if (!rel.virtual && rel.reftype == Relation.REFERENCE) {
|
case Types.TIMESTAMP:
|
||||||
// INode n = p.getNodeValue ();
|
stmt.setTimestamp (stmtNumber, p.getTimestampValue());
|
||||||
// String foreignID = n == null ? null : n.getID ();
|
break;
|
||||||
updated++;
|
|
||||||
rec.setValue (rel.getDbField(), p.getStringValue ());
|
case Types.NULL:
|
||||||
}
|
stmt.setNull (stmtNumber, 0);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
p.dirty = false;
|
default:
|
||||||
if (!rel.isPrivate())
|
stmt.setString (stmtNumber, p.getStringValue());
|
||||||
markMappingAsUpdated = true;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (rel != null && rel.getDbField() != null) {
|
|
||||||
|
|
||||||
updated++;
|
|
||||||
rec.setValueNull (rel.getDbField());
|
|
||||||
}
|
}
|
||||||
|
p.dirty = false;
|
||||||
|
if (!rel.isPrivate())
|
||||||
|
markMappingAsUpdated = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
if (updated > 0) {
|
|
||||||
// mark the key value as clean so no try is made to update it
|
stmt.executeUpdate ();
|
||||||
rec.markValueClean (dbm.getIDField ());
|
|
||||||
rec.markForUpdate ();
|
} catch (Exception x) {
|
||||||
tds.save ();
|
x.printStackTrace ();
|
||||||
}
|
throw x;
|
||||||
} finally {
|
} finally {
|
||||||
if (tds != null) try {
|
if (stmt != null) try {
|
||||||
tds.close ();
|
stmt.close ();
|
||||||
} catch (Exception ignore) {}
|
} catch (Exception ignore) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (markMappingAsUpdated)
|
if (markMappingAsUpdated)
|
||||||
dbm.notifyDataChange ();
|
dbm.notifyDataChange ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import java.util.*;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.text.*;
|
import java.text.*;
|
||||||
import helma.objectmodel.*;
|
import helma.objectmodel.*;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A property implementation for Nodes stored inside a database. Basically
|
* A property implementation for Nodes stored inside a database. Basically
|
||||||
|
@ -19,13 +20,7 @@ public final class Property implements IProperty, Serializable, Cloneable {
|
||||||
private String propname;
|
private String propname;
|
||||||
private Node node;
|
private Node node;
|
||||||
|
|
||||||
private String svalue;
|
private Object value;
|
||||||
private boolean bvalue;
|
|
||||||
private long lvalue;
|
|
||||||
private double dvalue;
|
|
||||||
// protected String nvalueID;
|
|
||||||
private NodeHandle nhandle;
|
|
||||||
private Object jvalue;
|
|
||||||
|
|
||||||
private int type;
|
private int type;
|
||||||
|
|
||||||
|
@ -42,29 +37,29 @@ public final class Property implements IProperty, Serializable, Cloneable {
|
||||||
case STRING:
|
case STRING:
|
||||||
// try to convert from old format
|
// try to convert from old format
|
||||||
if (node.version < 7)
|
if (node.version < 7)
|
||||||
svalue = in.readUTF ();
|
value = in.readUTF ();
|
||||||
else
|
else
|
||||||
svalue = (String) in.readObject ();
|
value = in.readObject ();
|
||||||
break;
|
break;
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
bvalue = in.readBoolean ();
|
value = in.readBoolean () ? Boolean.TRUE : Boolean.FALSE;
|
||||||
break;
|
break;
|
||||||
case INTEGER:
|
case INTEGER:
|
||||||
case DATE:
|
case DATE:
|
||||||
lvalue = in.readLong ();
|
value = new Long (in.readLong ());
|
||||||
break;
|
break;
|
||||||
case FLOAT:
|
case FLOAT:
|
||||||
dvalue = in.readDouble ();
|
value = new Double (in.readDouble ());
|
||||||
break;
|
break;
|
||||||
case NODE:
|
case NODE:
|
||||||
// try to convert from old format
|
// try to convert from old format
|
||||||
if (node.version > 4)
|
if (node.version > 4)
|
||||||
nhandle = (NodeHandle) in.readObject ();
|
value = (NodeHandle) in.readObject ();
|
||||||
else
|
else
|
||||||
nhandle = new NodeHandle (new DbKey (null, in.readUTF ()));
|
value = new NodeHandle (new DbKey (null, in.readUTF ()));
|
||||||
break;
|
break;
|
||||||
case JAVAOBJECT:
|
case JAVAOBJECT:
|
||||||
jvalue = in.readObject ();
|
value = in.readObject ();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (ClassNotFoundException x) {
|
} catch (ClassNotFoundException x) {
|
||||||
|
@ -78,26 +73,26 @@ public final class Property implements IProperty, Serializable, Cloneable {
|
||||||
out.writeInt (type);
|
out.writeInt (type);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case STRING:
|
case STRING:
|
||||||
out.writeObject (svalue);
|
out.writeObject (value);
|
||||||
break;
|
break;
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
out.writeBoolean (bvalue);
|
out.writeBoolean (((Boolean) value).booleanValue());
|
||||||
break;
|
break;
|
||||||
case INTEGER:
|
case INTEGER:
|
||||||
case DATE:
|
case DATE:
|
||||||
out.writeLong (lvalue);
|
out.writeLong (((Long) value).longValue());
|
||||||
break;
|
break;
|
||||||
case FLOAT:
|
case FLOAT:
|
||||||
out.writeDouble (dvalue);
|
out.writeDouble (((Double) value).doubleValue());
|
||||||
break;
|
break;
|
||||||
case NODE:
|
case NODE:
|
||||||
out.writeObject (nhandle);
|
out.writeObject (value);
|
||||||
break;
|
break;
|
||||||
case JAVAOBJECT:
|
case JAVAOBJECT:
|
||||||
if (jvalue != null && !(jvalue instanceof Serializable))
|
if (value != null && !(value instanceof Serializable))
|
||||||
out.writeObject (null);
|
out.writeObject (null);
|
||||||
else
|
else
|
||||||
out.writeObject (jvalue);
|
out.writeObject (value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,10 +109,10 @@ public final class Property implements IProperty, Serializable, Cloneable {
|
||||||
dirty = true;
|
dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Property (String propname, Node node, Node value) {
|
public Property (String propname, Node node, Node valueNode) {
|
||||||
this (propname, node);
|
this (propname, node);
|
||||||
type = NODE;
|
type = NODE;
|
||||||
nhandle = value == null ? null : value.getHandle ();
|
value = valueNode == null ? null : valueNode.getHandle ();
|
||||||
dirty = true;
|
dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,141 +121,115 @@ public final class Property implements IProperty, Serializable, Cloneable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getValue () {
|
public Object getValue () {
|
||||||
switch (type) {
|
return value;
|
||||||
case STRING:
|
|
||||||
return svalue;
|
|
||||||
case BOOLEAN:
|
|
||||||
return new Boolean (bvalue);
|
|
||||||
case INTEGER:
|
|
||||||
return new Long (lvalue);
|
|
||||||
case FLOAT:
|
|
||||||
return new Double (dvalue);
|
|
||||||
case DATE:
|
|
||||||
return new Date (lvalue);
|
|
||||||
case NODE:
|
|
||||||
return null;
|
|
||||||
case JAVAOBJECT:
|
|
||||||
return jvalue;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStringValue (String value) {
|
public int getType () {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStringValue (String str) {
|
||||||
if (type == NODE)
|
if (type == NODE)
|
||||||
unregisterNode ();
|
unregisterNode ();
|
||||||
if (type == JAVAOBJECT)
|
|
||||||
this.jvalue = null;
|
|
||||||
type = STRING;
|
type = STRING;
|
||||||
this.svalue = value;
|
value = str;
|
||||||
dirty = true;
|
dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setIntegerValue (long value) {
|
public void setIntegerValue (long l) {
|
||||||
if (type == NODE)
|
if (type == NODE)
|
||||||
unregisterNode ();
|
unregisterNode ();
|
||||||
if (type == JAVAOBJECT)
|
|
||||||
this.jvalue = null;
|
|
||||||
type = INTEGER;
|
type = INTEGER;
|
||||||
this.lvalue = value;
|
value = new Long(l);
|
||||||
dirty = true;
|
dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFloatValue (double value) {
|
public void setFloatValue (double d) {
|
||||||
if (type == NODE)
|
if (type == NODE)
|
||||||
unregisterNode ();
|
unregisterNode ();
|
||||||
if (type == JAVAOBJECT)
|
|
||||||
this.jvalue = null;
|
|
||||||
type = FLOAT;
|
type = FLOAT;
|
||||||
this.dvalue = value;
|
value = new Double(d);
|
||||||
dirty = true;
|
dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDateValue (Date value) {
|
public void setDateValue (Date date) {
|
||||||
if (type == NODE)
|
if (type == NODE)
|
||||||
unregisterNode ();
|
unregisterNode ();
|
||||||
if (type == JAVAOBJECT)
|
|
||||||
this.jvalue = null;
|
|
||||||
type = DATE;
|
type = DATE;
|
||||||
this.lvalue = value == null ? 0 : value.getTime();
|
value = date;
|
||||||
dirty = true;
|
dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBooleanValue (boolean value) {
|
public void setBooleanValue (boolean bool) {
|
||||||
if (type == NODE)
|
if (type == NODE)
|
||||||
unregisterNode ();
|
unregisterNode ();
|
||||||
if (type == JAVAOBJECT)
|
|
||||||
this.jvalue = null;
|
|
||||||
type = BOOLEAN;
|
type = BOOLEAN;
|
||||||
this.bvalue = value;
|
value = bool ? Boolean.TRUE : Boolean.FALSE;
|
||||||
dirty = true;
|
dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNodeValue (Node value) {
|
public void setNodeValue (Node node) {
|
||||||
// value.checkWriteLock ();
|
// value.checkWriteLock ();
|
||||||
if (type == NODE)
|
if (type == NODE)
|
||||||
unregisterNode ();
|
unregisterNode ();
|
||||||
if (type == JAVAOBJECT)
|
|
||||||
this.jvalue = null;
|
|
||||||
|
|
||||||
// registerNode (value);
|
// registerNode (value);
|
||||||
type = NODE;
|
type = NODE;
|
||||||
|
|
||||||
nhandle = value.getHandle ();
|
value = node == null ? null : node.getHandle ();
|
||||||
dirty = true;
|
dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNodeHandle (NodeHandle value) {
|
public void setNodeHandle (NodeHandle handle) {
|
||||||
if (type == NODE)
|
if (type == NODE)
|
||||||
unregisterNode ();
|
unregisterNode ();
|
||||||
if (type == JAVAOBJECT)
|
|
||||||
this.jvalue = null;
|
|
||||||
// registerNode (value);
|
// registerNode (value);
|
||||||
type = NODE;
|
type = NODE;
|
||||||
nhandle = value;
|
value = handle;
|
||||||
dirty = true;
|
dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NodeHandle getNodeHandle () {
|
public NodeHandle getNodeHandle () {
|
||||||
return nhandle;
|
if (type == NODE)
|
||||||
|
return (NodeHandle) value;
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void convertToNodeReference (DbMapping dbm) {
|
public void convertToNodeReference (DbMapping dbm) {
|
||||||
String id = getStringValue ();
|
if (value != null && !(value instanceof NodeHandle))
|
||||||
if (id == null)
|
value = new NodeHandle (new DbKey (dbm, value.toString ()));
|
||||||
nhandle = null;
|
|
||||||
else
|
|
||||||
nhandle = new NodeHandle (new DbKey (dbm, id));
|
|
||||||
type = NODE;
|
type = NODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setJavaObjectValue (Object value) {
|
public void setJavaObjectValue (Object obj) {
|
||||||
if (type == NODE)
|
if (type == NODE)
|
||||||
unregisterNode ();
|
unregisterNode ();
|
||||||
type = JAVAOBJECT;
|
type = JAVAOBJECT;
|
||||||
this.jvalue = value;
|
value = obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tell a the value node that it is no longer used as a property.
|
* tell a the value node that it is no longer used as a property.
|
||||||
* If this was the "main" property for the node, also remove all other references.
|
* If this was the "main" property for the node, also remove all other references.
|
||||||
*/
|
*/
|
||||||
protected void unregisterNode () {
|
protected void unregisterNode () {
|
||||||
Node nvalue = null;
|
if (value == null || !(value instanceof NodeHandle))
|
||||||
if (nhandle != null)
|
return;
|
||||||
nvalue = nhandle.getNode (node.nmgr);
|
NodeHandle nhandle = (NodeHandle) value;
|
||||||
|
Node nvalue = nhandle.getNode (node.nmgr);
|
||||||
|
|
||||||
DbMapping nvmap = null;
|
DbMapping nvmap = null;
|
||||||
Relation nvrel = null;
|
Relation nvrel = null;
|
||||||
if (node.dbmap != null) {
|
if (node.dbmap != null) {
|
||||||
nvmap = node.dbmap.getPropertyMapping (propname);
|
nvmap = node.dbmap.getPropertyMapping (propname);
|
||||||
nvrel = node.dbmap.getPropertyRelation (propname);
|
nvrel = node.dbmap.getPropertyRelation (propname);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nvalue == null)
|
if (nvalue == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
nvalue.checkWriteLock ();
|
nvalue.checkWriteLock ();
|
||||||
// check if the property node is also a subnode
|
// check if the property node is also a subnode
|
||||||
// BUG: this doesn't work because properties for subnode/properties are never stored and therefore
|
// BUG: this doesn't work because properties for subnode/properties are never stored and therefore
|
||||||
|
@ -281,22 +250,20 @@ public final class Property implements IProperty, Serializable, Cloneable {
|
||||||
|
|
||||||
|
|
||||||
public String getStringValue () {
|
public String getStringValue () {
|
||||||
|
if (value == null)
|
||||||
|
return null;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case STRING:
|
case STRING:
|
||||||
return svalue;
|
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
return bvalue ? "true" : "false";
|
|
||||||
case DATE:
|
|
||||||
SimpleDateFormat format = new SimpleDateFormat ("dd.MM.yy HH:mm");
|
|
||||||
return format.format (new Date (lvalue));
|
|
||||||
case INTEGER:
|
case INTEGER:
|
||||||
return Long.toString (lvalue);
|
|
||||||
case FLOAT:
|
case FLOAT:
|
||||||
return Double.toString (dvalue);
|
|
||||||
case NODE:
|
|
||||||
return nhandle == null ? null : nhandle.getID ();
|
|
||||||
case JAVAOBJECT:
|
case JAVAOBJECT:
|
||||||
return jvalue == null ? null : jvalue.toString ();
|
return value.toString ();
|
||||||
|
case DATE:
|
||||||
|
SimpleDateFormat format = new SimpleDateFormat ("dd.MM.yy hh:mm:ss");
|
||||||
|
return format.format ((Date) value);
|
||||||
|
case NODE:
|
||||||
|
return ((NodeHandle) value).getID ();
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -306,51 +273,64 @@ public final class Property implements IProperty, Serializable, Cloneable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getIntegerValue () {
|
public long getIntegerValue () {
|
||||||
if (type == INTEGER)
|
if (type == INTEGER)
|
||||||
return lvalue;
|
return ((Long) value).longValue ();
|
||||||
return 0;
|
if (type == FLOAT)
|
||||||
|
return ((Double) value).longValue ();
|
||||||
|
try {
|
||||||
|
return Long.parseLong (getStringValue());
|
||||||
|
} catch (Exception x) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getFloatValue () {
|
public double getFloatValue () {
|
||||||
if (type == FLOAT)
|
if (type == FLOAT)
|
||||||
return dvalue;
|
return ((Double) value).doubleValue();
|
||||||
return 0.0;
|
if (type == INTEGER)
|
||||||
|
return ((Long) value).doubleValue ();
|
||||||
|
try {
|
||||||
|
return Double.parseDouble (getStringValue());
|
||||||
|
} catch (Exception x) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Date getDateValue () {
|
public Date getDateValue () {
|
||||||
if (type == DATE)
|
if (type == DATE)
|
||||||
return new Date (lvalue);
|
return (Date) value;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Timestamp getTimestampValue () {
|
||||||
|
if (type == DATE && value != null)
|
||||||
|
return new Timestamp (((Date) value).getTime());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getBooleanValue () {
|
public boolean getBooleanValue () {
|
||||||
if (type == BOOLEAN)
|
if (type == BOOLEAN)
|
||||||
return bvalue;
|
return ((Boolean) value).booleanValue();
|
||||||
|
if (type == INTEGER)
|
||||||
|
return !(0 == getIntegerValue());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public INode getNodeValue () {
|
public INode getNodeValue () {
|
||||||
|
if (type == NODE && value != null) {
|
||||||
if (nhandle != null) {
|
NodeHandle nhandle = (NodeHandle) value;
|
||||||
Node n = nhandle.getNode (node.nmgr);
|
return nhandle.getNode (node.nmgr);
|
||||||
if (n != null) return n;
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getJavaObjectValue () {
|
public Object getJavaObjectValue () {
|
||||||
if (type == JAVAOBJECT)
|
if (type == JAVAOBJECT)
|
||||||
return jvalue;
|
return value;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int getType () {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue