001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.jsp.search.config.parser.simplesearch.daterestrictions;
029
030import org.opencms.file.CmsObject;
031import org.opencms.jsp.search.config.parser.simplesearch.daterestrictions.I_CmsDateRestriction.TimeDirection;
032import org.opencms.jsp.search.config.parser.simplesearch.daterestrictions.I_CmsDateRestriction.TimeUnit;
033import org.opencms.main.CmsLog;
034import org.opencms.util.CmsStringUtil;
035import org.opencms.xml.content.CmsXmlContentValueLocation;
036
037import java.util.Date;
038
039import org.apache.commons.logging.Log;
040
041/**
042 * Parses date restrictions in a list configuration.<p>
043 *
044 */
045public class CmsDateRestrictionParser {
046
047    /** XML node name. */
048    public static final String N_RANGE = "Range";
049
050    /** XML node name. */
051    public static final String N_PAST_FUTURE = "PastFuture";
052
053    /** XML node name. */
054    public static final String N_FROM_TODAY = "FromToday";
055
056    /** XML node name. */
057    public static final String N_TO = "To";
058
059    /** XML node name. */
060    public static final String N_FROM = "From";
061
062    /** XML node name. */
063    public static final String N_DIRECTION = "Direction";
064
065    /** XML node name. */
066    public static final String N_UNIT = "Unit";
067
068    /** XML node name. */
069    public static final String N_COUNT = "Count";
070
071    /** Logger instance for this class.*/
072    public static final Log LOG = CmsLog.getLog(CmsDateRestrictionParser.class);
073
074    /** The CMS context used. */
075    public CmsObject m_cms;
076
077    /**
078     * Creates a new instance.<p>
079     *
080     * @param cms the CMS context to use
081     */
082    public CmsDateRestrictionParser(CmsObject cms) {
083        m_cms = cms;
084    }
085
086    /**
087     * Parses a date restriction.<p>
088     *
089     * @param dateRestriction the location of the date restriction
090     *
091     * @return the date restriction
092     */
093    public I_CmsDateRestriction parse(CmsXmlContentValueLocation dateRestriction) {
094
095        I_CmsDateRestriction result = null;
096        result = parseRange(dateRestriction);
097        if (result != null) {
098            return result;
099        }
100        result = parseFromToday(dateRestriction);
101        if (result != null) {
102            return result;
103        }
104        result = parsePastFuture(dateRestriction);
105        return result;
106    }
107
108    /**
109     * Parses a date.<p>
110     *
111     * @param dateLoc the location of the date
112     * @return the date, or null if it could not be parsed
113     */
114    private Date parseDate(CmsXmlContentValueLocation dateLoc) {
115
116        if (dateLoc == null) {
117            return null;
118        }
119        String dateStr = dateLoc.getValue().getStringValue(m_cms);
120        if (CmsStringUtil.isEmptyOrWhitespaceOnly(dateStr)) {
121            return null;
122        }
123        try {
124            return new Date(Long.parseLong(dateStr));
125        } catch (Exception e) {
126            LOG.info(e.getLocalizedMessage() + " date = " + dateStr, e);
127            return null;
128        }
129    }
130
131    /**
132     * Parses a time direction.<p>
133     *
134     * @param location the location of the time direction
135     *
136     * @return the time direction, or null if it could not be parsed
137     */
138    private I_CmsDateRestriction.TimeDirection parseDirection(CmsXmlContentValueLocation location) {
139
140        try {
141            return TimeDirection.valueOf(location.getValue().getStringValue(m_cms));
142        } catch (Exception e) {
143            return null;
144        }
145    }
146
147    /**
148     * Parses a date restriction of type 'FromToday'.<p>
149     *
150     * @param dateRestriction the location of the date restriction
151     *
152     * @return the date restriction
153     */
154    private I_CmsDateRestriction parseFromToday(CmsXmlContentValueLocation dateRestriction) {
155
156        CmsXmlContentValueLocation location = dateRestriction.getSubValue(N_FROM_TODAY);
157        if (location == null) {
158            return null;
159        }
160        CmsXmlContentValueLocation countLoc = location.getSubValue(N_COUNT);
161        CmsXmlContentValueLocation unitLoc = location.getSubValue(N_UNIT);
162        CmsXmlContentValueLocation directionLoc = location.getSubValue(N_DIRECTION);
163
164        TimeDirection direction = parseDirection(directionLoc);
165        Integer count = parsePositiveNumber(countLoc);
166        TimeUnit unit = parseUnit(unitLoc);
167        if (count == null) {
168            return null;
169        }
170        return new CmsDateFromTodayRestriction(count.intValue(), unit, direction);
171    }
172
173    /**
174     * Parses a date restriction of type 'Past/Future'.<p>
175     *
176     * @param dateRestriction the location of the date restriction
177     *
178     * @return the date restriction
179     */
180    private I_CmsDateRestriction parsePastFuture(CmsXmlContentValueLocation dateRestriction) {
181
182        CmsXmlContentValueLocation location = dateRestriction.getSubValue(N_PAST_FUTURE);
183        if (location == null) {
184            return null;
185        }
186        CmsXmlContentValueLocation directionLoc = location.getSubValue(N_DIRECTION);
187        TimeDirection direction = parseDirection(directionLoc);
188        return new CmsDatePastFutureRestriction(direction);
189    }
190
191    /**
192     * Parses a positive integer.<p>
193     *
194     * @param loc the location of the positive number
195     * @return the number, or null if it could not be parsed
196     */
197    private Integer parsePositiveNumber(CmsXmlContentValueLocation loc) {
198
199        if (loc == null) {
200            return null;
201        }
202        try {
203            Integer result = Integer.valueOf(loc.getValue().getStringValue(m_cms).trim());
204            if (result.intValue() < 0) {
205                return null;
206            } else {
207                return result;
208            }
209        } catch (Exception e) {
210            LOG.info(e.getLocalizedMessage(), e);
211            return null;
212        }
213    }
214
215    /**
216     * Parses a date restriction of 'range' type.<p>
217     *
218     * @param dateRestriction the location of the date restriction
219     *
220     * @return the date restriction or null if it could not be parsed
221     */
222    private I_CmsDateRestriction parseRange(CmsXmlContentValueLocation dateRestriction) {
223
224        CmsXmlContentValueLocation location = dateRestriction.getSubValue(N_RANGE);
225        if (location == null) {
226            return null;
227        }
228        CmsXmlContentValueLocation fromLoc = location.getSubValue(N_FROM);
229        CmsXmlContentValueLocation toLoc = location.getSubValue(N_TO);
230        Date fromDate = parseDate(fromLoc);
231        Date toDate = parseDate(toLoc);
232        if ((fromDate != null) || (toDate != null)) {
233            return new CmsDateRangeRestriction(fromDate, toDate);
234        } else {
235            return null;
236        }
237    }
238
239    /**
240     * Parses a time unit.<p>
241     *
242     * @param location the location containing the time unit
243     *
244     * @return the time unit
245     */
246    private TimeUnit parseUnit(CmsXmlContentValueLocation location) {
247
248        if (location == null) {
249            return null;
250        }
251        return TimeUnit.valueOf(location.getValue().getStringValue(m_cms));
252    }
253
254}