Several changes/fixes in DbMapping:
* Relation mappings that are overwritten in sub-prototypes no longer override the parent prototype's Relation object but creates its own Relation * Generally enable all things to be overwritten in DbMappings that inherit from another relational DbMapping. That means it should now be possible to really change lots of things from a parent DbMapping and a child DbMapping. * Improved property enumeration which now merges properties defined in the DbMapping inherit chain * Cleaned up and improved variable naming.
This commit is contained in:
parent
49f011ab87
commit
d2aa17041f
5 changed files with 158 additions and 127 deletions
|
@ -7,6 +7,7 @@ import helma.framework.core.Application;
|
||||||
import helma.util.Updatable;
|
import helma.util.Updatable;
|
||||||
import helma.util.SystemProperties;
|
import helma.util.SystemProperties;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
@ -28,15 +29,15 @@ public final class DbMapping implements Updatable {
|
||||||
// properties from where the mapping is read
|
// properties from where the mapping is read
|
||||||
SystemProperties props;
|
SystemProperties props;
|
||||||
|
|
||||||
// name of data source to which this mapping writes
|
// name of data dbSource to which this mapping writes
|
||||||
DbSource source;
|
DbSource dbSource;
|
||||||
// name of datasource
|
// name of datasource
|
||||||
String sourceName;
|
String dbSourceName;
|
||||||
// name of db table
|
// name of db table
|
||||||
String table;
|
String tableName;
|
||||||
|
|
||||||
// list of properties to try for parent
|
// list of properties to try for parent
|
||||||
ParentInfo[] parent;
|
ParentInfo[] parentInfo;
|
||||||
|
|
||||||
// Relations describing subnodes and properties.
|
// Relations describing subnodes and properties.
|
||||||
Relation subRelation;
|
Relation subRelation;
|
||||||
|
@ -101,7 +102,7 @@ public final class DbMapping implements Updatable {
|
||||||
prop2db = new HashMap ();
|
prop2db = new HashMap ();
|
||||||
db2prop = new HashMap ();
|
db2prop = new HashMap ();
|
||||||
|
|
||||||
parent = null;
|
parentInfo = null;
|
||||||
|
|
||||||
idField = null;
|
idField = null;
|
||||||
}
|
}
|
||||||
|
@ -123,7 +124,7 @@ public final class DbMapping implements Updatable {
|
||||||
|
|
||||||
columnMap = new HashMap ();
|
columnMap = new HashMap ();
|
||||||
|
|
||||||
parent = null;
|
parentInfo = null;
|
||||||
|
|
||||||
idField = null;
|
idField = null;
|
||||||
|
|
||||||
|
@ -145,7 +146,7 @@ public final class DbMapping implements Updatable {
|
||||||
*/
|
*/
|
||||||
public synchronized void update () {
|
public synchronized void update () {
|
||||||
// read in properties
|
// read in properties
|
||||||
table = props.getProperty ("_table");
|
tableName = props.getProperty ("_table");
|
||||||
idgen = props.getProperty ("_idgen");
|
idgen = props.getProperty ("_idgen");
|
||||||
// see if there is a field which specifies the prototype of objects, if different prototypes
|
// see if there is a field which specifies the prototype of objects, if different prototypes
|
||||||
// can be stored in this table
|
// can be stored in this table
|
||||||
|
@ -153,17 +154,17 @@ public final class DbMapping implements Updatable {
|
||||||
// see if this prototype extends (inherits from) any other prototype
|
// see if this prototype extends (inherits from) any other prototype
|
||||||
extendsProto = props.getProperty ("_extends");
|
extendsProto = props.getProperty ("_extends");
|
||||||
|
|
||||||
sourceName = props.getProperty ("_db");
|
dbSourceName = props.getProperty ("_db");
|
||||||
if (sourceName != null) {
|
if (dbSourceName != null) {
|
||||||
source = app.getDbSource (sourceName);
|
dbSource = app.getDbSource (dbSourceName);
|
||||||
if (source == null) {
|
if (dbSource == null) {
|
||||||
app.logEvent ("*** Data Source for prototype "+typename+" does not exist: "+sourceName);
|
app.logEvent ("*** Data Source for prototype "+typename+" does not exist: "+dbSourceName);
|
||||||
app.logEvent ("*** accessing or storing a "+typename+" object will cause an error.");
|
app.logEvent ("*** accessing or storing a "+typename+" object will cause an error.");
|
||||||
} else if (table == null) {
|
} else if (tableName == null) {
|
||||||
app.logEvent ("*** No table name specified for prototype "+typename);
|
app.logEvent ("*** No table name specified for prototype "+typename);
|
||||||
app.logEvent ("*** accessing or storing a "+typename+" object will cause an error.");
|
app.logEvent ("*** accessing or storing a "+typename+" object will cause an error.");
|
||||||
// mark mapping as invalid by nulling the source field
|
// mark mapping as invalid by nulling the dbSource field
|
||||||
source = null;
|
dbSource = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,11 +180,11 @@ public final class DbMapping implements Updatable {
|
||||||
if (parentSpec != null) {
|
if (parentSpec != null) {
|
||||||
// comma-separated list of properties to be used as parent
|
// comma-separated list of properties to be used as parent
|
||||||
StringTokenizer st = new StringTokenizer (parentSpec, ",;");
|
StringTokenizer st = new StringTokenizer (parentSpec, ",;");
|
||||||
parent = new ParentInfo[st.countTokens()];
|
parentInfo = new ParentInfo[st.countTokens()];
|
||||||
for (int i=0; i<parent.length; i++)
|
for (int i=0; i<parentInfo.length; i++)
|
||||||
parent[i] = new ParentInfo (st.nextToken().trim());
|
parentInfo[i] = new ParentInfo (st.nextToken().trim());
|
||||||
} else {
|
} else {
|
||||||
parent = null;
|
parentInfo = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastTypeChange = props.lastModified ();
|
lastTypeChange = props.lastModified ();
|
||||||
|
@ -197,8 +198,8 @@ public final class DbMapping implements Updatable {
|
||||||
parentMapping = app.getDbMapping (extendsProto);
|
parentMapping = app.getDbMapping (extendsProto);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (table != null && source != null) {
|
// if (tableName != null && dbSource != null) {
|
||||||
// app.logEvent ("set data source for "+typename+" to "+source);
|
// app.logEvent ("set data dbSource for "+typename+" to "+dbSource);
|
||||||
HashMap p2d = new HashMap ();
|
HashMap p2d = new HashMap ();
|
||||||
HashMap d2p = new HashMap ();
|
HashMap d2p = new HashMap ();
|
||||||
|
|
||||||
|
@ -210,10 +211,13 @@ public final class DbMapping implements Updatable {
|
||||||
if (!propName.startsWith ("_") && propName.indexOf (".") < 0) {
|
if (!propName.startsWith ("_") && propName.indexOf (".") < 0) {
|
||||||
String dbField = props.getProperty (propName);
|
String dbField = props.getProperty (propName);
|
||||||
// check if a relation for this propery already exists. If so, reuse it
|
// check if a relation for this propery already exists. If so, reuse it
|
||||||
Relation rel = propertyToRelation (propName);
|
Relation rel = (Relation) prop2db.get (propName.toLowerCase());
|
||||||
if (rel == null)
|
if (rel == null)
|
||||||
rel = new Relation (dbField, propName, this, props);
|
rel = new Relation (dbField, propName, this, props);
|
||||||
rel.update (dbField, props);
|
rel.update (dbField, props);
|
||||||
|
// key enumerations from SystemProperties are all lower case, which is why
|
||||||
|
// even though we don't do a toLowerCase() here,
|
||||||
|
// we have to when we lookup things in p2d later.
|
||||||
p2d.put (propName, rel);
|
p2d.put (propName, rel);
|
||||||
if (rel.columnName != null &&
|
if (rel.columnName != null &&
|
||||||
(rel.reftype == Relation.PRIMITIVE ||
|
(rel.reftype == Relation.PRIMITIVE ||
|
||||||
|
@ -238,7 +242,7 @@ public final class DbMapping implements Updatable {
|
||||||
subRelation.update (subnodeMapping, props);
|
subRelation.update (subnodeMapping, props);
|
||||||
// if subnodes are accessed via access name or group name,
|
// if subnodes are accessed via access name or group name,
|
||||||
// the subnode relation is also the property relation.
|
// the subnode relation is also the property relation.
|
||||||
if (subRelation.accessor != null || subRelation.groupby != null)
|
if (subRelation.accessName != null || subRelation.groupby != null)
|
||||||
propRelation = subRelation;
|
propRelation = subRelation;
|
||||||
} catch (Exception x) {
|
} catch (Exception x) {
|
||||||
app.logEvent ("Error reading _subnodes relation for "+typename+": "+x.getMessage ());
|
app.logEvent ("Error reading _subnodes relation for "+typename+": "+x.getMessage ());
|
||||||
|
@ -266,18 +270,23 @@ public final class DbMapping implements Updatable {
|
||||||
* Get a JDBC connection for this DbMapping.
|
* Get a JDBC connection for this DbMapping.
|
||||||
*/
|
*/
|
||||||
public Connection getConnection () throws ClassNotFoundException, SQLException {
|
public Connection getConnection () throws ClassNotFoundException, SQLException {
|
||||||
// if source was previously not available, check again
|
if (dbSourceName == null) {
|
||||||
if (source == null && sourceName != null)
|
if (parentMapping != null)
|
||||||
source = app.getDbSource (sourceName);
|
return parentMapping.getConnection ();
|
||||||
if (sourceName == null && parentMapping != null)
|
|
||||||
return parentMapping.getConnection ();
|
|
||||||
if (source == null) {
|
|
||||||
if (sourceName == null)
|
|
||||||
throw new SQLException ("Tried to get Connection from non-relational embedded data source.");
|
|
||||||
else
|
else
|
||||||
throw new SQLException ("Datasource is not defined: "+sourceName+".");
|
throw new SQLException ("Tried to get Connection from non-relational embedded data source.");
|
||||||
}
|
}
|
||||||
return source.getConnection ();
|
if (tableName == null) {
|
||||||
|
throw new SQLException ("Invalid DbMapping, _table not specified: "+this);
|
||||||
|
}
|
||||||
|
// if dbSource was previously not available, check again
|
||||||
|
if (dbSource == null) {
|
||||||
|
dbSource = app.getDbSource (dbSourceName);
|
||||||
|
}
|
||||||
|
if (dbSource == null) {
|
||||||
|
throw new SQLException ("Datasource is not defined: "+dbSourceName+".");
|
||||||
|
}
|
||||||
|
return dbSource.getConnection ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -285,27 +294,23 @@ public final class DbMapping implements Updatable {
|
||||||
* data source including URL, JDBC driver, username and password.
|
* data source including URL, JDBC driver, username and password.
|
||||||
*/
|
*/
|
||||||
public DbSource getDbSource () {
|
public DbSource getDbSource () {
|
||||||
if (source == null && parentMapping != null)
|
if (dbSource == null) {
|
||||||
return parentMapping.getDbSource ();
|
if (tableName != null && dbSourceName != null)
|
||||||
return source;
|
dbSource = app.getDbSource (dbSourceName);
|
||||||
|
else if (parentMapping != null)
|
||||||
|
return parentMapping.getDbSource ();
|
||||||
|
}
|
||||||
|
return dbSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the URL of the data source used for this mapping.
|
|
||||||
*/
|
|
||||||
public String getSourceID () {
|
|
||||||
if (source == null && parentMapping != null)
|
|
||||||
return parentMapping.getSourceID ();
|
|
||||||
return source == null ? "" : source.url;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the table name used for this type mapping.
|
* Get the table name used for this type mapping.
|
||||||
*/
|
*/
|
||||||
public String getTableName () {
|
public String getTableName () {
|
||||||
if (source == null && parentMapping != null)
|
if (tableName == null && parentMapping != null)
|
||||||
return parentMapping.getTableName ();
|
return parentMapping.getTableName ();
|
||||||
return table;
|
return tableName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -349,7 +354,7 @@ public final class DbMapping implements Updatable {
|
||||||
* Get the column used for (internal) names of objects of this type.
|
* Get the column used for (internal) names of objects of this type.
|
||||||
*/
|
*/
|
||||||
public String getNameField () {
|
public String getNameField () {
|
||||||
if (nameField == null && parentMapping != null)
|
if (nameField == null && parentMapping != null)
|
||||||
return parentMapping.getNameField ();
|
return parentMapping.getNameField ();
|
||||||
return nameField;
|
return nameField;
|
||||||
}
|
}
|
||||||
|
@ -358,7 +363,7 @@ public final class DbMapping implements Updatable {
|
||||||
* Get the column used for names of prototype.
|
* Get the column used for names of prototype.
|
||||||
*/
|
*/
|
||||||
public String getPrototypeField () {
|
public String getPrototypeField () {
|
||||||
if (protoField == null && parentMapping != null)
|
if (protoField == null && parentMapping != null)
|
||||||
return parentMapping.getPrototypeField ();
|
return parentMapping.getPrototypeField ();
|
||||||
return protoField;
|
return protoField;
|
||||||
}
|
}
|
||||||
|
@ -370,9 +375,13 @@ public final class DbMapping implements Updatable {
|
||||||
public String columnNameToProperty (String columnName) {
|
public String columnNameToProperty (String columnName) {
|
||||||
if (columnName == null)
|
if (columnName == null)
|
||||||
return null;
|
return null;
|
||||||
if (table == null && parentMapping != null)
|
return _columnNameToProperty (columnName.toUpperCase());
|
||||||
return parentMapping.columnNameToProperty (columnName);
|
}
|
||||||
Relation rel = (Relation) db2prop.get (columnName.toUpperCase ());
|
|
||||||
|
private String _columnNameToProperty (final String columnName) {
|
||||||
|
Relation rel = (Relation) db2prop.get (columnName);
|
||||||
|
if (rel == null && parentMapping != null)
|
||||||
|
return parentMapping._columnNameToProperty (columnName);
|
||||||
if (rel != null && (rel.reftype == Relation.PRIMITIVE || rel.reftype == Relation.REFERENCE))
|
if (rel != null && (rel.reftype == Relation.PRIMITIVE || rel.reftype == Relation.REFERENCE))
|
||||||
return rel.propName;
|
return rel.propName;
|
||||||
return null;
|
return null;
|
||||||
|
@ -384,11 +393,15 @@ public final class DbMapping implements Updatable {
|
||||||
public String propertyToColumnName (String propName) {
|
public String propertyToColumnName (String propName) {
|
||||||
if (propName == null)
|
if (propName == null)
|
||||||
return null;
|
return null;
|
||||||
if (table == null && parentMapping != null)
|
|
||||||
return parentMapping.propertyToColumnName (propName);
|
|
||||||
// FIXME: prop2db stores keys in lower case, because it gets them
|
// FIXME: prop2db stores keys in lower case, because it gets them
|
||||||
// from a SystemProperties object which converts keys to lower case.
|
// from a SystemProperties object which converts keys to lower case.
|
||||||
Relation rel = (Relation) prop2db.get (propName.toLowerCase());
|
return _propertyToColumnName (propName.toLowerCase ());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String _propertyToColumnName (final String propName) {
|
||||||
|
Relation rel = (Relation) prop2db.get (propName);
|
||||||
|
if (rel == null && parentMapping != null)
|
||||||
|
return parentMapping._propertyToColumnName (propName);
|
||||||
if (rel != null && (rel.reftype == Relation.PRIMITIVE || rel.reftype == Relation.REFERENCE))
|
if (rel != null && (rel.reftype == Relation.PRIMITIVE || rel.reftype == Relation.REFERENCE))
|
||||||
return rel.columnName;
|
return rel.columnName;
|
||||||
return null;
|
return null;
|
||||||
|
@ -400,9 +413,14 @@ public final class DbMapping implements Updatable {
|
||||||
public Relation columnNameToRelation (String columnName) {
|
public Relation columnNameToRelation (String columnName) {
|
||||||
if (columnName == null)
|
if (columnName == null)
|
||||||
return null;
|
return null;
|
||||||
if (table == null && parentMapping != null)
|
return _columnNameToRelation (columnName.toUpperCase());
|
||||||
return parentMapping.columnNameToRelation (columnName);
|
}
|
||||||
return (Relation) db2prop.get (columnName.toUpperCase ());
|
|
||||||
|
private Relation _columnNameToRelation (final String columnName) {
|
||||||
|
Relation rel = (Relation) db2prop.get (columnName);
|
||||||
|
if (rel == null && parentMapping != null)
|
||||||
|
return parentMapping._columnNameToRelation (columnName);
|
||||||
|
return rel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -411,11 +429,16 @@ public final class DbMapping implements Updatable {
|
||||||
public Relation propertyToRelation (String propName) {
|
public Relation propertyToRelation (String propName) {
|
||||||
if (propName == null)
|
if (propName == null)
|
||||||
return null;
|
return null;
|
||||||
if (table == null && parentMapping != null)
|
|
||||||
return parentMapping.propertyToRelation (propName);
|
|
||||||
// FIXME: prop2db stores keys in lower case, because it gets them
|
// FIXME: prop2db stores keys in lower case, because it gets them
|
||||||
// from a SystemProperties object which converts keys to lower case.
|
// from a SystemProperties object which converts keys to lower case.
|
||||||
return (Relation) prop2db.get (propName.toLowerCase());
|
return _propertyToRelation (propName.toLowerCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Relation _propertyToRelation (String propName) {
|
||||||
|
Relation rel = (Relation) prop2db.get (propName);
|
||||||
|
if (rel == null && parentMapping != null)
|
||||||
|
return parentMapping._propertyToRelation (propName);
|
||||||
|
return rel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -424,17 +447,17 @@ public final class DbMapping implements Updatable {
|
||||||
* determine its parent object.
|
* determine its parent object.
|
||||||
*/
|
*/
|
||||||
public synchronized ParentInfo[] getParentInfo () {
|
public synchronized ParentInfo[] getParentInfo () {
|
||||||
if (parent == null && parentMapping != null)
|
if (parentInfo == null && parentMapping != null)
|
||||||
return parentMapping.getParentInfo ();
|
return parentMapping.getParentInfo ();
|
||||||
return parent;
|
return parentInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public DbMapping getSubnodeMapping () {
|
public DbMapping getSubnodeMapping () {
|
||||||
if (subRelation != null)
|
if (subRelation != null)
|
||||||
return subRelation.otherType;
|
return subRelation.otherType;
|
||||||
if (parentMapping != null)
|
if (parentMapping != null)
|
||||||
return parentMapping.getSubnodeMapping ();
|
return parentMapping.getSubnodeMapping ();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -551,7 +574,7 @@ public final class DbMapping implements Updatable {
|
||||||
* not what we want.
|
* not what we want.
|
||||||
*/
|
*/
|
||||||
public boolean isRelational () {
|
public boolean isRelational () {
|
||||||
if (sourceName != null)
|
if (dbSourceName != null)
|
||||||
return true;
|
return true;
|
||||||
if (parentMapping != null)
|
if (parentMapping != null)
|
||||||
return parentMapping.isRelational ();
|
return parentMapping.isRelational ();
|
||||||
|
@ -565,7 +588,7 @@ public final class DbMapping implements Updatable {
|
||||||
public synchronized DbColumn[] getColumns() throws ClassNotFoundException, SQLException {
|
public synchronized DbColumn[] getColumns() throws ClassNotFoundException, SQLException {
|
||||||
if (!isRelational ())
|
if (!isRelational ())
|
||||||
throw new SQLException ("Can't get columns for non-relational data mapping "+this);
|
throw new SQLException ("Can't get columns for non-relational data mapping "+this);
|
||||||
if (source == null && parentMapping != null)
|
if (dbSource == null && parentMapping != null)
|
||||||
return parentMapping.getColumns ();
|
return parentMapping.getColumns ();
|
||||||
// Use local variable cols to avoid synchronization (schema may be nulled elsewhere)
|
// Use local variable cols to avoid synchronization (schema may be nulled elsewhere)
|
||||||
if (columns == null) {
|
if (columns == null) {
|
||||||
|
@ -656,7 +679,7 @@ public final class DbMapping implements Updatable {
|
||||||
* to be quoted in SQL queries.
|
* to be quoted in SQL queries.
|
||||||
*/
|
*/
|
||||||
public boolean needsQuotes (String columnName) throws SQLException {
|
public boolean needsQuotes (String columnName) throws SQLException {
|
||||||
if (table == null && parentMapping != null)
|
if (tableName == null && parentMapping != null)
|
||||||
return parentMapping.needsQuotes (columnName);
|
return parentMapping.needsQuotes (columnName);
|
||||||
try {
|
try {
|
||||||
DbColumn col = getColumn (columnName);
|
DbColumn col = getColumn (columnName);
|
||||||
|
@ -698,27 +721,38 @@ public final class DbMapping implements Updatable {
|
||||||
|
|
||||||
public void notifyDataChange () {
|
public void notifyDataChange () {
|
||||||
lastDataChange = System.currentTimeMillis ();
|
lastDataChange = System.currentTimeMillis ();
|
||||||
if (parentMapping != null && source == null)
|
if (parentMapping != null && dbSource == null)
|
||||||
parentMapping.notifyDataChange ();
|
parentMapping.notifyDataChange ();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized long getNewID (long dbmax) {
|
public synchronized long getNewID (long dbmax) {
|
||||||
if (parentMapping != null && source == null)
|
if (parentMapping != null && dbSource == null)
|
||||||
return parentMapping.getNewID (dbmax);
|
return parentMapping.getNewID (dbmax);
|
||||||
lastID = Math.max (dbmax+1, lastID+1);
|
lastID = Math.max (dbmax+1, lastID+1);
|
||||||
return lastID;
|
return lastID;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HashMap getProp2DB () {
|
|
||||||
if (table == null && parentMapping != null)
|
public Enumeration getPropertyEnumeration () {
|
||||||
return parentMapping.getProp2DB ();
|
HashSet set = new HashSet ();
|
||||||
return prop2db;
|
collectPropertyNames (set);
|
||||||
|
final Iterator it = set.iterator();
|
||||||
|
return new Enumeration () {
|
||||||
|
public boolean hasMoreElements() {
|
||||||
|
return it.hasNext();
|
||||||
|
}
|
||||||
|
public Object nextElement() {
|
||||||
|
return it.next();
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public Iterator getDBPropertyIterator () {
|
private void collectPropertyNames (HashSet basket) {
|
||||||
if (table == null && parentMapping != null)
|
// fetch propnames from parent mapping first, than add our own.
|
||||||
return parentMapping.getDBPropertyIterator ();
|
if (parentMapping != null)
|
||||||
return db2prop.values ().iterator ();
|
parentMapping.collectPropertyNames (basket);
|
||||||
|
if (!prop2db.isEmpty())
|
||||||
|
basket.addAll (prop2db.keySet());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -727,9 +761,9 @@ public final class DbMapping implements Updatable {
|
||||||
* db.
|
* db.
|
||||||
*/
|
*/
|
||||||
public String getStorageTypeName () {
|
public String getStorageTypeName () {
|
||||||
if (table == null && parentMapping != null)
|
if (tableName == null && parentMapping != null)
|
||||||
return parentMapping.getStorageTypeName ();
|
return parentMapping.getStorageTypeName ();
|
||||||
return sourceName == null ? null : typename;
|
return dbSourceName == null ? null : typename;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -502,8 +502,8 @@ public final class Node implements INode, Serializable {
|
||||||
Node p = parentHandle.getNode (nmgr);
|
Node p = parentHandle.getNode (nmgr);
|
||||||
DbMapping parentmap = p.getDbMapping ();
|
DbMapping parentmap = p.getDbMapping ();
|
||||||
Relation prel = parentmap.getPropertyRelation();
|
Relation prel = parentmap.getPropertyRelation();
|
||||||
if (prel != null && prel.subnodesAreProperties && prel.accessor != null) {
|
if (prel != null && prel.hasAccessName()) {
|
||||||
String propname = dbmap.columnNameToProperty (prel.accessor);
|
String propname = dbmap.columnNameToProperty (prel.accessName);
|
||||||
String propvalue = getString (propname);
|
String propvalue = getString (propname);
|
||||||
if (propvalue != null && propvalue.length() > 0) {
|
if (propvalue != null && propvalue.length() > 0) {
|
||||||
setName (propvalue);
|
setName (propvalue);
|
||||||
|
@ -664,9 +664,9 @@ public final class Node implements INode, Serializable {
|
||||||
if (parentmap != null) {
|
if (parentmap != null) {
|
||||||
// first try to retrieve name via generic property relation of parent
|
// first try to retrieve name via generic property relation of parent
|
||||||
Relation prel = parentmap.getPropertyRelation ();
|
Relation prel = parentmap.getPropertyRelation ();
|
||||||
if (prel != null && prel.otherType == dbmap && prel.accessor != null) {
|
if (prel != null && prel.otherType == dbmap && prel.accessName != null) {
|
||||||
// reverse look up property used to access this via parent
|
// reverse look up property used to access this via parent
|
||||||
Relation proprel = dbmap.columnNameToRelation (prel.accessor);
|
Relation proprel = dbmap.columnNameToRelation (prel.accessName);
|
||||||
if (proprel != null && proprel.propName != null)
|
if (proprel != null && proprel.propName != null)
|
||||||
newname = getString (proprel.propName);
|
newname = getString (proprel.propName);
|
||||||
}
|
}
|
||||||
|
@ -775,8 +775,9 @@ public final class Node implements INode, Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
// if subnodes are defined via realation, make sure its constraints are enforced.
|
// if subnodes are defined via realation, make sure its constraints are enforced.
|
||||||
if (dbmap != null && dbmap.getSubnodeRelation () != null)
|
if (dbmap != null && dbmap.getSubnodeRelation () != null) {
|
||||||
dbmap.getSubnodeRelation ().setConstraints (this, node);
|
dbmap.getSubnodeRelation ().setConstraints (this, node);
|
||||||
|
}
|
||||||
|
|
||||||
// if the new node is marked as TRANSIENT and this node is not, mark new node as NEW
|
// if the new node is marked as TRANSIENT and this node is not, mark new node as NEW
|
||||||
if (state != TRANSIENT && node.state == TRANSIENT)
|
if (state != TRANSIENT && node.state == TRANSIENT)
|
||||||
|
@ -836,10 +837,10 @@ public final class Node implements INode, Serializable {
|
||||||
// check if properties are subnodes (_properties.aresubnodes=true)
|
// check if properties are subnodes (_properties.aresubnodes=true)
|
||||||
if (dbmap != null && node.dbmap != null) {
|
if (dbmap != null && node.dbmap != null) {
|
||||||
Relation prel = dbmap.getPropertyRelation();
|
Relation prel = dbmap.getPropertyRelation();
|
||||||
if (prel != null && prel.accessor != null) {
|
if (prel != null && prel.accessName != null) {
|
||||||
Relation localrel = node.dbmap.columnNameToRelation (prel.accessor);
|
Relation localrel = node.dbmap.columnNameToRelation (prel.accessName);
|
||||||
// if no relation from db column to prop name is found, assume that both are equal
|
// if no relation from db column to prop name is found, assume that both are equal
|
||||||
String propname = localrel == null ? prel.accessor : localrel.propName;
|
String propname = localrel == null ? prel.accessName : localrel.propName;
|
||||||
String prop = node.getString (propname);
|
String prop = node.getString (propname);
|
||||||
if (prop != null && prop.length() > 0) {
|
if (prop != null && prop.length() > 0) {
|
||||||
INode old = getNode (prop);
|
INode old = getNode (prop);
|
||||||
|
@ -932,7 +933,7 @@ public final class Node implements INode, Serializable {
|
||||||
if (rel != null)
|
if (rel != null)
|
||||||
return (IPathElement) getNode (name);
|
return (IPathElement) getNode (name);
|
||||||
rel = dbmap.getSubnodeRelation ();
|
rel = dbmap.getSubnodeRelation ();
|
||||||
if (rel != null && rel.groupby == null && rel.accessor != null) {
|
if (rel != null && rel.groupby == null && rel.accessName != null) {
|
||||||
if (rel.otherType != null && rel.otherType.isRelational ())
|
if (rel.otherType != null && rel.otherType.isRelational ())
|
||||||
return (IPathElement) nmgr.getNode (this, name, rel);
|
return (IPathElement) nmgr.getNode (this, name, rel);
|
||||||
else
|
else
|
||||||
|
@ -1112,10 +1113,10 @@ public final class Node implements INode, Serializable {
|
||||||
// check if subnodes are also accessed as properties. If so, also unset the property
|
// check if subnodes are also accessed as properties. If so, also unset the property
|
||||||
if (dbmap != null && node.dbmap != null) {
|
if (dbmap != null && node.dbmap != null) {
|
||||||
Relation prel = dbmap.getPropertyRelation();
|
Relation prel = dbmap.getPropertyRelation();
|
||||||
if (prel != null && prel.accessor != null) {
|
if (prel != null && prel.accessName != null) {
|
||||||
Relation localrel = node.dbmap.columnNameToRelation (prel.accessor);
|
Relation localrel = node.dbmap.columnNameToRelation (prel.accessName);
|
||||||
// if no relation from db column to prop name is found, assume that both are equal
|
// if no relation from db column to prop name is found, assume that both are equal
|
||||||
String propname = localrel == null ? prel.accessor : localrel.propName;
|
String propname = localrel == null ? prel.accessName : localrel.propName;
|
||||||
String prop = node.getString (propname);
|
String prop = node.getString (propname);
|
||||||
if (prop != null && getNode (prop) == node)
|
if (prop != null && getNode (prop) == node)
|
||||||
unset (prop);
|
unset (prop);
|
||||||
|
@ -1309,17 +1310,13 @@ public final class Node implements INode, Serializable {
|
||||||
*/
|
*/
|
||||||
public Enumeration properties () {
|
public Enumeration properties () {
|
||||||
|
|
||||||
if (dbmap != null && dbmap.isRelational() && dbmap.getProp2DB ().size() > 0)
|
if (dbmap != null && dbmap.isRelational())
|
||||||
// return the properties defined in type.properties, if there are any
|
// return the properties defined in type.properties, if there are any
|
||||||
return new Enumeration () {
|
return dbmap.getPropertyEnumeration();
|
||||||
Iterator i = dbmap.getProp2DB().keySet().iterator();
|
|
||||||
public boolean hasMoreElements() {return i.hasNext();}
|
|
||||||
public Object nextElement () {return i.next();}
|
|
||||||
};
|
|
||||||
|
|
||||||
Relation prel = dbmap == null ? null : dbmap.getPropertyRelation ();
|
Relation prel = dbmap == null ? null : dbmap.getPropertyRelation ();
|
||||||
if (prel != null && prel.accessor != null && !prel.subnodesAreProperties
|
if (prel != null && prel.hasAccessName()
|
||||||
&& prel.otherType != null && prel.otherType.isRelational ())
|
&& prel.otherType != null && prel.otherType.isRelational ())
|
||||||
// return names of objects from a relational db table
|
// return names of objects from a relational db table
|
||||||
return nmgr.getPropertyNames (this, prel).elements ();
|
return nmgr.getPropertyNames (this, prel).elements ();
|
||||||
else if (propMap != null)
|
else if (propMap != null)
|
||||||
|
@ -1493,7 +1490,7 @@ public final class Node implements INode, Serializable {
|
||||||
propMap.put (p2, prop);
|
propMap.put (p2, prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if this may have an effect on the node's URL when using subnodesAreProperties
|
// check if this may have an effect on the node's URL when using accessname
|
||||||
// but only do this if we already have a parent set, i.e. if we are already stored in the db
|
// but only do this if we already have a parent set, i.e. if we are already stored in the db
|
||||||
Node parent = parentHandle == null ? null : (Node) getParent ();
|
Node parent = parentHandle == null ? null : (Node) getParent ();
|
||||||
|
|
||||||
|
@ -1504,7 +1501,7 @@ public final class Node implements INode, Serializable {
|
||||||
Relation propRel = parentmap.getPropertyRelation ();
|
Relation propRel = parentmap.getPropertyRelation ();
|
||||||
String dbcolumn = dbmap.propertyToColumnName (propname);
|
String dbcolumn = dbmap.propertyToColumnName (propname);
|
||||||
|
|
||||||
if (propRel != null && propRel.accessor != null && propRel.accessor.equals (dbcolumn)) {
|
if (propRel != null && propRel.accessName != null && propRel.accessName.equals (dbcolumn)) {
|
||||||
INode n = parent.getNode (value);
|
INode n = parent.getNode (value);
|
||||||
if (n != null && n != this) {
|
if (n != null && n != this) {
|
||||||
parent.unset (value);
|
parent.unset (value);
|
||||||
|
@ -1748,7 +1745,7 @@ public final class Node implements INode, Serializable {
|
||||||
// UPDATE: using n.getKey() instead of manually constructing key. HW 2002/09/13
|
// UPDATE: using n.getKey() instead of manually constructing key. HW 2002/09/13
|
||||||
tx.visitCleanNode (n.getKey(), n);
|
tx.visitCleanNode (n.getKey(), n);
|
||||||
// if the field is not the primary key of the property, also register it
|
// if the field is not the primary key of the property, also register it
|
||||||
if (rel != null && rel.accessor != null && state != TRANSIENT) {
|
if (rel != null && rel.accessName != null && state != TRANSIENT) {
|
||||||
Key secKey = new SyntheticKey (getKey (), propname);
|
Key secKey = new SyntheticKey (getKey (), propname);
|
||||||
nmgr.evictKey (secKey);
|
nmgr.evictKey (secKey);
|
||||||
tx.visitCleanNode (secKey, n);
|
tx.visitCleanNode (secKey, n);
|
||||||
|
|
|
@ -1027,8 +1027,8 @@ public final class NodeManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
String accessProp = null;
|
String accessProp = null;
|
||||||
if (rel.accessor != null && !rel.usesPrimaryKey ())
|
if (rel.accessName != null && !rel.usesPrimaryKey ())
|
||||||
accessProp = dbm.columnNameToProperty (rel.accessor);
|
accessProp = dbm.columnNameToProperty (rel.accessName);
|
||||||
|
|
||||||
while (rs.next ()) {
|
while (rs.next ()) {
|
||||||
// create new Nodes.
|
// create new Nodes.
|
||||||
|
@ -1048,7 +1048,7 @@ public final class NodeManager {
|
||||||
sn.add (new NodeHandle (primKey));
|
sn.add (new NodeHandle (primKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
// if relation doesn't use primary key as accessor, get accessor value
|
// if relation doesn't use primary key as accessName, get accessName value
|
||||||
String accessName = null;
|
String accessName = null;
|
||||||
if (accessProp != null) {
|
if (accessProp != null) {
|
||||||
accessName = node.getString (accessProp);
|
accessName = node.getString (accessProp);
|
||||||
|
@ -1166,7 +1166,7 @@ public final class NodeManager {
|
||||||
Vector retval = new Vector ();
|
Vector retval = new Vector ();
|
||||||
// if we do a groupby query (creating an intermediate layer of groupby nodes),
|
// if we do a groupby query (creating an intermediate layer of groupby nodes),
|
||||||
// retrieve the value of that field instead of the primary key
|
// retrieve the value of that field instead of the primary key
|
||||||
String namefield = rel.accessor;
|
String namefield = rel.accessName;
|
||||||
Connection con = rel.otherType.getConnection ();
|
Connection con = rel.otherType.getConnection ();
|
||||||
String table = rel.otherType.getTableName ();
|
String table = rel.otherType.getTableName ();
|
||||||
|
|
||||||
|
@ -1296,7 +1296,7 @@ public final class NodeManager {
|
||||||
if (home.getSubnodeRelation () != null) {
|
if (home.getSubnodeRelation () != null) {
|
||||||
// combine our key with the constraints in the manually set subnode relation
|
// combine our key with the constraints in the manually set subnode relation
|
||||||
q.append ("WHERE ");
|
q.append ("WHERE ");
|
||||||
q.append (rel.accessor);
|
q.append (rel.accessName);
|
||||||
q.append (" = '");
|
q.append (" = '");
|
||||||
q.append (escape(kstr));
|
q.append (escape(kstr));
|
||||||
q.append ("'");
|
q.append ("'");
|
||||||
|
|
|
@ -238,7 +238,7 @@ public final class Property implements IProperty, Serializable, Cloneable {
|
||||||
// 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
|
||||||
// never reused.
|
// never reused.
|
||||||
if (nvrel != null && nvrel.subnodesAreProperties) {
|
if (nvrel != null && nvrel.hasAccessName()) {
|
||||||
node.removeNode (nvalue);
|
node.removeNode (nvalue);
|
||||||
}
|
}
|
||||||
// only need to call unregisterPropLink if the value node is not stored in a relational db
|
// only need to call unregisterPropLink if the value node is not stored in a relational db
|
||||||
|
|
|
@ -52,10 +52,9 @@ public final class Relation {
|
||||||
boolean readonly;
|
boolean readonly;
|
||||||
boolean aggressiveLoading;
|
boolean aggressiveLoading;
|
||||||
boolean aggressiveCaching;
|
boolean aggressiveCaching;
|
||||||
boolean subnodesAreProperties;
|
|
||||||
boolean isPrivate;
|
boolean isPrivate;
|
||||||
|
|
||||||
String accessor; // db column used to access objects through this relation
|
String accessName; // db column used to access objects through this relation
|
||||||
String order;
|
String order;
|
||||||
String groupbyOrder;
|
String groupbyOrder;
|
||||||
String groupby;
|
String groupby;
|
||||||
|
@ -76,9 +75,8 @@ public final class Relation {
|
||||||
this.columnName = rel.columnName;
|
this.columnName = rel.columnName;
|
||||||
this.reftype = rel.reftype;
|
this.reftype = rel.reftype;
|
||||||
this.constraints = rel.constraints;
|
this.constraints = rel.constraints;
|
||||||
this.accessor = rel.accessor;
|
this.accessName = rel.accessName;
|
||||||
this.maxSize = rel.maxSize;
|
this.maxSize = rel.maxSize;
|
||||||
this.subnodesAreProperties = rel.subnodesAreProperties;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -199,10 +197,8 @@ public final class Relation {
|
||||||
aggressiveLoading = aggressiveCaching = false;
|
aggressiveLoading = aggressiveCaching = false;
|
||||||
}
|
}
|
||||||
// check if subnode condition should be applied for property relations
|
// check if subnode condition should be applied for property relations
|
||||||
accessor = props.getProperty (propName+".accessname");
|
accessName = props.getProperty (propName+".accessname");
|
||||||
if (accessor != null)
|
// parse contstraints
|
||||||
subnodesAreProperties = true;
|
|
||||||
// parse contstraints
|
|
||||||
String local = props.getProperty (propName+".local");
|
String local = props.getProperty (propName+".local");
|
||||||
String foreign = props.getProperty (propName+".foreign");
|
String foreign = props.getProperty (propName+".foreign");
|
||||||
if (local != null && foreign != null) {
|
if (local != null && foreign != null) {
|
||||||
|
@ -257,7 +253,7 @@ public final class Relation {
|
||||||
* and never stored to a persistent storage.
|
* and never stored to a persistent storage.
|
||||||
*/
|
*/
|
||||||
public boolean createPropertyOnDemand () {
|
public boolean createPropertyOnDemand () {
|
||||||
return virtual || accessor != null || groupby != null;
|
return virtual || accessName != null || groupby != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -321,13 +317,17 @@ public final class Relation {
|
||||||
if (reftype == REFERENCE)
|
if (reftype == REFERENCE)
|
||||||
return constraints.length == 1 && constraints[0].foreignKeyIsPrimary ();
|
return constraints.length == 1 && constraints[0].foreignKeyIsPrimary ();
|
||||||
if (reftype == COLLECTION)
|
if (reftype == COLLECTION)
|
||||||
return accessor == null || accessor.equalsIgnoreCase (otherType.getIDField ());
|
return accessName == null || accessName.equalsIgnoreCase (otherType.getIDField ());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAccessor () {
|
public boolean hasAccessName () {
|
||||||
return accessor;
|
return accessName != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAccessName () {
|
||||||
|
return accessName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Relation getSubnodeRelation () {
|
public Relation getSubnodeRelation () {
|
||||||
|
@ -445,7 +445,7 @@ public final class Relation {
|
||||||
String prefix = pre;
|
String prefix = pre;
|
||||||
if (kstr != null) {
|
if (kstr != null) {
|
||||||
q.append (prefix);
|
q.append (prefix);
|
||||||
String accessColumn = accessor == null ? otherType.getIDField () : accessor;
|
String accessColumn = accessName == null ? otherType.getIDField () : accessName;
|
||||||
q.append (accessColumn);
|
q.append (accessColumn);
|
||||||
q.append (" = ");
|
q.append (" = ");
|
||||||
// check if column is string type and value needs to be quoted
|
// check if column is string type and value needs to be quoted
|
||||||
|
|
Loading…
Add table
Reference in a new issue