blob: cf6bb8e188ede4801c27d7997e7c98b78a9d753a [file] [log] [blame]
// Copyright 2006, 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.corelib.internal;
import org.apache.tapestry5.ComponentAction;
import org.apache.tapestry5.Field;
import org.apache.tapestry5.internal.services.ClientBehaviorSupport;
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
import org.apache.tapestry5.ioc.internal.util.Defense;
import org.apache.tapestry5.ioc.internal.util.IdAllocator;
import org.apache.tapestry5.runtime.Component;
import org.apache.tapestry5.services.FormSupport;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.List;
/**
* Provides support to components enclosed by a form when the form is rendering (allowing the components to registry
* form submit callback commands), and also during form submission time.
* <p/>
* TODO: Most methods should only be invokable depending on whether the form is rendering or processing a submission.
*/
public class FormSupportImpl implements FormSupport
{
private final ClientBehaviorSupport clientBehaviorSupport;
private final boolean clientValidationEnabled;
private final IdAllocator idAllocator;
private final String clientId;
private final ObjectOutputStream actions;
private List<Runnable> commands;
private String encodingType;
/**
* Constructor used when processing a form submission.
*/
public FormSupportImpl()
{
this(null, null, null, false, null);
}
/**
* Constructor used when rendering.
*/
public FormSupportImpl(String clientId, ObjectOutputStream actions, ClientBehaviorSupport clientBehaviorSupport,
boolean clientValidationEnabled)
{
this(clientId, actions, clientBehaviorSupport, clientValidationEnabled, new IdAllocator());
}
/**
* Full constructor.
*/
public FormSupportImpl(String clientId, ObjectOutputStream actions, ClientBehaviorSupport clientBehaviorSupport,
boolean clientValidationEnabled, IdAllocator idAllocator)
{
this.clientId = clientId;
this.actions = actions;
this.clientBehaviorSupport = clientBehaviorSupport;
this.clientValidationEnabled = clientValidationEnabled;
this.idAllocator = idAllocator;
}
public String getFormId()
{
return clientId;
}
public String allocateControlName(String id)
{
return idAllocator.allocateId(id);
}
public <T> void store(T component, ComponentAction<T> action)
{
Component castComponent = Defense.cast(component, Component.class, "component");
Defense.notNull(action, "action");
String completeId = castComponent.getComponentResources().getCompleteId();
try
{
// Writing the complete id is not very efficient, but the GZip filter
// should help out there.
actions.writeUTF(completeId);
actions.writeObject(action);
}
catch (IOException ex)
{
throw new RuntimeException(InternalMessages.componentActionNotSerializable(completeId, ex), ex);
}
}
public <T> void storeAndExecute(T component, ComponentAction<T> action)
{
store(component, action);
action.execute(component);
}
public void defer(Runnable command)
{
if (commands == null) commands = CollectionFactory.newList();
commands.add(Defense.notNull(command, "command"));
}
public void executeDeferred()
{
if (commands == null) return;
for (Runnable r : commands)
r.run();
commands.clear();
}
public String getClientId()
{
return clientId;
}
public String getEncodingType()
{
return encodingType;
}
public void setEncodingType(String encodingType)
{
Defense.notBlank(encodingType, "encodingType");
if (this.encodingType != null && !this.encodingType.equals(encodingType))
throw new IllegalStateException(InternalMessages.conflictingEncodingType(this.encodingType, encodingType));
this.encodingType = encodingType;
}
public void addValidation(Field field, String validationName, String message, Object constraint)
{
if (clientValidationEnabled)
clientBehaviorSupport.addValidation(field, validationName, message, constraint);
}
}