You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by sv...@apache.org on 2018/07/03 18:18:51 UTC
wicket git commit: WICKET-6563 allow passing of SerializedPage
Repository: wicket
Updated Branches:
refs/heads/WICKET-6563 bcf76f517 -> a3604f7c3
WICKET-6563 allow passing of SerializedPage
between page stores
Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/a3604f7c
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/a3604f7c
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/a3604f7c
Branch: refs/heads/WICKET-6563
Commit: a3604f7c359f9bbd2df03d57831c3f0d838ef521
Parents: bcf76f5
Author: Sven Meier <sv...@apache.org>
Authored: Tue Jul 3 20:18:10 2018 +0200
Committer: Sven Meier <sv...@apache.org>
Committed: Tue Jul 3 20:18:25 2018 +0200
----------------------------------------------------------------------
.../wicket/DefaultPageManagerProvider.java | 4 +-
.../apache/wicket/pageStore/DiskPageStore.java | 11 +-
.../wicket/pageStore/InSessionPageStore.java | 115 +++++++++----------
.../apache/wicket/pageStore/SerializedPage.java | 74 ++++++++++++
.../wicket/pageStore/SerializingPageStore.java | 63 ++++++++++
.../wicket/versioning/PageVersioningTest.java | 7 +-
6 files changed, 207 insertions(+), 67 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/wicket/blob/a3604f7c/wicket-core/src/main/java/org/apache/wicket/DefaultPageManagerProvider.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/DefaultPageManagerProvider.java b/wicket-core/src/main/java/org/apache/wicket/DefaultPageManagerProvider.java
index c800935..0539355 100644
--- a/wicket-core/src/main/java/org/apache/wicket/DefaultPageManagerProvider.java
+++ b/wicket-core/src/main/java/org/apache/wicket/DefaultPageManagerProvider.java
@@ -28,6 +28,7 @@ import org.apache.wicket.pageStore.InMemoryPageStore;
import org.apache.wicket.pageStore.InSessionPageStore;
import org.apache.wicket.pageStore.NoopPageStore;
import org.apache.wicket.pageStore.RequestPageStore;
+import org.apache.wicket.pageStore.SerializingPageStore;
import org.apache.wicket.serialize.ISerializer;
import org.apache.wicket.settings.StoreSettings;
import org.apache.wicket.util.lang.Args;
@@ -45,9 +46,10 @@ import org.apache.wicket.util.lang.Bytes;
* <ul>
* <li>{@link RequestPageStore} caching pages until end of the request</li>
* <li>{@link InSessionPageStore} keeping the last accessed page in the session</li>
+ * <li>{@link SerializingPageStore} serializing all pages (so they are available for back-button </li>
* <li>{@link InMemoryPageStore} keeping all pages</li>
* </ul>
- * ... or if all pages should be kept in the session only:
+ * ... or if all pages should be kept in the session only without any serialization (no back-button support)
* <ul>
* <li>{@link RequestPageStore} caching pages until end of the request</li>
* <li>{@link InSessionPageStore} keeping a limited count of pages in the session, e.g. 10</li>
http://git-wip-us.apache.org/repos/asf/wicket/blob/a3604f7c/wicket-core/src/main/java/org/apache/wicket/pageStore/DiskPageStore.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/pageStore/DiskPageStore.java b/wicket-core/src/main/java/org/apache/wicket/pageStore/DiskPageStore.java
index b810218..85bed3e 100644
--- a/wicket-core/src/main/java/org/apache/wicket/pageStore/DiskPageStore.java
+++ b/wicket-core/src/main/java/org/apache/wicket/pageStore/DiskPageStore.java
@@ -188,6 +188,10 @@ public class DiskPageStore implements IPersistentPageStore
}
}
+ /**
+ * Supports {@link SerializedPage}s too - for this to work the delegating
+ * {@link IPageStore} must use the same {@link ISerializer} as this one.
+ */
@Override
public void addPage(IPageContext context, IManageablePage page)
{
@@ -196,7 +200,12 @@ public class DiskPageStore implements IPersistentPageStore
{
log.debug("Storing data for page with id '{}' in session with id '{}'", page.getPageId(), context.getSessionId());
- byte[] data = serializer.serialize(page);
+ byte[] data;
+ if (page instanceof SerializedPage) {
+ data = ((SerializedPage)page).getData();
+ } else {
+ data = serializer.serialize(page);
+ }
diskData.savePage(page.getPageId(), page.getClass(), data);
}
http://git-wip-us.apache.org/repos/asf/wicket/blob/a3604f7c/wicket-core/src/main/java/org/apache/wicket/pageStore/InSessionPageStore.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/pageStore/InSessionPageStore.java b/wicket-core/src/main/java/org/apache/wicket/pageStore/InSessionPageStore.java
index 3914464..e3d3e07 100644
--- a/wicket-core/src/main/java/org/apache/wicket/pageStore/InSessionPageStore.java
+++ b/wicket-core/src/main/java/org/apache/wicket/pageStore/InSessionPageStore.java
@@ -20,11 +20,12 @@ import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map.Entry;
+import java.util.LinkedList;
+import java.util.List;
import javax.servlet.http.HttpSession;
+import org.apache.wicket.DefaultPageManagerProvider;
import org.apache.wicket.MetaDataKey;
import org.apache.wicket.Session;
import org.apache.wicket.WicketRuntimeException;
@@ -33,8 +34,10 @@ import org.apache.wicket.serialize.ISerializer;
import org.apache.wicket.util.lang.Args;
/**
- * A store keeping a configurable maximum of pages in the session, delegating all or excessive pages
- * to another store.
+ * A store keeping a configurable maximum of pages in the session.
+ * <p>
+ * This store is used by {@link DefaultPageManagerProvider} as a cache in front
+ * of a persistent store.
*/
public class InSessionPageStore extends DelegatingPageStore
{
@@ -47,9 +50,7 @@ public class InSessionPageStore extends DelegatingPageStore
private ISerializer serializer;
private int maxPages;
-
- private boolean delegateAll = false;
-
+
/**
* Use this constructor, if sessions are never serialized.
*
@@ -93,16 +94,6 @@ public class InSessionPageStore extends DelegatingPageStore
this.maxPages = maxPages;
}
- /**
- * Delegated all pages, even those that are still kept in the session.
- */
- public InSessionPageStore delegateAll()
- {
- delegateAll = true;
-
- return this;
- }
-
@Override
public IManageablePage getPage(IPageContext context, int id)
{
@@ -120,7 +111,9 @@ public class InSessionPageStore extends DelegatingPageStore
{
SessionData data = getSessionData(context);
- data.addAndDelegate(context, page, maxPages, delegateAll, getDelegate());
+ data.add(context, page, maxPages);
+
+ super.addPage(context, page);
}
@Override
@@ -167,8 +160,10 @@ public class InSessionPageStore extends DelegatingPageStore
/**
* Pages, may partly be serialized.
+ * <p>
+ * Kept in list instead of map, since life pages might change their id during a request.
*/
- private LinkedHashMap<Integer, Serializable> pages = new LinkedHashMap<>();
+ private List<IManageablePage> pages = new LinkedList<>();
/**
* This method <em>must</em> be called each time it is retrieved from the session: <br/>
@@ -180,45 +175,27 @@ public class InSessionPageStore extends DelegatingPageStore
this.serializer = Args.notNull(serializer, "serializer");
}
- public synchronized void addAndDelegate(IPageContext context, IManageablePage page,
- int maxPages, boolean delegateAll, IPageStore delegate)
+ public synchronized void add(IPageContext context, IManageablePage page, int maxPages)
{
- pages.remove(page.getPageId());
- pages.put(page.getPageId(), page);
+ // move to end
+ remove(page);
+ pages.add(page);
- Serializable expelled = null;
- if (pages.size() > maxPages)
- {
- Iterator<Serializable> iterator = pages.values().iterator();
- expelled = iterator.next();
- iterator.remove();
- }
-
- if (delegateAll)
- {
- delegate.addPage(context, page);
- }
- else
+ while (pages.size() > maxPages)
{
- // when pages are not delegated automatically, we have to catch up
- // on an expelled page now
- if (expelled != null)
- {
- if (expelled instanceof byte[])
- {
- // ... which results in this suboptimal case, when the session was persisted:
- // in that case the expelled page is still in a serialized state, so we have
- // to deserialize it first to be able to delegate it
- expelled = (IManageablePage)serializer.deserialize((byte[])expelled);
- }
- delegate.addPage(context, (IManageablePage)expelled);
- }
+ pages.remove(0);
}
}
public synchronized void remove(IManageablePage page)
{
- pages.remove(page.getPageId());
+ Iterator<IManageablePage> iterator = pages.iterator();
+ while (iterator.hasNext()) {
+ if (iterator.next().getPageId() == page.getPageId()) {
+ iterator.remove();
+ break;
+ }
+ }
}
public synchronized void removeAll()
@@ -228,20 +205,30 @@ public class InSessionPageStore extends DelegatingPageStore
public synchronized IManageablePage get(int id)
{
- Serializable serializable = pages.get(id);
-
- if (serializable instanceof byte[])
+ IManageablePage page = null;
+
+ for (int p = 0; p < pages.size(); p++)
{
- if (serializer == null)
- {
- throw new IllegalStateException("SessionData#init() was not called");
- }
- serializable = (Serializable)serializer.deserialize((byte[])serializable);
+ IManageablePage candidate = pages.get(p);
- pages.put(id, serializable);
+ if (candidate.getPageId() == id) {
+ if (candidate instanceof SerializedPage)
+ {
+ if (serializer == null)
+ {
+ throw new IllegalStateException("SessionData#init() was not called");
+ }
+ candidate = (IManageablePage)serializer.deserialize(((SerializedPage)candidate).getData());
+
+ pages.set(id, candidate);
+ }
+
+ page = candidate;
+ break;
+ }
}
- return (IManageablePage)serializable;
+ return page;
}
/**
@@ -250,15 +237,17 @@ public class InSessionPageStore extends DelegatingPageStore
private void writeObject(final ObjectOutputStream output) throws IOException
{
// serialize pages if not already
- for (Entry<Integer, Serializable> entry : pages.entrySet())
+ for (int p = 0; p < pages.size(); p++)
{
- if (entry.getValue() instanceof IManageablePage)
+ IManageablePage page = pages.get(p);
+
+ if ((page instanceof SerializedPage) == false)
{
if (serializer == null)
{
throw new IllegalStateException("SessionData#init() was not called");
}
- entry.setValue(serializer.serialize(entry.getValue()));
+ pages.set(p, new SerializedPage(page.getPageId(), serializer.serialize(page)));
}
}
http://git-wip-us.apache.org/repos/asf/wicket/blob/a3604f7c/wicket-core/src/main/java/org/apache/wicket/pageStore/SerializedPage.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/pageStore/SerializedPage.java b/wicket-core/src/main/java/org/apache/wicket/pageStore/SerializedPage.java
new file mode 100644
index 0000000..86291d9
--- /dev/null
+++ b/wicket-core/src/main/java/org/apache/wicket/pageStore/SerializedPage.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.pageStore;
+
+import org.apache.wicket.page.IManageablePage;
+import org.apache.wicket.util.lang.Args;
+
+/**
+ * A wrapper around a serialized page.
+ * <p>
+ * {@link IPageStore} might choose to use this representation of a page internally,
+ * or accept it in {@link IPageStore#addPage(IPageContext, IManageablePage)}.
+ */
+class SerializedPage implements IManageablePage
+{
+
+ private final int pageId;
+
+ private final byte[] data;
+
+ public SerializedPage(int pageId, byte[] data)
+ {
+ this.pageId = pageId;
+ this.data = Args.notNull(data, "data");
+ }
+
+ @Override
+ public boolean isPageStateless()
+ {
+ return false;
+ }
+
+ @Override
+ public int getPageId()
+ {
+ return pageId;
+ }
+
+ public byte[] getData()
+ {
+ return data;
+ }
+
+ @Override
+ public void detach()
+ {
+ }
+
+ @Override
+ public boolean setFreezePageId(boolean freeze)
+ {
+ return false;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "[SerializedPage id = " + pageId + "]";
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/wicket/blob/a3604f7c/wicket-core/src/main/java/org/apache/wicket/pageStore/SerializingPageStore.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/pageStore/SerializingPageStore.java b/wicket-core/src/main/java/org/apache/wicket/pageStore/SerializingPageStore.java
new file mode 100644
index 0000000..3b5ac3a
--- /dev/null
+++ b/wicket-core/src/main/java/org/apache/wicket/pageStore/SerializingPageStore.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.pageStore;
+
+import org.apache.wicket.page.IManageablePage;
+import org.apache.wicket.serialize.ISerializer;
+import org.apache.wicket.util.lang.Args;
+
+/**
+ * A store that serializes all pages before delegating and vice versa.
+ */
+public class SerializingPageStore extends DelegatingPageStore
+{
+
+ private ISerializer serializer;
+
+ /**
+ * @param delegate
+ * store to delegate to
+ * @param serializer
+ * serializer to use if session gets persisted
+ */
+ public SerializingPageStore(IPageStore delegate, ISerializer serializer)
+ {
+ super(delegate);
+
+ this.serializer = Args.notNull(serializer, "serializer");
+ }
+
+ @Override
+ public IManageablePage getPage(IPageContext context, int id)
+ {
+ IManageablePage page = super.getPage(context, id);
+ if (page instanceof SerializedPage) {
+ page = (IManageablePage)serializer.deserialize(((SerializedPage)page).getData());
+ }
+
+ return super.getPage(context, id);
+ }
+
+ @Override
+ public void addPage(IPageContext context, IManageablePage page)
+ {
+ if (page instanceof SerializedPage == false) {
+ page = new SerializedPage(page.getPageId(), serializer.serialize(page));
+ }
+ super.addPage(context, page);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/wicket/blob/a3604f7c/wicket-core/src/test/java/org/apache/wicket/versioning/PageVersioningTest.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/versioning/PageVersioningTest.java b/wicket-core/src/test/java/org/apache/wicket/versioning/PageVersioningTest.java
index 4e6420e..3f0e443 100644
--- a/wicket-core/src/test/java/org/apache/wicket/versioning/PageVersioningTest.java
+++ b/wicket-core/src/test/java/org/apache/wicket/versioning/PageVersioningTest.java
@@ -26,8 +26,9 @@ import org.apache.wicket.page.PageManager;
import org.apache.wicket.pageStore.IPageStore;
import org.apache.wicket.pageStore.InMemoryPageStore;
import org.apache.wicket.pageStore.InSessionPageStore;
-import org.apache.wicket.pageStore.NoopPageStore;
+import org.apache.wicket.pageStore.SerializingPageStore;
import org.apache.wicket.protocol.http.WebApplication;
+import org.apache.wicket.serialize.java.JavaSerializer;
import org.apache.wicket.util.tester.WicketTester;
import org.junit.After;
import org.junit.Before;
@@ -59,7 +60,9 @@ public class PageVersioningTest
{
return () ->
{
- final IPageStore store = new InSessionPageStore(new NoopPageStore(), Integer.MAX_VALUE);
+ InMemoryPageStore inMemory = new InMemoryPageStore("test", Integer.MAX_VALUE);
+ SerializingPageStore serializing = new SerializingPageStore(inMemory, new JavaSerializer("test"));
+ final IPageStore store = new InSessionPageStore(serializing, Integer.MAX_VALUE);
return new PageManager(store);
};
}