jonathan and i have been brainstorming about removing private transient
boolean attached=false from our detachable models, and after an hour here is
what we came up with (see attachment). i know we use some custom
serialization for models, etc so do you guys this is going to interfere with
that? it almost seems too simple so i am a bit suspicious. if it works out
it should save a fair bit of memory.
one thing i know it will "break" is terracotta, it will need extra config to
replicate what we do in readobject()
-igor
Index: src/main/java/wicket/model/IDetachable.java
===================================================================
--- src/main/java/wicket/model/IDetachable.java (revision 501279)
+++ src/main/java/wicket/model/IDetachable.java (working copy)
@@ -33,4 +33,12 @@
* references that can be re-attached later.
*/
void detach();
+
+ /**
+ * Value that marks a variable as detached
+ *
+ * TODO improve this pathetic javadoc
+ */
+ public static Object DETACHED = new Object();
+
}
Index: src/main/java/wicket/model/LoadableDetachableModel.java
===================================================================
--- src/main/java/wicket/model/LoadableDetachableModel.java (revision
501283)
+++ src/main/java/wicket/model/LoadableDetachableModel.java (working copy)
@@ -16,6 +16,8 @@
*/
package wicket.model;
+import java.io.IOException;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -50,11 +52,9 @@
/** Logger. */
private static final Logger log =
LoggerFactory.getLogger(LoadableDetachableModel.class);
- /** keeps track of whether this model is attached or detached */
- private transient boolean attached = false;
/** temporary, transient object. */
- private transient T transientModelObject;
+ private transient Object transientModelObject = IDetachable.DETACHED;
/**
* Construct.
@@ -73,7 +73,19 @@
public LoadableDetachableModel(T object)
{
this.transientModelObject = object;
- attached = true;
+ }
+
+ private void readObject(java.io.ObjectInputStream in) throws
IOException,
+ ClassNotFoundException
+ {
+ in.defaultReadObject();
+ transientModelObject = DETACHED;
+ }
+
+
+ private boolean isAttached()
+ {
+ return transientModelObject != IDetachable.DETACHED;
}
/**
@@ -84,9 +96,8 @@
@Override
public void detach()
{
- if (attached)
+ if (isAttached())
{
- attached = false;
transientModelObject = null;
if (log.isDebugEnabled())
@@ -100,12 +111,12 @@
/**
* @see wicket.model.IModel#getObject()
*/
+ @SuppressWarnings("unchecked")
@Override
public final T getObject()
{
- if (!attached)
+ if (!isAttached())
{
- attached = true;
transientModelObject = load();
if (log.isDebugEnabled())
@@ -114,7 +125,7 @@
+ ", requestCycle " +
RequestCycle.get());
}
}
- return transientModelObject;
+ return (T)transientModelObject;
}
/**
@@ -125,7 +136,7 @@
{
StringBuffer sb = new StringBuffer();
sb.append("Model:classname=[").append(getClass().getName()).append("]");
-
sb.append(":attached=").append(attached).append(":tempModelObject=[").append(
+
sb.append(":attached=").append(isAttached()).append(":tempModelObject=[").append(
this.transientModelObject).append("]");
return sb.toString();
}