Author: knopp
Date: Tue Mar 31 20:49:14 2009
New Revision: 760608

URL: http://svn.apache.org/viewvc?rev=760608&view=rev
Log: (empty)

Added:
    
wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/page/persistent/disk/DiskDataStore.java
   (with props)
Modified:
    
wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
    
wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WicketFilter.java

Added: 
wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/page/persistent/disk/DiskDataStore.java
URL: 
http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/page/persistent/disk/DiskDataStore.java?rev=760608&view=auto
==============================================================================
--- 
wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/page/persistent/disk/DiskDataStore.java
 (added)
+++ 
wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/page/persistent/disk/DiskDataStore.java
 Tue Mar 31 20:49:14 2009
@@ -0,0 +1,375 @@
+package org.apache.wicket.page.persistent.disk;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Serializable;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.wicket.Application;
+import org.apache.wicket.WicketRuntimeException;
+import org.apache.wicket.page.persistent.DataStore;
+import org.apache.wicket.page.persistent.disk.PageWindowManager.PageWindow;
+import org.apache.wicket.protocol.http.WebApplication;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DiskDataStore implements DataStore
+{
+       private final String applicationName;
+       private final int maxSizePerPageSession;
+       private final FileChannelPool fileChannelPool;
+       private final File fileStoreFolder;
+       private final ConcurrentMap<String, SessionEntry> sessionEntryMap = new 
ConcurrentHashMap<String, SessionEntry>();
+
+       public DiskDataStore(String applicationName, File fileStoreFolder, int 
maxSizePerSession,
+                       int fileChannelPoolCapacity)
+       {
+               this.applicationName = applicationName;
+               this.fileStoreFolder = fileStoreFolder;
+               this.maxSizePerPageSession = maxSizePerSession;
+               this.fileChannelPool = new 
FileChannelPool(fileChannelPoolCapacity);
+       }
+
+       public DiskDataStore(String applicationName, int maxSizePerSession, int 
fileChannelPoolCapacity)
+       {
+               this(applicationName, getDefaultFileStoreFolder(), 
maxSizePerSession, fileChannelPoolCapacity);
+       }
+
+       public void destroy()
+       {
+               fileChannelPool.destroy();
+       }
+
+       public byte[] getData(String sessionId, int id)
+       {
+               SessionEntry sessionEntry = getSessionEntry(sessionId, false);
+               if (sessionEntry != null)
+               {
+                       return sessionEntry.loadPage(id);
+               }
+               else
+               {
+                       return null;    
+               }               
+       }
+
+       public boolean isReplicated()
+       {
+               return false;
+       }
+
+       public void removeData(String sessionId, int id)
+       {
+               SessionEntry sessionEntry = getSessionEntry(sessionId, false);
+               if (sessionEntry != null)
+               {
+                       sessionEntry.removePage(id);
+               }
+       }
+
+       public void removeData(String sessionId)
+       {
+               SessionEntry sessionEntry = getSessionEntry(sessionId, false);
+               if (sessionEntry != null)
+               {
+                       synchronized (sessionEntry)
+                       {
+                               sessionEntryMap.remove(sessionEntry);
+                               sessionEntry.unbind();  
+                       }                       
+               }
+       }
+
+       public void storeData(String sessionId, int id, byte[] data)
+       {
+               SessionEntry sessionEntry = getSessionEntry(sessionId, false);
+               if (sessionEntry != null)
+               {
+                       sessionEntry.savePage(id, data);
+               }
+       }
+       
+       private SessionEntry getSessionEntry(String sessionId, boolean create)
+       {
+               if (!create)
+               {
+                       return sessionEntryMap.get(sessionId);
+               }
+               else
+               {
+                       SessionEntry entry = new SessionEntry(this, sessionId);
+                       entry = sessionEntryMap.putIfAbsent(sessionId, entry);
+                       return entry;
+               }
+       }
+
+       protected static class SessionEntry implements Serializable
+       {
+               private static final long serialVersionUID = 1L;
+
+               private final String sessionId;
+               private transient DiskDataStore diskDataStore;
+               private String fileName;
+               private PageWindowManager manager;
+               private boolean unbound = false;
+
+               protected SessionEntry(DiskDataStore diskDataStore, String 
sessionId)
+               {
+                       this.diskDataStore = diskDataStore;                     
+                       this.sessionId = sessionId;
+               }
+               
+               private PageWindowManager getManager()
+               {
+                       if (manager == null)
+                       {
+                               manager = new 
PageWindowManager(diskDataStore.maxSizePerPageSession);;
+                       }
+                       return manager;
+               }
+               
+               private String getFileName()
+               {
+                       if (fileName == null)
+                       {
+                               fileName = 
diskDataStore.getSessionFileName(sessionId, true);; 
+                       }
+                       return fileName;
+               }
+               
+               /**
+                * @return session id
+                */
+               public String getSessionId()
+               {
+                       return sessionId;
+               }
+
+               /**
+                * Saves the serialized page to appropriate file.
+                * 
+                * @param page
+                */
+               public synchronized void savePage(int pageId, byte data[])
+               {
+                       if (unbound)
+                       {
+                               return;
+                       }
+                       // only save page that has some data
+                       if (data != null)
+                       {
+                               // allocate window for page
+                               PageWindow window = 
getManager().createPageWindow(pageId, data.length);
+
+                               // take the filechannel from the pool
+                               FileChannel channel = 
diskDataStore.fileChannelPool.getFileChannel(getFileName(), true);
+                               try
+                               {
+                                       // write the content
+                                       channel.write(ByteBuffer.wrap(data), 
window.getFilePartOffset());
+                               }
+                               catch (IOException e)
+                               {
+                                       log.error("Error writing to a channel " 
+ channel, e);
+                               }
+                               finally
+                               {
+                                       // return the "borrowed" file channel
+                                       
diskDataStore.fileChannelPool.returnFileChannel(channel);
+                               }
+                       }
+               }
+
+               /**
+                * Removes the page from pagemap file.
+                * 
+                * @param pageMapName
+                * @param pageId
+                */
+               public synchronized void removePage(int pageId)
+               {
+                       if (unbound)
+                       {
+                               return;
+                       }
+                       getManager().removePage(pageId);
+               }
+
+               /**
+                * Loads the part of pagemap file specified by the given 
PageWindow.
+                * 
+                * @param window
+                * @param pageMapFileName
+                * @return serialized page data
+                */
+               public byte[] loadPage(PageWindow window)
+               {                       
+                       byte[] result = null;
+                       FileChannel channel = 
diskDataStore.fileChannelPool.getFileChannel(getFileName(), false);
+                       if (channel != null)
+                       {
+                               ByteBuffer buffer = 
ByteBuffer.allocate(window.getFilePartSize());
+                               try
+                               {
+                                       channel.read(buffer, 
window.getFilePartOffset());
+                                       if (buffer.hasArray())
+                                       {
+                                               result = buffer.array();
+                                       }
+                               }
+                               catch (IOException e)
+                               {
+                                       log.error("Error reading from file 
channel " + channel, e);
+                               }
+                               finally
+                               {
+                                       
diskDataStore.fileChannelPool.returnFileChannel(channel);
+                               }
+                       }
+                       return result;
+               }
+               
+               /**
+                * Loads the specified page data.
+                * 
+                * @param pageMapName
+                * @param id
+                * @return page data or null if the page is no longer in 
pagemap file
+                */
+               public synchronized byte[] loadPage(int id)
+               {
+                       if (unbound)
+                       {
+                               return null;
+                       }
+                       byte[] result = null;
+                       PageWindow window = getManager().getPageWindow(id);
+                       if (window != null)
+                       {
+                               result = loadPage(window);
+                       }
+                       return result;
+               }
+               
+               /**
+                * Deletes all files for this session.
+                */
+               public synchronized void unbind()
+               {
+                       
diskDataStore.fileChannelPool.closeAndDeleteFileChannel(getFileName());
+                       File sessionFolder = 
diskDataStore.getSessionFolder(sessionId, false);
+                       if (sessionFolder.exists())
+                       {
+                               sessionFolder.delete();
+                       }
+                       unbound = true;
+               }
+       }
+
+       /**
+        * Returns the file name for specified session. If the session folder 
(folder that contains the
+        * file) does not exist and createSessionFolder is true, the folder 
will be created.
+        * 
+        * @param sessionId
+        * @param pageMapName
+        * @param createSessionFolder
+        * @return file name for pagemap
+        */
+       private String getSessionFileName(String sessionId, boolean 
createSessionFolder)
+       {
+               File sessionFolder = getSessionFolder(sessionId, 
createSessionFolder);
+               return new File(sessionFolder, "data").getAbsolutePath();
+       }
+
+       private static File getDefaultFileStoreFolder()
+       {
+               File dir = null;
+
+               if (Application.exists())
+               {
+                       dir = (File) ((WebApplication) 
Application.get()).getServletContext().getAttribute(
+                                       "javax.servlet.context.tempdir");
+               }
+
+               if (dir != null)
+               {
+                       return dir;
+               }
+               else
+               {
+                       try
+                       {
+                               return File.createTempFile("file-prefix", 
null).getParentFile();
+                       }
+                       catch (IOException e)
+                       {
+                               throw new WicketRuntimeException(e);
+                       }
+               }
+       }
+
+       private File getStoreFolder()
+       {
+               File storeFolder = new File(fileStoreFolder, applicationName + 
"-filestore");
+               return storeFolder;
+       }
+
+       /**
+        * Returns the folder for the specified sessions. If the folder doesn't 
exist and the create
+        * flag is set, the folder will be created.
+        * 
+        * @param sessionId
+        * @param create
+        * @return folder used to store session data
+        */
+       protected File getSessionFolder(String sessionId, boolean create)
+       {
+               File storeFolder = getStoreFolder();
+
+               sessionId = sessionId.replace('*', '_');
+               sessionId = sessionId.replace('/', '_');
+               sessionId = sessionId.replace(':', '_');
+
+               File sessionFolder = new File(storeFolder, sessionId);
+               if (create && sessionFolder.exists() == false)
+               {
+                       mkdirs(sessionFolder);
+               }
+               return sessionFolder;
+       }
+
+       /**
+        * Utility method for creating a directory
+        * 
+        * @param file
+        */
+       private void mkdirs(File file)
+       {
+               // for some reason, simple file.mkdirs sometimes fails under 
heavy load
+               for (int j = 0; j < 5; ++j)
+               {
+                       for (int i = 0; i < 10; ++i)
+                       {
+                               if (file.mkdirs())
+                               {
+                                       return;
+                               }
+                       }
+                       try
+                       {
+                               Thread.sleep(100);
+                       }
+                       catch (InterruptedException ignore)
+                       {
+                       }
+               }
+               log.error("Failed to make directory " + file);
+       }
+
+       private static final Logger log = 
LoggerFactory.getLogger(DiskDataStore.class);
+
+}

Propchange: 
wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/page/persistent/disk/DiskDataStore.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: 
wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
URL: 
http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WebApplication.java?rev=760608&r1=760607&r2=760608&view=diff
==============================================================================
--- 
wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
 (original)
+++ 
wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
 Tue Mar 31 20:49:14 2009
@@ -19,6 +19,8 @@
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
+import javax.servlet.ServletContext;
+
 import org.apache.wicket.Application;
 import org.apache.wicket.DefaultPageFactory;
 import org.apache.wicket.IPage;
@@ -235,4 +237,28 @@
                String key = sessionId + url.toString();
                storedResponses.put(key, response);
        }
