/* * Copyright 2001-2008 Geert Bevin (gbevin[remove] at uwyn dot com) * Licensed under the Apache License, Version 2.0 (the "License") * $Id: Xml2MemoryScheduler.java 3918 2008-04-14 17:35:35Z gbevin $ */ package com.uwyn.rife.scheduler.schedulermanagers; import com.uwyn.rife.config.Config; import com.uwyn.rife.config.RifeConfig; import com.uwyn.rife.scheduler.Executor; import com.uwyn.rife.scheduler.Scheduler; import com.uwyn.rife.scheduler.Task; import com.uwyn.rife.scheduler.Taskoption; import com.uwyn.rife.scheduler.exceptions.FrequencyException; import com.uwyn.rife.scheduler.exceptions.SchedulerException; import com.uwyn.rife.scheduler.exceptions.TaskManagerException; import com.uwyn.rife.scheduler.exceptions.TaskoptionManagerException; import com.uwyn.rife.scheduler.taskmanagers.MemoryTasks; import com.uwyn.rife.scheduler.taskoptionmanagers.MemoryTaskoptions; import com.uwyn.rife.xml.Xml2Data; import com.uwyn.rife.xml.exceptions.XmlErrorException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import org.xml.sax.Attributes; public class Xml2MemoryScheduler extends Xml2Data { private StringBuilder mCharacterData = null; private Scheduler mScheduler = null; private MemoryTasks mTasks = null; private MemoryTaskoptions mTaskoptions = null; private int mLastTaskId = -1; private Taskoption mLastTaskoption = null; public Scheduler getScheduler() { return mScheduler; } public void startDocument() { mCharacterData = new StringBuilder(); mTasks = new MemoryTasks(); mTaskoptions = new MemoryTaskoptions(); mScheduler = new Scheduler(mTasks, mTaskoptions); mLastTaskId = -1; mLastTaskoption = null; } public void endDocument() { mCharacterData = null; mTasks = null; mTaskoptions = null; mLastTaskId = -1; mLastTaskoption = null; } private String registerExecutor(String classname) throws XmlErrorException { try { Class<Executor> executor_class = (Class<Executor>)Class.forName(classname); Executor executor = executor_class.newInstance(); if (!mScheduler.addExecutor(executor)) { throw new XmlErrorException("Couldn't add the executor with class '"+classname+"' to the scheduler."); } return executor.getHandledTasktype(); } catch (ClassNotFoundException e) { throw new XmlErrorException("Error while retrieving the executor's class '"+classname+"'.", e); } catch (InstantiationException e) { throw new XmlErrorException("Error while instantiating the executor with class '"+classname+"'.", e); } catch (IllegalAccessException e) { throw new XmlErrorException("Error while instantiating the executor with class '"+classname+"'.", e); } catch (SchedulerException e) { throw new XmlErrorException("Error while adding the executor with class '"+classname+"' to the scheduler.", e); } } public void startElement(String namespaceURI, String localName, String qName, Attributes atts) { if (qName.equals("scheduler")) { // do nothing } else if (qName.equals("task")) { String classname = atts.getValue("classname"); String planned = atts.getValue("planned"); String frequency = atts.getValue("frequency"); String type = atts.getValue("type"); if ((null == classname || 0 == classname.length())) { if (null == type || 0 == type.length()) { throw new XmlErrorException("Either the executor's classname or the task type have to be specified."); } } else { if (type != null && type.length() > 0) { throw new XmlErrorException("A task type can't be specified if the executor's class has been specified."); } } // if an executor's classname has been specified, try to instantiate the executor and // register it with the scheduler if (classname != null && classname.length() > 0) { type = registerExecutor(classname); } // if no planned date has been specified, set it to the current time SimpleDateFormat dateformat = new SimpleDateFormat("yyyy/MM/dd HH:mm"); dateformat.setTimeZone(RifeConfig.Tools.getDefaultTimeZone()); Date planned_date = null; if (null == planned) { // no explicit planned date was provided // set it to the current time planned_date = new Date(); } else { try { planned_date = dateformat.parse(planned); } catch (ParseException e) { throw new XmlErrorException("Invalid planned '"+planned+"'.", e); } } // create the new task and add it to the scheduler Task task = new Task(); task.setType(type); task.setPlanned(planned_date); try { task.setFrequency(frequency); } catch (FrequencyException e) { throw new XmlErrorException("Invalid frequency '"+frequency+"'.", e); } try { mLastTaskId = mTasks.addTask(task); } catch (TaskManagerException e) { throw new XmlErrorException("Error while adding the task to the scheduler.", e); } // if no explicit planned date has been given, and a frequency has // been provided, rearrange the planned date to ensure that the // first execution happens on a valid frequency moment if (null == planned && frequency != null) { try { long one_minute_earlier = task.getPlanned()-60000; long first_valid_planned = task.getNextDate(one_minute_earlier); task.setPlanned(first_valid_planned); } catch (FrequencyException e) { // do nothing, the planned date will remain at the curren time } } } else if (qName.equals("option")) { mCharacterData = new StringBuilder(); mLastTaskoption = new Taskoption(); mLastTaskoption.setTaskId(mLastTaskId); mLastTaskoption.setName(atts.getValue("name")); } else if (qName.equals("config")) { if (mCharacterData != null && Config.hasRepInstance()) { mCharacterData.append(Config.getRepInstance().getString(atts.getValue("param"), "")); } } else if (qName.equals("executor")) { String classname = atts.getValue("classname"); registerExecutor(classname); } else { throw new XmlErrorException("Unsupport element name '"+qName+"'."); } } public void endElement(String namespaceURI, String localName, String qName) { if (qName.equals("option")) { mLastTaskoption.setValue(mCharacterData.toString()); try { mTaskoptions.addTaskoption(mLastTaskoption); } catch (TaskoptionManagerException e) { throw new XmlErrorException("Error while adding the taskoption with name '"+mLastTaskoption.getName()+"', value '"+mLastTaskoption.getValue()+"' and task id '"+mLastTaskoption.getTaskId()+"'.", e); } mCharacterData = new StringBuilder(); mLastTaskoption = null; } } public void characters(char[] ch, int start, int length) { if (length > 0) { mCharacterData.append(String.copyValueOf(ch, start, length)); } } }