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.newList;
018: import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
019:
020: import java.util.Collection;
021: import java.util.Collections;
022: import java.util.List;
023:
024: import org.apache.tapestry.services.PersistentFieldChange;
025: import org.apache.tapestry.services.PersistentFieldStrategy;
026: import org.apache.tapestry.services.Request;
027: import org.apache.tapestry.services.Session;
028:
029: /**
030: * Base class for strategies that store their values as keys in the session. Implements a uniform
031: * format for the keys, based on a prefix to identify the particular strategy.
032: */
033: public abstract class AbstractSessionPersistentFieldStrategy implements
034: PersistentFieldStrategy {
035: private final String _prefix;
036:
037: private final Request _request;
038:
039: protected AbstractSessionPersistentFieldStrategy(String prefix,
040: Request request) {
041: _prefix = prefix;
042: _request = request;
043: }
044:
045: public final Collection<PersistentFieldChange> gatherFieldChanges(
046: String pageName) {
047: Session session = _request.getSession(false);
048:
049: if (session == null)
050: return Collections.emptyList();
051:
052: List<PersistentFieldChange> result = newList();
053:
054: String fullPrefix = _prefix + pageName + ":";
055:
056: for (String name : session.getAttributeNames(fullPrefix)) {
057: PersistentFieldChange change = buildChange(name, session
058: .getAttribute(name));
059:
060: result.add(change);
061:
062: didReadChange(session, name);
063: }
064:
065: return result;
066: }
067:
068: /**
069: * Called after each key is read by {@link #gatherFieldChanges(String)}. This implementation
070: * does nothing, subclasses may override.
071: *
072: * @param session
073: * the session from which a value was just read
074: * @param attributeName
075: * the name of the attribute used to read a value
076: */
077: protected void didReadChange(Session session, String attributeName) {
078: }
079:
080: private PersistentFieldChange buildChange(String name,
081: Object attribute) {
082: // TODO: Regexp is probably too expensive for what we need here. Maybe an IOC InternalUtils
083: // method for this purpose?
084:
085: String[] chunks = name.split(":");
086:
087: // Will be empty string for the root component
088: String componentId = chunks[2];
089: String fieldName = chunks[3];
090:
091: return new PersistentFieldChangeImpl(componentId, fieldName,
092: attribute);
093: }
094:
095: public final void postChange(String pageName, String componentId,
096: String fieldName, Object newValue) {
097: notBlank(pageName, "pageName");
098: notBlank(fieldName, "fieldName");
099:
100: StringBuilder builder = new StringBuilder(_prefix);
101: builder.append(pageName);
102: builder.append(':');
103:
104: if (componentId != null)
105: builder.append(componentId);
106:
107: builder.append(':');
108: builder.append(fieldName);
109:
110: Session session = _request.getSession(true);
111:
112: session.setAttribute(builder.toString(), newValue);
113: }
114: }
|