blob: e8ce909abf9f1a862f9a6fdc666ccae69dc655a4 [file] [log] [blame]
/*
* Copyright (c) 1998, 2020 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 v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// 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.
*/
@Override
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
*/
@Override
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));
}
@Override
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;
}
}