Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

DecorateAll handler

  • Loading branch information...
commit 117512002720da7a51dcc9371821e75508bf8481 1 parent c8921d6
Phil Webb authored
13 ...e/src/main/java/org/springframework/springfaces/showcase/message/template/TemplateExampleController.java
View
@@ -0,0 +1,13 @@
+package org.springframework.springfaces.showcase.message.template;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+@Controller
+public class TemplateExampleController {
+
+ @RequestMapping("/template/decorateall")
+ public void simple() {
+ }
+
+}
48 springfaces-samples/springfaces-showcase/src/main/webapp/WEB-INF/pages/template/decorateall.xhtml
View
@@ -0,0 +1,48 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<ui:composition xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:util="http://java.sun.com/jsf/composite/components/util"
+ xmlns:s="http://www.springframework.org/tags/springfaces">
+
+ <h:head>
+ <title>Templates - Decorate All</title>
+ </h:head>
+
+ <h:body>
+ <h:form id="form">
+
+ <s:decorateAll template="decoratetemplate.xhtml">
+
+ <h:outputText id="otext" value="d1" />
+
+ <h:inputText id="itext" required="true"/>
+ <ui:param name="test" value="test" />
+ <ui:define name="help">
+ <h:outputText value="Help is here" />
+ </ui:define>
+
+ <h:panelGrid id="pg">
+ <p>Hello</p>
+ <div>test</div>
+ </h:panelGrid>
+ </s:decorateAll>
+
+ <ui:decorate template="decoratetemplate.xhtml">
+ <h:outputText id="d1" value="d1" />
+ <ui:define name="help">
+ <h:outputText value="Help is here" />
+ </ui:define>
+ </ui:decorate>
+
+ <ui:decorate template="decoratetemplate.xhtml">
+ <h:inputText id="d2" />
+ </ui:decorate>
+ </h:form>
+ </h:body>
+</ui:composition>
+
+
+
51 springfaces-samples/springfaces-showcase/src/main/webapp/WEB-INF/pages/template/decoratetemplate.xhtml
View
@@ -0,0 +1,51 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<ui:composition xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:util="http://java.sun.com/jsf/composite/components/util"
+ xmlns:s="http://www.springframework.org/tags/springfaces">
+
+ <h:body>
+ <ui:composition>
+
+ <!--
+ <s:componentInfo var="componentInfo" from="childrenOf">
+ <ui:param name="concattest" value="#{thecomponent.id}label"/>
+ <h:outputLabel styleClass="control-label" for="#{component.id}" value="#{message[component.id]}"/>
+ <ui:insert/>
+ </s:componentInfo>
+ -->
+
+ <div style="border: solid 1px red">
+
+<!--
+ <h:panelGroup styleClass="control-group">
+ <h:outputLabel styleClass="control-label" for="#{component.id}" value="#{message[component.id]}"/>
+ <ui:insert/>
+ <ui:insert name="afterComponent"/>
+ </h:panelGroup>
+-->
+
+
+ <p>
+ [
+ <h:panelGroup>
+ <ui:insert />
+ </h:panelGroup>
+ ]
+ </p>
+ <p>
+ <ui:insert name="help"/>
+ </p>
+ <p>
+ <h:outputText value="#{test}"/>
+ </p>
+ </div>
+ </ui:composition>
+ </h:body>
+</ui:composition>
+
+
+
106 springfaces/src/main/java/org/springframework/springfaces/template/facelets/DecorateAllHandler.java
View
@@ -0,0 +1,106 @@
+package org.springframework.springfaces.template.facelets;
+
+import java.io.IOException;
+import java.util.LinkedList;
+
+import javax.faces.component.UIComponent;
+import javax.faces.view.facelets.CompositeFaceletHandler;
+import javax.faces.view.facelets.FaceletContext;
+import javax.faces.view.facelets.FaceletHandler;
+import javax.faces.view.facelets.TagAttribute;
+import javax.faces.view.facelets.TagAttributeException;
+import javax.faces.view.facelets.TagConfig;
+import javax.faces.view.facelets.TagHandler;
+
+/**
+ * A {@link TagHandler} to support the <tt>s:decorateAll</tt> tag. Provides a drop-in replacement for
+ * <tt>ui:decorate</tt> that apply decoration against all children. Nested <tt>ui:param</tt> and <tt>ui:declare</tt>
+ * will be grouped with the component immediately above the element. This tag is particularly useful when writing HTML
+ * form templates.
+ *
+ * @see MojarraDecorateAllChildHandler
+ * @see MyFacesDecorateAllChildHandler
+ *
+ * @author Phillip Webb
+ */
+public class DecorateAllHandler extends TagHandler {
+
+ /**
+ * The template used to decorate children.
+ */
+ private TagAttribute template;
+
+ /**
+ * Child handlers that the decoration will be applied to.
+ */
+ private LinkedList<ChildHandler> childHandlers;
+
+ public DecorateAllHandler(TagConfig config) {
+ super(config);
+ this.template = this.getRequiredAttribute("template");
+ this.childHandlers = new LinkedList<ChildHandler>();
+ FaceletHandler[] handlers = getHandlers(this.nextHandler);
+ for (FaceletHandler handler : handlers) {
+ if (this.childHandlers.size() > 0 && this.childHandlers.getLast().canAdd(handler)) {
+ this.childHandlers.getLast().add(handler);
+ } else {
+ this.childHandlers.add(newChildHandler(handler));
+ }
+ }
+ }
+
+ private FaceletHandler[] getHandlers(FaceletHandler handler) {
+ if (this.nextHandler instanceof CompositeFaceletHandler) {
+ return ((CompositeFaceletHandler) this.nextHandler).getHandlers();
+ }
+ return new FaceletHandler[] { this.nextHandler };
+ }
+
+ private ChildHandler newChildHandler(FaceletHandler handler) {
+ return new MojarraDecorateAllChildHandler(handler);
+ }
+
+ public void apply(FaceletContext ctx, UIComponent parent) throws IOException {
+ String templatePath = this.template.getValue(ctx);
+ for (ChildHandler childHandler : this.childHandlers) {
+ try {
+ childHandler.apply(ctx, parent, templatePath);
+ } catch (IOException e) {
+ throw new TagAttributeException(this.tag, this.template, "Invalid path : " + templatePath);
+ }
+ }
+ }
+
+ /**
+ * Represents a single child handler to be decorated. Allows for JSF specific implementations (MyFaces, Mojarra).
+ */
+ static interface ChildHandler {
+
+ /**
+ * Returns if the specified handler should be {@link #add(FaceletHandler) added} to this child handler.
+ * @param handler the handler to consider
+ * @return <tt>true</tt> if the handler should be added to this child or <tt>false</tt> if a new
+ * {@link ChildHandler} should be created.
+ * @see #add(FaceletHandler)
+ */
+ boolean canAdd(FaceletHandler handler);
+
+ /**
+ * Add the specified handler to this child. This method will be called only when {@link #canAdd(FaceletHandler)}
+ * returns <tt>true</tt>
+ * @param handler the handler to add
+ * @see #canAdd(FaceletHandler)
+ */
+ void add(FaceletHandler handler);
+
+ /**
+ * Apply the decoration to this child.
+ * @param ctx the facelet context
+ * @param parent the parent component
+ * @param templatePath the path of the template used to decorate the child
+ * @throws IOException
+ */
+ void apply(FaceletContext ctx, UIComponent parent, String templatePath) throws IOException;
+ }
+
+}
95 ...aces/src/main/java/org/springframework/springfaces/template/facelets/MojarraDecorateAllChildHandler.java
View
@@ -0,0 +1,95 @@
+package org.springframework.springfaces.template.facelets;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.el.VariableMapper;
+import javax.faces.component.UIComponent;
+import javax.faces.view.facelets.FaceletContext;
+import javax.faces.view.facelets.FaceletHandler;
+
+import org.springframework.springfaces.template.facelets.DecorateAllHandler.ChildHandler;
+
+import com.sun.faces.facelets.FaceletContextImplBase;
+import com.sun.faces.facelets.TemplateClient;
+import com.sun.faces.facelets.el.VariableMapperWrapper;
+import com.sun.faces.facelets.tag.ui.DefineHandler;
+import com.sun.faces.facelets.tag.ui.ParamHandler;
+
+/**
+ * A {@link DecorateAllHandler.ChildHandler} for Mojarra.
+ *
+ * @see DecorateAllHandler
+ * @author Phillip Webb
+ */
+class MojarraDecorateAllChildHandler implements ChildHandler {
+
+ private FaceletHandler handler;
+ private Map<Object, DefineHandler> defineHandlers = new HashMap<Object, DefineHandler>();
+ private List<ParamHandler> paramHandlers = new ArrayList<ParamHandler>();
+
+ public MojarraDecorateAllChildHandler(FaceletHandler handler) {
+ this.handler = handler;
+ }
+
+ public boolean canAdd(FaceletHandler handler) {
+ return (handler instanceof DefineHandler) || (handler instanceof ParamHandler);
+ }
+
+ public void add(FaceletHandler handler) {
+ if (handler instanceof DefineHandler) {
+ addDefineHandler((DefineHandler) handler);
+ }
+ if (handler instanceof ParamHandler) {
+ addParamHandler((ParamHandler) handler);
+ }
+ }
+
+ private void addDefineHandler(DefineHandler handler) {
+ this.defineHandlers.put(handler.getName(), handler);
+ }
+
+ private void addParamHandler(ParamHandler faceletHandler) {
+ this.paramHandlers.add(faceletHandler);
+ }
+
+ public void apply(FaceletContext ctx, final UIComponent parent, String templatePath) throws IOException {
+ FaceletContextImplBase faceletContextImpl = (FaceletContextImplBase) ctx;
+ VariableMapper originalVariableMapper = ctx.getVariableMapper();
+ if (this.paramHandlers != null) {
+ ctx.setVariableMapper(new VariableMapperWrapper(originalVariableMapper));
+ for (ParamHandler paramHandler : this.paramHandlers) {
+ paramHandler.apply(ctx, parent);
+ }
+ }
+ TemplateClient client = new TemplateClient() {
+ public boolean apply(FaceletContext ctx, UIComponent parent, String name) throws IOException {
+ return applyTemplate(ctx, parent, name);
+ }
+ };
+ faceletContextImpl.pushClient(client);
+ try {
+ ctx.includeFacelet(parent, templatePath);
+ } finally {
+ faceletContextImpl.popClient(client);
+ faceletContextImpl.setVariableMapper(originalVariableMapper);
+ }
+ }
+
+ private boolean applyTemplate(FaceletContext ctx, UIComponent parent, String name) throws IOException {
+ if (name == null) {
+ this.handler.apply(ctx, parent);
+ return true;
+ }
+ DefineHandler definedHandler = this.defineHandlers.get(name);
+ if (definedHandler != null) {
+ definedHandler.applyDefinition(ctx, parent);
+ return true;
+ }
+ return false;
+ }
+
+}
11 ...aces/src/main/java/org/springframework/springfaces/template/facelets/MyFacesDecorateAllChildHandler.java
View
@@ -0,0 +1,11 @@
+package org.springframework.springfaces.template.facelets;
+
+/**
+ * A {@link DecorateAllHandler.ChildHandler} for MyFaces.
+ *
+ * @see DecorateAllHandler
+ * @author Phillip Webb
+ */
+class MyFacesDecorateAllChildHandler {
+ // FIXME implement this
+}
5 springfaces/src/main/java/org/springframework/springfaces/template/ui/UIComponentInfo.java
View
@@ -0,0 +1,5 @@
+package org.springframework.springfaces.template.ui;
+
+public class UIComponentInfo {
+
+}
4 springfaces/src/main/resources/META-INF/springfaces.taglib.xml
View
@@ -38,4 +38,8 @@
<component-type>spring.faces.SelectItems</component-type>
</component>
</tag>
+ <tag>
+ <tag-name>decorateAll</tag-name>
+ <handler-class>org.springframework.springfaces.template.facelets.DecorateAllHandler</handler-class>
+ </tag>
</facelet-taglib>
Please sign in to comment.
Something went wrong with that request. Please try again.