001/*
002 *  Copyright 2010 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.plugins.repository.query.expression;
017
018import org.ametys.plugins.repository.RepositoryConstants;
019
020/**
021 * Constructs an {@link Expression} corresponding to the String comparison with a metadata of type MULTILANGUAL.
022 */
023public class MultilingualStringExpression implements Expression
024{
025    private String _value;
026    private MetadataExpression _metadata;
027    private Operator _operator;
028    private boolean _caseInsensitive; 
029    private String _lang;
030    
031    /**
032     * Creates the comparison Expression.
033     * @param metadata the metadata name
034     * @param operator the operator to make the comparison
035     * @param value the String value
036     * @param lang the language code
037     */
038    public MultilingualStringExpression(String metadata, Operator operator, String value, String lang)
039    {
040        _value = value;
041        _operator = operator;
042        _metadata = new MetadataExpression(metadata);
043        _caseInsensitive = false;
044        _lang = lang;
045
046    }
047    
048    /**
049     * Creates the comparison Expression.
050     * @param metadata the metadata name
051     * @param operator the operator to make the comparison
052     * @param value the String value
053     * @param lang the language code
054     * @param context the expression context
055     */
056    public MultilingualStringExpression(String metadata, Operator operator, String value, String lang, ExpressionContext context)
057    {
058        _value = value;
059        _operator = operator;
060        _metadata = new MetadataExpression(metadata, context);
061        _caseInsensitive = context.caseInsensitive();
062        _lang = lang;
063    }
064    
065    public String build()
066    {
067        if (_operator.equals(Operator.WD))
068        {
069            if (_caseInsensitive)
070            {
071                return "jcr:like(fn:lower-case(" + _multilingualPath() + "), '%" + _escapeValue(_value.toLowerCase()) + "%')";
072            }
073            else
074            {
075                return "jcr:like(" + _multilingualPath() + ", '%" + _escapeValue(_value) + "%')";
076            }
077        }
078        else
079        {
080            if (_caseInsensitive)
081            {
082                return "fn:lower-case(" + _multilingualPath() + ") " + _operator + " '" + _value.toLowerCase().replaceAll("'", "''") + "'";
083            }
084            else
085            {
086                return _multilingualPath()  + " " + _operator + " '" + _value.replaceAll("'", "''") + "'";
087            }
088        }
089    }
090
091    private String _escapeValue(String value)
092    {
093        // First escape ' - " \ _ and %, Then escape ' into '' for XQuery compliance
094        return value.replaceAll("(['\\-_\"\\\\%])", "\\\\$1").replaceAll("'", "''");
095    }
096    
097    private String _multilingualPath()
098    {
099        return _metadata.build() + "/" + RepositoryConstants.NAMESPACE_PREFIX + ":" +  _lang;
100    }
101}