Java tutorial
/* * FrontlineSMS <http://www.frontlinesms.com> * Copyright 2007, 2008 kiwanja * * This file is part of FrontlineSMS. * * FrontlineSMS is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or (at * your option) any later version. * * FrontlineSMS is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser * General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with FrontlineSMS. If not, see <http://www.gnu.org/licenses/>. */ package net.frontlinesms.plugins.reminders; import java.util.Date; import java.util.Calendar; import java.util.HashMap; import java.util.List; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.text.DateFormat; import net.frontlinesms.EmailServerHandler; import net.frontlinesms.FrontlineSMS; import net.frontlinesms.FrontlineUtils; import net.frontlinesms.data.repository.ContactDao; import net.frontlinesms.data.repository.EmailDao; import net.frontlinesms.plugins.BasePluginThinletTabController; import net.frontlinesms.ui.Icon; import net.frontlinesms.ui.ThinletUiEventHandler; import net.frontlinesms.ui.UiGeneratorController; import net.frontlinesms.ui.handler.ComponentPagingHandler; import net.frontlinesms.ui.handler.PagedComponentItemProvider; import net.frontlinesms.ui.handler.PagedListDetails; import net.frontlinesms.ui.i18n.InternationalisationUtils; import org.apache.log4j.Logger; import org.springframework.context.ApplicationContext; import thinlet.Thinlet; import thinlet.ThinletText; import net.frontlinesms.plugins.reminders.data.domain.ExpiredReminder; import net.frontlinesms.plugins.reminders.data.domain.Reminder; import net.frontlinesms.plugins.reminders.data.domain.Reminder.Status; import net.frontlinesms.plugins.reminders.data.repository.ReminderDao; import net.frontlinesms.data.domain.Contact; import net.frontlinesms.data.domain.Email; import net.frontlinesms.data.domain.EmailAccount; import net.frontlinesms.data.events.EntityDeleteWarning; import net.frontlinesms.events.EventObserver; import net.frontlinesms.events.FrontlineEventNotification; /* * RemindersThinletTabController * @author Dale Zak * * see {@link "http://www.frontlinesms.net"} for more details. * copyright owned by Kiwanja.net */ public class RemindersThinletTabController extends BasePluginThinletTabController<RemindersPluginController> implements ThinletUiEventHandler, EventObserver, PagedComponentItemProvider, RemindersCallback { private static Logger LOG = FrontlineUtils.getLogger(RemindersThinletTabController.class); private static final String TAB_XML = "/ui/plugins/reminders/remindersTab.xml"; /** * FrontlineSMS */ private FrontlineSMS frontlineController; /** * ApplicationContext */ private ApplicationContext applicationContext; /** * ReminderDao */ private final ReminderDao reminderDao; /** * ContactDao */ private final ContactDao contactDao; /** * EmailDao */ private final EmailDao emailDao; /** * EmailServerHandler */ private final EmailServerHandler emailManager; /** * Reminders pager */ private ComponentPagingHandler pagerReminders; private Object tabComponent; private Object tableReminders; private Object panelTableReminders; private Object menuReminders; private Object toolbarReminders; private static final String TAB_MENU_CREATE = "menuCreateReminder"; private static final String TAB_MENU_SEND = "menuSendReminder"; private static final String TAB_MENU_EDIT = "menuEditReminder"; private static final String TAB_MENU_DELETE = "menuDeleteReminder"; private static final String TAB_TOOLBAR_CREATE = "buttonCreateReminder"; private static final String TAB_TOOLBAR_SEND = "buttonSendReminder"; private static final String TAB_TOOLBAR_EDIT = "buttonEditReminder"; private static final String TAB_TOOLBAR_DELETE = "buttonDeleteReminder"; /** * RemindersThinletTabController * @param pluginController RemindersPluginController * @param uiController UiGeneratorController * @param applicationContext ApplicationContext */ public RemindersThinletTabController(RemindersPluginController pluginController, UiGeneratorController uiController, ApplicationContext applicationContext) { super(pluginController, uiController); this.applicationContext = applicationContext; this.tabComponent = uiController.loadComponentFromFile(TAB_XML, this); super.setTabComponent(this.tabComponent); this.reminderDao = (ReminderDao) applicationContext.getBean("reminderDao"); this.contactDao = this.ui.getFrontlineController().getContactDao(); this.emailDao = this.ui.getFrontlineController().getEmailDao(); this.emailManager = this.ui.getFrontlineController().getEmailServerHandler(); this.menuReminders = this.ui.find(this.tabComponent, "menuReminders"); this.toolbarReminders = this.ui.find(this.tabComponent, "toolbarReminders"); this.tableReminders = this.ui.find(this.tabComponent, "tableReminders"); this.pagerReminders = new ComponentPagingHandler(this.ui, this, tableReminders); this.panelTableReminders = this.ui.find(this.tabComponent, "panelTableReminders"); this.ui.add(this.panelTableReminders, this.pagerReminders.getPanel()); this.pagerReminders.setCurrentPage(0); this.pagerReminders.refresh(); } /** * The ScheduledExecutorService provider used for scheduling tasks */ private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); /** * Hashmap to store Reminders to allow cancelling of scheduled tasks */ private final HashMap<Reminder, ScheduledFuture<?>> futures = new HashMap<Reminder, ScheduledFuture<?>>(); /** * Hashmap to store expired Reminders to allow cancelling of expiry tasks */ private final HashMap<Reminder, ScheduledFuture<?>> expired = new HashMap<Reminder, ScheduledFuture<?>>(); public void notify(FrontlineEventNotification notification) { if (notification instanceof EntityDeleteWarning<?>) { Object entity = ((EntityDeleteWarning<?>) notification).getDatabaseEntity(); if (entity instanceof EmailAccount) { EmailAccount deletedEmailAccount = (EmailAccount) entity; for (Reminder reminder : reminderDao.getAllReminders()) { EmailAccount reminderEmailAccount = reminder.getEmailAccount(); if (reminderEmailAccount != null && reminderEmailAccount.equals(deletedEmailAccount)) { LOG.debug("WARNING, email account " + deletedEmailAccount.getAccountName() + " will be deleted!!"); try { reminder.setEmailAccount(null); reminderDao.updateReminder(reminder); } catch (Exception ex) { LOG.error("Error removing email account from Reminder", ex); } } } } } } /** * Schedule a Reminder */ public void scheduleReminder(Reminder reminder) { LOG.debug("Callback.scheduleReminder: " + reminder); if (reminder != null && reminder.getStatus() != Status.SENT) { Calendar start = (Calendar) reminder.getStartCalendar().clone(); Calendar end = reminder.getEndCalendar(); Calendar now = Calendar.getInstance(); if (reminder.getPeriod() > 0) { while (start.before(now)) { start.add(Calendar.MILLISECOND, (int) reminder.getPeriod()); } LOG.debug("Reminder Scheduled: " + reminder); long startDelay = start.getTimeInMillis() - now.getTimeInMillis(); ScheduledFuture<?> future = this.scheduler.scheduleAtFixedRate(reminder, startDelay, reminder.getPeriod(), TimeUnit.MILLISECONDS); this.futures.put(reminder, future); LOG.debug("Expiry Scheduled: " + reminder.getEndCalendar().getTime()); long endDelay = end.getTimeInMillis() - now.getTimeInMillis(); ExpiredReminder expiredReminder = new ExpiredReminder(reminder); ScheduledFuture<?> expiry = this.scheduler.schedule(expiredReminder, endDelay, TimeUnit.MILLISECONDS); this.expired.put(reminder, expiry); } else { LOG.debug("Reminder Scheduled: " + reminder); long startDelay = start.getTimeInMillis() - now.getTimeInMillis(); ScheduledFuture<?> future = this.scheduler.schedule(reminder, startDelay, TimeUnit.MILLISECONDS); this.futures.put(reminder, future); } } } /** * Stop a Reminder */ public void stopReminder(Reminder reminder) { LOG.debug("Callback.stopReminder: " + reminder); if (reminder != null && this.futures.containsKey(reminder)) { ScheduledFuture<?> future = this.futures.get(reminder); if (future != null) { boolean result = future.cancel(true); LOG.debug("Future Cancel: " + result); } ScheduledFuture<?> expiry = this.expired.get(reminder); if (expiry != null) { boolean result = expiry.cancel(true); LOG.debug("Expiry Cancel: " + result); } } } /** * Refresh Reminders */ public void refreshReminders(Reminder reminder) { LOG.debug("Callback.refreshReminders: " + reminder); if (reminder != null) { this.reminderDao.updateReminder(reminder); } this.pagerReminders.refresh(); } /** * Send a collection of Reminders * @param list */ public void sendReminder(Object list) { for (Object selected : this.ui.getSelectedItems(list)) { sendReminder((Reminder) this.ui.getAttachedObject(selected, Reminder.class)); } } /** * Send a Reminder */ public void sendReminder(Reminder reminder) { LOG.debug("sendReminder: " + reminder); LOG.debug("sendReminder: " + reminder); if (reminder != null) { if (reminder.getType() == Reminder.Type.EMAIL) { if (reminder.getEmailAccount() != null) { for (String contactName : reminder.getRecipientsArray()) { LOG.debug("Sending EMAIL"); Contact contact = this.contactDao.getContactByName(contactName); Email email = new Email(reminder.getEmailAccount(), contact.getEmailAddress(), reminder.getSubject(), reminder.getContent()); this.emailDao.saveEmail(email); this.emailManager.sendEmail(email); } this.ui.setStatus( InternationalisationUtils.getI18NString(RemindersConstants.EMAIL_REMINDER_SENT)); } else { this.ui.alert( InternationalisationUtils.getI18NString(RemindersConstants.MISSING_EMAIL_ACCOUNT)); } } else if (reminder.getType() == Reminder.Type.MESSAGE) { for (String contactName : reminder.getRecipientsArray()) { Contact contact = this.contactDao.getContactByName(contactName); if (contact != null) { LOG.debug("Sending MESSAGE"); this.frontlineController.sendTextMessage(contact.getPhoneNumber(), reminder.getContent()); } } this.ui.setStatus(InternationalisationUtils.getI18NString(RemindersConstants.SMS_REMINDER_SENT)); } Calendar now = Calendar.getInstance(); if (now.equals(reminder.getEndCalendar())) { LOG.debug("now == end: " + reminder); reminder.setStatus(Reminder.Status.SENT); } else if (now.after(reminder.getEndCalendar())) { LOG.debug("now > end: " + reminder); reminder.setStatus(Reminder.Status.SENT); } this.reminderDao.updateReminder(reminder); } this.pagerReminders.refresh(); } /** * Cancel all Reminders */ public void cancelAllReminders() { LOG.debug("Callback.cancelAllReminders"); if (this.scheduler != null) { this.scheduler.shutdownNow(); } } /** * Set Front * @param frontlineController FrontlineSMS */ public void setFrontline(FrontlineSMS frontlineController) { this.frontlineController = frontlineController; this.frontlineController.getEventBus().registerObserver(this); } /** * Get Thinlet tab * @return */ public Object getTab() { return super.getTabComponent(); } /** * Remove reminders */ public void removeSelectedFromReminderList() { LOG.debug("removeSelectedFromReminderList"); final Object[] selected = this.ui.getSelectedItems(this.tableReminders); for (Object o : selected) { Reminder reminder = this.ui.getAttachedObject(o, Reminder.class); LOG.debug("Deleting Reminder:" + reminder); if (reminder != null) { this.reminderDao.deleteReminder(reminder); if (reminder.getType() == Reminder.Type.EMAIL) { this.ui.setStatus( InternationalisationUtils.getI18NString(RemindersConstants.EMAIL_REMINDER_CREATED)); } else { this.ui.setStatus( InternationalisationUtils.getI18NString(RemindersConstants.SMS_REMINDER_CREATED)); } } } this.ui.removeConfirmationDialog(); this.pagerReminders.refresh(); this.enableOptions(this.tableReminders, this.menuReminders, this.toolbarReminders); } /** * Enable menu options and buttons accordingly * @param list * @param popup * @param toolbar */ public void enableOptions(Object list, Object popup, Object toolbar) { Object[] selectedItems = this.ui.getSelectedItems(list); boolean hasSelection = selectedItems.length > 0; for (Object item : this.ui.getItems(popup)) { String name = this.ui.getString(item, Thinlet.NAME); if (TAB_MENU_CREATE.equals(name)) { this.ui.setEnabled(item, true); } else if (TAB_MENU_EDIT.equals(name)) { this.ui.setEnabled(item, hasSelection); } else if (TAB_MENU_DELETE.equals(name)) { this.ui.setEnabled(item, hasSelection); } else if (TAB_MENU_SEND.equals(name)) { this.ui.setEnabled(item, hasSelection); } } for (Object item : this.ui.getItems(toolbar)) { String name = this.ui.getString(item, Thinlet.NAME); if (TAB_TOOLBAR_CREATE.equals(name)) { this.ui.setEnabled(item, true); } else if (TAB_TOOLBAR_EDIT.equals(name)) { this.ui.setEnabled(item, hasSelection); } else if (TAB_TOOLBAR_DELETE.equals(name)) { this.ui.setEnabled(item, hasSelection); } else if (TAB_TOOLBAR_SEND.equals(name)) { this.ui.setEnabled(item, hasSelection); } } } /** * Show Reminders create / edit dialog */ public void showReminderDialog() { showReminderDialog(null); } /** * Show Reminders create / edit dialog * @param reminderList */ public void showReminderDialog(Object reminderList) { RemindersDialogHandler dialogHandler = new RemindersDialogHandler(this.ui, this.applicationContext, this); dialogHandler.setFrontline(this.frontlineController); if (reminderList != null) { final Object selected = this.ui.getSelectedItem(reminderList); Reminder reminder = this.ui.getAttachedObject(selected, Reminder.class); dialogHandler.init(reminder); } else { dialogHandler.init(null); } } /** * Populate reminders table */ public PagedListDetails getListDetails(Object list, int startIndex, int limit) { LOG.debug("getListDetails:" + this.ui.getName(list)); List<Reminder> reminders = this.reminderDao.getAllReminders(startIndex, limit); Object[] listItems = toThinletReminders(reminders); return new PagedListDetails(listItems.length, listItems); } /** * Convert collection of reminders to table rows * @param reminders collection of reminders * @return collection of table rows */ private Object[] toThinletReminders(List<Reminder> reminders) { Object[] components = new Object[reminders.size()]; for (int i = 0; i < components.length; i++) { Reminder r = reminders.get(i); components[i] = getReminderRow(r); } return components; } /** * Get table row * @param reminder Reminder * @return table row */ private Object getReminderRow(Reminder reminder) { Object row = this.ui.createTableRow(reminder); if (reminder.getStatus() == Reminder.Status.SENT) { Object statusCell = this.ui.createTableCell(""); this.ui.setIcon(statusCell, Icon.TICK); this.ui.setChoice(statusCell, ThinletText.ALIGNMENT, ThinletText.CENTER); this.ui.add(row, statusCell); } else { this.ui.add(row, this.ui.createTableCell("")); } Object typeCell = this.ui.createTableCell(""); if (reminder.getType() == Reminder.Type.EMAIL) { this.ui.setIcon(typeCell, Icon.EMAIL); } else { this.ui.setIcon(typeCell, Icon.SMS); } this.ui.setChoice(typeCell, ThinletText.ALIGNMENT, ThinletText.CENTER); this.ui.add(row, typeCell); Object occuranceCell = this.ui.createTableCell(reminder.getOccurrenceLabel()); this.ui.setChoice(occuranceCell, ThinletText.ALIGNMENT, ThinletText.CENTER); this.ui.add(row, occuranceCell); DateFormat dateFormat = InternationalisationUtils.getDatetimeFormat(); if (reminder.getStartDate() > 0) { Date startdate = new Date(reminder.getStartDate()); this.ui.add(row, this.ui.createTableCell(dateFormat.format(startdate))); } else { this.ui.add(row, this.ui.createTableCell("")); } if (reminder.getEndDate() > 0) { Date enddate = new Date(reminder.getEndDate()); this.ui.add(row, this.ui.createTableCell(dateFormat.format(enddate))); } else { this.ui.add(row, this.ui.createTableCell("")); } this.ui.add(row, this.ui.createTableCell(reminder.getRecipients())); this.ui.add(row, this.ui.createTableCell(reminder.getSubject())); this.ui.add(row, this.ui.createTableCell(reminder.getContent())); return row; } }