001/*
002 * (C) Copyright 2013 Nuxeo SA (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 *     Anahide Tchertchian
016 */
017package org.nuxeo.ecm.platform.ui.web.tag.jsf;
018
019import javax.el.ValueExpression;
020import javax.faces.component.UIComponent;
021import javax.faces.component.ValueHolder;
022import javax.faces.view.facelets.FaceletContext;
023import javax.faces.view.facelets.MetaRule;
024import javax.faces.view.facelets.Metadata;
025import javax.faces.view.facelets.MetadataTarget;
026import javax.faces.view.facelets.TagAttribute;
027
028import org.nuxeo.ecm.platform.ui.web.binding.DefaultValueExpression;
029import org.nuxeo.ecm.platform.ui.web.tag.handler.GenericHtmlComponentHandler;
030
031/**
032 * Value holder rule, handling a default value using a {@link DefaultValueExpression} when a "defaultValue" attribute is
033 * set on the tag.
034 * <p>
035 * Assumes the standard value holder rule has already been processed, so that the corresponding value expression is
036 * already available on the component.
037 *
038 * @since 5.7.3
039 * @deprecated since 7.2: since this is a mixup between several attributes, this is not handled by rules anymore, see
040 *             {@link GenericHtmlComponentHandler#onComponentCreated(FaceletContext, UIComponent, UIComponent)}
041 */
042public class DefaultValueHolderRule extends MetaRule {
043
044    public static final DefaultValueHolderRule Instance = new DefaultValueHolderRule();
045
046    static final class LiteralValueMetadata extends Metadata {
047
048        private final String value;
049
050        LiteralValueMetadata(String value) {
051            this.value = value;
052        }
053
054        @Override
055        public void applyMetadata(FaceletContext ctx, Object instance) {
056            ((ValueHolder) instance).setValue(value);
057        }
058    }
059
060    static final class DynamicDefaultValueExpressionMetadata extends Metadata {
061
062        private final TagAttribute attr;
063
064        DynamicDefaultValueExpressionMetadata(TagAttribute attr) {
065            this.attr = attr;
066        }
067
068        @Override
069        public void applyMetadata(FaceletContext ctx, Object instance) {
070            UIComponent comp = (UIComponent) instance;
071            ValueExpression defaultVe = attr.getValueExpression(ctx, Object.class);
072            ValueExpression ve = comp.getValueExpression("value");
073            comp.setValueExpression("value", new DefaultValueExpression(ve, defaultVe));
074        }
075    }
076
077    @Override
078    public Metadata applyRule(String name, TagAttribute attribute, MetadataTarget meta) {
079        if (meta.isTargetInstanceOf(ValueHolder.class)) {
080
081            if ("defaultValue".equals(name)) {
082                if (attribute.isLiteral()) {
083                    return new LiteralValueMetadata(attribute.getValue());
084                } else {
085                    return new DynamicDefaultValueExpressionMetadata(attribute);
086                }
087            }
088
089        }
090        return null;
091    }
092
093}