
org.opensaml.util.resource.ResourceChangeWatcher Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of openws Show documentation
Show all versions of openws Show documentation
The OpenWS library provides a growing set of tools to work with web services at a low level. These tools include
classes for creating and reading SOAP messages, transport-independent clients for connecting to web services,
and various transports for use with those clients.
/*
* Copyright 2006 University Corporation for Advanced Internet Development, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.opensaml.util.resource;
import java.util.ArrayList;
import java.util.List;
import java.util.TimerTask;
import org.joda.time.DateTime;
import org.opensaml.util.resource.ResourceChangeListener.ResourceChange;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A watcher that invokes a callback when a resource update/deletion has been detected.
*/
public class ResourceChangeWatcher extends TimerTask {
/** Default polling frequency, 12 hours. */
public static final long DEFAULT_POLL_FREQUENCY = 1000 * 60 * 60 * 12;
/** Default maximum retry attempts, 0. */
public static final int DEFAULT_MAX_RETRY_ATTEMPTS = 0;
/** Class logger. */
private final Logger log = LoggerFactory.getLogger(ResourceChangeWatcher.class);
/** Resource being watched. */
private Resource watchedResource;
/** Frequency, in milliseconds, the resource is polled for changes. */
private long pollFrequency;
/** Max number of polls to try before considering the resource inaccessible. */
private int maxRetryAttempts;
/** Number of times the resource has been polled but generated an error. */
private int currentRetryAttempts;
/** Whether the resource currently exists. */
private boolean resourceExist;
/** Last time the resource was modified. */
private DateTime lastModification;
/** Registered listeners of resource change notifications. */
private List resourceListeners;
/**
* Constructor.
*
* @param resource the resource to be watched
*
* @throws ResourceException thrown if resource existence or last modification time can not be determined
*/
public ResourceChangeWatcher(Resource resource) throws ResourceException {
this(resource, DEFAULT_POLL_FREQUENCY, DEFAULT_MAX_RETRY_ATTEMPTS);
}
/**
* Constructor.
*
* @param resource the resource to be watched
* @param pollingFrequency the frequency, in milliseconds, to poll the resource for changes
*
* @throws ResourceException thrown if resource existence or last modification time can not be determined
*/
public ResourceChangeWatcher(Resource resource, long pollingFrequency) throws ResourceException {
this(resource, pollingFrequency, DEFAULT_MAX_RETRY_ATTEMPTS);
}
/**
* Constructor.
*
* @param resource the resource to be watched
* @param pollingFrequency the frequency, in milliseconds, to poll the resource for changes
* @param retryAttempts maximum number of poll attempts before the resource is considered inaccessible
*
* @throws ResourceException thrown if resource existence or last modification time can not be determined
*/
public ResourceChangeWatcher(Resource resource, long pollingFrequency, int retryAttempts) throws ResourceException {
if (resource == null) {
throw new NullPointerException("Watched resource is null");
}
if (pollingFrequency <= 0) {
throw new IllegalArgumentException("Polling frequency must be greater than zero");
}
if (retryAttempts < 0) {
throw new IllegalArgumentException("Max retry attempts must be greater than, or equal to, zero");
}
watchedResource = resource;
pollFrequency = pollingFrequency;
maxRetryAttempts = retryAttempts;
currentRetryAttempts = 0;
if (watchedResource.exists()) {
resourceExist = true;
lastModification = watchedResource.getLastModifiedTime();
} else {
resourceExist = false;
}
resourceListeners = new ArrayList(5);
log.debug("Watching resource: " + watchedResource.getLocation()
+ ", polling frequency: {}ms, max retry attempts: {}", pollFrequency, maxRetryAttempts);
}
/**
* Gets the frequency, in milliseconds, the watched resource should be polled.
*
* @return frequency the watched resource should be polled
*/
public long getPollingFrequency() {
return pollFrequency;
}
/**
* Gets the list of registered resource listeners. New listeners may be registered with the list or old ones
* removed.
*
* @return list of registered resource listeners
*/
public List getResourceListeners() {
return resourceListeners;
}
/** {@inheritDoc} */
public void run() {
try {
log.trace("Checking resource for changes: {}", watchedResource.getLocation());
if (watchedResource.exists()) {
if (!resourceExist) {
resourceExist = true;
signalListeners(ResourceChange.CREATION);
lastModification = watchedResource.getLastModifiedTime();
} else {
if (lastModification.isBefore(watchedResource.getLastModifiedTime())) {
signalListeners(ResourceChange.UPDATE);
lastModification = watchedResource.getLastModifiedTime();
}
}
} else {
if (resourceExist) {
resourceExist = false;
signalListeners(ResourceChange.DELETE);
}
}
currentRetryAttempts = 0;
} catch (ResourceException e) {
log.warn("Resource " + watchedResource.getLocation() + " could not be accessed", e);
currentRetryAttempts++;
if (currentRetryAttempts >= maxRetryAttempts) {
cancel();
log.error("Resource " + watchedResource.getLocation()
+ " was not accessible for max number of retry attempts. This resource will no longer be watched");
}
}
}
/**
* Signals all registered listeners of a resource change.
*
* @param changeType the resource change type
*/
protected void signalListeners(ResourceChange changeType) {
synchronized (resourceListeners) {
switch (changeType) {
case CREATION:
log.debug("Publishing creation event for resource: {}", watchedResource.getLocation());
for (ResourceChangeListener listener : resourceListeners) {
listener.onResourceCreate(watchedResource);
}
break;
case UPDATE:
log.debug("Publishing update event for resource: {}", watchedResource.getLocation());
for (ResourceChangeListener listener : resourceListeners) {
listener.onResourceUpdate(watchedResource);
}
break;
case DELETE:
log.debug("Publishing delete event for resource: {}", watchedResource.getLocation());
for (ResourceChangeListener listener : resourceListeners) {
listener.onResourceDelete(watchedResource);
}
break;
default:
break;
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy