1 22 package org.jboss.varia.scheduler; 23 24 import java.lang.reflect.Constructor ; 25 import java.security.InvalidParameterException ; 26 import java.text.SimpleDateFormat ; 27 import java.util.Date ; 28 import java.util.StringTokenizer ; 29 import java.util.Vector ; 30 import java.util.Arrays ; 31 32 import javax.management.InstanceNotFoundException ; 33 import javax.management.MalformedObjectNameException ; 34 import javax.management.Notification ; 35 import javax.management.NotificationEmitter ; 36 import javax.management.NotificationListener ; 37 import javax.management.ObjectName ; 38 import javax.management.MBeanServerInvocationHandler ; 39 import javax.management.timer.Timer ; 40 import javax.management.timer.TimerMBean ; 41 import javax.management.timer.TimerNotification ; 42 43 import org.jboss.logging.Logger; 44 import org.jboss.system.ServiceMBeanSupport; 45 import org.jboss.util.Classes; 46 47 68 public class Scheduler extends ServiceMBeanSupport 69 implements SchedulerMBean 70 { 71 72 76 public static String JNDI_NAME = "scheduler:domain"; 77 public static String JMX_NAME = "scheduler"; 78 public static String DEFAULT_TIMER_NAME = ScheduleManager.DEFAULT_TIMER_NAME; 79 80 private static final int NOTIFICATION = 0; 81 private static final int DATE = 1; 82 private static final int REPETITIONS = 2; 83 private static final int SCHEDULER_NAME = 3; 84 private static final int NULL = 4; 85 86 90 private long mActualSchedulePeriod; 91 private long mRemainingRepetitions = 0; 92 private int mNotificationID = -1; 93 private String mTimerName = DEFAULT_TIMER_NAME; 94 private ObjectName mTimerObjectName; 95 private TimerMBean mTimer; 96 private NotificationEmitter mTimerEmitter; 97 private Schedulable mSchedulable; 98 99 private boolean mScheduleIsStarted = false; 100 private boolean mWaitForNextCallToStop = false; 101 private boolean mStartOnStart = false; 102 private boolean mIsRestartPending = true; 103 104 private boolean mUseMBean = false; 106 107 private Class mSchedulableClass; 108 private String mSchedulableArguments; 109 private String [] mSchedulableArgumentList = new String [0]; 110 private String mSchedulableArgumentTypes; 111 private Class [] mSchedulableArgumentTypeList = new Class [0]; 112 113 private ObjectName mSchedulableMBean; 114 private String mSchedulableMBeanMethod; 115 private String mSchedulableMBeanMethodName; 116 private int[] mSchedulableMBeanArguments = new int[0]; 117 private String [] mSchedulableMBeanArgumentTypes = new String [0]; 118 119 private SimpleDateFormat mDateFormatter; 120 private Date mStartDate; 121 private String mStartDateString; 122 private boolean mStartDateIsNow; 123 private long mSchedulePeriod; 124 private long mInitialRepetitions; 125 private boolean mFixedRate = false; 126 127 private NotificationListener mListener; 128 129 133 136 public Scheduler() 137 { 138 } 139 140 145 public Scheduler(String pSchedulableClass, 146 long pSchedulePeriod) 147 { 148 setStartAtStartup(true); 149 setSchedulableClass(pSchedulableClass); 150 setSchedulePeriod(pSchedulePeriod); 151 } 152 153 162 public Scheduler(String pSchedulableClass, 163 String pInitArguments, 164 String pInitTypes, 165 String pInitialStartDate, 166 long pSchedulePeriod, 167 long pNumberOfRepetitions 168 ) 169 { 170 setStartAtStartup(true); 171 setSchedulableClass(pSchedulableClass); 172 setSchedulableArguments(pInitArguments); 173 setSchedulableArgumentTypes(pInitTypes); 174 setInitialStartDate(pInitialStartDate); 175 setSchedulePeriod(pSchedulePeriod); 176 setInitialRepetitions(pNumberOfRepetitions); 177 } 178 179 189 public Scheduler( 190 String pSchedulableClass, 191 String pInitArguments, 192 String pInitTypes, 193 String pDateFormat, 194 String pInitialStartDate, 195 long pSchedulePeriod, 196 long pNumberOfRepetitions 197 ) 198 { 199 setStartAtStartup(true); 200 setSchedulableClass(pSchedulableClass); 201 setSchedulableArguments(pInitArguments); 202 setSchedulableArgumentTypes(pInitTypes); 203 setDateFormat(pDateFormat); 204 setInitialStartDate(pInitialStartDate); 205 setSchedulePeriod(pSchedulePeriod); 206 setInitialRepetitions(pNumberOfRepetitions); 207 } 208 209 214 private void checkMBean() { 215 if (mSchedulableMBean == null) 216 { 217 log.debug("Schedulable MBean Object Name is not set"); 218 throw new InvalidParameterException ( 219 "Schedulable MBean must be set" 220 ); 221 } 222 if (mSchedulableMBeanMethodName == null) 223 { 224 mSchedulableMBeanMethodName = "perform"; 225 mSchedulableMBeanArguments = new int[]{DATE, REPETITIONS}; 226 mSchedulableMBeanArgumentTypes = new String []{ 227 Date .class.getName(), 228 Integer.TYPE.getName() 229 }; 230 } 231 } 232 233 private void createSchedulable() { 234 if (mSchedulableClass == null) 235 { 236 throw new InvalidParameterException ("Schedulable Class not set"); 237 } 238 if (mSchedulableArgumentList.length != mSchedulableArgumentTypeList.length) 239 { 240 throw new InvalidParameterException ( 241 "Schedulable Class Arguments and Types do not match in length" 242 ); 243 } 244 Object [] lArgumentList = new Object [mSchedulableArgumentTypeList.length]; 246 try 247 { 248 for (int i = 0; i < mSchedulableArgumentTypeList.length; i++) 249 { 250 Class lClass = mSchedulableArgumentTypeList[i]; 251 if (lClass == Boolean.TYPE) 252 { 253 lArgumentList[i] = new Boolean (mSchedulableArgumentList[i]); 254 } 255 else if (lClass == Integer.TYPE) 256 { 257 lArgumentList[i] = new Integer (mSchedulableArgumentList[i]); 258 } 259 else if (lClass == Long.TYPE) 260 { 261 lArgumentList[i] = new Long (mSchedulableArgumentList[i]); 262 } 263 else if (lClass == Short.TYPE) 264 { 265 lArgumentList[i] = new Short (mSchedulableArgumentList[i]); 266 } 267 else if (lClass == Float.TYPE) 268 { 269 lArgumentList[i] = new Float (mSchedulableArgumentList[i]); 270 } 271 else if (lClass == Double.TYPE) 272 { 273 lArgumentList[i] = new Double (mSchedulableArgumentList[i]); 274 } 275 else if (lClass == Byte.TYPE) 276 { 277 lArgumentList[i] = new Byte (mSchedulableArgumentList[i]); 278 } 279 else if (lClass == Character.TYPE) 280 { 281 lArgumentList[i] = new Character (mSchedulableArgumentList[i].charAt(0)); 282 } 283 else 284 { 285 Constructor lConstructor = lClass.getConstructor(new Class []{String .class}); 286 lArgumentList[i] = lConstructor.newInstance(new Object []{mSchedulableArgumentList[i]}); 287 } 288 } 289 } 290 catch (Exception e) 291 { 292 log.error("Could not load or create constructor argument", e); 293 throw new InvalidParameterException ("Could not load or create a constructor argument"); 294 } 295 try 296 { 297 Constructor lSchedulableConstructor = mSchedulableClass.getConstructor(mSchedulableArgumentTypeList); 299 mSchedulable = (Schedulable) lSchedulableConstructor.newInstance(lArgumentList); 301 } 302 catch (Exception e) 303 { 304 log.error("Could not find the constructor or create Schedulable instance", e); 305 throw new InvalidParameterException ("Could not find the constructor or create the Schedulable Instance"); 306 } 307 } 308 309 private Date getNow() { 310 long now = System.currentTimeMillis(); 311 return new Date (now + 1000); 312 } 313 314 private void initStartDate() { 315 if (mStartDateIsNow) 318 { 319 mStartDate = getNow(); 320 } 321 else 322 { 323 if (mStartDate.before(new Date ())) 325 { 326 long lNow = new Date ().getTime() + 100; 328 long lSkipRepeats = ((lNow - mStartDate.getTime()) / mActualSchedulePeriod) + 1; 329 log.debug("Old start date: " + mStartDate + ", now: " + new Date (lNow) + ", Skip repeats: " + lSkipRepeats); 330 if (mRemainingRepetitions > 0) 331 { 332 if (lSkipRepeats >= mRemainingRepetitions) 334 { 335 log.info("No repetitions left because start date is in the past and could " + 337 "not be reached by Initial Repetitions * Schedule Period"); 338 return; 339 } 340 else 341 { 342 mRemainingRepetitions -= lSkipRepeats; 344 } 345 } 346 mStartDate = new Date (mStartDate.getTime() + (lSkipRepeats * mActualSchedulePeriod)); 347 } 348 } 349 } 350 351 362 public void startSchedule() 363 { 364 if (isStarted()) 365 { 366 log.debug("already started"); 367 return; 368 } 369 370 if (mUseMBean) 371 { 372 checkMBean(); 373 } 374 else 375 { 376 createSchedulable(); 377 } 378 379 mRemainingRepetitions = mInitialRepetitions; 380 mActualSchedulePeriod = mSchedulePeriod; 381 initStartDate(); 382 383 log.debug("Schedule initial call to: " + mStartDate + ", remaining repetitions: " + mRemainingRepetitions); 384 mNotificationID = mTimer.addNotification( 385 "Schedule", "Scheduler Notification", 386 null, mStartDate, 388 new Long (mActualSchedulePeriod), 389 mRemainingRepetitions < 0 ? new Long (0) : new Long (mRemainingRepetitions), 390 Boolean.valueOf(mFixedRate) 391 ); 392 mListener = mUseMBean ? new MBeanListener() : new PojoScheduler(); 393 mTimerEmitter.addNotificationListener( 394 mListener, 395 new ScheduleManager.IdNotificationFilter(mNotificationID), 396 null 397 ); 398 mScheduleIsStarted = true; 399 mIsRestartPending = false; 400 } 401 402 406 public void stopSchedule() 407 { 408 stopSchedule(true); 409 } 410 411 421 public void stopSchedule(boolean pDoItNow) 422 { 423 log.debug("stopSchedule(" + pDoItNow + ")"); 424 try 425 { 426 if (mNotificationID < 0) 427 { 428 mScheduleIsStarted = false; 429 mWaitForNextCallToStop = false; 430 return; 431 } 432 if (pDoItNow) 433 { 434 log.debug("stopSchedule(), removing schedule id: " + mNotificationID); 435 mWaitForNextCallToStop = false; 436 if (mListener != null) 437 { 438 mTimerEmitter.removeNotificationListener(mListener); 439 try 440 { 441 mTimer.removeNotification(mNotificationID); 442 } 443 catch (InstanceNotFoundException e) 444 { 445 log.trace(e); 446 } 447 mListener = null; 448 } 449 mNotificationID = -1; 450 mScheduleIsStarted = false; 451 } 452 else 453 { 454 mWaitForNextCallToStop = true; 455 } 456 } 457 catch (Exception e) 458 { 459 log.error("stopSchedule failed", e); 460 } 461 } 462 463 468 public void restartSchedule() 469 { 470 stopSchedule(); 471 startSchedule(); 472 } 473 474 480 public String getSchedulableClass() 481 { 482 if (mSchedulableClass == null) 483 { 484 return null; 485 } 486 return mSchedulableClass.getName(); 487 } 488 489 502 public void setSchedulableClass(String pSchedulableClass) 503 throws InvalidParameterException 504 { 505 if (pSchedulableClass == null || pSchedulableClass.equals("")) 506 { 507 throw new InvalidParameterException ("Schedulable Class cannot be empty or undefined"); 508 } 509 try 510 { 511 ClassLoader loader = TCLActions.getContextClassLoader(); 513 mSchedulableClass = loader.loadClass(pSchedulableClass); 514 if (!isSchedulable(mSchedulableClass)) 516 { 517 String msg = "Given class " + pSchedulableClass + " is not instance of Schedulable"; 518 StringBuffer info = new StringBuffer (msg); 519 info.append("\nThe SchedulableClass info:"); 520 Classes.displayClassInfo(mSchedulableClass, info); 521 info.append("\nSchedulable.class info:"); 522 Classes.displayClassInfo(Schedulable.class, info); 523 log.debug(info.toString()); 524 throw new InvalidParameterException (msg); 525 } 526 } 527 catch (ClassNotFoundException e) 528 { 529 log.info("Failed to find: "+pSchedulableClass, e); 530 throw new InvalidParameterException ( 531 "Given class " + pSchedulableClass + " is not not found" 532 ); 533 } 534 mIsRestartPending = true; 535 mUseMBean = false; 536 } 537 538 545 public String getSchedulableArguments() 546 { 547 return mSchedulableArguments; 548 } 549 550 561 public void setSchedulableArguments(String pArgumentList) 562 { 563 if (pArgumentList == null || pArgumentList.equals("")) 564 { 565 mSchedulableArgumentList = new String [0]; 566 } 567 else 568 { 569 StringTokenizer lTokenizer = new StringTokenizer (pArgumentList, ","); 570 Vector lList = new Vector (); 571 while (lTokenizer.hasMoreTokens()) 572 { 573 String lToken = lTokenizer.nextToken().trim(); 574 if (lToken.equals("")) 575 { 576 lList.add("null"); 577 } 578 else 579 { 580 lList.add(lToken); 581 } 582 } 583 mSchedulableArgumentList = (String []) lList.toArray(new String [0]); 584 } 585 mSchedulableArguments = pArgumentList; 586 mIsRestartPending = true; 587 } 588 589 595 public String getSchedulableArgumentTypes() 596 { 597 return mSchedulableArgumentTypes; 598 } 599 600 614 public void setSchedulableArgumentTypes(String pTypeList) 615 throws InvalidParameterException 616 { 617 if (pTypeList == null || pTypeList.equals("")) 618 { 619 mSchedulableArgumentTypeList = new Class [0]; 620 } 621 else 622 { 623 StringTokenizer lTokenizer = new StringTokenizer (pTypeList, ","); 624 Vector lList = new Vector (); 625 while (lTokenizer.hasMoreTokens()) 626 { 627 String lToken = lTokenizer.nextToken().trim(); 628 Class lClass = null; 630 if (lToken.equals("short")) 631 { 632 lClass = Short.TYPE; 633 } 634 else if (lToken.equals("int")) 635 { 636 lClass = Integer.TYPE; 637 } 638 else if (lToken.equals("long")) 639 { 640 lClass = Long.TYPE; 641 } 642 else if (lToken.equals("byte")) 643 { 644 lClass = Byte.TYPE; 645 } 646 else if (lToken.equals("char")) 647 { 648 lClass = Character.TYPE; 649 } 650 else if (lToken.equals("float")) 651 { 652 lClass = Float.TYPE; 653 } 654 else if (lToken.equals("double")) 655 { 656 lClass = Double.TYPE; 657 } 658 else if (lToken.equals("boolean")) 659 { 660 lClass = Boolean.TYPE; 661 } 662 if (lClass == null) 663 { 664 try 665 { 666 ClassLoader loader = TCLActions.getContextClassLoader(); 668 lClass = loader.loadClass(lToken); 669 } 670 catch (ClassNotFoundException cnfe) 671 { 672 throw new InvalidParameterException ( 673 "The argument type: " + lToken + " is not a valid class or could not be found" 674 ); 675 } 676 } 677 lList.add(lClass); 678 } 679 mSchedulableArgumentTypeList = (Class []) lList.toArray(new Class [0]); 680 } 681 mSchedulableArgumentTypes = pTypeList; 682 mIsRestartPending = true; 683 } 684 685 690 public String getSchedulableMBean() 691 { 692 return mSchedulableMBean == null ? 693 null : 694 mSchedulableMBean.toString(); 695 } 696 697 714 public void setSchedulableMBean(String pSchedulableMBean) 715 throws InvalidParameterException 716 { 717 if (pSchedulableMBean == null) 718 { 719 throw new InvalidParameterException ("Schedulable MBean must be specified"); 720 } 721 try 722 { 723 mSchedulableMBean = new ObjectName (pSchedulableMBean); 724 mUseMBean = true; 725 } 726 catch (MalformedObjectNameException e) 727 { 728 throw new InvalidParameterException ("Schedulable MBean name invalid " + pSchedulableMBean); 729 } 730 } 731 732 735 public String getSchedulableMBeanMethod() 736 { 737 return mSchedulableMBeanMethod; 738 } 739 740 771 public void setSchedulableMBeanMethod(String pSchedulableMBeanMethod) 772 throws InvalidParameterException 773 { 774 if (pSchedulableMBeanMethod == null) 775 { 776 mSchedulableMBeanMethod = null; 777 return; 778 } 779 int lIndex = pSchedulableMBeanMethod.indexOf('('); 780 String lMethodName; 781 if (lIndex == -1) 782 { 783 lMethodName = pSchedulableMBeanMethod.trim(); 784 mSchedulableMBeanArguments = new int[0]; 785 mSchedulableMBeanArgumentTypes = new String [0]; 786 } 787 else 788 { 789 lMethodName = pSchedulableMBeanMethod.substring(0, lIndex).trim(); 790 } 791 if (lMethodName.equals("")) 792 { 793 lMethodName = "perform"; 794 } 795 if (lIndex >= 0) 796 { 797 int lIndex2 = pSchedulableMBeanMethod.indexOf(')'); 798 if (lIndex2 < lIndex) 799 { 800 throw new InvalidParameterException ("Schedulable MBean Method: closing bracket must be after opening bracket"); 801 } 802 if (lIndex2 < pSchedulableMBeanMethod.length() - 1) 803 { 804 String lRest = pSchedulableMBeanMethod.substring(lIndex2 + 1).trim(); 805 if (lRest.length() > 0) 806 { 807 throw new InvalidParameterException ("Schedulable MBean Method: nothing should be after closing bracket"); 808 } 809 } 810 String lArguments = pSchedulableMBeanMethod.substring(lIndex + 1, lIndex2).trim(); 811 if (lArguments.equals("")) 812 { 813 mSchedulableMBeanArguments = new int[0]; 814 mSchedulableMBeanArgumentTypes = new String [0]; 815 } 816 else 817 { 818 StringTokenizer lTokenizer = new StringTokenizer (lArguments, ", "); 819 mSchedulableMBeanArguments = new int[lTokenizer.countTokens()]; 820 mSchedulableMBeanArgumentTypes = new String [lTokenizer.countTokens()]; 821 for (int i = 0; lTokenizer.hasMoreTokens(); i++) 822 { 823 String lToken = lTokenizer.nextToken().trim(); 824 if (lToken.equals("NOTIFICATION")) 825 { 826 mSchedulableMBeanArguments[i] = NOTIFICATION; 827 mSchedulableMBeanArgumentTypes[i] = Notification .class.getName(); 828 } 829 else if (lToken.equals("DATE")) 830 { 831 mSchedulableMBeanArguments[i] = DATE; 832 mSchedulableMBeanArgumentTypes[i] = Date .class.getName(); 833 } 834 else if (lToken.equals("REPETITIONS")) 835 { 836 mSchedulableMBeanArguments[i] = REPETITIONS; 837 mSchedulableMBeanArgumentTypes[i] = Long.TYPE.getName(); 838 } 839 else if (lToken.equals("SCHEDULER_NAME")) 840 { 841 mSchedulableMBeanArguments[i] = SCHEDULER_NAME; 842 mSchedulableMBeanArgumentTypes[i] = ObjectName .class.getName(); 843 } 844 else 845 { 846 mSchedulableMBeanArguments[i] = NULL; 847 mSchedulableMBeanArgumentTypes[i] = lToken; 849 } 850 } 851 } 852 } 853 mSchedulableMBeanMethodName = lMethodName; 854 mSchedulableMBeanMethod = pSchedulableMBeanMethod; 855 } 856 857 863 public boolean isUsingMBean() 864 { 865 return mUseMBean; 866 } 867 868 874 public long getSchedulePeriod() 875 { 876 return mSchedulePeriod; 877 } 878 879 889 public void setSchedulePeriod(long pPeriod) 890 { 891 if (pPeriod <= 0) 892 { 893 throw new InvalidParameterException ("Schedulable Period may be not less or equals than 0"); 894 } 895 mSchedulePeriod = pPeriod; 896 mIsRestartPending = true; 897 } 898 899 904 public String getDateFormat() 905 { 906 if (mDateFormatter == null) 907 mDateFormatter = new SimpleDateFormat (); 908 return mDateFormatter.toPattern(); 909 } 910 911 918 public void setDateFormat(String dateFormat) 919 { 920 if (dateFormat == null || dateFormat.trim().length() == 0) 921 mDateFormatter = new SimpleDateFormat (); 922 else 923 mDateFormatter = new SimpleDateFormat (dateFormat); 924 } 925 926 932 public String getInitialStartDate() 933 { 934 return mStartDateString; 935 } 936 937 965 public void setInitialStartDate(String pStartDate) 966 { 967 mStartDateString = pStartDate == null ? "" : pStartDate.trim(); 968 if (mStartDateString.equals("")) 969 { 970 mStartDate = new Date (0); 971 } 972 else if (mStartDateString.equals("NOW")) 973 { 974 mStartDate = getNow(); 975 mStartDateIsNow = true; 976 } 977 else 978 { 979 try 980 { 981 long lDate = new Long (pStartDate).longValue(); 982 mStartDate = new Date (lDate); 983 mStartDateIsNow = false; 984 } 985 catch (NumberFormatException e) 986 { 987 try 988 { 989 if (mDateFormatter == null) 990 { 991 mDateFormatter = new SimpleDateFormat (); 992 } 993 mStartDate = mDateFormatter.parse(mStartDateString); 994 mStartDateIsNow = false; 995 } 996 catch (Exception e2) 997 { 998 log.error("Could not parse given date string: " + mStartDateString, e2); 999 throw new InvalidParameterException ("Schedulable Date is not of correct format: " + mStartDateString); 1000 } 1001 } 1002 } 1003 log.debug("Initial Start Date is set to: " + mStartDate); 1004 } 1005 1006 1011 public long getInitialRepetitions() 1012 { 1013 return mInitialRepetitions; 1014 } 1015 1016 1026 public void setInitialRepetitions(long pNumberOfCalls) 1027 { 1028 if (pNumberOfCalls <= 0) 1029 { 1030 pNumberOfCalls = -1; 1031 } 1032 mInitialRepetitions = pNumberOfCalls; 1033 mIsRestartPending = true; 1034 } 1035 1036 1041 public long getRemainingRepetitions() 1042 { 1043 return mRemainingRepetitions; 1044 } 1045 1046 1053 public boolean isStarted() 1054 { 1055 return mScheduleIsStarted; 1056 } 1057 1058 1063 public boolean isRestartPending() 1064 { 1065 return mIsRestartPending; 1066 } 1067 1068 1073 public boolean isStartAtStartup() 1074 { 1075 return mStartOnStart; 1076 } 1077 1078 1087 public void setStartAtStartup(boolean pStartAtStartup) 1088 { 1089 mStartOnStart = pStartAtStartup; 1090 } 1091 1092 1097 public boolean isActive() 1098 { 1099 return isStarted() && mRemainingRepetitions != 0; 1100 } 1101 1102 1107 public String getTimerName() 1108 { 1109 return mTimerName; 1110 } 1111 1112 1119 public void setTimerName(String pTimerName) 1120 { 1121 mTimerName = pTimerName; 1122 } 1123 1124 1129 public void setFixedRate(boolean fixedRate) 1130 { 1131 mFixedRate = fixedRate; 1132 } 1133 1134 1139 public boolean getFixedRate() 1140 { 1141 return mFixedRate; 1142 } 1143 1144 1148 1152 protected void startService() 1153 throws Exception 1154 { 1155 mTimerObjectName = new ObjectName (mTimerName); 1156 if (!getServer().isRegistered(mTimerObjectName)) 1157 { 1158 getServer().createMBean(Timer .class.getName(), mTimerObjectName); 1159 } 1160 mTimer = (TimerMBean )MBeanServerInvocationHandler.newProxyInstance(getServer(), 1161 mTimerObjectName, TimerMBean .class, true); 1162 mTimerEmitter = (NotificationEmitter )mTimer; 1163 if (!mTimer.isActive()) 1164 { 1165 mTimer.start(); 1166 } 1167 if (mStartOnStart) 1168 { 1169 log.debug("Start Scheduler on start up time"); 1170 startSchedule(); 1171 } 1172 } 1173 1174 protected void stopService() 1175 { 1176 stopSchedule(); 1177 } 1178 1179 private static boolean isSchedulable(Class c) 1180 { 1181 boolean lFound = false; 1182 do 1183 { 1184 Class [] lInterfaces = c.getInterfaces(); 1185 for (int i = 0; i < lInterfaces.length; i++) 1186 { 1187 if (lInterfaces[i] == Schedulable.class) 1188 { 1189 lFound = true; 1190 break; 1191 } 1192 } 1193 c = c.getSuperclass(); 1194 } 1195 while (c != null && !lFound); 1196 return lFound; 1197 } 1198 1199 1202 public abstract class BaseListener 1203 implements NotificationListener 1204 { 1205 final Logger log = Logger.getLogger(BaseListener.class); 1206 1207 public void handleNotification( 1208 Notification notification, 1209 Object handback 1210 ) 1211 { 1212 boolean trace = log.isTraceEnabled(); 1213 if (trace) 1214 { 1215 log.trace("handleNotification: " + notification); 1216 } 1217 if (!isStarted()) 1218 { 1219 log.trace("Scheduler not started"); 1220 stopSchedule(); 1221 return; 1222 } 1223 if (mRemainingRepetitions == 0) 1224 { 1225 log.trace("No more repetitions"); 1226 stopSchedule(); 1227 return; 1228 } 1229 if (mRemainingRepetitions > 0) 1230 { 1231 mRemainingRepetitions--; 1232 if (trace) 1233 log.trace("Remaining repetitions: " + mRemainingRepetitions); 1234 } 1235 invoke(notification); 1236 if (mWaitForNextCallToStop) 1237 { 1238 stopSchedule(); 1239 } 1240 } 1241 1242 1245 protected abstract void invoke(Notification notification); 1246 1247 } 1248 1249 1253 1256 public class PojoScheduler extends BaseListener 1257 { 1258 1259 protected void invoke(Notification notification) 1260 { 1261 ClassLoader currentTCL = TCLActions.getContextClassLoader(); 1262 try 1263 { 1264 ClassLoader loader = TCLActions.getClassLoader(mSchedulable.getClass()); 1265 TCLActions.setContextClassLoader(loader); 1266 Date lTimeStamp = new Date (notification.getTimeStamp()); 1267 mSchedulable.perform(lTimeStamp, getRemainingRepetitions()); 1268 } 1269 catch (Exception e) 1270 { 1271 log.error("Scheduler.perform call failed", e); 1272 } 1273 finally 1274 { 1275 TCLActions.setContextClassLoader(currentTCL); 1276 } 1277 } 1278 } 1279 1280 1283 public class MBeanListener extends BaseListener 1284 { 1285 protected void invoke(Notification notification) 1286 { 1287 Object [] lArguments = new Object [mSchedulableMBeanArguments.length]; 1288 for (int i = 0; i < lArguments.length; i++) 1289 { 1290 switch (mSchedulableMBeanArguments[i]) 1291 { 1292 case NOTIFICATION: 1293 lArguments[i] = notification; 1294 break; 1295 case DATE: 1296 lArguments[i] = new Date (notification.getTimeStamp()); 1297 break; 1298 case REPETITIONS: 1299 lArguments[i] = new Long (mRemainingRepetitions); 1300 break; 1301 case SCHEDULER_NAME: 1302 lArguments[i] = getServiceName(); 1303 break; 1304 default: 1305 lArguments[i] = null; 1306 } 1307 } 1308 if (log.isTraceEnabled()) 1309 { 1310 log.debug("invoke " + mSchedulableMBean + " " + mSchedulableMBeanMethodName); 1311 log.debug("arguments: " + Arrays.asList(lArguments)); 1312 log.debug("argument types: " + Arrays.asList(mSchedulableMBeanArgumentTypes)); 1313 } 1314 try 1315 { 1316 getServer().invoke( 1317 mSchedulableMBean, 1318 mSchedulableMBeanMethodName, 1319 lArguments, 1320 mSchedulableMBeanArgumentTypes 1321 ); 1322 } 1323 catch (Exception e) 1324 { 1325 log.error("Invoke failed for " + mSchedulableMBean + " " + mSchedulableMBeanMethodName, e); 1326 } 1327 } 1328 } 1329 1330} 1331 | Popular Tags |