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 unversioned true if the metadata is unversioned, false otherwise.
048     */
049    public StringExpression(String metadata, Operator operator, String value, boolean unversioned)
050    {
051        _value = value;
052        _operator = operator;
053        _metadata = new MetadataExpression(metadata, unversioned);
054        _caseInsensitive = false;
055    }
056    
057    /**
058     * Creates the comparison Expression.
059     * @param metadata the metadata name
060     * @param operator the operator to make the comparison
061     * @param value the String value
062     * @param unversioned true if the metadata is unversioned, false otherwise.
063     * @param caseInsensitive <code>true</code> if the search must be case insensitive.
064     */
065    public StringExpression(String metadata, Operator operator, String value, boolean unversioned, boolean caseInsensitive)
066    {
067        _value = value;
068        _operator = operator;
069        _metadata = new MetadataExpression(metadata, unversioned);
070        _caseInsensitive = caseInsensitive;
071    }
072    
073    public String build()
074    {
075        if (_operator.equals(Operator.WD))
076        {
077            if (_caseInsensitive)
078            {
079                return "jcr:like(fn:lower-case(" + _metadata.build() + "), '%" + _escapeValue(_value.toLowerCase()) + "%')";
080            }
081            else
082            {
083                return "jcr:like(" + _metadata.build() + ", '%" + _escapeValue(_value) + "%')";
084            }
085        }
086        else
087        {
088            if (_caseInsensitive)
089            {
090                return "fn:lower-case(" + _metadata.build() + ") " + _operator + " '" + _value.toLowerCase().replaceAll("'", "''") + "'";
091            }
092            else
093            {
094                return _metadata.build() + " " + _operator + " '" + _value.replaceAll("'", "''") + "'";
095            }
096        }
097    }
098    
099    private String _escapeValue(String value)
100    {
101        // First escape ' - " \ _ and %, Then escape ' into '' for XQuery compliance
102        return value.replaceAll("(['\\-_\"\\\\%])", "\\\\$1").replaceAll("'", "''");
103    }
104}