001/* 002 * (C) Copyright 2006-2014 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-2.1.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: AbstractWidgetTypeHandler.java 28491 2008-01-04 19:04:30Z sfermigier $ 018 */ 019 020package org.nuxeo.ecm.platform.forms.layout.facelets.plugins; 021 022import java.util.ArrayList; 023import java.util.List; 024import java.util.Map; 025 026import javax.faces.view.facelets.CompositeFaceletHandler; 027import javax.faces.view.facelets.FaceletContext; 028import javax.faces.view.facelets.FaceletHandler; 029import javax.faces.view.facelets.TagAttribute; 030import javax.faces.view.facelets.TagAttributes; 031import javax.faces.view.facelets.TagConfig; 032import javax.faces.view.facelets.ValidatorHandler; 033 034import org.apache.commons.lang.StringUtils; 035import org.nuxeo.ecm.platform.forms.layout.api.BuiltinWidgetModes; 036import org.nuxeo.ecm.platform.forms.layout.api.Widget; 037import org.nuxeo.ecm.platform.forms.layout.api.exceptions.WidgetException; 038import org.nuxeo.ecm.platform.forms.layout.facelets.FaceletHandlerHelper; 039import org.nuxeo.ecm.platform.forms.layout.facelets.RenderVariables; 040import org.nuxeo.ecm.platform.forms.layout.facelets.WidgetTypeHandler; 041import org.nuxeo.ecm.platform.forms.layout.facelets.dev.WidgetTypeDevTagHandler; 042import org.nuxeo.ecm.platform.ui.web.tag.handler.LeafFaceletHandler; 043import org.nuxeo.ecm.platform.ui.web.tag.handler.TagConfigFactory; 044import org.nuxeo.ecm.platform.ui.web.validator.DocumentConstraintValidator; 045 046import com.sun.faces.facelets.tag.ui.InsertHandler; 047 048/** 049 * Abstract widget type handler. 050 * 051 * @author <a href="mailto:at@nuxeo.com">Anahide Tchertchian</a> 052 */ 053public abstract class AbstractWidgetTypeHandler implements WidgetTypeHandler { 054 055 private static final long serialVersionUID = -2933485416045771633L; 056 057 /** 058 * @since 6.0 059 */ 060 public static final String DEV_TEMPLATE_PROPERTY_NAME = "dev_template"; 061 062 /** 063 * @since 6.0 064 */ 065 public static final String DISABLE_DEV_PROPERTY_NAME = "disable_dev"; 066 067 protected Map<String, String> properties; 068 069 public abstract FaceletHandler getFaceletHandler(FaceletContext ctx, TagConfig tagConfig, Widget widget, 070 FaceletHandler[] subHandlers) throws WidgetException; 071 072 public FaceletHandler getDevFaceletHandler(FaceletContext ctx, TagConfig tagConfig, Widget widget) 073 throws WidgetException { 074 if (Boolean.parseBoolean(getProperty(DISABLE_DEV_PROPERTY_NAME)) 075 || Boolean.parseBoolean((String) widget.getProperty(DISABLE_DEV_PROPERTY_NAME))) { 076 return null; 077 } 078 // lookup in the widget type configuration 079 String template = (String) widget.getProperty(DEV_TEMPLATE_PROPERTY_NAME); 080 if (StringUtils.isBlank(template)) { 081 template = getProperty(DEV_TEMPLATE_PROPERTY_NAME); 082 } 083 FaceletHandlerHelper helper = new FaceletHandlerHelper(ctx, tagConfig); 084 TagAttribute widgetAttr = helper.createAttribute("widget", 085 String.format("#{%s}", RenderVariables.widgetVariables.widget.name())); 086 TagAttributes devWidgetAttributes; 087 if (StringUtils.isBlank(template)) { 088 devWidgetAttributes = FaceletHandlerHelper.getTagAttributes(widgetAttr); 089 } else { 090 devWidgetAttributes = FaceletHandlerHelper.getTagAttributes(widgetAttr, 091 helper.createAttribute("template", template)); 092 } 093 TagConfig devWidgetConfig = TagConfigFactory.createTagConfig(tagConfig, widget.getTagConfigId(), 094 devWidgetAttributes, new LeafFaceletHandler()); 095 return new WidgetTypeDevTagHandler(devWidgetConfig); 096 } 097 098 public String getProperty(String name) { 099 if (properties != null) { 100 return properties.get(name); 101 } 102 return null; 103 } 104 105 /** 106 * Helper method, throws an exception if property value is null. 107 */ 108 public String getRequiredProperty(String name) throws WidgetException { 109 String value = getProperty(name); 110 if (value == null) { 111 throw new WidgetException(String.format( 112 "Required property %s is missing " + "on widget type configuration", name)); 113 } 114 return value; 115 } 116 117 public void setProperties(Map<String, String> properties) { 118 this.properties = properties; 119 } 120 121 /** 122 * Returns sub handlers as computed from tag information. 123 * <p> 124 * Adds an sub insert handler slot named {@link RenderVariables.widgetTemplatingZones#inside_input_widget} when 125 * widget is in edit mode. 126 * <p> 127 * Adds an sub document constraint validator handler named {@link DocumentConstraintValidator#VALIDATOR_ID} when 128 * widget is in edit mode. 129 * <p> 130 * 131 * @since 6.0 132 */ 133 protected FaceletHandler getNextHandler(FaceletContext ctx, TagConfig tagConfig, Widget widget, 134 FaceletHandler[] subHandlers, FaceletHandlerHelper helper) { 135 boolean isEdit = BuiltinWidgetModes.EDIT.equals(widget.getMode()); 136 return getNextHandler(ctx, tagConfig, widget, subHandlers, helper, isEdit, isEdit); 137 } 138 139 /** 140 * Returns sub handlers as computed from tag information. 141 * <p> 142 * Adds an input slot if corresponding boolean parameter is true. 143 * 144 * @since 6.0 145 * @deprecated since 7.2, use 146 * {@link #getNextHandler(FaceletContext, TagConfig, Widget, FaceletHandler[], FaceletHandlerHelper, boolean, boolean)} 147 * instead 148 */ 149 protected FaceletHandler getNextHandler(FaceletContext ctx, TagConfig tagConfig, Widget widget, 150 FaceletHandler[] subHandlers, FaceletHandlerHelper helper, boolean addInputSlot) { 151 return getNextHandler(ctx, tagConfig, widget, subHandlers, helper, addInputSlot, false); 152 } 153 154 /** 155 * Returns sub handlers as computed from tag information. 156 * <p> 157 * Adds an input slot if corresponding boolean parameter is true. 158 * <p> 159 * Adds an document constraint validator if corresponding boolean parameter is true. 160 * 161 * @since 7.2 162 */ 163 protected FaceletHandler getNextHandler(FaceletContext ctx, TagConfig tagConfig, Widget widget, 164 FaceletHandler[] subHandlers, FaceletHandlerHelper helper, boolean addInputSlot, 165 boolean addDocumentConstraintValidator) { 166 FaceletHandler leaf; 167 List<FaceletHandler> handlers = new ArrayList<>(); 168 if (subHandlers != null && subHandlers.length > 0) { 169 for (FaceletHandler fh : subHandlers) { 170 if (fh != null && !(fh instanceof LeafFaceletHandler)) { 171 handlers.add(fh); 172 } 173 } 174 } 175 if (addInputSlot) { 176 FaceletHandler slot = getInputSlotHandler(ctx, tagConfig, widget, subHandlers, helper); 177 if (slot != null) { 178 handlers.add(slot); 179 } 180 } 181 if (addDocumentConstraintValidator) { 182 FaceletHandler v = getDocumentConstraintValidatorHandler(ctx, tagConfig, widget, subHandlers, helper); 183 if (v != null) { 184 handlers.add(v); 185 } 186 } 187 if (handlers.size() == 0) { 188 leaf = new LeafFaceletHandler(); 189 } else { 190 leaf = new CompositeFaceletHandler(handlers.toArray(new FaceletHandler[] {})); 191 } 192 return leaf; 193 } 194 195 protected FaceletHandler getInputSlotHandler(FaceletContext ctx, TagConfig tagConfig, Widget widget, 196 FaceletHandler[] subHandlers, FaceletHandlerHelper helper) { 197 TagConfig config = TagConfigFactory.createTagConfig(tagConfig, tagConfig.getTagId(), 198 FaceletHandlerHelper.getTagAttributes(helper.createAttribute("name", 199 RenderVariables.widgetTemplatingZones.inside_input_widget.name())), new LeafFaceletHandler()); 200 return new InsertHandler(config); 201 } 202 203 protected FaceletHandler getDocumentConstraintValidatorHandler(FaceletContext ctx, TagConfig tagConfig, 204 Widget widget, FaceletHandler[] subHandlers, FaceletHandlerHelper helper) { 205 // XXX maybe take into account control on widget to handle sub properties validation (or not) 206 ValidatorHandler validator = helper.getValidateHandler(tagConfig.getTagId(), 207 FaceletHandlerHelper.getTagAttributes(), new LeafFaceletHandler(), 208 DocumentConstraintValidator.VALIDATOR_ID); 209 return validator; 210 } 211 212}