You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by mg...@apache.org on 2012/10/15 11:34:32 UTC

[3/7] git commit: WICKET-4812 Make SerializationChecker easier for extending so custom checks can be added to it

WICKET-4812 Make SerializationChecker easier for extending so custom checks can be added to it

Add support for exclusions by type before checking an object.
Re-work SessionSizeModel to be AbstractReadOnlyModel because otherwise it keeps a reference to the passed Session and during the calculation of the session size it fails that it is not detached. Now there is nothing to detach. Now it works with Session.get() only if it exists. It should not be possible to calculate the size of someone else's session anyway.


Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/8245be7a
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/8245be7a
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/8245be7a

Branch: refs/heads/master
Commit: 8245be7a05d3c144ad23a1f8b59ebd09d28cbf4b
Parents: 5e8c3dd
Author: Martin Tzvetanov Grigorov <mg...@apache.org>
Authored: Mon Oct 15 10:51:06 2012 +0200
Committer: Martin Tzvetanov Grigorov <mg...@apache.org>
Committed: Mon Oct 15 10:51:06 2012 +0200

----------------------------------------------------------------------
 .../wicket/core/util/io/SerializableChecker.java   |   12 ++-
 .../objects/checker/AbstractObjectChecker.java     |   70 +++++++++++++++
 .../core/util/objects/checker/IObjectChecker.java  |    7 ++
 .../objects/checker/NotDetachedModelChecker.java   |   29 ++++++-
 .../objects/checker/OrphanComponentChecker.java    |   58 ++++++++++++
 .../objects/checker/AbstractObjectCheckerTest.java |   31 +++++++
 .../wicket/serialize/java/JavaSerializerTest.java  |   14 +++
 .../devutils/debugbar/SessionSizeDebugPanel.java   |    4 +-
 .../devutils/inspector/SessionSizeModel.java       |   42 ++++++----
 9 files changed, 245 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/8245be7a/wicket-core/src/main/java/org/apache/wicket/core/util/io/SerializableChecker.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/core/util/io/SerializableChecker.java b/wicket-core/src/main/java/org/apache/wicket/core/util/io/SerializableChecker.java
index 6e5c298..c650e83 100644
--- a/wicket-core/src/main/java/org/apache/wicket/core/util/io/SerializableChecker.java
+++ b/wicket-core/src/main/java/org/apache/wicket/core/util/io/SerializableChecker.java
@@ -21,7 +21,7 @@ import java.io.NotSerializableException;
 import java.io.Serializable;
 import java.lang.reflect.Proxy;
 
-import org.apache.wicket.core.util.objects.checker.IObjectChecker;
+import org.apache.wicket.core.util.objects.checker.AbstractObjectChecker;
 import org.apache.wicket.core.util.objects.checker.ObjectChecker;
 
 
