001/* 002 * (C) Copyright 2006-2007 Nuxeo SAS (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * <a href="mailto:at@nuxeo.com">Anahide Tchertchian</a> 016 * 017 * $Id: LayoutRowTagHandler.java 30553 2008-02-24 15:51:31Z atchertchian $ 018 */ 019 020package org.nuxeo.ecm.platform.forms.layout.facelets; 021 022import java.io.IOException; 023import java.util.ArrayList; 024import java.util.HashMap; 025import java.util.List; 026import java.util.Map; 027 028import javax.el.ELException; 029import javax.el.ValueExpression; 030import javax.faces.FacesException; 031import javax.faces.component.UIComponent; 032import javax.faces.view.facelets.FaceletContext; 033import javax.faces.view.facelets.FaceletHandler; 034import javax.faces.view.facelets.TagAttribute; 035import javax.faces.view.facelets.TagConfig; 036import javax.faces.view.facelets.TagHandler; 037 038import org.apache.commons.logging.Log; 039import org.apache.commons.logging.LogFactory; 040import org.nuxeo.ecm.platform.forms.layout.api.Layout; 041import org.nuxeo.ecm.platform.forms.layout.api.LayoutRow; 042 043/** 044 * Layout row recursion tag handler. 045 * <p> 046 * Iterate over the layout rows and apply next handlers as many times as needed. 047 * <p> 048 * Only works when used inside a tag using the {@link LayoutTagHandler} template client. 049 * 050 * @author <a href="mailto:at@nuxeo.com">Anahide Tchertchian</a> 051 */ 052public class LayoutRowTagHandler extends TagHandler { 053 054 private static final Log log = LogFactory.getLog(LayoutRowTagHandler.class); 055 056 protected final TagConfig config; 057 058 public LayoutRowTagHandler(TagConfig config) { 059 super(config); 060 this.config = config; 061 } 062 063 /** 064 * For each row in layout, exposes row variables and applies next handler. 065 * <p> 066 * Needs layout to be exposed in context, so works in conjunction with {@link LayoutTagHandler}. 067 * <p> 068 * Row variables exposed: {@link RenderVariables.rowVariables#layoutRow} and 069 * {@link RenderVariables.rowVariables#layoutRowIndex}, as well as 070 * {@link RenderVariables.columnVariables#layoutColumn} and 071 * {@link RenderVariables.columnVariables#layoutColumnIndex}, that act are aliases. 072 */ 073 public void apply(FaceletContext ctx, UIComponent parent) throws IOException, FacesException, ELException { 074 // resolve rows from layout in context 075 Layout layout = null; 076 String layoutVariableName = RenderVariables.layoutVariables.layout.name(); 077 FaceletHandlerHelper helper = new FaceletHandlerHelper(ctx, config); 078 TagAttribute layoutAttribute = helper.createAttribute(layoutVariableName, 079 String.format("#{%s}", layoutVariableName)); 080 if (layoutAttribute != null) { 081 layout = (Layout) layoutAttribute.getObject(ctx, Layout.class); 082 } 083 if (layout == null) { 084 log.error("Could not resolve layout " + layoutAttribute); 085 return; 086 } 087 088 LayoutRow[] rows = layout.getRows(); 089 if (rows == null || rows.length == 0) { 090 return; 091 } 092 093 int rowCounter = 0; 094 for (LayoutRow row : rows) { 095 // expose row variables 096 Map<String, ValueExpression> variables = new HashMap<String, ValueExpression>(); 097 ValueExpression rowVe = ctx.getExpressionFactory().createValueExpression(row, LayoutRow.class); 098 variables.put(RenderVariables.rowVariables.layoutRow.name(), rowVe); 099 variables.put(RenderVariables.columnVariables.layoutColumn.name(), rowVe); 100 ValueExpression rowIndexVe = ctx.getExpressionFactory().createValueExpression(Integer.valueOf(rowCounter), 101 Integer.class); 102 variables.put(RenderVariables.rowVariables.layoutRowIndex.name(), rowIndexVe); 103 variables.put(RenderVariables.columnVariables.layoutColumnIndex.name(), rowIndexVe); 104 105 List<String> blockedPatterns = new ArrayList<String>(); 106 blockedPatterns.add(RenderVariables.rowVariables.layoutRow.name()); 107 blockedPatterns.add(RenderVariables.rowVariables.layoutRowIndex.name()); 108 blockedPatterns.add(RenderVariables.columnVariables.layoutColumn.name()); 109 blockedPatterns.add(RenderVariables.columnVariables.layoutColumnIndex.name()); 110 111 FaceletHandler handler = helper.getAliasTagHandler(row.getTagConfigId(), variables, blockedPatterns, 112 nextHandler); 113 handler.apply(ctx, parent); 114 rowCounter++; 115 } 116 } 117}