package com.google.sitebricks.rendering.control;
import com.google.inject.Inject;
import com.google.inject.Provider;
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.headless.Request;
import com.google.sitebricks.routing.PageBook;
import net.jcip.annotations.Immutable;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
/**
* @author Dhanji R. Prasanna (dhanji@gmail.com)
*/
@Immutable
class EmbedWidget implements Renderable {
private final Map<String, String> bindExpressions;
private final Map<String, ArgumentWidget> arguments;
private final Evaluator evaluator;
private final PageBook pageBook;
private final String targetPage;
private EmbeddedRespondFactory factory;
private Provider<Request> request;
public EmbedWidget(Map<String, ArgumentWidget> arguments, String expression,
Evaluator evaluator, PageBook pageBook, String targetPage) {
this.arguments = arguments;
this.evaluator = evaluator;
this.pageBook = pageBook;
this.targetPage = targetPage.toLowerCase();
//parse expression list
this.bindExpressions = Parsing.toBindMap(expression);
}
public void render(Object bound, Respond respond) {
PageBook.Page page = pageBook.forName(targetPage);
//create an instance of the embedded page
Object pageObject = page.instantiate();
//bind parameters to it as necessary
for (Map.Entry<String, String> entry : bindExpressions.entrySet()) {
evaluator.write(entry.getKey(), pageObject, evaluator.evaluate(entry.getValue(), bound));
}
//chain to embedded page (widget), with arguments
EmbeddedRespond embed = factory.get(arguments);
Request req = request.get();
try {
page.doMethod(req.method(), pageObject, "", req);
} catch (IOException e) {
throw new RuntimeException(e);
}
page.widget().render(pageObject, embed);
//extract and write embedded response to enclosing page's respond
respond.writeToHead(embed.toHeadString()); //TODO only write @Require tags
respond.write(embed.toString());
embed.clear();
}
public <T extends Renderable> Set<T> collect(Class<T> clazz) {
return Collections.emptySet();
}
@Inject
public void init(EmbeddedRespondFactory factory, Provider<Request> request) {
this.factory = factory;
this.request = request;
}
}