001/* 002 * jPOS Project [http://jpos.org] 003 * Copyright (C) 2000-2026 jPOS Software SRL 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU Affero General Public License as 007 * published by the Free Software Foundation, either version 3 of the 008 * License, or (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Affero General Public License for more details. 014 * 015 * You should have received a copy of the GNU Affero General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018 019package org.jpos.q2.iso; 020 021import org.jdom2.Element; 022import org.jpos.core.Configurable; 023import org.jpos.iso.ISOUtil; 024import org.jpos.q2.QBeanSupport; 025import org.jpos.q2.QFactory; 026 027import java.util.Calendar; 028import java.util.Date; 029import java.util.GregorianCalendar; 030 031/** 032 * DailyTask Adaptor 033 * 034 * @author Alejandro Revilla 035 * @version $Revision$ $Date$ 036 */ 037/** QBean adaptor that runs a configured {@link Runnable} task once per day at a configured time. */ 038public class DailyTaskAdaptor extends QBeanSupport implements Runnable { 039 /** The task to execute daily. */ 040 Runnable task; 041 /** The thread running the task loop. */ 042 Thread thisThread = null; 043 044 /** Default constructor. */ 045 public DailyTaskAdaptor () { 046 super (); 047 } 048 049 protected void initService () throws Exception { 050 QFactory factory = getServer().getFactory(); 051 Element e = getPersist (); 052 task = (Runnable) factory.newInstance (e.getChildTextTrim ("class")); 053 factory.setLogger (task, e); 054 } 055 protected void startService () throws Exception { 056 if (task instanceof Configurable) { 057 Element e = getPersist (); 058 QFactory factory = getServer().getFactory(); 059 ((Configurable)task).setConfiguration ( 060 factory.getConfiguration (e) 061 ); 062 } 063 (thisThread = new Thread(this)).start(); 064 } 065 protected void stopService () throws Exception { 066 if (thisThread != null) 067 thisThread.interrupt(); 068 } 069 public void run () { 070 while (running()) { 071 waitUntilStartTime(); 072 if (running()) { 073 Thread taskThread = new Thread(task); 074 taskThread.setDaemon (true); 075 taskThread.start(); 076 ISOUtil.sleep (1000); 077 } 078 } 079 } 080 /** 081 * Returns the next scheduled execution time based on the {@code start} configuration property. 082 * @return the next execution {@link Date} 083 */ 084 public Date getWhen() { 085 String s = cfg.get ("start")+":00:00"; // NOPMD 086 int hh = Integer.parseInt(s.substring (0, 2)); 087 int mm = Integer.parseInt(s.substring (3, 5)); 088 int ss = Integer.parseInt(s.substring (6, 8)); 089 090 Date now = new Date(); 091 Calendar cal = new GregorianCalendar(); 092 093 cal.setTime (now); 094 cal.set (Calendar.HOUR_OF_DAY, hh); 095 cal.set (Calendar.MINUTE, mm); 096 cal.set (Calendar.SECOND, ss); 097 098 Date when = cal.getTime(); 099 if (when.before(now)) 100 when = new Date(when.getTime() + 24*60*60*1000); 101 102 return when; 103 } 104 /** Blocks the current thread until the daily start time arrives. */ 105 protected void waitUntilStartTime() { 106 Date when = getWhen(); 107 while (running()) { 108 Date now = new GregorianCalendar().getTime(); 109 if (now.before (when)) { 110 long sleepTime = when.getTime() - now.getTime(); 111 if (sleepTime <= 0) { 112 ISOUtil.sleep(1000); 113 continue; 114 } 115 getLog().info ("sleeping", 116 sleepTime/1000 + " secs until " + when.toString() 117 ); 118 try { 119 Thread.sleep (sleepTime); 120 } catch (InterruptedException e) { 121 when = getWhen(); 122 } 123 } else 124 break; 125 } 126 } 127} 128