Author: nico
Date: 2010-04-03 16:38:43 +0200 (Sat, 03 Apr 2010)
New Revision: 41754
Modified:
mmbase/branches/MMBase-1_9/applications/editwizard/src/main/config/caches.xml
mmbase/branches/MMBase-1_9/applications/editwizard/src/main/java/org/mmbase/applications/editwizard/Wizard.java
mmbase/branches/MMBase-1_9/core/src/main/java/org/mmbase/module/core/MMObjectNode.java
mmbase/branches/MMBase-1_9/core/src/main/java/org/mmbase/util/magicfile/MagicXMLReader.java
mmbase/trunk/applications/editwizard/src/main/config/caches.xml
mmbase/trunk/applications/editwizard/src/main/java/org/mmbase/applications/editwizard/Wizard.java
mmbase/trunk/core/src/main/java/org/mmbase/module/core/MMObjectNode.java
mmbase/trunk/utils/src/main/java/org/mmbase/util/magicfile/MagicXMLReader.java
Log:
MMB-1948 Reduce memory footprint of collections and cached xmlfragements
Modified:
mmbase/branches/MMBase-1_9/applications/editwizard/src/main/config/caches.xml
===================================================================
---
mmbase/branches/MMBase-1_9/applications/editwizard/src/main/config/caches.xml
2010-04-03 14:16:48 UTC (rev 41753)
+++
mmbase/branches/MMBase-1_9/applications/editwizard/src/main/config/caches.xml
2010-04-03 14:38:43 UTC (rev 41754)
@@ -4,10 +4,6 @@
<!-- other caches ... -->
- <cache name="Editwizard nodes">
- <status>active</status>
- <size>100</size>
- </cache>
<cache name="Editwizard schemas">
<status>active</status>
<size>100</size>
Modified:
mmbase/branches/MMBase-1_9/applications/editwizard/src/main/java/org/mmbase/applications/editwizard/Wizard.java
===================================================================
---
mmbase/branches/MMBase-1_9/applications/editwizard/src/main/java/org/mmbase/applications/editwizard/Wizard.java
2010-04-03 14:16:48 UTC (rev 41753)
+++
mmbase/branches/MMBase-1_9/applications/editwizard/src/main/java/org/mmbase/applications/editwizard/Wizard.java
2010-04-03 14:38:43 UTC (rev 41754)
@@ -67,15 +67,14 @@
// File -> Document (resolved includes/shortcuts)
private static WizardSchemaCache wizardSchemaCache;
- private static NodeCache nodeCache; // it's absurd to name this NodeCache
static {
wizardSchemaCache = new WizardSchemaCache();
wizardSchemaCache.putCache();
- nodeCache = new NodeCache();
- nodeCache.putCache();
}
+ private Map<String, Node> nodePermissionCache = new HashMap<String,
Node>();
+
/**
* The cloud used to connect to MMBase
*/
@@ -304,7 +303,7 @@
* @throws WizardException if the object cannot be retrieved
*/
protected boolean checkNode(String objectNumber, String operation) throws
WizardException {
- Node node = nodeCache.get(objectNumber);
+ Node node = nodePermissionCache.get(objectNumber);
if (node == null) {
NodeList nodes = Utils.selectNodeList(data, ".//*...@number='" +
objectNumber + "']");
@@ -323,7 +322,7 @@
node = databaseConnector.getDataNode(null, objectNumber, null);
}
- nodeCache.put(objectNumber, node);
+ nodePermissionCache.put(objectNumber, node);
log.debug("Node loaded: " + node);
} else {
log.debug("Node found in cache: " + node);
@@ -2958,24 +2957,6 @@
}
/**
- * Caches objectNumber to Node.
- * @since MMBase-1.6.4
- */
- static class NodeCache extends Cache<String, Node> {
- NodeCache() {
- super(100);
- }
-
- public String getName() {
- return "Editwizard nodes";
- }
-
- public String getDescription() {
- return "objectNumber -> DOM Node";
- }
- }
-
- /**
* Caches File to Editwizard schema Document.
* @since MMBase-1.6.4
*/
Modified:
mmbase/branches/MMBase-1_9/core/src/main/java/org/mmbase/module/core/MMObjectNode.java
===================================================================
---
mmbase/branches/MMBase-1_9/core/src/main/java/org/mmbase/module/core/MMObjectNode.java
2010-04-03 14:16:48 UTC (rev 41753)
+++
mmbase/branches/MMBase-1_9/core/src/main/java/org/mmbase/module/core/MMObjectNode.java
2010-04-03 14:38:43 UTC (rev 41754)
@@ -61,8 +61,9 @@
* it can be used to optimise cacheing
* @since MMBase-1.8
*/
- private Map<String, Object> oldValues = Collections.synchronizedMap(new
HashMap<String, Object>());
-
+ private Map<String, Object> oldValues = null;
+
+
/**
* Holds the name - value pairs of this node (the node's fields).
* Most nodes will have a 'number' and an 'otype' field, and fields which
will differ by builder.
@@ -72,8 +73,9 @@
* Note: To avoid synchronisation conflicts, we can't really change the
type until the property is made private.
*/
protected Map<String, Object> values = Collections.synchronizedMap(new
HashMap<String, Object>());
- private Map<String, Long> sizes = Collections.synchronizedMap(new
HashMap<String, Long>());
+ private Map<String, Long> sizes = null;
+
/**
* Determines whether the node is being initialized (typically when it is
loaded from the database).
* Use {...@link #start} to start initializing, use {...@link #finish} to
end.
@@ -94,8 +96,8 @@
* Set which stores the keys of the fields that were changed
* since the last commit.
*/
- private Set<String> changed = Collections.synchronizedSet(new
HashSet<String>());
-
+ private Set<String> changed = null;
+
/**
* Pointer to the parent builder that is responsible for this node.
* Note: this may on occasion (due to optimization) differ for the node's
original builder.
@@ -172,8 +174,13 @@
isNew = node.isNew();
newContext = node.newContext;
values.putAll(node.getValues());
- values.putAll(node.getOldValues());
- sizes.putAll(node.sizes);
+ Map<String, Object> nodeOldValues = node.getOldValues();
+ if (nodeOldValues != null) {
+ values.putAll(nodeOldValues);
+ }
+ if (node.sizes != null) {
+ sizesMap().putAll(node.sizes);
+ }
}
/**
@@ -187,6 +194,27 @@
values = map;
}
+ private Map<String, Object> oldValuesMap() {
+ if (oldValues == null) {
+ oldValues = Collections.synchronizedMap(new HashMap<String,
Object>());
+ }
+ return oldValues;
+ }
+
+ private Set<String> changedMap() {
+ if (changed == null) {
+ changed = Collections.synchronizedSet(new HashSet<String>());
+ }
+ return changed;
+ }
+
+ private Map<String, Long> sizesMap() {
+ if (sizes == null) {
+ sizes = Collections.synchronizedMap(new HashMap<String, Long>());
+ }
+ return sizes;
+ }
+
/**
* Returns the actual builder of the node.
* Note that it is possible that, due to optimization, a node is currently
associated with
@@ -226,6 +254,9 @@
private void fixValues(final Map<String, Object> map, MMObjectBuilder bul)
{
+ if (map == null) {
+ return;
+ }
synchronized(map) {
Set<String> targetFields = bul.getFieldNames();
@@ -254,7 +285,6 @@
}
}
}
-
/**
* @since MMBase-1.9.1
*/
@@ -308,11 +338,14 @@
* @return <code>true</code> if the commit was succesfull,
<code>false</code> is it failed
*/
public boolean commit() {
+ assert values.get("number") != null;
boolean success = parent.commit(this);
if (success) {
isNew = false; // perhaps it is always already false (otherwise
insert is called, I think), but no matter, now it certainly isn't new!
} else {
- values.putAll(oldValues);
+ if (oldValues != null) {
+ values.putAll(oldValues);
+ }
}
clearChanged();
return success;
@@ -324,7 +357,9 @@
* @since MMBase-1.8
*/
public void cancel() {
- values.putAll(oldValues);
+ if (oldValues != null) {
+ values.putAll(oldValues);
+ }
clearChanged();
}
/**
@@ -373,6 +408,7 @@
* @since MMBase-1.7
*/
public boolean commit(UserContext user) {
+ assert values.get("number") != null;
boolean success = parent.safeCommit(this);
if (success) {
MMBaseCop mmbaseCop = parent.getMMBase().getMMBaseCop();
@@ -495,23 +531,25 @@
String defaultToString() {
StringBuilder result = new StringBuilder();
try {
- Set<Map.Entry<String, Object>> entrySet = values.entrySet();
synchronized(values) {
- Iterator<Map.Entry<String, Object>> i = entrySet.iterator();
- while (i.hasNext()) {
- Map.Entry<String, Object> entry = i.next();
+ for (Map.Entry<String, Object> entry : values.entrySet()) {
String key = entry.getKey();
- String value = "" + entry.getValue(); // XXX:should be
retrieveValue ?
- if (result.length() == 0) {
-
result.append(key).append("='").append(value).append("'");
+ if (result.length() > 0) {
+ result.append(", ");
+ }
+ result.append(key);
+ Object value = entry.getValue();
+ if (value == null) {
+ result.append(" is null");
} else {
-
result.append(",").append(key).append("='").append(value).append("'");
+
result.append("='").append(value.toString()).append("'");
}
}
}
} catch(Throwable e) {
result.append(values); // simpler version...
}
+ result.append(' ');
result.append(super.toString());
if (oldBuilder != null) {
result.append(" (to be converted from " +
oldBuilder.getTableName() + " to " + builder.getTableName() + ")");
@@ -539,7 +577,7 @@
} else {
log.warn("Tried to use non-existing field '" + fieldName + "'
of node '" + getNumber() + "' from " + getBuilder().getTableName());
if (log.isDebugEnabled()) {
- log.debug("Stacktrace", new Exception());
+ log.debug(new Exception());
} else {
log.warn(Logging.applicationStacktrace());
@@ -586,6 +624,9 @@
if (fieldValue != null && (fieldValue instanceof InputStream && (!
(fieldValue instanceof Serializable)))) {
fieldValue = new SerializableInputStream((InputStream) fieldValue,
getSize(fieldName));
}
+ if (fieldValue instanceof Node) {
+ fieldValue = Integer.valueOf(((Node) fieldValue).getNumber());
+ }
fieldValue = checkSerializable(fieldName, fieldValue);
if (checkFieldExistance(fieldName)) {
values.put(fieldName, fieldValue);
@@ -602,9 +643,9 @@
* @since MMBase-1.8
*/
private void storeOldValue(String fieldName, Object object) {
- if (! oldValues.containsKey(fieldName)) {
+ if (! oldValuesMap().containsKey(fieldName)) {
object = checkSerializable(fieldName, object);
- oldValues.put(fieldName, object);
+ oldValuesMap().put(fieldName, object);
}
}
@@ -658,81 +699,83 @@
* @return <code>true</code> When the field was changed, false otherwise.
*/
public boolean setValue(final String fieldName, Object fieldValue) {
- // check the value also when the parent thing is null
- Object originalValue = values.get(fieldName);
+ synchronized(values) {
+ // check the value also when the parent thing is null
+ Object originalValue = values.get(fieldName);
- if (fieldValue != VALUE_SHORTED) {
- // make sure this value remains not in the blob-cache.
- BlobCache blobs = parent.getBlobCache(fieldName);
- blobs.remove(blobs.getKey(getNumber(), fieldName));
- }
+ if (fieldValue != VALUE_SHORTED) {
+ // make sure this value remains not in the blob-cache.
+ BlobCache blobs = parent.getBlobCache(fieldName);
+ blobs.remove(blobs.getKey(getNumber(), fieldName));
+ }
- if (fieldValue instanceof DynamicDate) {
- // 'dynamic' values can of course not be stored in database, and
that is not the intentention too, so
- // store a static version
- fieldValue = new Date(((Date) fieldValue).getTime());
- }
+ if (fieldValue instanceof DynamicDate) {
+ // 'dynamic' values can of course not be stored in database,
and that is not the intentention too, so
+ // store a static version
+ fieldValue = new Date(((Date) fieldValue).getTime());
+ }
- if (log.isDebugEnabled()) {
- String string;
- if (fieldValue instanceof byte[]) {
- string = "byte array of size " + ((byte[])fieldValue).length;
- } else {
- string = Casting.toString(fieldValue);
- if (string.length() > 200) string = string.substring(0, 200);
+ if (log.isDebugEnabled()) {
+ String string;
+ if (fieldValue instanceof byte[]) {
+ string = "byte array of size " +
((byte[])fieldValue).length;
+ } else {
+ string = Casting.toString(fieldValue);
+ if (string.length() > 200) string = string.substring(0,
200);
+ }
+ log.debug("Setting " + fieldName + " to " + string);
}
- log.debug("Setting " + fieldName + " to " + string);
- }
- boolean changed =
- (! values.containsKey(fieldName)) ||
- (originalValue == null ? fieldValue != null : !
Casting.equals(originalValue, fieldValue));
- if (! changed) return false;
+ boolean changed =
+ (! values.containsKey(fieldName)) ||
+ (originalValue == null ? fieldValue != null : !
Casting.equals(originalValue, fieldValue));
+ if (! changed) return false;
- if (log.isDebugEnabled()) {
- log.debug("" + fieldName + ":" + originalValue + " --> " +
fieldValue);
- }
+ if (log.isDebugEnabled()) {
+ log.debug("" + fieldName + ":" + originalValue + " --> " +
fieldValue);
+ }
- //store the old value
- storeOldValue(fieldName, originalValue);
+ //store the old value
+ storeOldValue(fieldName, originalValue);
- // put the key/value in the value hashtable
- storeValue(fieldName, fieldValue);
- if (fieldValue instanceof byte[]) {
- setSize(fieldName, ((byte[]) fieldValue).length);
- log.debug("Setting length to " + ((byte[]) fieldValue).length);
- } else if (fieldValue instanceof
org.apache.commons.fileupload.FileItem) {
- org.apache.commons.fileupload.FileItem fi =
(org.apache.commons.fileupload.FileItem) fieldValue;
- setSize(fieldName, fi.getSize());
- } else if (fieldValue instanceof SerializableInputStream) {
- SerializableInputStream si = (SerializableInputStream) fieldValue;
- log.debug("Setting '" + fieldName + "' to " + si + " " +
si.getSize());
- setSize(fieldName, si.getSize());
- }
+ // put the key/value in the value hashtable
+ storeValue(fieldName, fieldValue);
+ if (fieldValue instanceof byte[]) {
+ setSize(fieldName, ((byte[]) fieldValue).length);
+ log.debug("Setting length to " + ((byte[]) fieldValue).length);
+ } else if (fieldValue instanceof
org.apache.commons.fileupload.FileItem) {
+ org.apache.commons.fileupload.FileItem fi =
(org.apache.commons.fileupload.FileItem) fieldValue;
+ setSize(fieldName, fi.getSize());
+ } else if (fieldValue instanceof SerializableInputStream) {
+ SerializableInputStream si = (SerializableInputStream)
fieldValue;
+ log.debug("Setting '" + fieldName + "' to " + si + " " +
si.getSize());
+ setSize(fieldName, si.getSize());
+ }
- // process the changed value (?)
- if (parent != null) {
- if(!parent.setValue(this, fieldName, originalValue)) {
- log.debug("setValue of parent returned false, no update
needed...");
- return false;
+ // process the changed value (?)
+ if (parent != null) {
+ if(!parent.setValue(this, fieldName, originalValue)) {
+ log.debug("setValue of parent returned false, no update
needed...");
+ return false;
+ }
+ } else {
+ log.error("parent was null for node with number" +
getNumber());
}
- } else {
- log.error("parent was null for node with number" + getNumber());
- }
- setUpdate(fieldName);
+ setUpdate(fieldName);
- if (fieldValue instanceof SerializableInputStream) {
- // in case this is alled from a transaction, it must be possible
to do it again on
- // actual commit
- try {
- SerializableInputStream si = (SerializableInputStream)
fieldValue;
- si.reset();
- } catch (IOException ioe) {
- log.error(ioe);
+ if (fieldValue instanceof SerializableInputStream) {
+ // in case this is alled from a transaction, it must be
possible to do it again on
+ // actual commit
+ try {
+ SerializableInputStream si = (SerializableInputStream)
fieldValue;
+ si.reset();
+ } catch (IOException ioe) {
+ log.error(ioe);
+ }
}
+ log.debug("" + sequence + getChanged());
+ return true;
}
- log.debug("" + sequence + getChanged());
- return true;
}
/**
@@ -742,7 +785,7 @@
* @since MMBase-1.8
*/
public void setSize(String fieldName, long size) {
- sizes.put(fieldName, size);
+ sizesMap().put(fieldName, size);
}
/**
* Returns the size (in byte) of the given field. This is mainly targeted
at fields of the type
@@ -752,8 +795,12 @@
* @since MMBase-1.8
*/
public long getSize(String fieldName) {
- Long l = sizes.get(fieldName);
- if (l != null) return l;
+ if (sizes != null) {
+ Long l = sizes.get(fieldName);
+ if (l != null) {
+ return l;
+ }
+ }
Object value = values.get(fieldName);
// Value is null so it does not occupy any space.
if (value == null) {
@@ -777,7 +824,7 @@
// on the next commit
if (! initializing) {
log.trace("Marking '" + fieldName + "' as changed in " + sequence);
- changed.add(fieldName);
+ changedMap().add(fieldName);
}
// is it a memory only field ? then send a fieldchange
if (state == Field.STATE_VIRTUAL) {
@@ -1012,7 +1059,7 @@
if (value == null) {
checkFieldExistance(fieldName);
log.debug("NULL on " + fieldName + " " + this, new Exception());
- return new ByteArrayInputStream(new byte[0]);
+ return new SerializableInputStream(new byte[0]);
} else {
if (log.isTraceEnabled()) {
log.trace("Found " + value);
@@ -1053,13 +1100,17 @@
}
} else {
v = (byte[]) blobs.get(key);
- log.debug("Found in " + v.length + " bytes in blob cache for
field " + fieldName );
- assert v.length == getSize(fieldName);
+ log.debug("Found in " + v.length + " bytes in blob cache for
field " + fieldName + " (expected " + getSize(fieldName) + " )");
+ //assert v.length == getSize(fieldName) : ("" + fieldName +
":" + v.length + " " + sizes);
+ if (v.length != getSize(fieldName)) {
+ log.warn("Found incorrect size in " + sizes + "(" +
fieldName + " should be " + v.length + "). Correcting now.");
+ setSize(fieldName, v.length);
+ }
}
- return v == null ? null : new ByteArrayInputStream(v);
+ return v == null ? null : new SerializableInputStream(v);
} else {
if (value instanceof byte[]) {
- return new ByteArrayInputStream((byte[]) value);
+ return new SerializableInputStream((byte[]) value);
} else {
// probably not a byte-array field, do something.
// this behavior is undefined!, don't depend on it.
@@ -1261,7 +1312,7 @@
* @return An unmodifiable Set containing Strings.
*/
public Set<String> getChanged() {
- return Collections.unmodifiableSet(changed);
+ return Collections.unmodifiableSet(changedMap());
}
/**
@@ -1269,7 +1320,7 @@
* @return <code>true</code> if changes have been made, <code>false</code>
otherwise
*/
public boolean isChanged() {
- return oldBuilder != null || newContext != null || changed.size() > 0;
+ return oldBuilder != null || newContext != null || (changed != null &&
changed.size() > 0);
}
/**
@@ -1281,8 +1332,12 @@
public boolean clearChanged() {
oldBuilder = null;
newContext = null;
- changed.clear();
- oldValues.clear();
+ if (changed != null) {
+ changed.clear();
+ }
+ if (oldValues != null) {
+ oldValues.clear();
+ }
return true;
}
@@ -1310,7 +1365,7 @@
* @since MMBase-1.8
*/
public Map<String, Object> getOldValues() {
- return Collections.unmodifiableMap(oldValues);
+ return Collections.unmodifiableMap(oldValuesMap());
}
/**
Modified:
mmbase/branches/MMBase-1_9/core/src/main/java/org/mmbase/util/magicfile/MagicXMLReader.java
===================================================================
---
mmbase/branches/MMBase-1_9/core/src/main/java/org/mmbase/util/magicfile/MagicXMLReader.java
2010-04-03 14:16:48 UTC (rev 41753)
+++
mmbase/branches/MMBase-1_9/core/src/main/java/org/mmbase/util/magicfile/MagicXMLReader.java
2010-04-03 14:38:43 UTC (rev 41754)
@@ -19,49 +19,55 @@
private static Logger log =
Logging.getLoggerInstance(MagicXMLReader.class);
- private static MagicXMLReader reader = null;
+ private static DetectorProvider provider;
+
protected static final String MAGICXMLFILE = "magic.xml";
// Name of the XML magic file - should reside in top config dir
- private static void setReader(String config) throws
IllegalArgumentException {
- try {
- InputSource is =
ResourceLoader.getConfigurationRoot().getInputSource(config);
- if (is != null) {
- reader = new MagicXMLReader(is);
- }
- } catch (IOException ie) {
- log.warn(ie);
- }
- }
+ private static void loadDetectorProvider(String config) throws
IllegalArgumentException {
+ try {
+ InputSource is =
ResourceLoader.getConfigurationRoot().getInputSource(config);
+ if (is != null) {
+ MagicXMLReader reader = new MagicXMLReader(is);
+ if (reader != null) {
+ log.info("Magic XML file is: " + reader.getSystemId());
+ final List<Detector> detectors = new
ArrayList<Detector>(reader.getDetectors());
+ DetectorProvider dp = new DetectorProvider() {
+ public List<Detector> getDetectors() {
+ return detectors;
+ }
+ };
+ provider = dp;
+ }
+ }
+ } catch (IOException ie) {
+ log.warn(ie);
+ }
+ }
- /**
- * Gets the one MagicXMLReader (there can only be one).
- * @return MagicXMLReader if mmbase was staterd or null if mmbase was not
started
- */
+ /**
+ * Gets the one MagicXMLReader (there can only be one).
+ * @return MagicXMLReader if mmbase was staterd or null if mmbase was not
started
+ */
- public synchronized static MagicXMLReader getInstance() {
- if (reader == null) { // can only occur once.
+ public synchronized static DetectorProvider getInstance() {
+ if (provider == null) { // can only occur once.
- setReader(MAGICXMLFILE);
+ loadDetectorProvider(MAGICXMLFILE);
- if (reader != null) {
- log.info("Magic XML file is: " + reader.getSystemId());
- }
+ ResourceWatcher watcher = new ResourceWatcher() {
+ public void onChange(String file) {
+ // reader is replaced on every change of magic.xml
+ loadDetectorProvider(file);
+ }
+ };
+ watcher.start();
+ watcher.add(MAGICXMLFILE);
- ResourceWatcher watcher = new ResourceWatcher() {
- public void onChange(String file) {
- // reader is replaced on every change of magic.xml
- setReader(file);
- }
- };
- watcher.start();
- watcher.add(MAGICXMLFILE);
-
- }
- return reader;
- }
- private List<Detector> detectors = null;
-
+ }
+ return provider;
+ }
+
private MagicXMLReader(InputSource is) {
super(is, MagicXMLReader.class);
}
@@ -82,25 +88,22 @@
/**
* Returns all 'Detectors'.
*/
- public List<Detector> getDetectors() {
- if (detectors == null) {
- detectors = new CopyOnWriteArrayList<Detector>();
- Element e = getElementByPath("magic.detectorlist");
- if (e == null) {
- log.fatal("Could not find magic/detectorlist in magic.xml");
- // aargh!
- return detectors;
+ public List<Detector> getDetectors() {
+ List<Detector> detectors = new CopyOnWriteArrayList<Detector>();
+ Element e = getElementByPath("magic.detectorlist");
+ if (e == null) {
+ log.fatal("Could not find magic/detectorlist in magic.xml");
+ // aargh!
+ return detectors;
+ }
+ for (Element element : getChildElements(e)) {
+ try {
+ Detector d = getOneDetector(element);
+ detectors.add(d);
+ } catch (Exception ex) {
+ log.error(ex.getClass() + " " + ex.getMessage() + ": " +
XMLWriter.write(element));
}
- for (Element element : getChildElements(e)) {
- try {
- Detector d = getOneDetector(element);
- detectors.add(d);
- } catch (Exception ex) {
- log.error(ex.getClass() + " " + ex.getMessage() + ": " +
XMLWriter.write(element));
- }
- }
}
-
return detectors;
}
Modified: mmbase/trunk/applications/editwizard/src/main/config/caches.xml
===================================================================
--- mmbase/trunk/applications/editwizard/src/main/config/caches.xml
2010-04-03 14:16:48 UTC (rev 41753)
+++ mmbase/trunk/applications/editwizard/src/main/config/caches.xml
2010-04-03 14:38:43 UTC (rev 41754)
@@ -4,10 +4,6 @@
<!-- other caches ... -->
- <cache name="Editwizard nodes">
- <status>active</status>
- <size>100</size>
- </cache>
<cache name="Editwizard schemas">
<status>active</status>
<size>100</size>
Modified:
mmbase/trunk/applications/editwizard/src/main/java/org/mmbase/applications/editwizard/Wizard.java
===================================================================
---
mmbase/trunk/applications/editwizard/src/main/java/org/mmbase/applications/editwizard/Wizard.java
2010-04-03 14:16:48 UTC (rev 41753)
+++
mmbase/trunk/applications/editwizard/src/main/java/org/mmbase/applications/editwizard/Wizard.java
2010-04-03 14:38:43 UTC (rev 41754)
@@ -67,15 +67,14 @@
// File -> Document (resolved includes/shortcuts)
private static WizardSchemaCache wizardSchemaCache;
- private static NodeCache nodeCache; // it's absurd to name this NodeCache
static {
wizardSchemaCache = new WizardSchemaCache();
wizardSchemaCache.putCache();
- nodeCache = new NodeCache();
- nodeCache.putCache();
}
+ private Map<String, Node> nodePermissionCache = new HashMap<String,
Node>();
+
/**
* The cloud used to connect to MMBase
*/
@@ -304,7 +303,7 @@
* @throws WizardException if the object cannot be retrieved
*/
protected boolean checkNode(String objectNumber, String operation) throws
WizardException {
- Node node = nodeCache.get(objectNumber);
+ Node node = nodePermissionCache.get(objectNumber);
if (node == null) {
NodeList nodes = Utils.selectNodeList(data, ".//*...@number='" +
objectNumber + "']");
@@ -323,7 +322,7 @@
node = databaseConnector.getDataNode(null, objectNumber, null);
}
- nodeCache.put(objectNumber, node);
+ nodePermissionCache.put(objectNumber, node);
log.debug("Node loaded: " + node);
} else {
log.debug("Node found in cache: " + node);
@@ -2958,24 +2957,6 @@
}
/**
- * Caches objectNumber to Node.
- * @since MMBase-1.6.4
- */
- static class NodeCache extends Cache<String, Node> {
- NodeCache() {
- super(100);
- }
-
- public String getName() {
- return "Editwizard nodes";
- }
-
- public String getDescription() {
- return "objectNumber -> DOM Node";
- }
- }
-
- /**
* Caches File to Editwizard schema Document.
* @since MMBase-1.6.4
*/
Modified:
mmbase/trunk/core/src/main/java/org/mmbase/module/core/MMObjectNode.java
===================================================================
--- mmbase/trunk/core/src/main/java/org/mmbase/module/core/MMObjectNode.java
2010-04-03 14:16:48 UTC (rev 41753)
+++ mmbase/trunk/core/src/main/java/org/mmbase/module/core/MMObjectNode.java
2010-04-03 14:38:43 UTC (rev 41754)
@@ -61,8 +61,9 @@
* it can be used to optimise cacheing
* @since MMBase-1.8
*/
- private Map<String, Object> oldValues = Collections.synchronizedMap(new
HashMap<String, Object>());
-
+ private Map<String, Object> oldValues = null;
+
+
/**
* Holds the name - value pairs of this node (the node's fields).
* Most nodes will have a 'number' and an 'otype' field, and fields which
will differ by builder.
@@ -72,8 +73,9 @@
* Note: To avoid synchronisation conflicts, we can't really change the
type until the property is made private.
*/
protected Map<String, Object> values = Collections.synchronizedMap(new
HashMap<String, Object>());
- private Map<String, Long> sizes = Collections.synchronizedMap(new
HashMap<String, Long>());
+ private Map<String, Long> sizes = null;
+
/**
* Determines whether the node is being initialized (typically when it is
loaded from the database).
* Use {...@link #start} to start initializing, use {...@link #finish} to
end.
@@ -94,8 +96,8 @@
* Set which stores the keys of the fields that were changed
* since the last commit.
*/
- private Set<String> changed = Collections.synchronizedSet(new
HashSet<String>());
-
+ private Set<String> changed = null;
+
/**
* Pointer to the parent builder that is responsible for this node.
* Note: this may on occasion (due to optimization) differ for the node's
original builder.
@@ -172,8 +174,13 @@
isNew = node.isNew();
newContext = node.newContext;
values.putAll(node.getValues());
- values.putAll(node.getOldValues());
- sizes.putAll(node.sizes);
+ Map<String, Object> nodeOldValues = node.getOldValues();
+ if (nodeOldValues != null) {
+ values.putAll(nodeOldValues);
+ }
+ if (node.sizes != null) {
+ sizesMap().putAll(node.sizes);
+ }
}
/**
@@ -187,6 +194,27 @@
values = map;
}
+ private Map<String, Object> oldValuesMap() {
+ if (oldValues == null) {
+ oldValues = Collections.synchronizedMap(new HashMap<String,
Object>());
+ }
+ return oldValues;
+ }
+
+ private Set<String> changedMap() {
+ if (changed == null) {
+ changed = Collections.synchronizedSet(new HashSet<String>());
+ }
+ return changed;
+ }
+
+ private Map<String, Long> sizesMap() {
+ if (sizes == null) {
+ sizes = Collections.synchronizedMap(new HashMap<String, Long>());
+ }
+ return sizes;
+ }
+
/**
* Returns the actual builder of the node.
* Note that it is possible that, due to optimization, a node is currently
associated with
@@ -226,6 +254,9 @@
private void fixValues(final Map<String, Object> map, MMObjectBuilder bul)
{
+ if (map == null) {
+ return;
+ }
synchronized(map) {
Set<String> targetFields = bul.getFieldNames();
@@ -312,7 +343,9 @@
if (success) {
isNew = false; // perhaps it is always already false (otherwise
insert is called, I think), but no matter, now it certainly isn't new!
} else {
- values.putAll(oldValues);
+ if (oldValues != null) {
+ values.putAll(oldValues);
+ }
}
clearChanged();
return success;
@@ -324,7 +357,9 @@
* @since MMBase-1.8
*/
public void cancel() {
- values.putAll(oldValues);
+ if (oldValues != null) {
+ values.putAll(oldValues);
+ }
clearChanged();
}
/**
@@ -608,9 +643,9 @@
* @since MMBase-1.8
*/
private void storeOldValue(String fieldName, Object object) {
- if (! oldValues.containsKey(fieldName)) {
+ if (! oldValuesMap().containsKey(fieldName)) {
object = checkSerializable(fieldName, object);
- oldValues.put(fieldName, object);
+ oldValuesMap().put(fieldName, object);
}
}
@@ -750,7 +785,7 @@
* @since MMBase-1.8
*/
public void setSize(String fieldName, long size) {
- sizes.put(fieldName, size);
+ sizesMap().put(fieldName, size);
}
/**
* Returns the size (in byte) of the given field. This is mainly targeted
at fields of the type
@@ -760,9 +795,11 @@
* @since MMBase-1.8
*/
public long getSize(String fieldName) {
- Long l = sizes.get(fieldName);
- if (l != null) {
- return l;
+ if (sizes != null) {
+ Long l = sizes.get(fieldName);
+ if (l != null) {
+ return l;
+ }
}
Object value = values.get(fieldName);
// Value is null so it does not occupy any space.
@@ -787,7 +824,7 @@
// on the next commit
if (! initializing) {
log.trace("Marking '" + fieldName + "' as changed in " + sequence);
- changed.add(fieldName);
+ changedMap().add(fieldName);
}
// is it a memory only field ? then send a fieldchange
if (state == Field.STATE_VIRTUAL) {
@@ -1275,7 +1312,7 @@
* @return An unmodifiable Set containing Strings.
*/
public Set<String> getChanged() {
- return Collections.unmodifiableSet(changed);
+ return Collections.unmodifiableSet(changedMap());
}
/**
@@ -1283,7 +1320,7 @@
* @return <code>true</code> if changes have been made, <code>false</code>
otherwise
*/
public boolean isChanged() {
- return oldBuilder != null || newContext != null || changed.size() > 0;
+ return oldBuilder != null || newContext != null || (changed != null &&
changed.size() > 0);
}
/**
@@ -1295,8 +1332,12 @@
public boolean clearChanged() {
oldBuilder = null;
newContext = null;
- changed.clear();
- oldValues.clear();
+ if (changed != null) {
+ changed.clear();
+ }
+ if (oldValues != null) {
+ oldValues.clear();
+ }
return true;
}
@@ -1324,7 +1365,7 @@
* @since MMBase-1.8
*/
public Map<String, Object> getOldValues() {
- return Collections.unmodifiableMap(oldValues);
+ return Collections.unmodifiableMap(oldValuesMap());
}
/**
Modified:
mmbase/trunk/utils/src/main/java/org/mmbase/util/magicfile/MagicXMLReader.java
===================================================================
---
mmbase/trunk/utils/src/main/java/org/mmbase/util/magicfile/MagicXMLReader.java
2010-04-03 14:16:48 UTC (rev 41753)
+++
mmbase/trunk/utils/src/main/java/org/mmbase/util/magicfile/MagicXMLReader.java
2010-04-03 14:38:43 UTC (rev 41754)
@@ -19,15 +19,26 @@
private static Logger log =
Logging.getLoggerInstance(MagicXMLReader.class);
- private static MagicXMLReader reader = null;
+ private static DetectorProvider provider;
+
protected static final String MAGICXMLFILE = "magic.xml";
// Name of the XML magic file - should reside in top config dir
- private static void setReader(String config) throws
IllegalArgumentException {
+ private static void loadDetectorProvider(String config) throws
IllegalArgumentException {
try {
InputSource is =
ResourceLoader.getConfigurationRoot().getInputSource(config);
if (is != null) {
- reader = new MagicXMLReader(is);
+ MagicXMLReader reader = new MagicXMLReader(is);
+ if (reader != null) {
+ log.info("Magic XML file is: " + reader.getSystemId());
+ final List<Detector> detectors = new
ArrayList<Detector>(reader.getDetectors());
+ DetectorProvider dp = new DetectorProvider() {
+ public List<Detector> getDetectors() {
+ return detectors;
+ }
+ };
+ provider = dp;
+ }
}
} catch (IOException ie) {
log.warn(ie);
@@ -39,29 +50,24 @@
* @return MagicXMLReader if mmbase was staterd or null if mmbase was not
started
*/
- public synchronized static MagicXMLReader getInstance() {
- if (reader == null) { // can only occur once.
+ public synchronized static DetectorProvider getInstance() {
+ if (provider == null) { // can only occur once.
- setReader(MAGICXMLFILE);
+ loadDetectorProvider(MAGICXMLFILE);
- if (reader != null) {
- log.info("Magic XML file is: " + reader.getSystemId());
- }
+ ResourceWatcher watcher = new ResourceWatcher() {
+ public void onChange(String file) {
+ // reader is replaced on every change of magic.xml
+ loadDetectorProvider(file);
+ }
+ };
+ watcher.start();
+ watcher.add(MAGICXMLFILE);
- ResourceWatcher watcher = new ResourceWatcher() {
- public void onChange(String file) {
- // reader is replaced on every change of magic.xml
- setReader(file);
- }
- };
- watcher.start();
- watcher.add(MAGICXMLFILE);
-
- }
- return reader;
+ }
+ return provider;
}
- private List<Detector> detectors = null;
-
+
private MagicXMLReader(InputSource is) {
super(is, MagicXMLReader.class);
}
@@ -83,24 +89,21 @@
* Returns all 'Detectors'.
*/
public List<Detector> getDetectors() {
- if (detectors == null) {
- detectors = new CopyOnWriteArrayList<Detector>();
- Element e = getElementByPath("magic.detectorlist");
- if (e == null) {
- log.fatal("Could not find magic/detectorlist in magic.xml");
- // aargh!
- return detectors;
+ List<Detector> detectors = new CopyOnWriteArrayList<Detector>();
+ Element e = getElementByPath("magic.detectorlist");
+ if (e == null) {
+ log.fatal("Could not find magic/detectorlist in magic.xml");
+ // aargh!
+ return detectors;
+ }
+ for (Element element : getChildElements(e)) {
+ try {
+ Detector d = getOneDetector(element);
+ detectors.add(d);
+ } catch (Exception ex) {
+ log.error(ex.getClass() + " " + ex.getMessage() + ": " +
XMLWriter.write(element));
}
- for (Element element : getChildElements(e)) {
- try {
- Detector d = getOneDetector(element);
- detectors.add(d);
- } catch (Exception ex) {
- log.error(ex.getClass() + " " + ex.getMessage() + ": " +
XMLWriter.write(element));
- }
- }
}
-
return detectors;
}
_______________________________________________
Cvs mailing list
[email protected]
http://lists.mmbase.org/mailman/listinfo/cvs