001: // Copyright 2007 The Apache Software Foundation
002: //
003: // Licensed under the Apache License, Version 2.0 (the "License");
004: // you may not use this file except in compliance with the License.
005: // You may obtain a copy of the License at
006: //
007: // http://www.apache.org/licenses/LICENSE-2.0
008: //
009: // Unless required by applicable law or agreed to in writing, software
010: // distributed under the License is distributed on an "AS IS" BASIS,
011: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: // See the License for the specific language governing permissions and
013: // limitations under the License.
014:
015: package org.apache.tapestry.internal.services;
016:
017: import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newConcurrentMap;
018:
019: import java.util.Map;
020:
021: import org.apache.tapestry.services.ApplicationStateContribution;
022: import org.apache.tapestry.services.ApplicationStateCreator;
023: import org.apache.tapestry.services.ApplicationStateManager;
024: import org.apache.tapestry.services.ApplicationStatePersistenceStrategy;
025: import org.apache.tapestry.services.ApplicationStatePersistenceStrategySource;
026:
027: public class ApplicationStateManagerImpl implements
028: ApplicationStateManager {
029: static final String DEFAULT_STRATEGY = "session";
030:
031: static class ApplicationStateAdapter<T> {
032: private final Class<T> _asoClass;
033:
034: private final ApplicationStatePersistenceStrategy _strategy;
035:
036: private final ApplicationStateCreator<T> _creator;
037:
038: ApplicationStateAdapter(Class<T> asoClass,
039: ApplicationStatePersistenceStrategy strategy,
040: ApplicationStateCreator<T> creator) {
041: _asoClass = asoClass;
042: _strategy = strategy;
043: _creator = creator;
044: }
045:
046: T getOrCreate() {
047: return _strategy.get(_asoClass, _creator);
048: }
049:
050: void set(T aso) {
051: _strategy.set(_asoClass, aso);
052: }
053:
054: boolean exists() {
055: return _strategy.exists(_asoClass);
056: }
057: };
058:
059: /**
060: * The map will be extended periodically as new ASOs, not in the configuration, are encountered.
061: * Thut is is thread safe.
062: */
063: private final Map<Class, ApplicationStateAdapter> _classToAdapter = newConcurrentMap();
064:
065: private final ApplicationStatePersistenceStrategySource _source;
066:
067: @SuppressWarnings("unchecked")
068: public ApplicationStateManagerImpl(
069: Map<Class, ApplicationStateContribution> configuration,
070: ApplicationStatePersistenceStrategySource source) {
071: _source = source;
072:
073: for (Class asoClass : configuration.keySet()) {
074: ApplicationStateContribution contribution = configuration
075: .get(asoClass);
076:
077: ApplicationStateAdapter adapter = newAdapter(asoClass,
078: contribution.getStrategy(), contribution
079: .getCreator());
080:
081: _classToAdapter.put(asoClass, adapter);
082: }
083:
084: }
085:
086: @SuppressWarnings("unchecked")
087: private <T> ApplicationStateAdapter<T> newAdapter(
088: final Class<T> asoClass, String strategyName,
089: ApplicationStateCreator<T> creator) {
090: if (creator == null)
091: creator = new ApplicationStateCreator<T>() {
092: public T create() {
093: try {
094: return asoClass.newInstance();
095: } catch (Exception ex) {
096: throw new RuntimeException(ex);
097: }
098: }
099:
100: };
101:
102: ApplicationStatePersistenceStrategy strategy = _source
103: .get(strategyName);
104:
105: return new ApplicationStateAdapter(asoClass, strategy, creator);
106: }
107:
108: @SuppressWarnings("unchecked")
109: private <T> ApplicationStateAdapter<T> getAdapter(Class<T> asoClass) {
110: ApplicationStateAdapter<T> result = _classToAdapter
111: .get(asoClass);
112:
113: // Not found is completely OK, we'll define it on the fly.
114:
115: if (result == null) {
116: result = newAdapter(asoClass, DEFAULT_STRATEGY, null);
117: _classToAdapter.put(asoClass, result);
118: }
119:
120: return result;
121: }
122:
123: public <T> T get(Class<T> asoClass) {
124: return getAdapter(asoClass).getOrCreate();
125: }
126:
127: public <T> void set(Class<T> asoClass, T aso) {
128: getAdapter(asoClass).set(aso);
129: }
130:
131: public <T> boolean exists(Class<T> asoClass) {
132: return getAdapter(asoClass).exists();
133: }
134:
135: }
|