I have a requirement to not depend on HttpSession, but the Form
component has a @Persist field that Tapestry wants to store in a
session. What are some options to avoid this?
I may have posted this before, but here it is again. I think it's a
pretty good solution.
I created a session persistence strategy that only stores non-null
values, and extended the Form to only store the validation if there
are errors... The changes to the existing classes are minor.
Here's the code.
import org.apache.tapestry.ValidationTracker;
import org.apache.tapestry.ValidationTrackerImpl;
import org.apache.tapestry.annotations.Persist;
/**
* Overrides the core [EMAIL PROTECTED]
org.apache.tapestry.corelib.components.Form} in order to store the
validation tracker only
* when there is something to track.
* <p/>
* Created by IntelliJ IDEA.
* User: joshcanfield
* Date: Oct 26, 2007
*/
public class Form extends org.apache.tapestry.corelib.components.Form {
@Persist("nonnull")
private ValidationTracker _tracker;
private ValidationTracker _nonPersistedTracker;
public ValidationTracker getDefaultTracker() {
if (_nonPersistedTracker == null) {
if (_tracker != null) {
// _tracker is loaded via injection magic when it's
in the session
_nonPersistedTracker = _tracker;
} else {
_nonPersistedTracker = new ValidationTrackerImpl();
}
}
return _nonPersistedTracker;
}
public void setDefaultTracker(ValidationTracker defaultTracker) {
_nonPersistedTracker = defaultTracker;
}
protected void onAction() {
if (_nonPersistedTracker.getHasErrors()) {
_tracker = _nonPersistedTracker;
} else {
_tracker = null;
}
}
}
import org.apache.tapestry.internal.services.PersistentFieldChangeImpl;
import static
org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
import org.apache.tapestry.services.PersistentFieldChange;
import org.apache.tapestry.services.PersistentFieldStrategy;
import org.apache.tapestry.services.Request;
import org.apache.tapestry.services.Session;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* Created by IntelliJ IDEA.
* User: joshcanfield
* Date: Oct 26, 2007
*/
public class NonNullSessionPersistentFieldStrategy implements
PersistentFieldStrategy {
/**
* Prefix used to identify keys stored in the session.
*/
static final String PREFIX = "nonnull:";
private final Request _request;
protected NonNullSessionPersistentFieldStrategy(Request request) {
_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);
}
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);
}
}
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);
// because we don't want to create a session when the object
is null
Session session = _request.getSession(newValue != null);
if (session != null) {
session.setAttribute(builder.toString(), newValue);
}
}
}
Add this to your app module:
public void contributePersistentFieldManager(
MappedConfiguration<String, PersistentFieldStrategy>
configuration, Request request) {
configuration.add("nonnull", new
NonNullSessionPersistentFieldStrategy(request));
}
On Apr 6, 2008, at 2:22 PM, Fernando Padilla wrote:
I have a requirement to not depend on HttpSession, but the Form
component has a @Persist field that Tapestry wants to store in a
session. What are some options to avoid this?
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]