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
018/**
019 * Constructs an {@link Expression} corresponding to the String comparison with a metadata.
020 */
021public class StringExpression implements Expression
022{
023    private String _value;
024    private MetadataExpression _metadata;
025    private Operator _operator;
026    private boolean _caseInsensitive; 
027    
028    /**
029     * Creates the comparison Expression.
030     * @param metadata the metadata name
031     * @param operator the operator to make the comparison
032     * @param value the String value
033     */
034    public StringExpression(String metadata, Operator operator, String value)
035    {
036        _value = value;
037        _operator = operator;
038        _metadata = new MetadataExpression(metadata);
039        _caseInsensitive = false;
040    }
041    
042    /**
043     * Creates the comparison Expression.
044     * @param metadata the metadata name
045     * @param operator the operator to make the comparison
046     * @param value the String value
047     * @param context the expression context
048     */
049    public StringExpression(String metadata, Operator operator, String value, ExpressionContext context)
050    {
051        _value = value;
052        _operator = operator;
053        _metadata = new MetadataExpression(metadata, context);
054        _caseInsensitive = context.caseInsensitive();
055    }
056    
057    public String build()
058    {
059        if (_operator.equals(Operator.WD))
060        {
061            if (_caseInsensitive)
062            {
063                return "jcr:like(fn:lower-case(" + _metadata.build() + "), '%" + _escapeValue(_value.toLowerCase()) + "%')";
064            }
065            else
066            {
067                return "jcr:like(" + _metadata.build() + ", '%" + _escapeValue(_value) + "%')";
068            }
069        }
070        else
071        {
072            if (_caseInsensitive)
073            {
074                return "fn:lower-case(" + _metadata.build() + ") " + _operator + " '" + _value.toLowerCase().replaceAll("'", "''") + "'";
075            }
076            else
077            {
078                return _metadata.build() + " " + _operator + " '" + _value.replaceAll("'", "''") + "'";
079            }
080        }
081    }
082    
083    private String _escapeValue(String value)
084    {
085        // First escape ' - " \ _ and %, Then escape ' into '' for XQuery compliance
086        return value.replaceAll("(['\\-_\"\\\\%])", "\\\\$1").replaceAll("'", "''");
087    }
088}