+       
+       /**
+        * Gets the servlet context for this application. Use this to get 
references to absolute paths,
+        * global web.xml parameters (&lt;context-param&gt;), etc.
+        * 
+        * @return The servlet context for this application
+        */
+       public ServletContext getServletContext()
+       {
+               if (wicketFilter != null)
+               {
+                       return 
wicketFilter.getFilterConfig().getServletContext();
+               }
+               throw new IllegalStateException("servletContext is not set yet. 
Any code in your"
+                       + " Application object that uses the wicket filter 
instance should be put"
+                       + " in the init() method instead of your constructor");
+       }
+       
+       public void setWicketFilter(WicketFilter wicketFilter)
+       {
+               this.wicketFilter = wicketFilter;
+       }
+       
+       private WicketFilter wicketFilter;
 }

Modified: 
wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WicketFilter.java
URL: 
http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WicketFilter.java?rev=760608&r1=760607&r2=760608&view=diff
==============================================================================
--- 
wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WicketFilter.java
 (original)
+++ 
wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WicketFilter.java
 Tue Mar 31 20:49:14 2009
@@ -218,6 +218,7 @@
                IWebApplicationFactory factory = getApplicationFactory();
                webApplication = factory.createApplication(this);
                webApplication.setName(filterConfig.getFilterName());
+               webApplication.setWicketFilter(this);
                
                initFilterPath();
                


Reply via email to