All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.sitebricks.rendering.control.XmlWidget Maven / Gradle / Ivy

The newest version!
package com.google.sitebricks.rendering.control;

import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.sitebricks.Renderable;
import com.google.sitebricks.Respond;
import com.google.sitebricks.compiler.EvaluatorCompiler;
import com.google.sitebricks.compiler.ExpressionCompileException;
import com.google.sitebricks.compiler.Token;
import com.google.sitebricks.headless.Request;
import com.google.sitebricks.rendering.Attributes;
import com.google.sitebricks.rendering.SelfRendering;
import net.jcip.annotations.ThreadSafe;

import java.util.*;

/**
 * 

Widget renders an XML-like tag

* * @author Dhanji R. Prasanna ([email protected]) */ @ThreadSafe @SelfRendering class XmlWidget implements Renderable { private final WidgetChain widgetChain; private final boolean selfClosed; private final String name; private final Map> attributes; // HACK Extremely ouch! Replace with Assisted inject. private static volatile Provider request; private static final Set CONTEXTUAL_ATTRIBS; static { Set set = new HashSet(); set.add("href"); set.add("action"); set.add("src"); CONTEXTUAL_ATTRIBS = Collections.unmodifiableSet(set); } XmlWidget(WidgetChain widgetChain, String name, EvaluatorCompiler compiler, @Attributes Map attributes) throws ExpressionCompileException { this.widgetChain = widgetChain; this.name = name; this.attributes = Collections.unmodifiableMap(compile(attributes, compiler)); //hacky. Script tags should not be self-closed due to IE insanity. this.selfClosed = widgetChain instanceof TerminalWidgetChain && !"script".equalsIgnoreCase(name); } //compiles a map of name:value attrs into a map of name:token renderables static Map> compile(Map attributes, EvaluatorCompiler compiler) throws ExpressionCompileException { Map> map = new LinkedHashMap>(); for (Map.Entry attribute : attributes.entrySet()) { map.put(attribute.getKey(), compiler.tokenizeAndCompile(attribute.getValue())); } return map; } public void render(Object bound, Respond respond) { writeOpenTag(bound, respond, name, attributes); //write children if (selfClosed) { respond.write("/>"); //write self-closed tag } else { respond.write('>'); widgetChain.render(bound, respond); //close tag respond.write("'); } } static void writeOpenTag(Object bound, Respond respond, String name, Map> attributes) { respond.write('<'); respond.write(name); respond.write(' '); //write attributes for (Map.Entry> attribute : attributes.entrySet()) { respond.write(attribute.getKey()); respond.write("=\""); final List tokenList = attribute.getValue(); for (int i = 0; i < tokenList.size(); i++) { Token token = tokenList.get(i); if (token.isExpression()) { respond.write(token.render(bound)); } else { respond.write( contextualizeIfNeeded(attribute.getKey(), (0 == i), token.render(bound))); } } respond.write("\" "); } respond.chew(); } private static String contextualizeIfNeeded(String attribute, boolean isFirstToken, String raw) { if (isFirstToken && CONTEXTUAL_ATTRIBS.contains(attribute)) { //add context to path if needed if (raw.startsWith("/")) raw = request.get().context() + raw; } return raw; } public Set collect(Class clazz) { return widgetChain.collect(clazz); } @Inject public void setRequestProvider(Provider requestProvider) { XmlWidget.request = requestProvider; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy