/* * ==========================================================================*\ * | $Id: LocalApplicationSupportStrategy.java,v 1.3 2011/01/16 20:33:00 * mwoodsvt Exp $ * |*-------------------------------------------------------------------------*| * | Copyright (C) 2009-2010 Virginia Tech | | This file is part of the * Student-Library. | | The Student-Library is free software; you can * redistribute it and/or | modify it under the terms of the GNU Lesser General * Public License as | published by the Free Software Foundation; either version * 3 of the | License, or (at your option) any later version. | | The * Student-Library is distributed in the hope that it will be useful, | but * WITHOUT ANY WARRANTY; without even the implied warranty of | MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the | GNU Lesser General Public * License for more details. | | You should have received a copy of the GNU * Lesser General Public License | along with the Student-Library; if not, see * <http://www.gnu.org/licenses/>. * \*========================================================================== */ package student.web.internal; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.util.HashMap; import java.util.Map; import com.thoughtworks.xstream.converters.reflection.ReflectionProvider; import com.thoughtworks.xstream.core.JVM; import student.web.ApplicationPersistentMap; import student.web.SharedPersistentMap; import student.web.internal.PersistentStorageManager.StoredObject; import student.web.internal.converters.Alias; // ------------------------------------------------------------------------- /** * Defines the support methods needed to implement server-specific storage * features for an {@link student.web.Application} that is running as a plain * old Java program, rather than in the context of a web server application. * * @author Stephen Edwards * @author Last changed by $Author: mwoodsvt $ * @version $Revision: 1.7 $, $Date: 2011/06/21 14:57:28 $ */ public class LocalApplicationSupportStrategy implements ApplicationSupportStrategy { // ~ Instance/static variables ............................................. private static ThreadLocal<Map<String, Object>> localSessionMap = new ThreadLocal<Map<String, Object>>() { public Map<String, Object> initialValue() { return null; } }; private Map<String, Object> sessionValues; private String path = "index.zhtml"; // ~ Constructor ........................................................... // ---------------------------------------------------------- /** * Create a new object. */ public LocalApplicationSupportStrategy() { if ( localSessionMap.get() == null ) { sessionValues = new HashMap<String, Object>(); localSessionMap.set( sessionValues ); } else { sessionValues = localSessionMap.get(); } } // ~ Public Methods ........................................................ // ---------------------------------------------------------- /** * Get a parameter passed to this page in the query part of the URL. * * @param name * The name of the parameter to retrieve * @return The parameter's value on the current page, or null if there is * none. */ public String getPageParameter( String name ) { return null; } // ---------------------------------------------------------- /** * Get a parameter stored in the current session. * * @param name * The name of the parameter to retrieve * @return The parameter's value in the current session, or null if there is * none. */ public Object getSessionParameter( String name ) { return sessionValues.get( name ); } // ---------------------------------------------------------- /** * Remove a parameter stored in the current session, if it exists. * * @param name * The name of the parameter to remove * @return The removed value, if the parameter existed, or null if there is * no value to remove. */ public Object removeSessionParameter( String name ) { return sessionValues.remove( name ); } // ---------------------------------------------------------- /** * Store a value in the current session. If a value already exists for the * given name, it is replaced. * * @param name * The name of the parameter to store * @param value * The value to store * @return The previous value in the current session associated with the * given name, if there is one, or null otherwise. */ public Object setSessionParameter( String name, Object value ) { return sessionValues.put( name, value ); } // ---------------------------------------------------------- /** * Cause the web application to show a different web page in the user's web * browser. * * @param url * The new web page to show in the user's browser */ public void showWebPage( String url ) { if ( url != null && url.length() > 0 ) { System.out.println( "web application switches to page: " + url ); path = url; } } // ---------------------------------------------------------- /** * Retrieve the name of the current ZHTML file, such as "index.zhtml" or * "lab02.zhtml". * * @return The name of the current ZHTML file, without any directory * component, or "" if there is none. */ public String getCurrentPageName() { String result = getCurrentPagePath(); int pos = result.lastIndexOf( '/' ); if ( pos >= 0 ) { result = result.substring( 0, pos ); } return result; } // ---------------------------------------------------------- /** * Retrieve the relative path name of the current ZHTML file, such as * "/Fall09/mypid/index.zhtml" or "/Fall09/mypid/lab02/lab02.zhtml". * * @return The name path to the current ZHTML file, or "" if there is none. */ public String getCurrentPagePath() { return path; } public Map<String, StoredObject> getPersistentCache( String cacheId ) { Map<String, Map<String,StoredObject>> cacheStore = getCacheStore(); Object cache = cacheStore.get( cacheId ); if(cache == null) return null; return (Map<String,StoredObject>)cache; } private Map<String, Map<String, StoredObject>> getCacheStore() { Object cacheStoreRaw = this.getSessionParameter("persistent_cache"); if(cacheStoreRaw == null) { cacheStoreRaw = new HashMap<String,Map<String,StoredObject>>(); this.setSessionParameter( "persistent_cache", cacheStoreRaw ); } return (Map<String, Map<String,StoredObject>>)cacheStoreRaw; } public Map<String,StoredObject> initPersistentCache( String cacheId ) { Map<String, Map<String,StoredObject>> cacheStore = getCacheStore(); Map<String,StoredObject> cache = new HashMap<String,StoredObject>(); cacheStore.put( cacheId, cache ); return cache; } private Alias getAliasId(Object value) { // Map<String, Alias> aliasMap = getInternalAliasSessionMap(); Map<String,Map<String,StoredObject>> allCaches = this.getCacheStore(); if(allCaches == null) return null; for(String cacheId : allCaches.keySet()) { Map<String,StoredObject> cache = allCaches.get( cacheId ); for(String cachedObject : cache.keySet()) if(cache.get( cachedObject ).value() == value) { return new Alias(cachedObject,cacheId); } } return null; } public Object resolveAlias(Object value) { if(value != null && value instanceof Alias) { //Ew.... my trick didnt work, if I dont grab a custom loader, i cant find the classes when i reload it. Snapshot preserveLocal = Snapshot.getLocal(); Alias alias = (Alias)value; Object resolved = null; if(alias.getContextMap().startsWith(ApplicationPersistentMap.APP_STORE)) { ApplicationPersistentMap<Object> pMap = new ApplicationPersistentMap<Object>(ApplicationPersistentMap.findIdentifier(alias.getContextMap()),Object.class, this.getClass().getClassLoader()); resolved = pMap.get( alias.getKey() ); } else if(alias.getContextMap().startsWith(SharedPersistentMap.CONTEXT_OBJECT)) { SharedPersistentMap<Object> pMap = new SharedPersistentMap<Object>(Object.class, this.getClass().getClassLoader()); resolved = pMap.get( alias.getKey() ); } Snapshot.setLocal( preserveLocal ); return resolved; } return value; } public Object getAlias( Object value ) { Alias alias = getAliasId(value); if(alias == null) { return value; } return alias; } public ReflectionProvider getReflectionProvider() { //Nothing special needed, let xstream pick the best one. return (new JVM()).bestReflectionProvider(); } public InputStream getObjectSource( File src ) { if(src.exists()) { try { return new FileInputStream(src); } catch ( FileNotFoundException e ) { //Just return null so that we mark the file as to not be loaded } } return null; } public OutputStream getObjectOutput( File dest ) { try { return new FileOutputStream(dest); } catch ( FileNotFoundException e ) { return null; } } public File getPersistentFile( String subDir ) { return new File(subDir); } public File getPersistentFile( File baseDir, String subDir ) { return new File(baseDir, subDir); } public File getPersistentBase() { return new File("data"); } private static final String _SERVER_SESSION_MAP = "_server_session_map"; public Map<String, Object> getSessionPersistentMap() { Map<String,Object> self = (Map<String, Object>)getSessionParameter( _SERVER_SESSION_MAP ); if ( self == null ) { self = new HashMap<String, Object>(); setSessionParameter( _SERVER_SESSION_MAP, self ); } return self; } }