blob: b2f8f2cbc0ed16353864f2e020ce70d8ac07dd1d [file] [log] [blame]
/*
* 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.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import org.apache.wicket.Application;
import org.apache.wicket.Page;
import org.apache.wicket.protocol.http.SecondLevelCacheSessionStore.IPageStore;
import org.apache.wicket.util.lang.Objects;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Stores pages on disk.
* <p>
* Override {@link #getWorkDir()} to change the default directory for pages, which is configured
* from the javax.servlet.context.tempdir attribute in the servlet context.
*
* @author jcompagner
*/
public class TestFilePageStore implements IPageStore
{
/** log. */
protected static Logger log = LoggerFactory.getLogger(TestFilePageStore.class);
public void destroy()
{
}
private final File defaultWorkDir;
private final String appName;
volatile long totalSavingTime = 0;
volatile long totalSerializationTime = 0;
private volatile int saved;
private volatile int bytesSaved;
/**
* Construct.
*/
public TestFilePageStore()
{
this((File)((WebApplication)Application.get()).getServletContext().getAttribute(
"javax.servlet.context.tempdir"));
}
/**
* Construct.
*
* @param dir
* The directory to save to.
*/
public TestFilePageStore(File dir)
{
defaultWorkDir = dir;
appName = Application.get().getApplicationKey();
}
private class SessionPageKey
{
private final String sessionId;
private final int id;
private final int versionNumber;
private final int ajaxVersionNumber;
private final String pageMap;
private final String pageClassName;
SessionPageKey(String sessionId, Page page)
{
this(sessionId, page.getNumericId(), page.getCurrentVersionNumber(),
page.getAjaxVersionNumber(), page.getPageMapName(), page.getClass());
}
<T extends Page> SessionPageKey(String sessionId, int id, int versionNumber,
int ajaxVersionNumber, String pagemap, Class<T> pageClass)
{
this.sessionId = sessionId;
this.id = id;
this.versionNumber = versionNumber;
this.ajaxVersionNumber = ajaxVersionNumber;
pageClassName = pageClass.getName();
pageMap = pagemap;
}
/**
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode()
{
return sessionId.hashCode() + id + versionNumber;
}
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj)
{
if (obj instanceof SessionPageKey)
{
SessionPageKey key = (SessionPageKey)obj;
return id == key.id &&
versionNumber == key.versionNumber &&
ajaxVersionNumber == key.ajaxVersionNumber &&
((pageMap != null && pageMap.equals(key.pageMap)) || (pageMap == null && key.pageMap == null)) &&
sessionId.equals(key.sessionId);
}
return false;
}
/**
* @see java.lang.Object#toString()
*/
@Override
public String toString()
{
return "SessionPageKey[" + sessionId + "," + id + "," + versionNumber + "," +
ajaxVersionNumber + ", " + pageMap + "]";
}
}
public <T> Page getPage(String sessionId, String pagemap, int id, int versionNumber,
int ajaxVersionNumber)
{
SessionPageKey currentKey = new SessionPageKey(sessionId, id, versionNumber,
ajaxVersionNumber, pagemap, null);
File sessionDir = new File(getWorkDir(), sessionId);
File pageFile = getPageFile(currentKey, sessionDir);
if (pageFile.exists())
{
long t1 = System.currentTimeMillis();
FileInputStream fis = null;
try
{
byte[] pageData = null;
fis = new FileInputStream(pageFile);
int length = (int)pageFile.length();
ByteBuffer bb = ByteBuffer.allocate(length);
fis.getChannel().read(bb);
if (bb.hasArray())
{
pageData = bb.array();
}
else
{
pageData = new byte[length];
bb.get(pageData);
}
long t2 = System.currentTimeMillis();
Page page = (Page)Objects.byteArrayToObject(pageData);
page = page.getVersion(versionNumber);
if (page != null && log.isDebugEnabled())
{
long t3 = System.currentTimeMillis();
log.debug("restoring page " + page.getClass() + "[" + page.getNumericId() +
"," + page.getCurrentVersionNumber() + "] size: " + pageData.length +
" for session " + sessionId + " took " + (t2 - t1) +
" miliseconds to read in and " + (t3 - t2) + " miliseconds to deserialize");
}
final Page ret = page;
return ret;
}
catch (Exception e)
{
log.error("Error", e);
}
}
return null;
}
public void pageAccessed(String sessionId, Page page)
{
}
public void removePage(String sessionId, String pageMapName, int pageId)
{
}
public void storePage(String sessionId, Page page)
{
SessionPageKey key = new SessionPageKey(sessionId, page);
byte[] serialized = Objects.objectToByteArray(page);
// map.put(key, serialized);
savePage(key, serialized);
}
public void unbind(String sessionId)
{
}
private File getPageFile(SessionPageKey key, File sessionDir)
{
return new File(sessionDir, appName + "-pm-" + key.pageMap + "-p-" + key.id + "-v-" +
key.versionNumber + "-a-" + key.ajaxVersionNumber);
}
private File getWorkDir()
{
return defaultWorkDir;
}
private void savePage(SessionPageKey key, byte[] bytes)
{
File sessionDir = new File(getWorkDir(), key.sessionId);
sessionDir.mkdirs();
File pageFile = getPageFile(key, sessionDir);
FileOutputStream fos = null;
long t1 = System.currentTimeMillis();
int length = 0;
try
{
fos = new FileOutputStream(pageFile);
ByteBuffer bb = ByteBuffer.wrap(bytes);
fos.getChannel().write(bb);
length = bytes.length;
}
catch (Exception e)
{
log.error("Error saving page " + key.pageClassName + " [" + key.id + "," +
key.versionNumber + "] for the sessionid " + key.sessionId);
}
finally
{
try
{
if (fos != null)
{
fos.close();
}
}
catch (IOException ex)
{
// ignore
}
}
long t3 = System.currentTimeMillis();
if (log.isDebugEnabled())
{
log.debug("storing page " + key.pageClassName + "[" + key.id + "," + key.versionNumber +
"] size: " + length + " for session " + key.sessionId + " took " + (t3 - t1) +
" miliseconds to save");
}
totalSavingTime += (t3 - t1);
saved++;
bytesSaved += length;
}
public boolean containsPage(String sessionId, String pageMapName, int pageId, int pageVersion)
{
return false;
}
}