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();
        }

Reply via email to