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: ValueExpressionHelper.java 28460 2008-01-03 15:34:05Z sfermigier $
018 */
019
020package org.nuxeo.ecm.platform.forms.layout.facelets;
021
022import java.util.ArrayList;
023import java.util.List;
024
025import org.apache.commons.lang.StringUtils;
026import org.nuxeo.ecm.platform.el.DocumentModelResolver;
027import org.nuxeo.ecm.platform.forms.layout.api.FieldDefinition;
028import org.nuxeo.ecm.platform.ui.web.util.ComponentTagUtils;
029
030/**
031 * Helper for managing value expressions.
032 *
033 * @author <a href="mailto:at@nuxeo.com">Anahide Tchertchian</a>
034 */
035public class ValueExpressionHelper {
036
037    private ValueExpressionHelper() {
038    }
039
040    /**
041     * Returns true if given expression contains some special characters, in which case no transformation of the widget
042     * field definition will be done to make it compliant with {@link DocumentModelResolver} lookups when handling
043     * document fields. Special characters are:
044     * <ul>
045     * <li>".": this makes it possible to resolve subelements, for instance "myfield.mysubfield".</li>
046     * <li>"[": this makes it possible to include map or array sub elements, for instance
047     * "contextData['request/comment']" to fill a document model context map.</li>
048     * </ul>
049     *
050     * @throws NullPointerException if expression is null
051     */
052    public static boolean isFormattedAsELExpression(String expression) {
053        if (expression.contains(".") || expression.contains("[")) {
054            return true;
055        }
056        return false;
057    }
058
059    /**
060     * Returns the value expression string representation without the surrounding brackets, for instance:
061     * "value.property" instead of #{value.property}.
062     */
063    public static String createBareExpressionString(String valueName, FieldDefinition field) {
064        if (field == null || "".equals(field.getPropertyName())) {
065            return valueName;
066        }
067
068        String fieldName = field.getFieldName();
069        if (ComponentTagUtils.isStrictValueReference(fieldName)) {
070            // already an EL expression => ignore schema name, do not resolve
071            // field, ignore previous expression elements
072            return ComponentTagUtils.getBareValueName(fieldName);
073        } else if (isFormattedAsELExpression(fieldName)) {
074            // already formatted as an EL expression => ignore schema name, do
075            // not resolve field and do not modify expression format
076            String format = "%s.%s";
077            if (fieldName.startsWith(".") || fieldName.startsWith("[")) {
078                format = "%s%s";
079            }
080            return String.format(format, valueName, fieldName);
081        } else {
082            List<String> expressionElements = new ArrayList<String>();
083            expressionElements.add(valueName);
084
085            // try to resolve schema name/prefix
086            String schemaName = field.getSchemaName();
087            if (schemaName == null) {
088                String propertyName = field.getFieldName();
089                String[] s = propertyName.split(":");
090                if (s.length == 2) {
091                    schemaName = s[0];
092                    fieldName = s[1];
093                }
094            }
095
096            if (schemaName != null) {
097                expressionElements.add(String.format("['%s']", schemaName));
098            }
099
100            // handle xpath expressions
101            String[] splittedFieldName = fieldName.split("/");
102            for (String item : splittedFieldName) {
103                try {
104                    expressionElements.add(String.format("[%s]", Integer.valueOf(Integer.parseInt(item))));
105                } catch (NumberFormatException e) {
106                    expressionElements.add(String.format("['%s']", item));
107                }
108            }
109
110            return StringUtils.join(expressionElements, "");
111        }
112    }
113
114    public static String createExpressionString(String valueName, FieldDefinition field) {
115        String bareExpression = createBareExpressionString(valueName, field);
116        return String.format("#{%s}", bareExpression);
117    }
118
119}