/* (c) 2014 Open Source Geospatial Foundation - all rights reserved * (c) 2001 - 2013 OpenPlans * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.importer; import java.text.ParsePosition; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Encapsulates a date format and regular expression. * * @author Justin Deoliveira, OpenGeo */ public class DatePattern implements java.io.Serializable { private static final long serialVersionUID = 1L; final String format; final String regex; final boolean strict; final boolean forceGmt; Pattern pattern; /** * Constructor with defaults, <tt>forceGmt</tt> set to <tt>true</tt> and <tt>strict</tt> * set to <tt>false</tt>. */ public DatePattern(String format, String regex) { this(format, regex, true, false); } /** * Constructor. * * @param format The date format * @param regex The regular expression to pull the date out of a another string. * @param forceGmt Whether the pattern should assume the GMT time zone. * @param strict Whether or not this pattern must apply the regular expression to match before * parsing a date. */ public DatePattern(String format, String regex, boolean forceGmt, boolean strict) { this.format = format; this.regex = regex; this.forceGmt = forceGmt; this.strict = strict; } public String getFormat() { return format; } public SimpleDateFormat dateFormat() { SimpleDateFormat dateFormat = new SimpleDateFormat(format, Locale.CANADA); if (forceGmt) { dateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); } return dateFormat; } public String getRegex() { return regex; } public Pattern pattern() { if (pattern == null) { //wrap the regex in a group and match anything around it (use reluctant wildcard matching) pattern = Pattern.compile(".*?(" + regex + ").*?", Pattern.CASE_INSENSITIVE); } return pattern; } /** * When true the {@link #matchAndParse(String)} method should be used. */ public boolean isStrict() { return strict; } public Date matchAndParse(String str) { Matcher m = pattern().matcher(str); if (!m.matches()) { return null; } str = m.group(1); return doParse(str); } public Date parse(String str) { if (isStrict()) { //matchAndParse should be called return null; } return doParse(str); } Date doParse(String str) { /* * We do not use the standard method DateFormat.parse(String), because * if the parsing stops before the end of the string, the remaining * characters are just ignored and no exception is thrown. So we have to * ensure that the whole string is correct for the format. */ ParsePosition pos = new ParsePosition(0); Date p = dateFormat().parse(str, pos); if (p != null && pos.getIndex() == str.length()) { return p; } return null; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (forceGmt ? 1231 : 1237); result = prime * result + ((format == null) ? 0 : format.hashCode()); result = prime * result + ((regex == null) ? 0 : regex.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; DatePattern other = (DatePattern) obj; if (forceGmt != other.forceGmt) return false; if (format == null) { if (other.format != null) return false; } else if (!format.equals(other.format)) return false; if (regex == null) { if (other.regex != null) return false; } else if (!regex.equals(other.regex)) return false; return true; } }