001/* 002 * (C) Copyright 2011 Nuxeo SA (http://nuxeo.com/) and others. 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 * 016 * Contributors: 017 * Olivier Grisel 018 */ 019package org.nuxeo.ecm.platform.suggestbox.utils; 020 021import java.time.DateTimeException; 022import java.time.ZoneOffset; 023import java.time.ZonedDateTime; 024import java.util.Calendar; 025import java.util.GregorianCalendar; 026import java.util.regex.Matcher; 027import java.util.regex.Pattern; 028 029import org.nuxeo.ecm.platform.suggestbox.service.suggesters.DocumentSearchByDateSuggester; 030 031/** 032 * @deprecated since 11.1 only used from deprecated {@link DocumentSearchByDateSuggester} 033 */ 034@Deprecated 035public class DateMatcher { 036 037 private static final Pattern YEAR_ONLY_MATCHER = Pattern.compile("^\\d{4}$"); 038 039 private static final Pattern MONTH_DIGIT_ONLY_MATCHER = Pattern.compile("^\\d{2}$"); 040 041 private static final Pattern YEAR_MONTHS_MATCHER = Pattern.compile("^\\d{4}[_ -:]\\d{2}$"); 042 043 private static final Pattern MONTHS_YEAR_MATCHER = Pattern.compile("^\\d{2}[_ -:]\\d{4}$"); 044 045 private static final Pattern MONTHS_DAY_YEAR_MATCHER = Pattern.compile("^\\d{2}[_ -:]\\d{2,}[_ -:]\\d{4}$"); 046 047 private static final Pattern YEAR_MONTHS_DAY_MATCHER = Pattern.compile("^\\d{4}[_ -:]\\d{2,}[_ -:]\\d{2}$"); 048 049 private boolean withYears = false; 050 051 private boolean withMonth = false; 052 053 private boolean withDay = false; 054 055 private final Calendar dateSuggestion; 056 057 private DateMatcher(boolean withYears, boolean withMonth, boolean withDay, Calendar dateSuggestion) { 058 this.withYears = withYears; 059 this.withMonth = withMonth; 060 this.withDay = withDay; 061 this.dateSuggestion = dateSuggestion; 062 } 063 064 public boolean isWithYears() { 065 return withYears; 066 } 067 068 public void setWithYears(boolean withYears) { 069 this.withYears = withYears; 070 } 071 072 public boolean isWithMonth() { 073 return withMonth; 074 } 075 076 public void setWithMonth(boolean withMonth) { 077 this.withMonth = withMonth; 078 } 079 080 public boolean isWitDay() { 081 return withDay; 082 } 083 084 public void setWitDay(boolean witDay) { 085 withDay = witDay; 086 } 087 088 public Calendar getDateSuggestion() { 089 return dateSuggestion; 090 } 091 092 public boolean hasMatch() { 093 return getDateSuggestion() != null; 094 } 095 096 public static Matcher parsingDate(Pattern pattern, String input) { 097 return pattern.matcher(input.trim()); 098 } 099 100 public static DateMatcher fromInput(String input) { 101 try { 102 return doFromInput(input); 103 } catch (NumberFormatException e) { 104 return new DateMatcher(false, false, false, null); 105 } 106 } 107 108 public static DateMatcher doFromInput(String input) { 109 Matcher matcher = parsingDate(YEAR_ONLY_MATCHER, input); 110 111 if (matcher.find()) { 112 return new DateMatcher(true, false, false, dateToInstance(Integer.parseInt(matcher.group()), 1, 1)); 113 } 114 matcher = parsingDate(MONTH_DIGIT_ONLY_MATCHER, input); 115 if (matcher.find()) { 116 int month = Integer.parseInt(matcher.group()); 117 if (month > 12 || month < 1) { 118 return new DateMatcher(false, true, false, null); 119 } 120 return new DateMatcher(false, true, false, 121 dateToInstance(Calendar.getInstance().get(Calendar.YEAR), month, 1)); 122 } 123 matcher = parsingDate(YEAR_MONTHS_MATCHER, input); 124 if (matcher.find()) { 125 int month = Integer.parseInt(matcher.group().substring(5)); 126 if (month > 12 || month < 1) { 127 return new DateMatcher(true, true, false, null); 128 } 129 int year = Integer.parseInt(matcher.group().substring(0, 4)); 130 131 return new DateMatcher(true, true, false, dateToInstance(year, month, 1)); 132 } 133 matcher = parsingDate(MONTHS_YEAR_MATCHER, input); 134 if (matcher.find()) { 135 int month = Integer.parseInt(matcher.group().substring(0, 2)); 136 if (month > 12 || month < 1) { 137 return new DateMatcher(true, true, false, null); 138 } 139 int year = Integer.parseInt(matcher.group().substring(3)); 140 141 return new DateMatcher(true, true, false, dateToInstance(year, month, 1)); 142 143 } 144 matcher = parsingDate(MONTHS_DAY_YEAR_MATCHER, input); 145 if (matcher.find()) { 146 int first = Integer.parseInt(matcher.group().substring(0, 2)); 147 int second = Integer.parseInt(matcher.group().substring(3, 5)); 148 int year = Integer.parseInt(matcher.group().substring(6)); 149 int control = first + second; 150 if (control < 2 || control > 12 + 31 || first < 1 || second < 1) { 151 return new DateMatcher(true, true, true, null); 152 } else if (control < 12 + 12 + 1) { 153 return new DateMatcher(true, true, true, dateToInstance(year, first, second)); 154 } 155 int month = first; 156 int day = second; 157 if (first > second) { 158 month = second; 159 day = first; 160 } 161 Calendar dateToInstance = dateToInstance(year, month, day); 162 return new DateMatcher(true, true, true, dateToInstance); 163 } 164 matcher = parsingDate(YEAR_MONTHS_DAY_MATCHER, input); 165 if (matcher.find()) { 166 int year = Integer.parseInt(matcher.group().substring(0, 4)); 167 int first = Integer.parseInt(matcher.group().substring(5, 7)); 168 int second = Integer.parseInt(matcher.group().substring(8)); 169 int control = first + second; 170 if (control < 2 || control > 12 + 31 || first < 1 || second < 1) { 171 return new DateMatcher(true, true, true, null); 172 } else if (control < 12 + 12 + 1) { 173 return new DateMatcher(true, true, true, dateToInstance(year, first, second)); 174 } 175 int month = first; 176 int day = second; 177 if (first > second) { 178 month = second; 179 day = first; 180 } 181 Calendar dateToInstance = dateToInstance(year, month, day); 182 return new DateMatcher(true, true, true, dateToInstance); 183 } 184 185 return new DateMatcher(false, false, false, null); 186 } 187 188 protected static Calendar dateToInstance(int year, int month, int day) { 189 try { 190 return GregorianCalendar.from(ZonedDateTime.of(year, month, day, 12, 0, 0, 0, ZoneOffset.UTC)); 191 } catch (IllegalArgumentException | DateTimeException e) { 192 return null; 193 } 194 } 195 196}