1 22 package com.scalagent.scheduler; 23 24 import java.io.*; 25 import java.util.*; 26 27 import org.objectweb.util.monolog.api.BasicLevel; 28 import org.objectweb.util.monolog.api.Logger; 29 30 import fr.dyade.aaa.agent.*; 31 32 80 public class Scheduler extends ProxyAgent { 81 82 public static Logger logger = Debug.getLogger(Scheduler.class.getName()); 83 84 85 private static boolean initialized = false; 86 87 88 public static String defaultName = "DefaultScheduler"; 89 90 99 public static void init(String args, boolean firstTime) throws Exception { 100 if (initialized) return; 101 initialized = true; 102 103 if (! firstTime) return; 104 105 Scheduler scheduler = new Scheduler(); 106 scheduler.deploy(); 107 } 108 109 public static void stopService() { 110 } 112 113 119 public static AgentId getDefault(short serverId) { 120 return new AgentId(serverId, serverId, AgentId.SchedulerServiceStamp); 121 } 122 123 129 public static AgentId getDefault() { 130 return getDefault(AgentServer.getServerId()); 131 } 132 133 134 ScheduleItem items; 135 136 ConditionItem conditions; 137 138 139 transient SchedulerAlarm alarm; 140 141 146 public Scheduler(String schedulerName) { 147 super(schedulerName); 148 blockingCnx = false; 149 items = null; 150 conditions = null; 151 alarm = null; 152 } 153 154 158 private Scheduler() throws IOException { 159 super(defaultName, AgentId.SchedulerServiceStamp); 160 blockingCnx = false; 161 items = null; 162 conditions = null; 163 alarm = null; 164 } 165 166 172 public Scheduler(short to, String name) { 173 super(to, name); 174 blockingCnx = false; 175 items = null; 176 conditions = null; 177 alarm = null; 178 } 179 180 181 186 public String toString() { 187 return "(" + super.toString() + 188 ",items=" + items + 189 ",conditions=" + conditions + ")"; 190 } 191 192 193 197 public void connect() throws Exception { 198 alarm = new SchedulerAlarm(); 199 ois = alarm; 200 } 201 202 205 public void disconnect() throws IOException { 206 if (alarm != null) { 207 alarm.close(); 209 alarm = null; 210 ois = null; 211 } 212 } 213 214 215 221 ConditionItem addCondition(String name) { 222 if (conditions == null) { 223 conditions = new ConditionItem(name); 224 return conditions; 225 } 226 ConditionItem prev = null; 227 for (ConditionItem item = conditions; item != null; item = item.next) { 228 int cmp = name.compareTo(item.name); 229 if (cmp == 0) 230 return item; 231 if (cmp < 0) 232 break; 233 prev = item; 234 } 235 236 ConditionItem newItem = new ConditionItem(name); 237 if (prev == null) { 238 newItem.next = conditions; 239 conditions = newItem; 240 } else { 241 newItem.next = prev.next; 242 prev.next = newItem; 243 } 244 245 return newItem; 246 } 247 248 254 ConditionItem findCondition(String name) { 255 if (conditions == null) 256 return null; 257 for (ConditionItem item = conditions; item != null; item = item.next) { 258 int cmp = name.compareTo(item.name); 259 if (cmp == 0) 260 return item; 261 if (cmp < 0) 262 break; 263 } 264 265 return null; 266 } 267 268 273 void removeCondition(String name) { 274 if (conditions == null) 275 return; 276 ConditionItem prev = null; 277 for (ConditionItem item = conditions; item != null; item = item.next) { 278 int cmp = name.compareTo(item.name); 279 if (cmp == 0) 280 break; 281 if (cmp < 0) 282 return; 283 prev = item; 284 } 285 286 if (prev == null) { 287 conditions = conditions.next; 288 } else { 289 prev.next = prev.next.next; 290 } 291 } 292 293 300 protected void agentInitialize(boolean firstTime) throws Exception { 301 super.agentInitialize(firstTime); 303 304 checkItems(true); 306 } 307 308 327 public void react(AgentId from, Notification not) throws Exception { 328 if (logger.isLoggable(BasicLevel.DEBUG)) 329 logger.log(BasicLevel.DEBUG, "Scheduler.react(" + from + ',' + not + ')'); 330 if (not instanceof ScheduleEvent) { 331 doReact(from, (ScheduleEvent) not); 332 } else if (not instanceof ScheduleNotification) { 333 doReact(from, (ScheduleNotification) not); 334 } else if (not instanceof AddConditionListener) { 335 doReact(from, (AddConditionListener) not); 336 } else if (not instanceof RemoveConditionListener) { 337 doReact(from, (RemoveConditionListener) not); 338 } else { 341 super.react(from, not); 342 } 343 } 344 345 352 protected void doReact(AgentId from, ScheduleEvent not) throws Exception { 353 insertItem(not); 355 356 checkItems(false); 358 } 359 360 367 protected void doReact(AgentId from, ScheduleNotification not) throws Exception { 368 checkItems(false); 370 } 371 372 379 protected void doReact(AgentId from, AddConditionListener not) throws Exception { 380 addConditionListener(not.name, from); 381 } 382 383 390 protected void doReact(AgentId from, RemoveConditionListener not) throws Exception { 391 removeConditionListener(not.name, from); 392 } 393 394 401 405 410 protected void insertItem(ScheduleEvent not) throws Exception { 411 Date now = new Date(); 412 ScheduleItem newItem = new ScheduleItem(not); 413 414 newItem.date = not.nextDate(now); 416 417 if (newItem.date == null) { 419 if (! not.outdatedRestart) return; 420 newItem.date = now; 421 } 422 423 insertItem(newItem); 424 } 425 426 432 protected void insertItem(ScheduleItem newItem) throws Exception { 433 if (newItem.date == null) return; 434 435 if (items == null) { 436 items = newItem; 437 } else { 438 ScheduleItem prev = null; 439 440 for (ScheduleItem item = items; item != null; item = item.next) { 441 if (!newItem.date.after(item.date)) 442 break; 443 prev = item; 444 } 445 446 if (prev == null) { 447 if (items != null) { 448 newItem.next = items; 449 items.prev = newItem; 450 } 451 items = newItem; 452 } else { 453 newItem.next = prev.next; 454 newItem.prev = prev; 455 prev.next = newItem; 456 if (newItem.next != null) 457 newItem.next.prev = newItem; 458 } 459 } 460 } 461 462 468 protected void checkItems(boolean restart) throws Exception { 469 if (logger.isLoggable(BasicLevel.DEBUG)) 470 logger.log(BasicLevel.DEBUG, "Scheduler.checkItems(" + restart + ')'); 471 Date now = new Date(); 472 473 checkLoop: 474 for (ScheduleItem item = items; item != null;) { 475 if (item.date != null && 476 item.date.after(now)) 477 break checkLoop; 478 479 ScheduleItem nextItem = item.next; 480 481 if (! restart || 482 item.event.outdatedRestart || 483 item.status || (item.event.duration > 0 && 485 new Date(item.date.getTime() + 486 (item.event.duration * 1000)).after(now)) 487 ) { 488 item.status = ! item.status; 490 signalEvent(item); 491 } 492 493 if (item.status == true) { 495 if (item.event.duration > 0) { 496 item.date.setTime(item.date.getTime() + (item.event.duration * 1000)); 498 } else { 499 item.status = ! item.status; 501 } 502 } 503 if (item.status == false) { 504 item.date = item.event.nextDate(now); 505 if ((item.date != null) && ! item.date.after(now)) 508 item.date = null; 509 } 510 511 if (item.date == null) { 512 removeItem(item); 514 item = nextItem; 515 continue checkLoop; 516 } 517 518 if (nextItem == null || 520 ! item.date.after(nextItem.date)) { 521 continue checkLoop; 522 } 523 524 removeItem(item); 526 insertItem(item); 528 529 item = nextItem; 530 } 531 532 if (items != null) { 534 alarm.setTime(items.date.getTime() - now.getTime()); 535 } 536 } 537 538 543 void removeItem(ScheduleItem item) { 544 if (item.next != null) 545 item.next.prev = item.prev; 546 if (item.prev == null) 547 items = item.next; 548 else 549 item.prev.next = item.next; 550 item.prev = item.next = null; 551 552 ConditionItem citem = findCondition(item.event.name); 554 if (citem == null) 555 return; 556 Enumeration listeners = citem.listeners.getListeners(); 557 if (listeners != null && 558 listeners.hasMoreElements()) 559 return; 560 for (ScheduleItem sitem = items; sitem != null; sitem = sitem.next) { 561 if (sitem.event.name.equals(item.event.name)) 562 return; 563 } 564 removeCondition(item.event.name); 565 } 566 567 573 protected void addConditionListener(String condition, AgentId listener) throws Exception { 574 ConditionItem citem = addCondition(condition); 575 citem.listeners.addListener(listener); 576 577 for (ScheduleItem item = items; item != null; item = item.next) { 578 if (! item.event.name.equals(condition)) 579 continue; 580 if (item.status) 581 sendTo(listener, new Condition(item.event.name, item.status)); 582 } 583 } 584 585 591 protected void removeConditionListener(String condition, AgentId listener) throws Exception { 592 ConditionItem citem = findCondition(condition); 593 if (citem == null) 594 return; 595 citem.listeners.removeListener(listener); 596 597 Enumeration listeners = citem.listeners.getListeners(); 599 if (listeners != null && 600 listeners.hasMoreElements()) 601 return; 602 for (ScheduleItem item = items; item != null; item = item.next) { 603 if (item.event.name.equals(condition)) 604 return; 605 } 606 removeCondition(condition); 607 } 608 609 614 protected void signalEvent(ScheduleItem item) { 615 ConditionItem condition = findCondition(item.event.name); 616 if (condition == null) 617 return; 618 sendTo(condition.listeners, new Condition(item.event.name, item.status)); 619 } 620 621 628 protected void driverDone(DriverDone not) throws IOException { 629 630 } 631 } 632 | Popular Tags |