package student.web; import java.util.AbstractMap.SimpleEntry; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import student.web.internal.ApplicationSupportStrategy; import student.web.internal.LocalityService; // TODO: add equals()/hashCode()/toString() to all persistent maps /** * The Session persistence layer represents all of the persisted items * associated with the current web session. In a desktop development environment * a session is equivalent to a single execution of the JVM. There is a single * map in the system for all session objects this means that many of the methods * do not respect the generic type argument of this class. * * @author mjw87 * * @param <T> */ public class SessionPersistentMap<T> implements PersistentMap<T> { private ApplicationSupportStrategy support; private Class<T> typeAware; private Map<String, Object> self; @SuppressWarnings("unchecked") public SessionPersistentMap( Class<T> type ) { support = LocalityService.getSupportStrategy(); this.typeAware = type; this.self = support.getSessionPersistentMap(); } public int size() { return self.size(); } public boolean isEmpty() { return self.isEmpty(); } public boolean containsKey( Object key ) { assert key instanceof String : "Persistence maps only allows for keys of type String"; return self.containsKey( key ); } public boolean containsValue( Object value ) { if ( value == null || !typeAware.isInstance( value ) ) return false; return self.containsValue( value ); } @SuppressWarnings("unchecked") public T get( Object key ) { assert key instanceof String : "Persistence maps only allows for keys of type String"; Object o = self.get( key ); Object unAlias = support.resolveAlias( o ); if(unAlias != null) o = unAlias; if ( o != null && typeAware.isInstance( o ) ) return (T)o; return null; } @SuppressWarnings("unchecked") public T put( String key, T value ) { assert key != null : "An objectId cannot be null"; assert key.length() > 0 : "An objectId cannot be an empty string"; assert !( value instanceof Class ) : "The object to store cannot be a class; perhaps you wanted " + "to provide an instance of this class instead?"; Object o = get( key ); Object aliasValue = support.getAlias(value); if ( o == null || !typeAware.isInstance( o ) ) o = null; self.put( key, aliasValue ); return (T)o; } @SuppressWarnings("unchecked") public T remove( Object key ) { assert key instanceof String : "Persistence maps only allows for keys of type String"; String objectId = (String)key; assert objectId != null : "An key cannot be null"; Object o = self.get( objectId ); if ( o == null || !typeAware.isInstance( o ) ) o = null; self.remove( objectId ); return (T)o; } public void putAll( Map<? extends String, ? extends T> m ) { self.putAll( m ); } public void clear() { self.clear(); } public Set<String> keySet() { return self.keySet(); } @SuppressWarnings("unchecked") public Collection<T> values() { Set<String> keys = keySet(); Set<T> values = new HashSet<T>(); for ( String key : keys ) { Object o = self.get( key ); if ( typeAware.isInstance( o ) ) { values.add( (T)o ); } else { values.add( null ); } } return values; } @SuppressWarnings("unchecked") public Set<java.util.Map.Entry<String, T>> entrySet() { Set<java.util.Map.Entry<String, Object>> entrySet = self.entrySet(); Set<java.util.Map.Entry<String, T>> projectedEntrySet = new HashSet<java.util.Map.Entry<String, T>>(); for ( java.util.Map.Entry<String, Object> entry : entrySet ) { String key = entry.getKey(); T value; if ( typeAware.isInstance( self.get( key ) ) ) { value = (T)self.get(key); } else { value = null; } Entry<String, T> newEntry = new SimpleEntry<String, T>( key, value ); projectedEntrySet.add( newEntry ); } return projectedEntrySet; } }