package org.apache.slide.projector.processor.form;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import org.apache.slide.projector.ContentType;
import org.apache.slide.projector.Context;
import org.apache.slide.projector.Processor;
import org.apache.slide.projector.Result;
import org.apache.slide.projector.Store;
import org.apache.slide.projector.URI;
import org.apache.slide.projector.descriptor.ParameterDescriptor;
import org.apache.slide.projector.descriptor.ResultDescriptor;
import org.apache.slide.projector.descriptor.ResultEntryDescriptor;
import org.apache.slide.projector.descriptor.StateDescriptor;
import org.apache.slide.projector.descriptor.StringValueDescriptor;
import org.apache.slide.projector.descriptor.ValidationException;
import org.apache.slide.projector.engine.ProcessorManager;
import org.apache.slide.projector.i18n.ErrorMessage;
import org.apache.slide.projector.i18n.ParameterMessage;
import org.apache.slide.projector.processor.SimpleProcessor;
import org.apache.slide.projector.processor.process.Process;
import org.apache.slide.projector.value.BooleanValue;
import org.apache.slide.projector.value.MapValue;
import org.apache.slide.projector.value.StringValue;
import org.apache.slide.projector.value.URIValue;
/**
* @version $Revision: 1.4 $
*/
public class FormHandler implements Processor {
public final static String RESULT = "result";
private final static String INSTRUCTION_IDENTIFIER = "instruction:";
private final static ParameterDescriptor[] parameterDescriptors = new ParameterDescriptor[0];
private final static ResultDescriptor resultDescriptor = new ResultDescriptor(
new StateDescriptor[] { StateDescriptor.OK_DESCRIPTOR },
new ResultEntryDescriptor[] {
new ResultEntryDescriptor(SimpleProcessor.OUTPUT, new ParameterMessage("trigger/output"), ContentType.DYNAMIC, true)
});
public Result process(Map parameter, Context context) throws Exception {
// Lookup valid instruction
String trigger = null;
for ( Iterator i = parameter.entrySet().iterator(); i.hasNext(); ) {
Map.Entry entry = (Map.Entry)i.next();
String key = (String)entry.getKey();
if ( key.startsWith(Form.TRIGGER_IDENTIFIER) ) {
if ( key.indexOf('.') > 0 ) {
trigger = key.substring(0, key.indexOf('.'));
break;
}
}
}
if ( trigger == null ) {
throw new ValidationException(new ErrorMessage("trigger/triggerParameterMissing"));
}
// Decode instruction
StringTokenizer tokenizer = new StringTokenizer(StringValueDescriptor.ANY.valueOf(parameter.get(INSTRUCTION_IDENTIFIER+trigger), context).toString(), ";");
URI actionURI = new URIValue(tokenizer.nextToken());
boolean validate = Boolean.valueOf(tokenizer.nextToken()).booleanValue();
boolean wizard = Boolean.valueOf(tokenizer.nextToken()).booleanValue();
String lastStep = tokenizer.nextToken();
String targetStep = tokenizer.nextToken();
String domain = tokenizer.nextToken();
List involvedParamters = new ArrayList();
while ( tokenizer.hasMoreTokens() ) {
involvedParamters.add(tokenizer.nextToken());
}
Store store = context.getStore(Store.SESSION);
// 1. Store all (request) parameters into requested domain
Map map;
MapValue mapResource = (MapValue)store.get(domain);
if ( mapResource == null ) {
map = new HashMap();
mapResource = new MapValue(map);
store.put(domain, mapResource);
} else {
map = mapResource.getMap();
}
map.put(ControlComposer.VALIDATE, new BooleanValue(validate));
map.put(Process.STEP, new StringValue(targetStep));
map.putAll(parameter);
if ( validate ) {
// 2. Validate parameters
Processor processor = ProcessorManager.getInstance().getProcessor(actionURI);
try {
// Validate only given parameters to enable wizard like forms
ParameterDescriptor[] parameterDescriptors = processor.getParameterDescriptors();
for ( int i = 0; i < parameterDescriptors.length; i++ ) {
String parameterName = parameterDescriptors[i].getName();
if ( involvedParamters.contains(parameterName) ) {
map.put(parameterName, ProcessorManager.prepareValue(parameterDescriptors[i], parameter.get(parameterName), context));
}
}
if ( wizard ) {
// Don't validate target step form
map.put(ControlComposer.VALIDATE, BooleanValue.FALSE);
}
} catch ( ValidationException exception ) {
// 3. Go back to form step if validation failes
map.put(Process.STEP, new StringValue(lastStep));
}
}
// 4. Launch target step if validation is successfull
Processor formProcess = ProcessorManager.getInstance().getProcessor(new URIValue(domain));
map.remove(RESULT);
Result formResult = formProcess.process(parameter, context);
map.put(RESULT, formResult);
Processor bookmark = ProcessorManager.getInstance().getProcessor(context.getBookmark());
return bookmark.process(parameter, context);
}
public ParameterDescriptor[] getParameterDescriptors() {
return parameterDescriptors;
}
public ResultDescriptor getResultDescriptor() {
return resultDescriptor;
}
}