blob: d45def525315ed8e492add825f2e10068d067a12 [file] [log] [blame]
// Copyright 2007, 2008 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.tapestry5.internal.services;
import static org.apache.tapestry5.ioc.internal.util.CollectionFactory.newList;
import static org.apache.tapestry5.ioc.internal.util.Defense.notBlank;
import org.apache.tapestry5.services.PersistentFieldChange;
import org.apache.tapestry5.services.PersistentFieldStrategy;
import org.apache.tapestry5.services.Request;
import org.apache.tapestry5.services.Session;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* Base class for strategies that store their values as keys in the session. Implements a uniform format for the keys,
* based on a prefix to identify the particular strategy.
*/
public abstract class AbstractSessionPersistentFieldStrategy implements PersistentFieldStrategy
{
private final String prefix;
private final Request request;
protected AbstractSessionPersistentFieldStrategy(String prefix, Request request)
{
this.prefix = prefix;
this.request = request;
}
public final Collection<PersistentFieldChange> gatherFieldChanges(String pageName)
{
Session session = request.getSession(false);
if (session == null) return Collections.emptyList();
List<PersistentFieldChange> result = newList();
String fullPrefix = prefix + pageName + ":";
for (String name : session.getAttributeNames(fullPrefix))
{
PersistentFieldChange change = buildChange(name, session.getAttribute(name));
result.add(change);
didReadChange(session, name);
}
return result;
}
public void discardChanges(String pageName)
{
Session session = request.getSession(false);
if (session == null) return;
String fullPrefix = prefix + pageName + ":";
for (String name : session.getAttributeNames(fullPrefix))
{
session.setAttribute(name, null);
}
}
/**
* Called after each key is read by {@link #gatherFieldChanges(String)}. This implementation does nothing,
* subclasses may override.
*
* @param session the session from which a value was just read
* @param attributeName the name of the attribute used to read a value
*/
protected void didReadChange(Session session, String attributeName)
{
}
private PersistentFieldChange buildChange(String name, Object attribute)
{
// TODO: Regexp is probably too expensive for what we need here. Maybe an IOC InternalUtils
// method for this purpose?
String[] chunks = name.split(":");
// Will be empty string for the root component
String componentId = chunks[2];
String fieldName = chunks[3];
return new PersistentFieldChangeImpl(componentId, fieldName, attribute);
}
public final void postChange(String pageName, String componentId, String fieldName,
Object newValue)
{
notBlank(pageName, "pageName");
notBlank(fieldName, "fieldName");
StringBuilder builder = new StringBuilder(prefix);
builder.append(pageName);
builder.append(':');
if (componentId != null) builder.append(componentId);
builder.append(':');
builder.append(fieldName);
Session session = request.getSession(newValue != null);
// TAPESTRY-2308: The session will be false when newValue is null and the session
// does not already exist.
if (session != null)
{
session.setAttribute(builder.toString(), newValue);
}
}
}