/*=============================================================================*
* Copyright 2006 The Apache Software Foundation
*
* 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.apache.muse.ws.resource.lifetime.impl;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.TimerTask;
import javax.xml.namespace.QName;
import org.apache.muse.core.routing.MessageHandler;
import org.apache.muse.util.LoggingUtils;
import org.apache.muse.util.ReflectUtils;
import org.apache.muse.util.Timer;
import org.apache.muse.util.messages.Messages;
import org.apache.muse.util.messages.MessagesFactory;
import org.apache.muse.ws.resource.WsResource;
import org.apache.muse.ws.resource.impl.AbstractWsResourceCapability;
import org.apache.muse.ws.resource.lifetime.ScheduledTermination;
import org.apache.muse.ws.addressing.soap.SoapFault;
/**
*
* SimpleScheduledTermination is Muse's default implementation of the WS-RL
* ScheduledResourceTermination capability. It uses Java's built in timer
* mechanism to manage scheduled terminations. This class does not provide any
* actual resource shutdown operations - it only removes the resource's visibility
* to internal and external clients at a specified time.
*
* @author Dan Jemiolo (danj)
*
*/
public class SimpleScheduledTermination
extends AbstractWsResourceCapability implements ScheduledTermination
{
//
// Used to lookup all exception messages
//
protected static Messages _MESSAGES =
MessagesFactory.get(SimpleScheduledTermination.class);
//
// Used to fire the timer task that kills the resource if/when the
// termination time is reached
//
private Timer _terminationTimer = null;
protected MessageHandler createSetTerminationTimeHandler()
{
MessageHandler handler = new SetTerminationTimeHandler();
Method method = ReflectUtils.getFirstMethod(getClass(), "setTerminationTime");
handler.setMethod(method);
return handler;
}
public Date getCurrentTime()
{
return new Date();
}
public QName[] getPropertyNames()
{
return PROPERTIES;
}
public Date getTerminationTime()
{
return _terminationTimer.getScheduledTime();
}
public void initialize()
throws SoapFault
{
super.initialize();
//
// create the timer that can be used for acting on the
// termination time, but DON'T start it
//
TimerTask scheduledDestruction = new DestroyTimerTask(getWsResource());
_terminationTimer = new Timer(scheduledDestruction);
setMessageHandler(createSetTerminationTimeHandler());
}
public Date setTerminationTime(Date time)
{
//
// case 1: null time, so we're cancelling the timer
//
if (time == null)
_terminationTimer.cancel();
//
// case 2: valid time, no previous time, we're scheduling
// the timer for the first time
//
else if (_terminationTimer.getScheduledTime() == null)
_terminationTimer.schedule(time);
//
// case 3: valid time, previous time exists, we're rescheduling
//
else
_terminationTimer.reschedule(time);
return time;
}
public void shutdown()
throws SoapFault
{
//
// make sure we stop the timer so we don't get a concurrency error
// by trying to terminate ourselves in the midst of termination
//
_terminationTimer.cancel();
super.shutdown();
}
/**
*
* DestroyTimerTask is a simple {@linkplain TimerTask TimerTask} that invokes
* a Resource's shutdown() method. It does not perform any the actual
* destruction or cleanup tasks.
*
* @author Dan Jemiolo (danj)
*
*/
class DestroyTimerTask extends TimerTask
{
private WsResource _resource = null;
public DestroyTimerTask(WsResource resource)
{
_resource = resource;
}
/**
*
* Invokes the resource's WS-RL Destroy operation.
*
*/
public void run()
{
try
{
_resource.shutdown();
}
catch (SoapFault fault)
{
//
// If the resource destructor fails, there's not much
// we can do - there is no caller to report back to,
// so we just log the info
//
LoggingUtils.logError(_resource.getLog(), fault);
}
}
}
}