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: DocumentLayoutTagHandler.java 26053 2007-10-16 01:45:43Z atchertchian $ 018 */ 019 020package org.nuxeo.ecm.platform.forms.layout.facelets; 021 022import java.io.IOException; 023import java.util.ArrayList; 024import java.util.Arrays; 025import java.util.List; 026 027import javax.el.ELException; 028import javax.faces.FacesException; 029import javax.faces.component.UIComponent; 030import javax.faces.view.facelets.CompositeFaceletHandler; 031import javax.faces.view.facelets.FaceletContext; 032import javax.faces.view.facelets.FaceletHandler; 033import javax.faces.view.facelets.TagAttribute; 034import javax.faces.view.facelets.TagAttributes; 035import javax.faces.view.facelets.TagConfig; 036import javax.faces.view.facelets.TagHandler; 037 038import org.apache.commons.lang.StringUtils; 039import org.apache.commons.logging.Log; 040import org.apache.commons.logging.LogFactory; 041import org.nuxeo.ecm.core.api.DocumentModel; 042import org.nuxeo.ecm.platform.forms.layout.api.BuiltinModes; 043import org.nuxeo.ecm.platform.types.adapter.TypeInfo; 044import org.nuxeo.ecm.platform.ui.web.tag.handler.TagConfigFactory; 045 046/** 047 * Document layout tag handler. 048 * <p> 049 * Computes layouts in given facelet context, for given mode and document attributes. 050 * <p> 051 * Document must be resolved at the component tree construction so it cannot be bound to an iteration value. 052 * 053 * @author <a href="mailto:at@nuxeo.com">Anahide Tchertchian</a> 054 */ 055public class DocumentLayoutTagHandler extends TagHandler { 056 057 @SuppressWarnings("unused") 058 private static final Log log = LogFactory.getLog(DocumentLayoutTagHandler.class); 059 060 protected final TagConfig config; 061 062 protected final TagAttribute mode; 063 064 protected final TagAttribute documentMode; 065 066 protected final TagAttribute documentModeFallback; 067 068 protected final TagAttribute value; 069 070 protected final TagAttribute template; 071 072 /** 073 * @since 5.4.2 074 */ 075 protected final TagAttribute defaultLayout; 076 077 /** 078 * @since 5.4.2 079 */ 080 protected final TagAttribute includeAnyMode; 081 082 protected final TagAttribute[] vars; 083 084 protected final String[] reservedVarsArray = { "id", "name", "mode", "documentMode", "value", "template", 085 "defaultLayout", "includeAnyMode" }; 086 087 public DocumentLayoutTagHandler(TagConfig config) { 088 super(config); 089 this.config = config; 090 mode = getRequiredAttribute("mode"); 091 documentMode = getAttribute("documentMode"); 092 documentModeFallback = getAttribute("documentModeFallback"); 093 value = getRequiredAttribute("value"); 094 template = getAttribute("template"); 095 defaultLayout = getAttribute("defaultLayout"); 096 includeAnyMode = getAttribute("includeAnyMode"); 097 vars = tag.getAttributes().getAll(); 098 } 099 100 /** 101 * If resolved document has layouts, apply each of them. 102 */ 103 public void apply(FaceletContext ctx, UIComponent parent) throws IOException, FacesException, ELException { 104 Object document = value.getObject(ctx, DocumentModel.class); 105 if (!(document instanceof DocumentModel)) { 106 return; 107 } 108 109 TypeInfo typeInfo = ((DocumentModel) document).getAdapter(TypeInfo.class); 110 if (typeInfo == null) { 111 return; 112 } 113 String modeValue = mode.getValue(ctx); 114 String documentModeValue = null; 115 if (documentMode != null) { 116 documentModeValue = documentMode.getValue(ctx); 117 } 118 String documentModeFallbackValue = null; 119 if (documentModeFallback != null) { 120 documentModeFallbackValue = documentModeFallback.getValue(ctx); 121 } 122 boolean useAnyMode = true; 123 if (includeAnyMode != null) { 124 useAnyMode = includeAnyMode.getBoolean(ctx); 125 } 126 String defaultMode = documentModeFallbackValue; 127 if (StringUtils.isBlank(defaultMode) && useAnyMode) { 128 defaultMode = BuiltinModes.ANY; 129 } 130 String[] layoutNames = typeInfo.getLayouts(documentModeValue == null ? modeValue : documentModeValue, 131 defaultMode); 132 if (layoutNames == null || layoutNames.length == 0) { 133 // fallback on default layout 134 if (defaultLayout != null) { 135 layoutNames = new String[] { defaultLayout.getValue() }; 136 } else { 137 // no layout => do nothing 138 return; 139 } 140 } 141 142 FaceletHandlerHelper helper = new FaceletHandlerHelper(ctx, config); 143 TagAttribute modeAttr = helper.createAttribute("mode", modeValue); 144 List<FaceletHandler> handlers = new ArrayList<FaceletHandler>(); 145 FaceletHandler leaf = nextHandler; 146 for (String layoutName : layoutNames) { 147 TagAttributes attributes = FaceletHandlerHelper.getTagAttributes( 148 helper.createAttribute("name", layoutName), modeAttr, value); 149 if (template != null) { 150 attributes = FaceletHandlerHelper.addTagAttribute(attributes, template); 151 } 152 // add other variables put on original tag 153 List<String> reservedVars = Arrays.asList(reservedVarsArray); 154 for (TagAttribute var : vars) { 155 String localName = var.getLocalName(); 156 if (!reservedVars.contains(localName)) { 157 attributes = FaceletHandlerHelper.addTagAttribute(attributes, var); 158 } 159 } 160 TagConfig tagConfig = TagConfigFactory.createTagConfig(config, null, attributes, leaf); 161 handlers.add(new LayoutTagHandler(tagConfig)); 162 } 163 CompositeFaceletHandler composite = new CompositeFaceletHandler(handlers.toArray(new FaceletHandler[0])); 164 composite.apply(ctx, parent); 165 } 166}