//# 0 errors, 93 messages
//#
/*
    //#RollerTask.java:1:1: class: org.apache.roller.weblogger.business.runnable.RollerTask
 * Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  The ASF licenses this file to You
 * 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.  For additional information regarding
 * copyright in this work, please see the NOTICE file in the top level
 * directory of this distribution.
 */

package org.apache.roller.weblogger.business.runnable;

import java.util.Date;
import java.util.Enumeration;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.roller.weblogger.WebloggerException;
import org.apache.roller.weblogger.config.WebloggerConfig;
import org.apache.roller.util.DateUtil;


/**
 * An abstract class representing a scheduled task in Roller.
 *
 * This class extends the java.util.TimerTask class and adds in some Roller
 * specifics.
 */
public abstract class RollerTask implements Runnable {
    //#RollerTask.java:37: method: void org.apache.roller.weblogger.business.runnable.RollerTask.org.apache.roller.weblogger.business.runnable.RollerTask()
    //#RollerTask.java:37: end of method: void org.apache.roller.weblogger.business.runnable.RollerTask.org.apache.roller.weblogger.business.runnable.RollerTask()
    
    private static Log log = LogFactory.getLog(RollerTask.class);
    //#RollerTask.java:39: method: org.apache.roller.weblogger.business.runnable.RollerTask.org.apache.roller.weblogger.business.runnable.RollerTask__static_init
    //#RollerTask.java:39: Warning: method not available
    //#    -- call on Log org.apache.commons.logging.LogFactory:getLog(Class)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.business.runnable.RollerTask
    //#    method: org.apache.roller.weblogger.business.runnable.RollerTask__static_init
    //#    unanalyzed callee: Log org.apache.commons.logging.LogFactory:getLog(Class)
    //#output(org.apache.roller.weblogger.business.runnable.RollerTask__static_init): __Descendant_Table[org/apache/roller/weblogger/business/runnable/RollerTask]
    //#output(org.apache.roller.weblogger.business.runnable.RollerTask__static_init): __Dispatch_Table.getAdjustedTime(Ljava/util/Date;Ljava/lang/String;)Ljava/util/Date;
    //#output(org.apache.roller.weblogger.business.runnable.RollerTask__static_init): __Dispatch_Table.getClientId()Ljava/lang/String;
    //#output(org.apache.roller.weblogger.business.runnable.RollerTask__static_init): __Dispatch_Table.getInterval()I
    //#output(org.apache.roller.weblogger.business.runnable.RollerTask__static_init): __Dispatch_Table.getLeaseTime()I
    //#output(org.apache.roller.weblogger.business.runnable.RollerTask__static_init): __Dispatch_Table.getName()Ljava/lang/String;
    //#output(org.apache.roller.weblogger.business.runnable.RollerTask__static_init): __Dispatch_Table.getStartTime(Ljava/util/Date;)Ljava/util/Date;
    //#output(org.apache.roller.weblogger.business.runnable.RollerTask__static_init): __Dispatch_Table.getStartTimeDesc()Ljava/lang/String;
    //#output(org.apache.roller.weblogger.business.runnable.RollerTask__static_init): __Dispatch_Table.getTaskProperties()Ljava/util/Properties;
    //#output(org.apache.roller.weblogger.business.runnable.RollerTask__static_init): __Dispatch_Table.init()V
    //#output(org.apache.roller.weblogger.business.runnable.RollerTask__static_init): log
    //#post(org.apache.roller.weblogger.business.runnable.RollerTask__static_init): __Descendant_Table[org/apache/roller/weblogger/business/runnable/RollerTask] == &__Dispatch_Table
    //#post(org.apache.roller.weblogger.business.runnable.RollerTask__static_init): __Dispatch_Table.getAdjustedTime(Ljava/util/Date;Ljava/lang/String;)Ljava/util/Date; == &getAdjustedTime
    //#post(org.apache.roller.weblogger.business.runnable.RollerTask__static_init): __Dispatch_Table.getClientId()Ljava/lang/String; == &getClientId
    //#post(org.apache.roller.weblogger.business.runnable.RollerTask__static_init): __Dispatch_Table.getInterval()I == &getInterval
    //#post(org.apache.roller.weblogger.business.runnable.RollerTask__static_init): __Dispatch_Table.getLeaseTime()I == &getLeaseTime
    //#post(org.apache.roller.weblogger.business.runnable.RollerTask__static_init): __Dispatch_Table.getName()Ljava/lang/String; == &getName
    //#post(org.apache.roller.weblogger.business.runnable.RollerTask__static_init): __Dispatch_Table.getStartTime(Ljava/util/Date;)Ljava/util/Date; == &getStartTime
    //#post(org.apache.roller.weblogger.business.runnable.RollerTask__static_init): __Dispatch_Table.getStartTimeDesc()Ljava/lang/String; == &getStartTimeDesc
    //#post(org.apache.roller.weblogger.business.runnable.RollerTask__static_init): __Dispatch_Table.getTaskProperties()Ljava/util/Properties; == &getTaskProperties
    //#post(org.apache.roller.weblogger.business.runnable.RollerTask__static_init): __Dispatch_Table.init()V == &init
    //#post(org.apache.roller.weblogger.business.runnable.RollerTask__static_init): init'ed(log)
    //#RollerTask.java:39: end of method: org.apache.roller.weblogger.business.runnable.RollerTask.org.apache.roller.weblogger.business.runnable.RollerTask__static_init
    
    
    /**
     * Initialization.  Run once before the task is started.
     */
    public void init() throws WebloggerException {
        // no-op by default
    }
    //#RollerTask.java:47: method: void org.apache.roller.weblogger.business.runnable.RollerTask.init()
    //#RollerTask.java:47: end of method: void org.apache.roller.weblogger.business.runnable.RollerTask.init()
    
    
    /**
     * Get the unique name for this task.
     *
     * @return The unique name for this task.
     */
    public abstract String getName();
    
    
    /**
     * Get the unique id representing a specific instance of a task.  This is
     * important for tasks being run in a clustered environment so that a 
     * lease can be associated with a single cluster member.
     *
     * @return The unique client identifier for this task instance.
     */
    public abstract String getClientId();
    
    
    /**
     * When should this task be started?  The task is given the current time
     * so that it may determine a start time relative to the current time, 
     * such as the end of the day or hour.
     *
     * It is acceptable to return the currentTime object passed in or any other
     * time after it.  If the return value is before currentTime then it will
     * be ignored and the task will be started at currentTime.
     *
     * @param currentTime The current time.
     * @return The Date when this task should be started.
     */
    public abstract Date getStartTime(Date currentTime);
    
    
    /**
     * Get a string description of the start time of the given task.
     * 
     * Should be one of ... 'immediate', 'startOfDay', 'startOfHour'
     * 
     * @return The start time description.
     */
    public abstract String getStartTimeDesc();
    
    
    /**
     * How often should the task run, in seconds.
     *
     * example: 3600 means this task runs once every hour.
     *
     * @return The interval the task should be run at, in minutes.
     */
    public abstract int getInterval();
    
    
    /**
     * Get the time, in seconds, this task wants to be leased for.
     *
     * example: 300 means the task is allowed 5 minutes to run.
     *
     * @return The time this task should lease its lock for, in minutes.
     */
    public abstract int getLeaseTime();
    
    
    /**
     * Get the properties from WebloggerConfig which pertain to this task.
     * 
     * This extracts all properties from the WebloggerConfig of the type
     * task.<taskname>.<prop>=value and returns them in a properties object
     * where each item is keyed by <prop>.
     */
    protected Properties getTaskProperties() {
        
        String prefix = "tasks."+this.getName()+".";
    //#RollerTask.java:122: method: Properties org.apache.roller.weblogger.business.runnable.RollerTask.getTaskProperties()
    //#RollerTask.java:122: Warning: suspicious precondition
    //#    the precondition for this.__Tag is not a contiguous range of values
    //#    severity: SUPPRESSED
    //#    class: org.apache.roller.weblogger.business.runnable.RollerTask
    //#    method: Properties getTaskProperties()
    //#    suspicious precondition index: [4]
    //#input(Properties getTaskProperties()): "."._tainted
    //#input(Properties getTaskProperties()): "="._tainted
    //#input(Properties getTaskProperties()): "Fetching property ["._tainted
    //#input(Properties getTaskProperties()): "PingQueueTask"._tainted
    //#input(Properties getTaskProperties()): "ResetHitCountsTask"._tainted
    //#input(Properties getTaskProperties()): "ScheduledEntriesTask"._tainted
    //#input(Properties getTaskProperties()): "TurnoverReferersTask"._tainted
    //#input(Properties getTaskProperties()): "]"._tainted
    //#input(Properties getTaskProperties()): "tasks."._tainted
    //#input(Properties getTaskProperties()): "tasks.clientId"._tainted
    //#input(Properties getTaskProperties()): __Descendant_Table[org/apache/roller/weblogger/business/pings/PingQueueTask]
    //#input(Properties getTaskProperties()): __Descendant_Table[org/apache/roller/weblogger/business/runnable/ResetHitCountsTask]
    //#input(Properties getTaskProperties()): __Descendant_Table[org/apache/roller/weblogger/business/runnable/RollerTaskWithLeasing]
    //#input(Properties getTaskProperties()): __Descendant_Table[org/apache/roller/weblogger/business/runnable/RollerTask]
    //#input(Properties getTaskProperties()): __Descendant_Table[org/apache/roller/weblogger/business/runnable/ScheduledEntriesTask]
    //#input(Properties getTaskProperties()): __Descendant_Table[org/apache/roller/weblogger/business/runnable/TurnoverReferersTask]
    //#input(Properties getTaskProperties()): __Descendant_Table[others]
    //#input(Properties getTaskProperties()): __Dispatch_Table.getName()Ljava/lang/String;
    //#input(Properties getTaskProperties()): org/apache/roller/weblogger/business/pings/PingQueueTask.__Dispatch_Table.getName()Ljava/lang/String;
    //#input(Properties getTaskProperties()): org/apache/roller/weblogger/business/runnable/ResetHitCountsTask.__Dispatch_Table.getName()Ljava/lang/String;
    //#input(Properties getTaskProperties()): org/apache/roller/weblogger/business/runnable/RollerTaskWithLeasing.__Dispatch_Table.getName()Ljava/lang/String;
    //#input(Properties getTaskProperties()): org/apache/roller/weblogger/business/runnable/ScheduledEntriesTask.__Dispatch_Table.getName()Ljava/lang/String;
    //#input(Properties getTaskProperties()): org/apache/roller/weblogger/business/runnable/TurnoverReferersTask.__Dispatch_Table.getName()Ljava/lang/String;
    //#input(Properties getTaskProperties()): org/apache/roller/weblogger/config/WebloggerConfig.config
    //#input(Properties getTaskProperties()): org/apache/roller/weblogger/config/WebloggerConfig.log
    //#input(Properties getTaskProperties()): this
    //#input(Properties getTaskProperties()): this.__Tag
    //#output(Properties getTaskProperties()): new Properties(getTaskProperties#2) num objects
    //#output(Properties getTaskProperties()): return_value
    //#new obj(Properties getTaskProperties()): new Properties(getTaskProperties#2)
    //#pre[1] (Properties getTaskProperties()): org/apache/roller/weblogger/config/WebloggerConfig.config != null
    //#pre[2] (Properties getTaskProperties()): org/apache/roller/weblogger/config/WebloggerConfig.log != null
    //#pre[4] (Properties getTaskProperties()): this.__Tag in {org/apache/roller/weblogger/business/pings/PingQueueTask, org/apache/roller/weblogger/business/runnable/ResetHitCountsTask, org/apache/roller/weblogger/business/runnable/RollerTask, org/apache/roller/weblogger/business/runnable/RollerTaskWithLeasing, org/apache/roller/weblogger/business/runnable/ScheduledEntriesTask, org/apache/roller/weblogger/business/runnable/TurnoverReferersTask}
    //#presumption(Properties getTaskProperties()): java.util.Enumeration:nextElement(...)@129 != null
    //#presumption(Properties getTaskProperties()): java.util.Properties:keys(...)@205 != null
    //#post(Properties getTaskProperties()): return_value == &new Properties(getTaskProperties#2)
    //#post(Properties getTaskProperties()): new Properties(getTaskProperties#2) num objects == 1
    //#unanalyzed(Properties getTaskProperties()): Effects-of-calling:java.util.Properties:keys
    //#unanalyzed(Properties getTaskProperties()): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(Properties getTaskProperties()): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(Properties getTaskProperties()): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(Properties getTaskProperties()): Effects-of-calling:java.lang.String:trim
    //#unanalyzed(Properties getTaskProperties()): Effects-of-calling:org.apache.commons.logging.Log:debug
    //#unanalyzed(Properties getTaskProperties()): Effects-of-calling:java.util.Properties:getProperty
    //#test_vector(Properties getTaskProperties()): java.lang.String:startsWith(...)@131: {0}, {1}
    //#test_vector(Properties getTaskProperties()): java.util.Enumeration:hasMoreElements(...)@128: {0}, {1}
        
        Properties taskProps = new Properties();
        
        String key = null;
    //#RollerTask.java:126: Warning: unused assignment
    //#    unused assignment into key
    //#    severity: SUPPRESSED
    //#    class: org.apache.roller.weblogger.business.runnable.RollerTask
    //#    method: Properties getTaskProperties()
    //#    Attribs:  Uncertain
        Enumeration keys = WebloggerConfig.keys();
        while(keys.hasMoreElements()) {
            key = (String) keys.nextElement();
            
            if(key.startsWith(prefix)) {
                taskProps.setProperty(key.substring(prefix.length()), 
                        WebloggerConfig.getProperty(key));
            }
        }
        
        // special addition for clientId property that applies to all tasks
        taskProps.setProperty("clientId", WebloggerConfig.getProperty("tasks.clientId"));
        
        return taskProps;
    //#RollerTask.java:140: end of method: Properties org.apache.roller.weblogger.business.runnable.RollerTask.getTaskProperties()
    }
    
    
    /**
     * A convenience method for calculating an adjusted time given an initial
     * Date to work from and a "changeFactor" which describes how the time 
     * should be adjusted.
     *
     * Allowed change factors are ...
     *   'immediate' - no change
     *   'startOfHour' - top of the hour, beginning with next hour
     *   'startOfDay' - midnight, beginning on the next day
     */
    protected Date getAdjustedTime(Date startTime, String changeFactor) {
        
        if(startTime == null || changeFactor == null) {
    //#RollerTask.java:156: method: Date org.apache.roller.weblogger.business.runnable.RollerTask.getAdjustedTime(Date, String)
    //#input(Date getAdjustedTime(Date, String)): changeFactor
    //#input(Date getAdjustedTime(Date, String)): startTime
    //#output(Date getAdjustedTime(Date, String)): return_value
    //#post(Date getAdjustedTime(Date, String)): init'ed(return_value)
    //#test_vector(Date getAdjustedTime(Date, String)): changeFactor: Inverse{null}, Addr_Set{null}
    //#test_vector(Date getAdjustedTime(Date, String)): startTime: Addr_Set{null}, Inverse{null}
    //#test_vector(Date getAdjustedTime(Date, String)): java.lang.String:equals(...)@162: {0}, {1}
    //#test_vector(Date getAdjustedTime(Date, String)): java.lang.String:equals(...)@164: {0}, {1}
            return startTime;
        }
        
        Date adjustedTime = startTime;
        
        if("startOfDay".equals(changeFactor)) {
            adjustedTime = DateUtil.getEndOfDay(startTime);
    //#RollerTask.java:163: Warning: method not available
    //#    -- call on Date org.apache.roller.util.DateUtil:getEndOfDay(Date)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.business.runnable.RollerTask
    //#    method: Date getAdjustedTime(Date, String)
    //#    unanalyzed callee: Date org.apache.roller.util.DateUtil:getEndOfDay(Date)
        } else if("startOfHour".equals(changeFactor)) {
            adjustedTime = DateUtil.getEndOfHour(startTime);
    //#RollerTask.java:165: Warning: method not available
    //#    -- call on Date org.apache.roller.util.DateUtil:getEndOfHour(Date)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.business.runnable.RollerTask
    //#    method: Date getAdjustedTime(Date, String)
    //#    unanalyzed callee: Date org.apache.roller.util.DateUtil:getEndOfHour(Date)
        }
        
        return adjustedTime;
    //#RollerTask.java:168: end of method: Date org.apache.roller.weblogger.business.runnable.RollerTask.getAdjustedTime(Date, String)
    }
    
}
    //#RollerTask.java:: end of class: org.apache.roller.weblogger.business.runnable.RollerTask
