package com.google.sitebricks.rendering.control;
import com.google.inject.Inject;
import com.google.sitebricks.Evaluator;
import com.google.sitebricks.Renderable;
import com.google.sitebricks.Respond;
import com.google.sitebricks.compiler.Parsing;
import com.google.sitebricks.conversion.TypeConverter;
import com.google.sitebricks.rendering.EmbedAs;
import net.jcip.annotations.Immutable;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* @author Dhanji R. Prasanna (dhanji@gmail.com)
*/
@Immutable
@EmbedAs("Repeat")
class RepeatWidget implements Renderable {
private final WidgetChain widgetChain;
private final String items;
private final String var;
private final String pageVar;
private final Evaluator evaluator;
private TypeConverter converter;
private static final String DEFAULT_PAGEVAR = "__page";
private static final String DEFAULT_VAR = "__this";
public RepeatWidget(WidgetChain widgetChain, String expression, Evaluator evaluator) {
this.widgetChain = widgetChain;
final Map<String,String> map = Parsing.toBindMap(expression);
this.items = map.get("items");
String var = map.get("var");
if (null != var)
this.var = Parsing.stripQuotes(var);
else
this.var = DEFAULT_VAR;
//by default the page comes in as __page
String pageVar = map.get("pageVar");
if (null == pageVar)
pageVar = DEFAULT_PAGEVAR;
else
pageVar = Parsing.stripQuotes(pageVar);
this.pageVar = pageVar;
this.evaluator = evaluator;
}
@Inject
public void setConverter(TypeConverter converter)
{
this.converter = converter;
}
public void render(Object bound, Respond respond) {
Object value = evaluator.evaluate(items, bound);
//do nothing if the collection is unavailable for some reason
if (null == value)
return;
Collection<?> items = converter.convert(value, Collection.class);
Map<String, Object> context = new HashMap<String, Object>();
//set up context variables
int i = 0;
for (Object thing : items) {
//decorate with some context
context.put(var, thing);
context.put(pageVar, respond.pageObject());
context.put("index", i++);
context.put("isLast", i == items.size());
widgetChain.render(context, respond);
}
}
public <T extends Renderable> Set<T> collect(Class<T> clazz) {
return widgetChain.collect(clazz);
}
}