📄 secondlevelcachesessionstore.java
字号:
/* * 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.protocol.http;import java.io.IOException;import java.io.Serializable;import java.util.HashMap;import org.apache.wicket.Application;import org.apache.wicket.Component;import org.apache.wicket.IPageMap;import org.apache.wicket.Page;import org.apache.wicket.PageMap;import org.apache.wicket.Request;import org.apache.wicket.RequestCycle;import org.apache.wicket.Session;import org.apache.wicket.WicketRuntimeException;import org.apache.wicket.protocol.http.pagestore.DiskPageStore;import org.apache.wicket.session.pagemap.IPageMapEntry;import org.apache.wicket.util.collections.IntHashMap;import org.apache.wicket.version.IPageVersionManager;import org.apache.wicket.version.undo.Change;import org.slf4j.Logger;import org.slf4j.LoggerFactory;/** * FIXME document me! * * @author jcompagner */public class SecondLevelCacheSessionStore extends HttpSessionStore{ private static Logger log = LoggerFactory.getLogger(SecondLevelCacheSessionStore.class); /** * This interface is used by the SecondLevelCacheSessionStore so that pages can be stored to a * persistent layer. Implementation should store the page that it gets under the id and version * number. So that every page version can be reconstructed when asked for. * * @see DiskPageStore as default implementation. */ public static interface IPageStore { /** * Destroy the store. */ void destroy(); /** * Restores a page version from the persistent layer. * <p> * Note that the versionNumber and ajaxVersionNumber parameters may be -1. * <ul> * <li>If ajaxVersionNumber is -1 and versionNumber is specified, the page store must * return the page with highest ajax version. * <li>If both versionNumber and ajaxVersioNumber are -1, the pagestore must return last * touched (saved) page version with given id. * </ul> * * @param sessionId * @param pagemap * @param id * @param versionNumber * @param ajaxVersionNumber * @return The page */ Page getPage(String sessionId, String pagemap, int id, int versionNumber, int ajaxVersionNumber); /** * This method is called when the page is accessed. A IPageStore implementation can block * until a save of that page version is done. So that a specific page version is always * restore able. * * @param sessionId * @param page */ void pageAccessed(String sessionId, Page page); /** * Removes a page from the persistent layer. * * @param sessionId * The session of the page that must be removed * @param pagemap * The pagemap of the page that must be removed * @param id * The id of the page. */ void removePage(String sessionId, String pagemap, int id); /** * Stores the page to a persistent layer. The page should be stored under the id and the * version number. * * @param sessionId * @param page */ void storePage(String sessionId, Page page); /** * The pagestore should cleanup all the pages for that sessionid. * * @param sessionId */ void unbind(String sessionId); /** * Returns whether the PageStore contains given page. * * @param sessionId * @param pageMapName * @param pageId * @param pageVersion * @return boolean If the page was found */ boolean containsPage(String sessionId, String pageMapName, int pageId, int pageVersion); } /** * Marker interface for PageStores that support replication of serialized pages across cluster, * which means that the lastPage attribute of {@link SecondLevelCachePageMap} does not have to * be serialized; * * @author Matej Knopp */ public static interface IClusteredPageStore extends IPageStore { }; /** * Some PageStores might want to preprocess page before serialization. For example if the * PageStore serializes page, it might keep the serialized page during the request. So when the * pagemap gets serialized (for session replication) in the request thread, the pagestore can * provide the already serialized data. * * @author Matej Knopp */ public static interface ISerializationAwarePageStore extends IPageStore { /** * Process the page before the it gets serialized. The page can be either real page instance * of object returned by {@link #restoreAfterSerialization(Serializable)}. * * @param sessionId * @param page * @return The Page itself or a SerializedContainer for that page */ public Serializable prepareForSerialization(String sessionId, Object page); /** * This method should restore the serialized page to intermediate object that can be * converted to real page instance using {@link #convertToPage(Object)}. * * @param sessionId * @param serializable * @return Page */ public Object restoreAfterSerialization(Serializable serializable); /** * * @param page * @return */ public Page convertToPage(Object page); }; /** * Page map implementation for this session store. */ private static final class SecondLevelCachePageMap extends PageMap { private static final long serialVersionUID = 1L; private transient Object lastPage = null; private final String applicationKey; private String sessionId; private IPageStore getPageStore() { Application application = Application.get(applicationKey); if (application != null) { SecondLevelCacheSessionStore store = (SecondLevelCacheSessionStore)application.getSessionStore(); return store.getStore(); } else { // may happen when getPageStore() is called before application is initialized // for example on session initialization when cluster node starts return null; } } private Page getLastPage() { Page result = null; if (lastPage instanceof Page) { result = (Page)lastPage; } else if (lastPage != null) { IPageStore store = getPageStore(); if (store instanceof ISerializationAwarePageStore) { lastPage = result = ((ISerializationAwarePageStore)store).convertToPage(lastPage); } } return result; } private void setLastPage(Page lastPage) { this.lastPage = lastPage; } /** * Construct. * * @param sessionId * @param application * @param name */ private SecondLevelCachePageMap(String sessionId, Application application, String name) { super(name); applicationKey = application.getApplicationKey(); this.sessionId = sessionId; } public boolean containsPage(int id, int versionNumber) { Page lastPage = this.lastPage instanceof Page ? (Page)this.lastPage : null; if (lastPage != null && lastPage.getNumericId() == id && lastPage.getCurrentVersionNumber() == versionNumber) { return true; } else { return getStore().containsPage(getSession().getId(), getName(), id, versionNumber); } } /** * @see org.apache.wicket.PageMap#get(int, int) */ public Page get(int id, int versionNumber) { HashMap pageMaps = (HashMap)usedPages.get(); if (pageMaps == null) { pageMaps = new HashMap(); usedPages.set(pageMaps); } IntHashMap pages = (IntHashMap)pageMaps.get(getName()); if (pages == null) { pages = new IntHashMap(); pageMaps.put(getName(), pages); } // for now i only get by id. // does it really make any sense that there are multiply instances // of the // same page are alive in one session?? Page page = (Page)pages.get(id); if (page != null) { return page; } String sessionId = getSession().getId(); if (getLastPage() != null && getLastPage().getNumericId() == id) { page = versionNumber != -1 ? getLastPage().getVersion(versionNumber) : getLastPage(); if (page != null) { // ask the page store if it is ready saving the page. getStore().pageAccessed(sessionId, page); pages.put(id, page); return page; } } if (sessionId != null) { setLastPage(null); page = getStore().getPage(sessionId, getName(), id, versionNumber, -1); pages.put(id, page); return page; } return null; } /** * @see org.apache.wicket.PageMap#put(org.apache.wicket.Page) */ public void put(Page page) { if (!page.isPageStateless()) { Session session = getSession(); String sessionId = session.getId(); if (sessionId != null && !session.isSessionInvalidated()) { // the id could have changed from null during request this.sessionId = sessionId; getStore().storePage(sessionId, page); setLastPage(page); dirty(); } } } /** * @see org.apache.wicket.PageMap#clear() */ public void clear() { super.clear(); String sessionId = getSession().getId(); if (sessionId != null) { getStore().removePage(sessionId, getName(), -1); } } /** * @see org.apache.wicket.PageMap#removeEntry(org.apache.wicket.session.pagemap.IPageMapEntry) */ public void removeEntry(IPageMapEntry entry) { String sessionId = getSession().getId(); if (sessionId != null) { getStore().removePage(sessionId, getName(), entry.getNumericId()); } } private IPageStore getStore() { return ((SecondLevelCacheSessionStore)Application.get().getSessionStore()).getStore();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -