View Javadoc
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.directory.shared.kerberos;
21  
22  
23  import java.text.ParseException;
24  import java.util.Calendar;
25  import java.util.Date;
26  import java.util.Locale;
27  import java.util.TimeZone;
28  
29  import org.apache.directory.api.util.Strings;
30  
31  
32  /**
33   * An specialization of the ASN.1 GeneralTime. The Kerberos time contains date and
34   * time up to the seconds, but with no fractional seconds. It's also always
35   * expressed as UTC timeZone, thus the 'Z' at the end of its string representation.
36   * 
37   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
38   */
39  public class KerberosTime implements Comparable<KerberosTime>, java.io.Serializable
40  {
41      /**
42       * 
43       */
44      private static final long serialVersionUID = -7541256140193748103L;
45  
46      /** The UTC timeZone */
47      private static final TimeZone UTC = TimeZone.getTimeZone( "UTC" );
48  
49      /** The KerberosTime as a String*/
50      private String date;
51  
52      /** The kerberosTime, as a long */
53      private long kerberosTime;
54  
55      /** Constant for the {@link KerberosTime} "infinity." */
56      public static final KerberosTimeros/KerberosTime.html#KerberosTime">KerberosTime INFINITY = new KerberosTime( Long.MAX_VALUE );
57  
58      /** The number of milliseconds in a minute. */
59      public static final int MINUTE = 60000;
60  
61      /** The number of milliseconds in a day. */
62      public static final int DAY = MINUTE * 1440;
63  
64      /** The number of milliseconds in a week. */
65      public static final int WEEK = MINUTE * 10080;
66  
67  
68      /**
69       * Creates a new instance of a KerberosTime object
70       */
71      public KerberosTime()
72      {
73          kerberosTime = ( System.currentTimeMillis() / 1000L ) * 1000L; // drop the ms
74          convertInternal( kerberosTime );
75      }
76  
77  
78      /**
79       * Creates a new instance of a KerberosTime object
80       * 
81       * @param date the KerberosTime to store
82       */
83      public KerberosTime( String date )
84      {
85          try
86          {
87              setDate( date );
88          }
89          catch ( ParseException pe )
90          {
91              throw new IllegalArgumentException( "Bad time : " + date );
92          }
93      }
94  
95  
96      /**
97       * Creates a new instance of a KerberosTime object
98       */
99      public KerberosTime( long date )
100     {
101         convertInternal( date );
102     }
103 
104 
105     /**
106      * Creates a new instance of KerberosTime.
107      *
108      * @param time
109      */
110     public KerberosTime( Date time )
111     {
112         kerberosTime = ( time.getTime() / 1000L ) * 1000L; // drop the ms
113         convertInternal( kerberosTime );
114     }
115 
116 
117     /**
118      * converts the given milliseconds time to seconds and
119      * also formats the time to the generalized form
120      * 
121      * @param date the time in milliseconds
122      */
123     private void convertInternal( long date )
124     {
125         Calendar calendar = Calendar.getInstance( UTC, Locale.ROOT );
126         calendar.setTimeInMillis( date );
127 
128         synchronized ( KerberosUtils.UTC_DATE_FORMAT )
129         {
130             this.date = KerberosUtils.UTC_DATE_FORMAT.format( calendar.getTime() );
131         }
132 
133         kerberosTime = ( calendar.getTimeInMillis() / 1000L ) * 1000L; // drop the ms
134     }
135 
136 
137     /**
138      * Returns the {@link KerberosTime} as a long.
139      *
140      * @return The {@link KerberosTime} as a long.
141      */
142     public long getTime()
143     {
144         return kerberosTime;
145     }
146 
147 
148     /**
149      * Returns the {@link KerberosTime} as a {@link Date}.
150      *
151      * @return The {@link KerberosTime} as a {@link Date}.
152      */
153     public Date toDate()
154     {
155         return new Date( kerberosTime );
156     }
157 
158 
159     /**
160      * Returns the {@link KerberosTime} for a given zulu time.
161      *
162      * @param zuluTime
163      * @return The {@link KerberosTime}.
164      * @throws ParseException
165      */
166     public static KerberosTime getTime( String zuluTime ) throws ParseException
167     {
168         Date date = null;
169 
170         synchronized ( KerberosUtils.UTC_DATE_FORMAT )
171         {
172             date = KerberosUtils.UTC_DATE_FORMAT.parse( zuluTime );
173         }
174 
175         return new KerberosTime( date );
176     }
177 
178 
179     /**
180      * Sets the date if it's a valid KerberosTime
181      * @param date The date to store
182      */
183     public void setDate( String date ) throws ParseException
184     {
185         synchronized ( KerberosUtils.UTC_DATE_FORMAT )
186         {
187             kerberosTime = KerberosUtils.UTC_DATE_FORMAT.parse( date ).getTime();
188         }
189 
190         convertInternal( kerberosTime );
191     }
192 
193 
194     /**
195      * @return The date as a byte[]
196      */
197     public byte[] getBytes()
198     {
199         return Strings.getBytesUtf8( date );
200     }
201 
202 
203     /**
204      * @return The stored date
205      */
206     public String getDate()
207     {
208         return date;
209     }
210 
211 
212     @Override
213     public int hashCode()
214     {
215         return ( int ) kerberosTime;
216     }
217 
218 
219     @Override
220     public boolean equals( Object obj )
221     {
222         if ( this == obj )
223         {
224             return true;
225         }
226 
227         if ( !( obj instanceof KerberosTime ) )
228         {
229             return true;
230         }
231 
232         KerberosTime../../../org/apache/directory/shared/kerberos/KerberosTime.html#KerberosTime">KerberosTime other = ( KerberosTime ) obj;
233 
234         return kerberosTime == other.kerberosTime;
235     }
236 
237 
238     /**
239      * Returns whether this {@link KerberosTime} is within the given clockskew.
240      *
241      * @param clockSkew
242      * @return true if this {@link KerberosTime} is within the given clockskew.
243      */
244     public boolean isInClockSkew( long clockSkew )
245     {
246         // The KerberosTime does not have milliseconds
247         long delta = Math.abs( kerberosTime - System.currentTimeMillis() );
248 
249         return delta < clockSkew;
250     }
251 
252 
253     /**
254      * compares current kerberos time with the given kerberos time
255      * @param that the kerberos time against which the current kerberos time is compared
256      * @return 0 if both times are equal,<br>
257      *         -1 if current time is less than the given time and<br>
258      *         1 if the given time is greater than the current time
259      */
260     public int compareTo( KerberosTime that )
261     {
262         final int BEFORE = -1;
263         final int EQUAL = 0;
264         final int AFTER = 1;
265 
266         // this optimization is usually worthwhile, and can always be added
267         if ( this == that )
268         {
269             return EQUAL;
270         }
271 
272         // primitive numbers follow this form
273         if ( this.kerberosTime < that.kerberosTime )
274         {
275             return BEFORE;
276         }
277 
278         if ( this.kerberosTime > that.kerberosTime )
279         {
280             return AFTER;
281         }
282 
283         return EQUAL;
284     }
285 
286 
287     /**
288      * checks if the current kerberos time is less or equal than the given kerberos time
289      * @param ktime the kerberos time against which the current kerberos time needs to be compared
290      * @return true if current kerberos time is less or equal than the given kerberos time, false otherwise
291      */
292     public boolean lessThan( KerberosTime ktime )
293     {
294         return kerberosTime <= ktime.kerberosTime;
295     }
296 
297 
298     /**
299      * checks if the current kerberos time is greater than the given kerberos time
300      * @param ktime the kerberos time against which the currnet kerberos time needs to be compared
301      * @return true if current kerberos time is greater than the given kerberos time, false otherwise
302      */
303     public boolean greaterThan( KerberosTime ktime )
304     {
305         return kerberosTime > ktime.kerberosTime;
306     }
307 
308 
309     /**
310      * Returns whether this {@link KerberosTime} is zero.
311      *
312      * @return true if this {@link KerberosTime} is zero.
313      */
314     public boolean isZero()
315     {
316         return kerberosTime == 0;
317     }
318 
319 
320     /**
321      * {@inheritDoc}
322      */
323     public String toString()
324     {
325         return date;
326     }
327 }