From 1db31dc40501f0f23e2cbb8abde340c2ba73e52b Mon Sep 17 00:00:00 2001 From: Simon Oberhammer Date: Wed, 14 Mar 2012 10:19:23 +0100 Subject: [PATCH] case-sensitivity-switch implemented by kmfdm --- src/helma/framework/core/Application.java | 20 ++++++- src/helma/framework/core/Session.java | 2 +- src/helma/objectmodel/TransientNode.java | 33 ++++++++--- src/helma/objectmodel/db/DbMapping.java | 7 ++- src/helma/objectmodel/db/Node.java | 55 ++++++++++++------- .../objectmodel/dom/XmlDatabaseReader.java | 8 ++- src/helma/scripting/rhino/HopObject.java | 2 +- 7 files changed, 89 insertions(+), 38 deletions(-) diff --git a/src/helma/framework/core/Application.java b/src/helma/framework/core/Application.java index 82e11c5d..4e0704f2 100644 --- a/src/helma/framework/core/Application.java +++ b/src/helma/framework/core/Application.java @@ -64,6 +64,9 @@ public final class Application implements Runnable { // embedded db directory File dbDir; + // false if hopobjects are case sensitive (default) + public boolean caseInsensitive; + // this application's node manager protected NodeManager nmgr; @@ -224,6 +227,8 @@ public final class Application implements Runnable { } this.name = name; + + this.caseInsensitive = "true".equalsIgnoreCase(server.getAppsProperties(name).getProperty("caseInsensitive")); this.repositories = new ArrayList(); this.repositories.addAll(Arrays.asList(repositories)); @@ -432,7 +437,7 @@ public final class Application implements Runnable { nmgr.init(dbDir.getAbsoluteFile(), props); // create the app cache node exposed as app.data - cachenode = new TransientNode("app"); + cachenode = new TransientNode(Application.this, "app"); // create and init session manager String sessionMgrImpl = props.getProperty("sessionManagerImpl", @@ -1384,6 +1389,19 @@ public final class Application implements Runnable { } return null; } + + /** + * Returns the correct property name which is either case sensitive or case insensitive + * @param propName the raw property name + * @return the correct property name + */ + public String correctPropertyName(String propName) { + if (propName == null) + return null; + if (caseInsensitive) + return propName.toLowerCase(); + return propName; + } /** * Return the application's classloader diff --git a/src/helma/framework/core/Session.java b/src/helma/framework/core/Session.java index 91d132ba..af59317f 100644 --- a/src/helma/framework/core/Session.java +++ b/src/helma/framework/core/Session.java @@ -73,7 +73,7 @@ public class Session implements Serializable { this.app = app; this.uid = null; this.userHandle = null; - cacheNode = new TransientNode("session"); + cacheNode = new TransientNode(app, "session"); cacheLastModified = cacheNode.lastModified(); // HACK - decrease timestamp by 1 to notice modifications // taking place immediately after object creation diff --git a/src/helma/objectmodel/TransientNode.java b/src/helma/objectmodel/TransientNode.java index c0c41e68..4ef01e76 100644 --- a/src/helma/objectmodel/TransientNode.java +++ b/src/helma/objectmodel/TransientNode.java @@ -17,6 +17,8 @@ package helma.objectmodel; import helma.framework.IPathElement; +import helma.framework.core.Application; +import helma.framework.core.RequestEvaluator; import helma.objectmodel.db.DbMapping; import helma.objectmodel.db.Relation; import helma.objectmodel.db.Node; @@ -44,6 +46,7 @@ public class TransientNode implements INode, Serializable { protected long lastmodified; protected String id; protected String name; + private final Application app; // is the main identity a named property or an anonymous node in a collection? protected boolean anonymous = false; @@ -53,21 +56,27 @@ public class TransientNode implements INode, Serializable { /** * Creates a new TransientNode object. */ - public TransientNode() { + public TransientNode(Application app) { id = generateID(); name = id; created = lastmodified = System.currentTimeMillis(); + this.app=app; + } + + private TransientNode() { + app=null; } /** * Make a new TransientNode object with a given name */ - public TransientNode(String n) { + public TransientNode(Application app, String n) { id = generateID(); name = (n == null || n.length() == 0) ? id : n; // HACK - decrease creation and last-modified timestamp by 1 so we notice // modifications that take place immediately after object creation created = lastmodified = System.currentTimeMillis() - 1; + this.app = app; } public static String generateID() { @@ -236,7 +245,7 @@ public class TransientNode implements INode, Serializable { anon = true; } - INode n = new TransientNode(nm); + INode n = new TransientNode(app, nm); if (anon) { addNode(n, where); @@ -367,7 +376,8 @@ public class TransientNode implements INode, Serializable { } private TransientProperty getProperty(String propname) { - TransientProperty prop = (propMap == null) ? null : (TransientProperty) propMap.get(propname); + TransientProperty prop = (propMap == null) ? null + : (TransientProperty) propMap.get(correctPropertyName(propname)); // check if we have to create a virtual node if ((prop == null) && (dbmap != null)) { @@ -388,7 +398,7 @@ public class TransientNode implements INode, Serializable { node.setDbMapping(rel.getVirtualMapping()); setNode(propname, node); - return (TransientProperty) propMap.get(propname); + return (TransientProperty) propMap.get(correctPropertyName(propname)); } public IProperty get(String propname) { @@ -485,11 +495,12 @@ public class TransientNode implements INode, Serializable { } propname = propname.trim(); - TransientProperty prop = (TransientProperty) propMap.get(propname); + String cpn = correctPropertyName(propname); + TransientProperty prop = (TransientProperty) propMap.get(cpn); if (prop == null) { prop = new TransientProperty(propname, this); - propMap.put(propname, prop); + propMap.put(cpn, prop); } return prop; @@ -552,7 +563,7 @@ public class TransientNode implements INode, Serializable { public void unset(String propname) { if (propMap != null && propname != null) { - propMap.remove(propname); + propMap.remove(correctPropertyName(propname)); lastmodified = System.currentTimeMillis(); } } @@ -576,7 +587,7 @@ public class TransientNode implements INode, Serializable { */ public synchronized INode getCacheNode() { if (cacheNode == null) { - cacheNode = new TransientNode(); + cacheNode = new TransientNode(app); } return cacheNode; @@ -588,4 +599,8 @@ public class TransientNode implements INode, Serializable { public synchronized void clearCacheNode() { cacheNode = null; } + + private String correctPropertyName(String propname) { + return app.correctPropertyName(propname); + } } diff --git a/src/helma/objectmodel/db/DbMapping.java b/src/helma/objectmodel/db/DbMapping.java index de0a6aea..7cc3e5ac 100644 --- a/src/helma/objectmodel/db/DbMapping.java +++ b/src/helma/objectmodel/db/DbMapping.java @@ -315,6 +315,7 @@ public final class DbMapping { // ignore internal properties (starting with "_") and sub-options (containing a ".") if (!propName.startsWith("_") && propName.indexOf(".") < 0) { Object propValue = entry.getValue(); + propName = app.correctPropertyName(propName); // check if a relation for this propery already exists. If so, reuse it Relation rel = (Relation) prop2db.get(propName); @@ -637,7 +638,7 @@ public final class DbMapping { } private String _propertyToColumnName(final String propName) { - Relation rel = (Relation) prop2db.get(propName); + Relation rel = (Relation) prop2db.get(app.correctPropertyName(propName)); if ((rel == null) && (parentMapping != null)) { return parentMapping._propertyToColumnName(propName); @@ -683,7 +684,7 @@ public final class DbMapping { } private Relation _propertyToRelation(String propName) { - Relation rel = (Relation) prop2db.get(propName); + Relation rel = (Relation) prop2db.get(app.correctPropertyName(propName)); if ((rel == null) && (parentMapping != null)) { return parentMapping._propertyToRelation(propName); @@ -866,7 +867,7 @@ public final class DbMapping { return null; } - Relation rel = (Relation) prop2db.get(propname); + Relation rel = (Relation) prop2db.get(app.correctPropertyName(propname)); if ((rel == null) && (parentMapping != null)) { rel = parentMapping.getExactPropertyRelation(propname); diff --git a/src/helma/objectmodel/db/Node.java b/src/helma/objectmodel/db/Node.java index e5429144..2cab8f44 100644 --- a/src/helma/objectmodel/db/Node.java +++ b/src/helma/objectmodel/db/Node.java @@ -1602,7 +1602,8 @@ public final class Node implements INode { null : dbmap.getExactPropertyRelation(propname); // 1) check if the property is contained in the propMap - Property prop = propMap == null ? null : (Property) propMap.get(propname); + Property prop = propMap == null ? null : + (Property) propMap.get(correctPropertyName(propname)); if (prop != null) { if (rel != null) { @@ -1631,7 +1632,7 @@ public final class Node implements INode { n.setDbMapping(rel.getVirtualMapping()); n.setParent(this); setNode(propname, n); - return (Property) propMap.get(propname); + return (Property) propMap.get(correctPropertyName(propname)); } // 2) check if this is a create-on-demand node property @@ -1798,14 +1799,15 @@ public final class Node implements INode { } propname = propname.trim(); - Property prop = (Property) propMap.get(propname); + String p2 = correctPropertyName(propname); + Property prop = (Property) propMap.get(p2); if (prop != null) { prop.setValue(value, type); } else { prop = new Property(propname, this); prop.setValue(value, type); - propMap.put(propname, prop); + propMap.put(p2, prop); } lastmodified = System.currentTimeMillis(); @@ -1833,7 +1835,8 @@ public final class Node implements INode { } propname = propname.trim(); - Property prop = (Property) propMap.get(propname); + String p2 = correctPropertyName(propname); + Property prop = (Property) propMap.get(p2); String oldvalue = null; if (prop != null) { @@ -1848,7 +1851,7 @@ public final class Node implements INode { } else { prop = new Property(propname, this); prop.setStringValue(value); - propMap.put(propname, prop); + propMap.put(p2, prop); } if (dbmap != null) { @@ -1944,14 +1947,15 @@ public final class Node implements INode { } propname = propname.trim(); - Property prop = (Property) propMap.get(propname); + String p2 = correctPropertyName(propname); + Property prop = (Property) propMap.get(p2); if (prop != null) { prop.setIntegerValue(value); } else { prop = new Property(propname, this); prop.setIntegerValue(value); - propMap.put(propname, prop); + propMap.put(p2, prop); } notifyPropertyChange(propname); @@ -1981,14 +1985,15 @@ public final class Node implements INode { } propname = propname.trim(); - Property prop = (Property) propMap.get(propname); + String p2 = correctPropertyName(propname); + Property prop = (Property) propMap.get(p2); if (prop != null) { prop.setFloatValue(value); } else { prop = new Property(propname, this); prop.setFloatValue(value); - propMap.put(propname, prop); + propMap.put(p2, prop); } notifyPropertyChange(propname); @@ -2018,14 +2023,15 @@ public final class Node implements INode { } propname = propname.trim(); - Property prop = (Property) propMap.get(propname); + String p2 = correctPropertyName(propname); + Property prop = (Property) propMap.get(p2); if (prop != null) { prop.setBooleanValue(value); } else { prop = new Property(propname, this); prop.setBooleanValue(value); - propMap.put(propname, prop); + propMap.put(p2, prop); } notifyPropertyChange(propname); @@ -2055,14 +2061,15 @@ public final class Node implements INode { } propname = propname.trim(); - Property prop = (Property) propMap.get(propname); + String p2 = correctPropertyName(propname); + Property prop = (Property) propMap.get(p2); if (prop != null) { prop.setDateValue(value); } else { prop = new Property(propname, this); prop.setDateValue(value); - propMap.put(propname, prop); + propMap.put(p2, prop); } notifyPropertyChange(propname); @@ -2092,14 +2099,15 @@ public final class Node implements INode { } propname = propname.trim(); - Property prop = (Property) propMap.get(propname); + String p2 = correctPropertyName(propname); + Property prop = (Property) propMap.get(p2); if (prop != null) { prop.setJavaObjectValue(value); } else { prop = new Property(propname, this); prop.setJavaObjectValue(value); - propMap.put(propname, prop); + propMap.put(p2, prop); } notifyPropertyChange(propname); @@ -2177,6 +2185,7 @@ public final class Node implements INode { } propname = propname.trim(); + String p2 = correctPropertyName(propname); if (rel == null && dbmap != null) { // widen relation to non-exact (collection) mapping rel = dbmap.getPropertyRelation(propname); @@ -2191,7 +2200,7 @@ public final class Node implements INode { } } - Property prop = (propMap == null) ? null : (Property) propMap.get(propname); + Property prop = (propMap == null) ? null : (Property) propMap.get(p2); if (prop != null) { if ((prop.getType() == IProperty.NODE) && @@ -2223,7 +2232,7 @@ public final class Node implements INode { propMap = new Hashtable(); } - propMap.put(propname, prop); + propMap.put(p2, prop); if (state == CLEAN && isPersistable) { markAs(MODIFIED); @@ -2273,9 +2282,9 @@ public final class Node implements INode { if (propMap != null) { if (relational) { - p = (Property) propMap.get(propname); + p = (Property) propMap.get(correctPropertyName(propname)); } else { - p = (Property) propMap.remove(propname); + p = (Property) propMap.remove(correctPropertyName(propname)); } } @@ -2477,7 +2486,7 @@ public final class Node implements INode { */ public synchronized INode getCacheNode() { if (cacheNode == null) { - cacheNode = new TransientNode(); + cacheNode = new TransientNode(this.getApp()); } return cacheNode; @@ -2558,4 +2567,8 @@ public final class Node implements INode { private Application getApp() { return nmgr.nmgr.app; } + + private String correctPropertyName(String propname) { + return getApp().correctPropertyName(propname); + } } \ No newline at end of file diff --git a/src/helma/objectmodel/dom/XmlDatabaseReader.java b/src/helma/objectmodel/dom/XmlDatabaseReader.java index bbd83e4f..cb34cacd 100644 --- a/src/helma/objectmodel/dom/XmlDatabaseReader.java +++ b/src/helma/objectmodel/dom/XmlDatabaseReader.java @@ -144,7 +144,7 @@ public final class XmlDatabaseReader extends DefaultHandler implements XmlConsta currentNode.setPropMap(propMap); } - propMap.put(propName, prop); + propMap.put(correctPropertyName(propName), prop); } } else { // a primitive property @@ -170,6 +170,10 @@ public final class XmlDatabaseReader extends DefaultHandler implements XmlConsta } } + private String correctPropertyName(String propName) { + return this.currentNode.getDbMapping().getApplication().correctPropertyName(propName); + } + /** * * @@ -233,7 +237,7 @@ public final class XmlDatabaseReader extends DefaultHandler implements XmlConsta currentNode.setPropMap(propMap); } - propMap.put(elementName, prop); + propMap.put(correctPropertyName(elementName), prop); elementName = null; elementType = null; charValue = null; diff --git a/src/helma/scripting/rhino/HopObject.java b/src/helma/scripting/rhino/HopObject.java index d4c3d8cd..c6dc6a03 100644 --- a/src/helma/scripting/rhino/HopObject.java +++ b/src/helma/scripting/rhino/HopObject.java @@ -1133,7 +1133,7 @@ public class HopObject extends ScriptableObject implements Wrapper, PropertyReco if (node == null || node.getState() == Node.INVALID) { // We probably have a deleted node. // Replace with empty transient node to avoid throwing an exception. - node = new TransientNode(); + node = new TransientNode(core.app); } } return node;