/******************************************************************************* | |
* Copyright (c) 1998, 2013 Oracle and/or its affiliates. All rights reserved. | |
* This program and the accompanying materials are made available under the | |
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 | |
* which accompanies this distribution. | |
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html | |
* and the Eclipse Distribution License is available at | |
* http://www.eclipse.org/org/documents/edl-v10.php. | |
* | |
* Contributors: | |
* Oracle - initial API and implementation from Oracle TopLink | |
******************************************************************************/ | |
package org.eclipse.persistence.descriptors.invalidation; | |
import java.util.*; | |
import org.eclipse.persistence.internal.identitymaps.CacheKey; | |
import org.eclipse.persistence.descriptors.invalidation.CacheInvalidationPolicy; | |
/** | |
* PUBLIC: | |
* A CacheInvalidationPolicy that allows objects to expire every day at a specific time. | |
* A daily cache invalidation policy is created with an hour, minute, second and millisecond | |
* when objects will expire. Objects will expire in the cache every day at that time. | |
* @see CacheInvalidationPolicy | |
*/ | |
public class DailyCacheInvalidationPolicy extends CacheInvalidationPolicy { | |
protected Calendar expiryTime = null; | |
protected Calendar previousExpiry = null;// previous expiry is stored for efficiency | |
/** | |
* INTERNAL: | |
* Default constructor for Project XML | |
* if setters are not called to set expiry times, expiry time will be the time of | |
* day at which this object is instantiated. | |
*/ | |
public DailyCacheInvalidationPolicy() { | |
expiryTime = Calendar.getInstance(); | |
previousExpiry = (Calendar)expiryTime.clone(); | |
previousExpiry.add(Calendar.DAY_OF_YEAR, -1); | |
} | |
/** | |
* PUBLIC: | |
* Construct a daily policy that will allow objects to expire at a specific time of day. | |
* Provide the hour, minute, second and millisecond. Objects that make use of this policy | |
* will be set to expire at that exact time every day. | |
*/ | |
public DailyCacheInvalidationPolicy(int hour, int minute, int second, int millisecond) { | |
setExpiryTime(hour, minute, second, millisecond); | |
} | |
/** | |
* INTERNAL: | |
* Return the next expiry time. | |
*/ | |
public long getExpiryTimeInMillis(CacheKey key) { | |
incrementExpiry(); | |
return this.expiryTime.getTimeInMillis(); | |
} | |
/** | |
* INTERNAL: | |
* Get the expiry time as a Calendar. Used for setting the expiry time in deployment XML | |
*/ | |
public Calendar getExpiryTime() { | |
return expiryTime; | |
} | |
/** | |
* INTERNAL: | |
* Return true if this object has expire or is invalid | |
*/ | |
public boolean isInvalidated(CacheKey key, long currentTimeMillis) { | |
if (key.getInvalidationState() == CacheKey.CACHE_KEY_INVALID) { | |
return true; | |
} | |
long expiryMillis = expiryTime.getTimeInMillis(); | |
long readTime = key.getReadTime(); | |
if (currentTimeMillis < expiryMillis) { | |
long previousExpiryMillis = previousExpiry.getTimeInMillis(); | |
if (readTime >= previousExpiryMillis) { | |
// both current time and read time are between expiry yesterday and expiry today - not expired | |
return false; | |
} else if (currentTimeMillis >= previousExpiryMillis) { | |
// read time is less than previous expiry and current time is after it. - expired and need update of expiry | |
return true; | |
} else { | |
// read time is before previous expiry and so is current time - strange case, but not expired | |
return false; | |
} | |
} else { | |
if (readTime < expiryMillis) { | |
// current time is greater than expiry and read time is before - expire and update expiry | |
incrementExpiry(); | |
return true; | |
} else { | |
// current time and read time are greater than expiry - no expire and update expiry | |
incrementExpiry(); | |
return false; | |
} | |
} | |
} | |
/** | |
* INTERNAL: | |
* Update the expiry time to be the day after the current day. | |
*/ | |
public void incrementExpiry() { | |
long currentTimeMillis = System.currentTimeMillis(); | |
long expiryInMillis = expiryTime.getTimeInMillis(); | |
if (currentTimeMillis <= expiryInMillis) { | |
// no updated needed. Return for efficiency | |
return; | |
} | |
while (currentTimeMillis > expiryTime.getTimeInMillis()) { | |
// increment the expiry time until it is after the current time | |
previousExpiry.add(Calendar.DAY_OF_YEAR, 1); | |
expiryTime.add(Calendar.DAY_OF_YEAR, 1); | |
} | |
} | |
/** | |
* PUBLIC: | |
* Set a new expiry time for this object | |
* Provide the hour, minute, second and millisecond. Objects which make use of this policy | |
* will be set to expire at that exact time every day. | |
*/ | |
public void setExpiryTime(int hour, int minute, int second, int millisecond) { | |
expiryTime = Calendar.getInstance(); | |
expiryTime.set(Calendar.HOUR_OF_DAY, hour); | |
expiryTime.set(Calendar.MINUTE, minute); | |
expiryTime.set(Calendar.SECOND, second); | |
expiryTime.set(Calendar.MILLISECOND, millisecond); | |
previousExpiry = (Calendar)expiryTime.clone(); | |
previousExpiry.add(Calendar.DAY_OF_YEAR, -1); | |
incrementExpiry(); | |
} | |
/** | |
* INTERNAL: | |
* Set the expiry time based on a Calendar. Used for setting the expiry time from | |
* deployment XML. | |
*/ | |
public void setExpiryTime(Calendar calendar) { | |
setExpiryTime(calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND), calendar.get(Calendar.MILLISECOND)); | |
} | |
public Object clone() { | |
DailyCacheInvalidationPolicy clone = null; | |
try { | |
clone = (DailyCacheInvalidationPolicy)super.clone(); | |
if (this.expiryTime != null) { | |
clone.setExpiryTime((Calendar)this.expiryTime.clone()); | |
} | |
if (this.previousExpiry != null) { | |
clone.previousExpiry = (Calendar)this.previousExpiry.clone(); | |
} | |
} catch (Exception exception) { | |
throw new InternalError("clone failed"); | |
} | |
return clone; | |
} | |
} |