001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020package org.apache.directory.shared.kerberos; 021 022 023import java.text.ParseException; 024import java.util.Calendar; 025import java.util.Date; 026import java.util.Locale; 027import java.util.TimeZone; 028 029import org.apache.directory.api.util.Strings; 030 031 032/** 033 * An specialization of the ASN.1 GeneralTime. The Kerberos time contains date and 034 * time up to the seconds, but with no fractional seconds. It's also always 035 * expressed as UTC timeZone, thus the 'Z' at the end of its string representation. 036 * 037 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 038 */ 039public class KerberosTime implements Comparable<KerberosTime>, java.io.Serializable 040{ 041 /** 042 * 043 */ 044 private static final long serialVersionUID = -7541256140193748103L; 045 046 /** The UTC timeZone */ 047 private static final TimeZone UTC = TimeZone.getTimeZone( "UTC" ); 048 049 /** The KerberosTime as a String*/ 050 private String date; 051 052 /** The kerberosTime, as a long */ 053 private long kerberosTime; 054 055 /** Constant for the {@link KerberosTime} "infinity." */ 056 public static final KerberosTime INFINITY = new KerberosTime( Long.MAX_VALUE ); 057 058 /** The number of milliseconds in a minute. */ 059 public static final int MINUTE = 60000; 060 061 /** The number of milliseconds in a day. */ 062 public static final int DAY = MINUTE * 1440; 063 064 /** The number of milliseconds in a week. */ 065 public static final int WEEK = MINUTE * 10080; 066 067 068 /** 069 * Creates a new instance of a KerberosTime object 070 */ 071 public KerberosTime() 072 { 073 kerberosTime = ( System.currentTimeMillis() / 1000L ) * 1000L; // drop the ms 074 convertInternal( kerberosTime ); 075 } 076 077 078 /** 079 * Creates a new instance of a KerberosTime object 080 * 081 * @param date the KerberosTime to store 082 */ 083 public KerberosTime( String date ) 084 { 085 try 086 { 087 setDate( date ); 088 } 089 catch ( ParseException pe ) 090 { 091 throw new IllegalArgumentException( "Bad time : " + date ); 092 } 093 } 094 095 096 /** 097 * Creates a new instance of a KerberosTime object 098 */ 099 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 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}