@@ -39,7 +39,9 @@ public class SerializableChecker extends ObjectChecker
 {
 	/**
 	 * Exception that is thrown when a non-serializable object was found.
+	 * @deprecated ObjectCheckException is thrown instead
 	 */
+	@Deprecated
 	public static final class WicketNotSerializableException extends ObjectCheckException
 	{
 		private static final long serialVersionUID = 1L;
@@ -54,7 +56,7 @@ public class SerializableChecker extends ObjectChecker
 	 * An implementation of IObjectChecker that checks whether the object
 	 * implements {@link Serializable} interface
 	 */
-	public static class ObjectSerializationChecker implements IObjectChecker
+	public static class ObjectSerializationChecker extends AbstractObjectChecker
 	{
 		/** Exception that should be set as the cause when throwing a new exception. */
 		private final NotSerializableException cause;
@@ -80,6 +82,12 @@ public class SerializableChecker extends ObjectChecker
 			this.cause = cause;
 		}
 
+		/**
+		 * Makes the check for all objects. Exclusions by type is not supported.
+		 * @param object
+		 *      the object to check
+		 * @return the {@link Result#SUCCESS} if the object can be serialized.
+		 */
 		@Override
 		public Result check(Object object)
 		{

http://git-wip-us.apache.org/repos/asf/wicket/blob/8245be7a/wicket-core/src/main/java/org/apache/wicket/core/util/objects/checker/AbstractObjectChecker.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/core/util/objects/checker/AbstractObjectChecker.java b/wicket-core/src/main/java/org/apache/wicket/core/util/objects/checker/AbstractObjectChecker.java
new file mode 100644
index 0000000..2684d0d
--- /dev/null
+++ b/wicket-core/src/main/java/org/apache/wicket/core/util/objects/checker/AbstractObjectChecker.java
@@ -0,0 +1,70 @@
+package org.apache.wicket.core.util.objects.checker;
+
+import java.util.List;
+
+import org.apache.wicket.util.lang.Args;
+import org.apache.wicket.util.lang.Generics;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A base class for IObjectChecker implementations which handles the logic
+ * for checking type exclusions.
+ */
+public abstract class AbstractObjectChecker implements IObjectChecker
+{
+	private static final Logger LOGGER = LoggerFactory.getLogger(AbstractObjectChecker.class);
+
+	private final List<Class<?>> exclusions;
+
+	protected AbstractObjectChecker()
+	{
+		this(Generics.<Class<?>>newArrayList());
+	}
+
+	protected AbstractObjectChecker(List<Class<?>> exclusions)
+	{
+		this.exclusions = Args.notNull(exclusions, "exclusions");
+	}
+
+	@Override
+	public Result check(Object object)
+	{
+		Result result = Result.SUCCESS;
+
+		if (object != null && getExclusions().isEmpty() == false)
+		{
+			Class<?> objectType = object.getClass();
+			for (Class<?> excludedType : getExclusions())
+			{
+				if (excludedType.isAssignableFrom(objectType))
+				{
+					LOGGER.debug("Object with type '{}' wont be checked because its type is excluded ({})",
+							objectType, excludedType);
+					return result;
+				}
+			}
+		}
+
+		result = doCheck(object);
+
+		return result;
+	}
+
+	/**
+	 * The implementations should make the specific check on the object.
+	 * @param object
+	 *      the object to check
+	 * @return the {@link Result result} of the specific check
+	 */
+	protected Result doCheck(Object object)
+	{
+		return Result.SUCCESS;
+	}
+
+	@Override
+	public List<Class<?>> getExclusions()
+	{
+		return exclusions;
+	}
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/8245be7a/wicket-core/src/main/java/org/apache/wicket/core/util/objects/checker/IObjectChecker.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/core/util/objects/checker/IObjectChecker.java b/wicket-core/src/main/java/org/apache/wicket/core/util/objects/checker/IObjectChecker.java
index b9d935d..b1a2d67 100644
--- a/wicket-core/src/main/java/org/apache/wicket/core/util/objects/checker/IObjectChecker.java
+++ b/wicket-core/src/main/java/org/apache/wicket/core/util/objects/checker/IObjectChecker.java
@@ -16,6 +16,8 @@
  */
 package org.apache.wicket.core.util.objects.checker;
 
+import java.util.List;
+
 import org.apache.wicket.util.lang.Args;
 
 /**
@@ -107,4 +109,9 @@ public interface IObjectChecker
 	 * @return a Result object describing whether the check is successful or not
 	 */
 	Result check(Object object);
+
+	/**
+	 * @return A list of types which should not be checked by this checker
+	 */
+	List<Class<?>> getExclusions();
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/8245be7a/wicket-core/src/main/java/org/apache/wicket/core/util/objects/checker/NotDetachedModelChecker.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/core/util/objects/checker/NotDetachedModelChecker.java b/wicket-core/src/main/java/org/apache/wicket/core/util/objects/checker/NotDetachedModelChecker.java
index 21fc0c0..6b6f7eb 100644
--- a/wicket-core/src/main/java/org/apache/wicket/core/util/objects/checker/NotDetachedModelChecker.java
+++ b/wicket-core/src/main/java/org/apache/wicket/core/util/objects/checker/NotDetachedModelChecker.java
@@ -16,6 +16,8 @@
  */
 package org.apache.wicket.core.util.objects.checker;
 
+import java.util.List;
+
 import org.apache.wicket.model.LoadableDetachableModel;
 
 /**
@@ -23,10 +25,33 @@ import org.apache.wicket.model.LoadableDetachableModel;
  * result when the checked object is a {@link LoadableDetachableModel}
  * and it is model object is still attached.
  */
-public class NotDetachedModelChecker implements IObjectChecker
+public class NotDetachedModelChecker extends AbstractObjectChecker
 {
+	/**
+	 * Constructor.
+	 *
+	 * Checks all passed objects.
+	 */
+	public NotDetachedModelChecker()
+	{
+		super();
+	}
+
+	/**
+	 * Constructor.
+	 *
+	 * Checks objects which types are not excluded.
+	 *
+	 * @param exclusions
+	 *      a list of types which should not be checked
+	 */
+	public NotDetachedModelChecker(List<Class<?>> exclusions)
+	{
+		super(exclusions);
+	}
+
 	@Override
-	public Result check(Object obj)
+	public Result doCheck(Object obj)
 	{
 		Result result = Result.SUCCESS;
 

http://git-wip-us.apache.org/repos/asf/wicket/blob/8245be7a/wicket-core/src/main/java/org/apache/wicket/core/util/objects/checker/OrphanComponentChecker.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/core/util/objects/checker/OrphanComponentChecker.java b/wicket-core/src/main/java/org/apache/wicket/core/util/objects/checker/OrphanComponentChecker.java
new file mode 100644
index 0000000..a2acbe8
--- /dev/null
+++ b/wicket-core/src/main/java/org/apache/wicket/core/util/objects/checker/OrphanComponentChecker.java
@@ -0,0 +1,58 @@
+package org.apache.wicket.core.util.objects.checker;
+
+import java.util.List;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.Page;
+
+/**
+ * A checker that doesn't allow the serialization of {@link Component component}s
+ * which are not a {@link Page page} and have no parent component.
+ *
+ * <p>
+ *     Note: The Wizard component from wicket-extensions use such kind of orphaned components
+ *     and will fail this check unless the step classes are specified as exclusions.
+ * </p>
+ */
+public class OrphanComponentChecker extends AbstractObjectChecker
+{
+	/**
+	 * Constructor.
+	 *
+	 * Checks all passed objects.
+	 */
+	public OrphanComponentChecker()
+	{
+		super();
+	}
+
+	/**
+	 * Constructor.
+	 *
+	 * Checks objects which types are not excluded.
+	 *
+	 * @param exclusions
+	 *      a list of types which should not be checked
+	 */
+	public OrphanComponentChecker(List<Class<?>> exclusions)
+	{
+		super(exclusions);
+	}
+
+	@Override
+	public Result doCheck(Object object)
+	{
+		Result result = Result.SUCCESS;
+
+		if (object instanceof Component)
+		{
+			Component component = (Component) object;
+			if (component instanceof Page == false && component.getParent() == null)
+			{
+				result = new Result(Result.Status.FAILURE, "A component without a parent is detected.");
+			}
+		}
+
+		return result;
+	}
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/8245be7a/wicket-core/src/test/java/org/apache/wicket/core/util/objects/checker/AbstractObjectCheckerTest.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/core/util/objects/checker/AbstractObjectCheckerTest.java b/wicket-core/src/test/java/org/apache/wicket/core/util/objects/checker/AbstractObjectCheckerTest.java
new file mode 100644
index 0000000..0c8d7eb
--- /dev/null
+++ b/wicket-core/src/test/java/org/apache/wicket/core/util/objects/checker/AbstractObjectCheckerTest.java
@@ -0,0 +1,31 @@
+package org.apache.wicket.core.util.objects.checker;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Tests for AbstractObjectChecker
+ */
+public class AbstractObjectCheckerTest extends Assert
+{
+	@Test
+	public void doCheckIsNotCalledForExcludedTypes()
+	{
+		List exclusions = Arrays.asList(CharSequence.class);
+
+		IObjectChecker checker = new AbstractObjectChecker(exclusions)
+		{
+			@Override
+			protected Result doCheck(Object object)
+			{
+				throw new AssertionError("Must not be called");
+			}
+		};
+
+		IObjectChecker.Result result = checker.check("A String. It's type is excluded by CharSequence");
+		assertEquals(IObjectChecker.Result.SUCCESS, result);
+	}
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/8245be7a/wicket-core/src/test/java/org/apache/wicket/serialize/java/JavaSerializerTest.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/serialize/java/JavaSerializerTest.java b/wicket-core/src/test/java/org/apache/wicket/serialize/java/JavaSerializerTest.java
index f599c61..b40eac5 100644
--- a/wicket-core/src/test/java/org/apache/wicket/serialize/java/JavaSerializerTest.java
+++ b/wicket-core/src/test/java/org/apache/wicket/serialize/java/JavaSerializerTest.java
@@ -98,4 +98,18 @@ public class JavaSerializerTest extends WicketTestCase
 	}
 
 	private static class NotSerializableObject {}
+
+	@Test
+	public void normal()
+	{
+		JavaSerializer serializer = new JavaSerializer("JavaSerializerTest-normal") {
+			@Override
+			protected ObjectOutputStream newObjectOutputStream(OutputStream out) throws IOException
+			{
+				return new ObjectCheckerObjectOutputStream(out);
+			}
+		};
+		byte[] bytes = serializer.serialize("Something to serialize");
+		System.err.println("bytes: " + bytes.length);
+	}
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/8245be7a/wicket-devutils/src/main/java/org/apache/wicket/devutils/debugbar/SessionSizeDebugPanel.java
----------------------------------------------------------------------
diff --git a/wicket-devutils/src/main/java/org/apache/wicket/devutils/debugbar/SessionSizeDebugPanel.java b/wicket-devutils/src/main/java/org/apache/wicket/devutils/debugbar/SessionSizeDebugPanel.java
index 7623725..712200b 100644
--- a/wicket-devutils/src/main/java/org/apache/wicket/devutils/debugbar/SessionSizeDebugPanel.java
+++ b/wicket-devutils/src/main/java/org/apache/wicket/devutils/debugbar/SessionSizeDebugPanel.java
@@ -18,7 +18,6 @@ package org.apache.wicket.devutils.debugbar;
 
 import org.apache.wicket.Component;
 import org.apache.wicket.Page;
-import org.apache.wicket.Session;
 import org.apache.wicket.devutils.inspector.LiveSessionsPage;
 import org.apache.wicket.devutils.inspector.SessionSizeModel;
 import org.apache.wicket.model.AbstractReadOnlyModel;
@@ -54,6 +53,7 @@ public class SessionSizeDebugPanel extends StandardDebugPanel
 	 * Construct.
 	 * 
 	 * @param id
+	 *      the component id
 	 */
 	public SessionSizeDebugPanel(final String id)
 	{
@@ -80,7 +80,7 @@ public class SessionSizeDebugPanel extends StandardDebugPanel
 		{
 			private static final long serialVersionUID = 1L;
 
-			private final IModel<Bytes> size = new SessionSizeModel(Session.get());
+			private final IModel<Bytes> size = new SessionSizeModel();
 
 			@Override
 			public String getObject()

http://git-wip-us.apache.org/repos/asf/wicket/blob/8245be7a/wicket-devutils/src/main/java/org/apache/wicket/devutils/inspector/SessionSizeModel.java
----------------------------------------------------------------------
diff --git a/wicket-devutils/src/main/java/org/apache/wicket/devutils/inspector/SessionSizeModel.java b/wicket-devutils/src/main/java/org/apache/wicket/devutils/inspector/SessionSizeModel.java
index 539721c..7cc3026 100644
--- a/wicket-devutils/src/main/java/org/apache/wicket/devutils/inspector/SessionSizeModel.java
+++ b/wicket-devutils/src/main/java/org/apache/wicket/devutils/inspector/SessionSizeModel.java
@@ -17,40 +17,50 @@
 package org.apache.wicket.devutils.inspector;
 
 import org.apache.wicket.Session;
-import org.apache.wicket.model.LoadableDetachableModel;
-import org.apache.wicket.util.lang.Bytes;
 import org.apache.wicket.core.util.lang.WicketObjects;
+import org.apache.wicket.model.AbstractReadOnlyModel;
+import org.apache.wicket.util.lang.Bytes;
 
 /**
- * 
+ * Calculates
  */
-public class SessionSizeModel extends LoadableDetachableModel<Bytes>
+public class SessionSizeModel extends AbstractReadOnlyModel<Bytes>
 {
 	private static final long serialVersionUID = 1L;
 
-	private Session session;
-
 	/**
 	 * Construct.
 	 * 
-	 * @param session
 	 */
-	public SessionSizeModel(final Session session)
+	public SessionSizeModel()
 	{
-		this.session = session;
 	}
 
-	@Override
-	protected Bytes load()
+	/**
+	 * Constructor that calculates the size of the passed Session.
+	 *
+	 * @param ignored
+	 *      the session which size to measure. Ignored.
+	 */
+	@Deprecated
+	public SessionSizeModel(@SuppressWarnings("unused")Session ignored)
 	{
-		long sizeOfSession = WicketObjects.sizeof(session);
-		return sizeOfSession > -1 ? Bytes.bytes(sizeOfSession) : null;
 	}
 
 	@Override
-	protected void onDetach()
+	public Bytes getObject()
 	{
-		super.onDetach();
-		session = null;
+		Bytes result = null;
+		if (Session.exists())
+		{
+			long sizeOfSession = WicketObjects.sizeof(Session.get());
+			if (sizeOfSession > -1)
+			{
+				result = Bytes.bytes(sizeOfSession);
+			}
+		}
+
+
+		return result;
 	}
 }