1 /*****************************************************************
2 * Licensed to the Apache Software Foundation (ASF) under one *
3 * or more contributor license agreements. See the NOTICE file *
4 * distributed with this work for additional information *
5 * regarding copyright ownership. The ASF licenses this file *
6 * to you under the Apache License, Version 2.0 (the *
7 * "License"); you may not use this file except in compliance *
8 * with the License. You may obtain a copy of the License at *
9 * *
10 * http://www.apache.org/licenses/LICENSE-2.0 *
11 * *
12 * Unless required by applicable law or agreed to in writing, *
13 * software distributed under the License is distributed on an *
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
15 * KIND, either express or implied. See the License for the *
16 * specific language governing permissions and limitations *
17 * under the License. *
18 ****************************************************************/
19
20 package org.apache.mailet.dates;
21
22 import java.text.ParseException;
23 import java.util.Date;
24 import java.util.Locale;
25 import java.util.TimeZone;
26
27 /***
28 * A thread-safe date formatting class to produce dates formatted in accord with the
29 * specifications of RFC 977.
30 *
31 */
32 public class RFC977DateFormat implements SimplifiedDateFormat {
33
34 /***
35 * Internal date formatter for long date formats
36 */
37 private final SynchronizedDateFormat internalLongDateFormat;
38
39 /***
40 * Internal date formatter for short date formats
41 */
42 private final SynchronizedDateFormat internalShortDateFormat;
43
44 /***
45 * Constructor for RFC977DateFormat
46 */
47 public RFC977DateFormat() {
48 internalLongDateFormat = new SynchronizedDateFormat("yyyyMMdd HHmmss", Locale.ENGLISH);
49 internalShortDateFormat = new SynchronizedDateFormat("yyMMdd HHmmss", Locale.ENGLISH);
50 }
51
52 /***
53 * This method returns the long form of the RFC977 Date
54 *
55 * @return java.lang.String
56 * @param d Date
57 */
58 public String format(Date d) {
59 return internalLongDateFormat.format(d);
60 }
61
62 /***
63 * Parses text from the beginning of the given string to produce a date.
64 * The method may not use the entire text of the given string.
65 * <p>
66 * This method is designed to be thread safe, so we wrap our delegated
67 * parse method in an appropriate synchronized block.
68 *
69 * @param source A <code>String</code> whose beginning should be parsed.
70 * @return A <code>Date</code> parsed from the string.
71 * @throws ParseException if the beginning of the specified string
72 * cannot be parsed.
73 */
74 public Date parse(String source) throws ParseException {
75 source = source.trim();
76 if (source.indexOf(' ') == 6) {
77 return internalShortDateFormat.parse(source);
78 } else {
79 return internalLongDateFormat.parse(source);
80 }
81 }
82
83 /***
84 * Sets the time zone of this SynchronizedDateFormat object.
85 * @param zone the given new time zone.
86 */
87 public void setTimeZone(TimeZone zone) {
88 synchronized(this) {
89 internalShortDateFormat.setTimeZone(zone);
90 internalLongDateFormat.setTimeZone(zone);
91 }
92 }
93
94 /***
95 * Gets the time zone.
96 * @return the time zone associated with this SynchronizedDateFormat.
97 */
98 public TimeZone getTimeZone() {
99 synchronized(this) {
100 return internalShortDateFormat.getTimeZone();
101 }
102 }
103
104 /***
105 * Specify whether or not date/time parsing is to be lenient. With
106 * lenient parsing, the parser may use heuristics to interpret inputs that
107 * do not precisely match this object's format. With strict parsing,
108 * inputs must match this object's format.
109 * @param lenient when true, parsing is lenient
110 * @see java.util.Calendar#setLenient
111 */
112 public void setLenient(boolean lenient)
113 {
114 synchronized(this) {
115 internalShortDateFormat.setLenient(lenient);
116 internalLongDateFormat.setLenient(lenient);
117 }
118 }
119
120 /***
121 * Tell whether date/time parsing is to be lenient.
122 * @return whether this SynchronizedDateFormat is lenient.
123 */
124 public boolean isLenient()
125 {
126 synchronized(this) {
127 return internalShortDateFormat.isLenient();
128 }
129 }
130
131
132 /***
133 * Overrides equals
134 */
135 public boolean equals(Object obj) {
136 if (this == obj) {
137 return true;
138 }
139 if (!(obj instanceof RFC977DateFormat)) {
140 return false;
141 }
142 RFC977DateFormat theOtherRFC977DateFormat = (RFC977DateFormat)obj;
143 synchronized (this) {
144 return ((internalShortDateFormat.equals(theOtherRFC977DateFormat.internalShortDateFormat)) &&
145 (internalLongDateFormat.equals(theOtherRFC977DateFormat.internalLongDateFormat)));
146 }
147 }
148
149 /***
150 * Overrides hashCode
151 */
152 public int hashCode() {
153 return (int)(internalLongDateFormat.hashCode() & internalShortDateFormat.hashCode());
154 }
155
156 }