package org.apache.slide.projector.processor.tree;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import org.apache.slide.projector.ConfigurationException;
import org.apache.slide.projector.Context;
import org.apache.slide.projector.Result;
import org.apache.slide.projector.URI;
import org.apache.slide.projector.descriptor.MapValueDescriptor;
import org.apache.slide.projector.descriptor.ParameterDescriptor;
import org.apache.slide.projector.descriptor.StringValueDescriptor;
import org.apache.slide.projector.descriptor.TreeValueDescriptor;
import org.apache.slide.projector.i18n.ParameterMessage;
import org.apache.slide.projector.processor.SimpleProcessor;
import org.apache.slide.projector.processor.TemplateRenderer;
import org.apache.slide.projector.value.ArrayValue;
import org.apache.slide.projector.value.MapValue;
import org.apache.slide.projector.value.StreamableValue;
import org.apache.slide.projector.value.StringValue;
import org.apache.slide.projector.value.Value;
public class TreeRenderer extends TemplateRenderer {
final private static String HEADER_FRAGMENT = "header ";
final private static String FOOTER_FRAGMENT = "footer ";
final private static String FIRST_FRAGMENT = "first ";
final private static String LAST_FRAGMENT = "last ";
final private static String EVEN_FRAGMENT = "even ";
final private static String DEFAULT_FRAGMENT = "default ";
final private static String EMPTY_FRAGMENT = "empty ";
final private static String OPEN_FOLDER_FRAGMENT = "open ";
final private static String CLOSED_FOLDER_FRAGMENT = "closed ";
final private static String ACTIVE_FRAGMENT = "active ";
final public static String ID = "id";
final public static String ACTIVE_ID = "activeId";
private ParameterDescriptor []parameterDescriptors;
public TreeRenderer() {
setRequiredFragments(new String[] { DEFAULT_FRAGMENT });
setOptionalFragments(new String[] { HEADER_FRAGMENT, FOOTER_FRAGMENT, FIRST_FRAGMENT, LAST_FRAGMENT,
EVEN_FRAGMENT, EMPTY_FRAGMENT, OPEN_FOLDER_FRAGMENT, CLOSED_FOLDER_FRAGMENT, ACTIVE_FRAGMENT });
}
public void configure(StreamableValue config) throws ConfigurationException {
super.configure(config);
List validMapEntries = new ArrayList();
for ( Iterator i = parameterDescriptions.iterator(); i.hasNext(); ) {
ParameterDescriptor parentParameter = (ParameterDescriptor)i.next();
if ( !parentParameter.getName().equals(FRAGMENT) ) {
validMapEntries.add(parentParameter);
}
}
parameterDescriptors = new ParameterDescriptor[] {
new ParameterDescriptor(ID, new ParameterMessage("treeRenderer/id"), new TreeValueDescriptor(new StringValueDescriptor())),
new ParameterDescriptor(SimpleProcessor.INPUT, new ParameterMessage("treeRenderer/input"), new TreeValueDescriptor(new MapValueDescriptor(validMapEntries)))
};
}
public Result process(Map parameter, Context context) throws Exception {
Value[] idArray = ((ArrayValue)parameter.get(ID)).getArray();
Value[] inputArray = ((ArrayValue)parameter.get(SimpleProcessor.INPUT)).getArray();
URI activeIdResource = (URI)context.getBookmark();
String activeId = null;
int[] active = new int[0];
if ( activeIdResource != null ) {
activeId = activeIdResource.toString();
String path = buildPathToActiveNode(null, activeId, idArray);
if ( path != null ) {
StringTokenizer tokenizer = new StringTokenizer(path, ",");
active = new int[tokenizer.countTokens()];
int counter = 0;
while ( tokenizer.hasMoreTokens() ) {
active[counter] = Integer.parseInt(tokenizer.nextToken());
counter++;
}
}
}
return new Result(OK, OUTPUT, new StringValue(process(parameter, idArray, inputArray, active, 0, context), "text/html", false ));
}
private String buildPathToActiveNode(String path, String activeId, Value[] idArray) {
for ( int i = 0; i < idArray.length; i++ ) {
if ( idArray[i] instanceof StringValue && ((StringValue)idArray[i]).toString().equals(activeId) ) {
if ( path != null) {
return path+","+i;
} else {
return String.valueOf(i);
}
} else if ( idArray[i] instanceof ArrayValue ) {
String newPath;
if ( path != null) {
newPath = path+","+i;
} else {
newPath = String.valueOf(i);
}
String nestedPath = buildPathToActiveNode(newPath, activeId, ((ArrayValue)idArray[i]).getArray());
if ( nestedPath != null ) {
return nestedPath;
}
}
}
return null;
}
public String process(Map parameter, Value[] idArray, Value[] inputArray, int[] active, int level, Context context) throws Exception {
StringBuffer buffer = new StringBuffer(1024);
Template defaultTemplate = getRequiredFragment(DEFAULT_FRAGMENT+level);
Template headerTemplate = getOptionalFragment(HEADER_FRAGMENT+level);
Template footerTemplate = getOptionalFragment(FOOTER_FRAGMENT+level);
Template firstTemplate = getOptionalFragment(FIRST_FRAGMENT+level);
Template lastTemplate = getOptionalFragment(LAST_FRAGMENT+level);
Template evenTemplate = getOptionalFragment(EVEN_FRAGMENT+level);
Template activeTemplate = getOptionalFragment(ACTIVE_FRAGMENT+level);
Template emptyTemplate = getOptionalFragment(EMPTY_FRAGMENT+level);
Template openTemplate = getOptionalFragment(OPEN_FOLDER_FRAGMENT+level);
Template closedTemplate = getOptionalFragment(CLOSED_FOLDER_FRAGMENT+level);
if ( headerTemplate != null ) headerTemplate.evaluate(buffer, parameter);
for ( int i = 0; i < idArray.length; i++ ) {
if ( inputArray[i] instanceof MapValue ) {
parameter.putAll(((MapValue)inputArray[i]).getMap());
}
if ( inputArray[i] instanceof ArrayValue ) {
// Array resources can only follow StringResources that indicate the folders name
if ( ( active.length <= level || active[level] == i)) {
buffer.append(process(parameter, ((ArrayValue)idArray[i]).getArray(), ((ArrayValue)inputArray[i]).getArray(), active, level+1, context));
}
} else if ( i < idArray.length-1 && idArray[i+1] instanceof ArrayValue && openTemplate != null && (active.length <= level || active[level] == i)) {
openTemplate.evaluate(buffer, parameter);
} else if ( i < idArray.length-1 && idArray[i+1] instanceof ArrayValue && closedTemplate != null ) {
closedTemplate.evaluate(buffer, parameter);
} else if ( level == active.length-1 && i == active[level] && activeTemplate != null ) {
activeTemplate.evaluate(buffer, parameter);
} else if ( i == 0 && firstTemplate != null ) {
firstTemplate.evaluate(buffer, parameter);
} else if ( i == idArray.length-1 && lastTemplate != null ) {
lastTemplate.evaluate(buffer, parameter);
} else if ( evenTemplate != null && i%2 == 0 ) {
evenTemplate.evaluate(buffer, parameter);
} else if ( defaultTemplate != null ) {
defaultTemplate.evaluate(buffer, parameter);
}
}
if ( footerTemplate != null ) footerTemplate.evaluate(buffer, parameter);
return buffer.toString();
}
public ParameterDescriptor[] getParameterDescriptors() {
return parameterDescriptors;
}
}