View Javadoc
1   /*
2    * This file is part of ***  M y C o R e  ***
3    * See http://www.mycore.de/ for details.
4    *
5    * MyCoRe is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    *
10   * MyCoRe is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with MyCoRe.  If not, see <http://www.gnu.org/licenses/>.
17   */
18  
19  package org.mycore.mods;
20  
21  import static org.mycore.mods.MCRMODSDateFormat.DATE_LOCALE;
22  import static org.mycore.mods.MCRMODSDateFormat.MODS_TIMEZONE;
23  
24  import java.text.ParseException;
25  import java.util.Calendar;
26  import java.util.Date;
27  import java.util.GregorianCalendar;
28  import java.util.Objects;
29  
30  import org.jdom2.Element;
31  import org.mycore.common.MCRException;
32  
33  /**
34   * Helper class to parse and build MODS date elements, see
35   * http://www.loc.gov/standards/mods/userguide/generalapp.html#encoding
36   * 
37   * @author Frank L\u00FCtzenkirchen
38   */
39  public class MCRMODSDateHelper {
40  
41      public static Date getDate(Element element) {
42          if (element == null) {
43              return null;
44          }
45  
46          String text = element.getTextTrim();
47          if ((text == null) || text.isEmpty()) {
48              return null;
49          }
50  
51          String encoding = element.getAttributeValue("encoding", "unknown").toLowerCase(DATE_LOCALE);
52          String key = encoding + "-" + text.length();
53          MCRMODSDateFormat format = firstNonNull(MCRMODSDateFormat.getFormat(key),
54              MCRMODSDateFormat.getFormat(encoding));
55          if (format == null) {
56              throw reportParseException(encoding, text, null);
57          }
58          try {
59              return format.parseDate(text);
60          } catch (ParseException ex) {
61              throw reportParseException(encoding, text, ex);
62          }
63      }
64  
65      @SafeVarargs
66      private static <T> T firstNonNull(T... o) {
67          for (T test : Objects.requireNonNull(o)) {
68              if (test != null) {
69                  return test;
70              }
71          }
72          throw new NullPointerException();
73      }
74  
75      public static GregorianCalendar getCalendar(Element element) {
76          Date date = getDate(element);
77          if (date == null) {
78              return null;
79          }
80          GregorianCalendar cal = new GregorianCalendar(MODS_TIMEZONE, DATE_LOCALE);
81          cal.setTime(date);
82          return cal;
83      }
84  
85      public static void setDate(Element element, Date date, MCRMODSDateFormat encoding) {
86          Objects.requireNonNull(encoding, "encoding is required: " + encoding);
87          element.setText(encoding.formatDate(date));
88          element.setAttribute("encoding", encoding.asEncodingAttributeValue());
89      }
90  
91      public static void setDate(Element element, GregorianCalendar cal, MCRMODSDateFormat encoding) {
92          setDate(element, encoding.isDateOnly() ? adjustTimeOffset(cal) : cal.getTime(), encoding);
93      }
94  
95      private static Date adjustTimeOffset(GregorianCalendar cal) {
96          GregorianCalendar clone = new GregorianCalendar(MODS_TIMEZONE, DATE_LOCALE);
97          clone.set(cal.get(Calendar.YEAR),
98              cal.get(Calendar.MONTH),
99              cal.get(Calendar.DAY_OF_MONTH));
100         return clone.getTime();
101     }
102 
103     private static MCRException reportParseException(String encoding, String text, ParseException ex) {
104         String msg = "Unable to parse MODS date encoded " + encoding + " " + text;
105         return new MCRException(msg, ex);
106     }
107 }