001/*
002 *  Copyright 2014 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.cms.search.query;
017
018import java.text.DateFormat;
019import java.text.SimpleDateFormat;
020import java.util.Date;
021
022/**
023 * Represents a {@link Query} testing a date field.
024 */
025public class DateQuery extends AbstractFieldQuery
026{
027    
028    /** The date format. */
029    public static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
030    
031    /** The operator. */
032    protected Operator _operator;
033    /** The value to test. */
034    protected Date _value;
035    
036    /**
037     * Build a DateQuery testing the existence of the field.
038     * @param fieldPath the field path.
039     */
040    public DateQuery(String fieldPath)
041    {
042        this(fieldPath, Operator.EXISTS, null);
043    }
044    
045    /**
046     * Build a DateQuery.
047     * @param fieldPath the field's path
048     * @param value the value.
049     */
050    public DateQuery(String fieldPath, Date value)
051    {
052        this(fieldPath, Operator.EQ, value);
053    }
054    
055    /**
056     * Build a DateQuery.
057     * @param fieldPath the field's path
058     * @param op the operator.
059     * @param value the value.
060     */
061    public DateQuery(String fieldPath, Operator op, Date value)
062    {
063        super(fieldPath);
064        _operator = op;
065        _value = value;
066    }
067    
068    /**
069     * Get the operator.
070     * @return the operator.
071     */
072    public Operator getOperator()
073    {
074        return _operator;
075    }
076    
077    /**
078     * Get the value.
079     * @return the value.
080     */
081    public Date getValue()
082    {
083        return _value;
084    }
085    
086    @Override
087    public String build() throws QuerySyntaxException
088    {
089        StringBuilder query = new StringBuilder();
090        
091        if (_operator == Operator.NE)
092        {
093            query.append('-');
094        }
095        
096        query.append(_fieldPath).append("_dt:");
097        
098        if (_operator == Operator.EXISTS)
099        {
100            query.append(QueryHelper.EXISTS_VALUE);
101        }
102        else
103        {
104            appendDateValue(query, _operator, _value);
105        }
106        
107        return query.toString();
108    }
109    
110    /**
111     * Format and append the given date to a StringBuilder.
112     * @param query The string builder containing the query being built.
113     * @param operator The query operator.
114     * @param value The test value.
115     */
116    public static void appendDateValue(StringBuilder query, Operator operator, Date value)
117    {
118        String strValue = DATE_FORMAT.format(value);
119        
120        if (operator == Operator.EQ || operator == Operator.NE)
121        {
122            query.append('"').append(strValue).append('"');
123        }
124        else if (operator == Operator.GT)
125        {
126            query.append('{').append(strValue).append(" TO *]");
127        }
128        else if (operator == Operator.GE)
129        {
130            query.append('[').append(strValue).append(" TO *]");
131        }
132        else if (operator == Operator.LT)
133        {
134            query.append("[* TO ").append(strValue).append('}');
135        }
136        else if (operator == Operator.LE)
137        {
138            query.append("[* TO ").append(strValue).append(']');
139        }
140    }
141    
142}