/*
* Copyright 2005-2008 Pentaho Corporation. All rights reserved.
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program 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.
*
* Copyright 2008 - 2009 Pentaho Corporation. All rights reserved.
*
* Created
* @author Steven Barkdull
*/
package org.pentaho.pac.client.scheduler.ctlr;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.pentaho.gwt.widgets.client.controls.ProgressPopupPanel;
import org.pentaho.gwt.widgets.client.controls.schededitor.ScheduleEditor;
import org.pentaho.gwt.widgets.client.dialogs.MessageDialogBox;
import org.pentaho.gwt.widgets.client.ui.ICallback;
import org.pentaho.gwt.widgets.client.utils.CronParseException;
import org.pentaho.gwt.widgets.client.utils.TimeUtil;
import org.pentaho.pac.client.ISchedulerServiceAsync;
import org.pentaho.pac.client.PacServiceFactory;
import org.pentaho.pac.client.common.ui.IResponseCallback;
import org.pentaho.pac.client.common.ui.dialog.ConfirmDialog;
import org.pentaho.pac.client.common.ui.dialog.MessageDialog;
import org.pentaho.pac.client.i18n.Messages;
import org.pentaho.pac.client.scheduler.model.Schedule;
import org.pentaho.pac.client.scheduler.model.SchedulesModel;
import org.pentaho.pac.client.scheduler.view.DualModeScheduleEditor;
import org.pentaho.pac.client.scheduler.view.ScheduleCreatorDialog;
import org.pentaho.pac.client.scheduler.view.SchedulerToolbar;
import org.pentaho.pac.client.scheduler.view.SchedulesListCtrl;
import org.pentaho.pac.client.scheduler.view.SolutionRepositoryActionSequenceListEditor;
import org.pentaho.pac.client.scheduler.view.ScheduleCreatorDialog.TabIndex;
import org.pentaho.pac.client.utils.ExceptionParser;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.ButtonBase;
import com.google.gwt.user.client.ui.Widget;
public class SchedulerToolbarController {
private SchedulerToolbar schedulerToolbar;
private SchedulesListCtrl schedulesListCtrl;
private ScheduleCreatorDialog scheduleCreatorDialog = null;
private SchedulesListController schedulesListController = null;
private SolutionRepositoryActionSequenceListEditorController solRepActionSequenceEditorController = null;
private SchedulesModel schedulesModel = null;
private static final int INVALID_SCROLL_POS = -1;
private static final String DISABLED = "disabled"; //$NON-NLS-1$
private boolean isInitialized = false;
private boolean loadingInitialized = false;
private static String SUSPENDED_SCHEDULER_STATE = "suspended"; //$NON-NLS-1$
private static String NORMAL_SCHEDULER_STATE = "normal"; //$NON-NLS-1$
public SchedulerToolbarController( ScheduleCreatorDialog pScheduleCreatorDialog,
SchedulerToolbar schedulerToolbar, SchedulesListCtrl schedulesListCtrl ) {
this.scheduleCreatorDialog = pScheduleCreatorDialog;
this.schedulerToolbar = schedulerToolbar;
this.schedulesListCtrl = schedulesListCtrl;
}
public void init( SchedulesListController pSchedulesListController,
SolutionRepositoryActionSequenceListEditorController solRepActionSequenceEditorController ) {
if ( !isInitialized ) {
this.schedulesListController = pSchedulesListController;
this.solRepActionSequenceEditorController = solRepActionSequenceEditorController;
final SchedulerToolbarController localThis = this;
schedulerToolbar.setOnCreateListener( new ICallback<Widget>() {
public void onHandle(Widget w) {
localThis.handleCreateSchedule();
}
});
schedulerToolbar.setOnUpdateListener( new ICallback<Widget>() {
public void onHandle(Widget w) {
localThis.handleUpdateSchedule();
}
});
schedulerToolbar.setOnDeleteListener( new ICallback<Widget>() {
public void onHandle(Widget w) {
localThis.handleDeleteSchedules();
}
});
schedulerToolbar.setOnResumeListener( new ICallback<Widget>() {
public void onHandle(Widget w) {
localThis.handleResumeSchedules();
}
});
schedulerToolbar.setOnSuspendListener( new ICallback<Widget>() {
public void onHandle(Widget w) {
localThis.handlePauseSchedules();
}
});
schedulerToolbar.setOnRunNowListener( new ICallback<Widget>() {
public void onHandle(Widget w) {
localThis.handleRunNowSchedules();
}
});
schedulerToolbar.setOnRefreshListener( new ICallback<Widget>() {
public void onHandle(Widget w) {
loadJobsTable();
// TODO sbarkdull reload sol rep model/view
}
});
schedulerToolbar.setOnFilterListChangeListener( new ICallback<String>() {
public void onHandle(String s) {
updateSchedulesTable();
}
});
ICallback<SolutionRepositoryActionSequenceListEditor> loadingCompleteHandler = new ICallback<SolutionRepositoryActionSequenceListEditor>() {
public void onHandle(SolutionRepositoryActionSequenceListEditor o) {
localThis.handleLoadingComplete();
}
};
scheduleCreatorDialog.getSolutionRepositoryActionSequenceEditor().setOnLoadingCompleteHandler( loadingCompleteHandler );
loadJobsTable(); // TODO sbarkdull belongs in SchedulesListController
enableTools();
isInitialized = true;
}
}
private List<Schedule> getSortedSchedulesList( List<Schedule> scheduleList ) {
assert null != scheduleList : "getSortedSchedulesList(): Schedule list cannot be null."; //$NON-NLS-1$
Collections.sort( scheduleList, new Comparator<Schedule>() {
public int compare(Schedule s1, Schedule s2) {
return s1.getJobName().compareToIgnoreCase( s2.getJobName() );
}
});
return scheduleList;
}
private void updateSchedulesTable() {
List<Schedule> scheduleList = schedulesModel.getScheduleList();
schedulesListController.updateSchedulesTable(
getSortedSchedulesList( getFilteredSchedulesList( scheduleList ) ) );
}
private List<Schedule> getFilteredSchedulesList( List<Schedule> scheduleList ) {
List<Schedule> filteredList = null;
String filterVal = schedulerToolbar.getFilterValue();
if ( !SchedulerToolbar.ALL_GROUPS_FILTER.equals( filterVal ) ) {
filteredList = new ArrayList<Schedule>();
for ( int ii=0; ii<scheduleList.size(); ++ii ) {
Schedule s = scheduleList.get( ii );
if ( s.getJobGroup().equals( filterVal ) ) {
filteredList.add( s );
}
}
} else {
filteredList = scheduleList;
}
return filteredList;
}
private void updateSchedule() {
AsyncCallback<Object> updateScheduleResponseCallback = new AsyncCallback<Object>() {
public void onSuccess( Object o ) {
scheduleCreatorDialog.hide();
loadJobsTable();
}
public void onFailure(Throwable caught) {
MessageDialogBox messageDialog = new MessageDialogBox(ExceptionParser.getErrorHeader(caught.getMessage()), ExceptionParser.getErrorMessage(caught.getMessage(),caught.getMessage()), false, false, true);
messageDialog.center();
}
};
final List<Schedule> scheduleList = schedulesListCtrl.getSelectedSchedules();
Schedule oldSchedule = scheduleList.get( 0 );
DualModeScheduleEditor scheduleEditor = scheduleCreatorDialog.getScheduleEditor();
ISchedulerServiceAsync schedSvc = scheduleEditor.isSubscriptionSchedule()
? PacServiceFactory.getSubscriptionService()
: PacServiceFactory.getSchedulerService();
String cronStr = scheduleEditor.getCronString();
Date startDate = scheduleEditor.getStartDate();
Date endDate = scheduleEditor.getEndDate();
if ( null == cronStr ) { // must be a repeating schedule
String startTime = scheduleEditor.getStartTime(); // format of string should be: HH:MM:SS AM/PM, e.g. 7:12:28 PM
startDate = TimeUtil.getDateTime( startTime, startDate );
endDate = (null != endDate) ? TimeUtil.getDateTime( startTime, endDate ) : null;
}
ScheduleEditor.ScheduleType rt = scheduleEditor.getScheduleType();
switch ( rt ) {
case RUN_ONCE:
schedSvc.updateRepeatSchedule(
oldSchedule.getJobName(),
oldSchedule.getJobGroup(),
oldSchedule.getSchedId(),
scheduleEditor.getName().trim(),
scheduleEditor.getGroupName().trim(),
scheduleEditor.getDescription().trim(),
startDate,
endDate,
"0" /*repeat count*/, //$NON-NLS-1$
"0" /*repeat time*/, //$NON-NLS-1$
scheduleCreatorDialog.getSolutionRepositoryActionSequenceEditor().getActionsAsString().trim(),
updateScheduleResponseCallback
);
break;
case SECONDS: // fall through
case MINUTES: // fall through
case HOURS: // fall through
case DAILY: // fall through
case WEEKLY: // fall through
case MONTHLY: // fall through
case YEARLY:
if ( null == cronStr ) {
String repeatInterval = Long.toString( TimeUtil.secsToMillisecs(
scheduleEditor.getRepeatInSecs() ) );
schedSvc.updateRepeatSchedule(
oldSchedule.getJobName(),
oldSchedule.getJobGroup(),
oldSchedule.getSchedId(),
scheduleEditor.getName().trim(),
scheduleEditor.getGroupName().trim(),
scheduleEditor.getDescription().trim(),
startDate,
endDate,
null /*repeat count*/,
repeatInterval.trim(),
scheduleCreatorDialog.getSolutionRepositoryActionSequenceEditor().getActionsAsString().trim(),
updateScheduleResponseCallback
);
break;
} else {
// fall through to case CRON
}
case CRON:
schedSvc.updateCronSchedule(
oldSchedule.getJobName(),
oldSchedule.getJobGroup(),
oldSchedule.getSchedId(),
scheduleEditor.getName().trim(),
scheduleEditor.getGroupName().trim(),
scheduleEditor.getDescription().trim(),
startDate,
endDate,
cronStr.trim(),
scheduleCreatorDialog.getSolutionRepositoryActionSequenceEditor().getActionsAsString().trim(),
updateScheduleResponseCallback
);
break;
default:
throw new RuntimeException( Messages.getString("invalidRunType", rt.toString() ) ); //$NON-NLS-1$
}
}
/**
*
*/
@SuppressWarnings("fallthrough")
private void updateScheduleWithNewScheduleType() {
final List<Schedule> scheduleList = schedulesListCtrl.getSelectedSchedules();
Schedule oldSchedule = scheduleList.get( 0 );
AsyncCallback<Object> deleteScheduleCallback = new AsyncCallback<Object>() {
public void onSuccess( Object o ) {
createSchedule();
}
public void onFailure(Throwable caught) {
MessageDialogBox messageDialog = new MessageDialogBox(ExceptionParser.getErrorHeader(caught.getMessage()), ExceptionParser.getErrorMessage(caught.getMessage(), caught.getMessage()), false, false, true);
messageDialog.center();
}
};
// TODO sbarkdull scheduleCreatorDialog -> scheduleEditorDialog
DualModeScheduleEditor scheduleEditor = scheduleCreatorDialog.getScheduleEditor();
ISchedulerServiceAsync schedSvc = null;
if ( oldSchedule.isSubscriptionSchedule() != scheduleEditor.isSubscriptionSchedule() ) {
// they are changing the schedule type, so delete it, and add a new one
schedSvc = oldSchedule.isSubscriptionSchedule()
? PacServiceFactory.getSubscriptionService()
: PacServiceFactory.getSchedulerService();
List<Schedule> deleteList = new ArrayList<Schedule>();
deleteList.add( oldSchedule );
schedSvc.deleteJobs(deleteList, deleteScheduleCallback );
} else {
// they are NOT changing the schedule type, so just update the existing schedule.
updateSchedule();
}
}
/**
* Merge the two maps into one map. Add all key-values in the schedulerMap to
* the mergedMap, unless the key is in both the schedulerMap and subscriptionMap.
* If it is in both maps, add the one from the subscriptionMap.
* NOTE: all elements in subscriptionMap should be in the schedulerMap, but not the
* inverse.
*
* @param schedulerMap
* @param subscriptionMap
* @return
*/
private static List<Schedule> mergeSchedules( Map<String,Schedule> schedulerMap,
Map<String,Schedule> subscriptionMap ) {
Schedule currentSched = null;
List<Schedule> mergedList = new ArrayList<Schedule>();
for ( Map.Entry<String,Schedule> me : schedulerMap.entrySet() ) {
Schedule subscriptionSchedule = subscriptionMap.get( me.getKey() );
if ( null != subscriptionSchedule ) {
currentSched = subscriptionSchedule;
} else {
currentSched = me.getValue();
}
mergedList.add( currentSched );
}
return mergedList;
}
private void initFilterList() {
String currentFilter = schedulerToolbar.getFilterValue();
currentFilter = ( null == currentFilter ) ? SchedulerToolbar.ALL_GROUPS_FILTER : currentFilter;
Set<String> groupNames = new HashSet<String>();
List<Schedule> scheduleList = schedulesModel.getScheduleList();
for ( int ii=0; ii<scheduleList.size(); ++ii ) {
Schedule s = scheduleList.get( ii );
String groupName = s.getJobGroup();
if ( !groupNames.contains( groupName ) ) {
groupNames.add( groupName );
}
}
schedulerToolbar.clearFilters();
schedulerToolbar.addFilterItem( SchedulerToolbar.ALL_GROUPS_FILTER );
for ( String name : groupNames ) {
schedulerToolbar.addFilterItem(name );
}
schedulerToolbar.setFilterValue( currentFilter );
}
private void loadJobsTable() {
final ProgressPopupPanel loadingPanel = new ProgressPopupPanel();
loadingPanel.setLabelText( Messages.getString("loading") ); //$NON-NLS-1$
loadingPanel.center();
final int currScrollPos = schedulesListCtrl.getScrollPosition();
final Map<String,Schedule> schedulesMap = new HashMap<String,Schedule>();
AsyncCallback<Map<String,Schedule>> schedulerServiceCallback = new AsyncCallback<Map<String,Schedule>>() {
public void onSuccess( Map<String,Schedule> pSchedulesMap ) {
schedulesMap.putAll( pSchedulesMap );
enableTools();
AsyncCallback<Map<String,Schedule>> subscriptionServiceCallback = new AsyncCallback<Map<String,Schedule>>() {
public void onSuccess( Map<String,Schedule> subscriptionSchedulesMap ) {
List<Schedule> schedulesList = mergeSchedules( schedulesMap, subscriptionSchedulesMap );
schedulesModel = new SchedulesModel();
schedulesModel.add( schedulesList );
initFilterList();
updateSchedulesTable();
if ( INVALID_SCROLL_POS != currScrollPos ) {
schedulesListCtrl.setScrollPosition( currScrollPos );
}
enableTools();
loadingPanel.hide();
} // end inner onSuccess
public void onFailure(Throwable caught) {
loadingPanel.hide();
schedulesListCtrl.setTempMessage( Messages.getString("noSchedules") ); //$NON-NLS-1$
MessageDialog messageDialog = new MessageDialog( Messages.getString("error"), //$NON-NLS-1$
caught.getMessage() );
messageDialog.center();
enableTools();
} // end inner onFailure
}; // end subscriptionServiceCallback
PacServiceFactory.getSubscriptionService().getJobNames( subscriptionServiceCallback );
} // end outer onSuccess
public void onFailure(Throwable caught) {
loadingPanel.hide();
schedulesListCtrl.setTempMessage( Messages.getString("noSchedules") ); //$NON-NLS-1$
MessageDialogBox messageDialog = new MessageDialogBox(ExceptionParser.getErrorHeader(caught.getMessage()), ExceptionParser.getErrorMessage(caught.getMessage(), caught.getMessage()), false, false, true);
messageDialog.center();
messageDialog.show();
enableTools();
} // end outer onFailure
}; // end schedulerServiceCallback
PacServiceFactory.getSchedulerService().getJobNames( schedulerServiceCallback );
}
public void enableTools() {
List<Schedule> scheduleList = schedulesListCtrl.getSelectedSchedules();
boolean suspendEnabled = false, resumeEnabled = false;
boolean resolvedSuspended = false, resolvedEnabled = false;
for (Schedule schedule:scheduleList) {
if (!resolvedSuspended && !schedule.getTriggerState().equalsIgnoreCase(SUSPENDED_SCHEDULER_STATE)){
suspendEnabled = true;
resolvedSuspended = true;
}
if (!resolvedEnabled && !schedule.getTriggerState().equalsIgnoreCase(NORMAL_SCHEDULER_STATE)){
resumeEnabled = true;
resolvedEnabled = true;
}
}
int numSelectedItems = scheduleList.size();
enableWidget( schedulerToolbar.getCreateBtn(), true );
enableWidget( schedulerToolbar.getUpdateBtn(), 1 == numSelectedItems );
enableWidget( schedulerToolbar.getDeleteBtn(), numSelectedItems > 0 );
enableWidget( schedulerToolbar.getSuspendBtn(), suspendEnabled );
enableWidget( schedulerToolbar.getResumeBtn(), resumeEnabled );
enableWidget( schedulerToolbar.getRunNowBtn(), numSelectedItems > 0 );
enableWidget( schedulerToolbar.getRefreshBtn(), true );
}
private static void enableWidget( ButtonBase btn, boolean isEnabled ) {
btn.setEnabled( isEnabled );
if ( isEnabled ) {
btn.removeStyleDependentName( DISABLED );
} else {
btn.addStyleDependentName( DISABLED );
}
}
/**
* NOTE: this method is extremely similar to updateSchedule, when modifying this method,
* consider modifying updateSchedule in a similar way.
*/
@SuppressWarnings("fallthrough")
private void createSchedule() {
// TODO, List<Schedule> is probably not what we will get back
AsyncCallback<Object> responseCallback = new AsyncCallback<Object>() {
public void onSuccess( Object o ) {
scheduleCreatorDialog.hide();
loadJobsTable();
}
public void onFailure(Throwable caught) {
MessageDialogBox messageDialog = new MessageDialogBox(ExceptionParser.getErrorHeader(caught.getMessage()), ExceptionParser.getErrorMessage(caught.getMessage(), caught.getMessage()), false, false, true);
messageDialog.center();
}
}; // end responseCallback
// TODO sbarkdull scheduleCreatorDialog -> scheduleEditorDialog
DualModeScheduleEditor scheduleEditor = scheduleCreatorDialog.getScheduleEditor();
String cronStr = scheduleEditor.getCronString();
Date startDate = scheduleEditor.getStartDate();
Date endDate = scheduleEditor.getEndDate();
if ( null == cronStr ) { // must be a repeating schedule
String startTime = scheduleEditor.getStartTime(); // format of string should be: HH:MM:SS AM/PM, e.g. 7:12:28 PM
startDate = TimeUtil.getDateTime( startTime, startDate );
endDate = (null != endDate) ? TimeUtil.getDateTime( startTime, endDate ) : null;
}
ScheduleEditor.ScheduleType rt = scheduleEditor.getScheduleType();
// TODO sbarkdull, if we want to support creation of scheduler schedules, we need to supply
// a UI mechanism like a checkbox to allow user to identify scheduler vs subscription,
// and then test the value of the check box instead of the following "true".
ISchedulerServiceAsync schedSvc = scheduleEditor.isSubscriptionSchedule()
? PacServiceFactory.getSubscriptionService()
: PacServiceFactory.getSchedulerService();
switch ( rt ) {
case RUN_ONCE:
schedSvc.createRepeatSchedule(
scheduleEditor.getName().trim(),
scheduleEditor.getGroupName().trim(),
scheduleEditor.getDescription().trim(),
startDate,
endDate,
"0" /*repeat count*/, //$NON-NLS-1$
"0" /*repeat time*/, //$NON-NLS-1$
scheduleCreatorDialog.getSolutionRepositoryActionSequenceEditor().getActionsAsString().trim(),
responseCallback
);
break;
case SECONDS: // fall through
case MINUTES: // fall through
case HOURS: // fall through
case DAILY: // fall through
case WEEKLY: // fall through
case MONTHLY: // fall through
case YEARLY:
if ( null == cronStr ) {
String repeatInterval = Long.toString( TimeUtil.secsToMillisecs(
scheduleEditor.getRepeatInSecs() ) );
schedSvc.createRepeatSchedule(
scheduleEditor.getName().trim(),
scheduleEditor.getGroupName().trim(),
scheduleEditor.getDescription().trim(),
startDate,
endDate,
null /*repeat count*/,
repeatInterval.trim(),
scheduleCreatorDialog.getSolutionRepositoryActionSequenceEditor().getActionsAsString().trim(),
responseCallback
);
break;
} else {
// fall through to case CRON
}
case CRON:
schedSvc.createCronSchedule(
scheduleEditor.getName().trim(),
scheduleEditor.getGroupName().trim(),
scheduleEditor.getDescription().trim(),
startDate,
endDate,
cronStr.trim(),
scheduleCreatorDialog.getSolutionRepositoryActionSequenceEditor().getActionsAsString().trim(),
responseCallback
);
break;
default:
throw new RuntimeException( Messages.getString("invalidRunType", rt.toString() ) ); //$NON-NLS-1$
}
}
private void deleteSelectedSchedules() {
final List<Schedule> selectedScheduleList = schedulesListCtrl.getSelectedSchedules();
AsyncCallback<Object> outerCallback = new AsyncCallback<Object>() {
public void onSuccess(Object result) {
AsyncCallback<Object> innerCallback = new AsyncCallback<Object>() {
public void onSuccess(Object pResult) {
loadJobsTable();
}
public void onFailure(Throwable caught) {
MessageDialogBox messageDialog = new MessageDialogBox(ExceptionParser.getErrorHeader(caught.getMessage()), ExceptionParser.getErrorMessage(caught.getMessage(), caught.getMessage()), false, false, true);
messageDialog.center();
}
}; // end inner callback
final List<Schedule> subscriptionSchedList = getSubscriptionSchedules( selectedScheduleList );
PacServiceFactory.getSubscriptionService().deleteJobs( subscriptionSchedList, innerCallback );
} // end onSuccess
public void onFailure(Throwable caught) {
MessageDialogBox messageDialog = new MessageDialogBox(ExceptionParser.getErrorHeader(caught.getMessage()), ExceptionParser.getErrorMessage(caught.getMessage(), caught.getMessage()), false, false, true);
messageDialog.center();
}
}; // end outer callback -----------
List<Schedule> nonSubscriptionSchedList = getSchedules( selectedScheduleList );
PacServiceFactory.getSchedulerService().deleteJobs( nonSubscriptionSchedList, outerCallback );
}
/**
* initialize the <code>scheduleEditor</code>'s user interface with
* the contents of the <code>sched</code>.
*
* @param scheduleEditor
* @param sched
* @throws CronParseException if sched has a non-empty CRON string, and the CRON string is not valid.
*/
private void initScheduleCreatorDialog( Schedule sched ) throws CronParseException {
scheduleCreatorDialog.reset( new Date() );
initScheduleEditor( sched );
initSolutionRepositoryActionSequenceEditor( sched );
}
private void initScheduleEditor( Schedule sched ) throws CronParseException {
DualModeScheduleEditor scheduleEditor = scheduleCreatorDialog.getScheduleEditor();
scheduleEditor.setSubscriptionSchedule( sched.isSubscriptionSchedule() );
scheduleEditor.setName( sched.getJobName() );
scheduleEditor.setGroupName( sched.getJobGroup() );
scheduleEditor.setDescription( sched.getDescription() );
String repeatIntervalInMillisecs = sched.getRepeatInterval();
if ( sched.isCronSchedule() ) {
scheduleEditor.setCronString( sched.getCronString() ); // throws CronParseException
} else if ( sched.isRepeatSchedule() ) {
long repeatIntervalInSecs = TimeUtil.millsecondsToSecs( Long.parseLong( repeatIntervalInMillisecs ) );
if ( 0 == repeatIntervalInSecs ) {
// run once
scheduleEditor.setScheduleType( ScheduleEditor.ScheduleType.RUN_ONCE );
} else {
// run multiple
scheduleEditor.setRepeatInSecs( (int) repeatIntervalInSecs );
}
} else {
throw new RuntimeException( Messages.getString("illegalStateMissingCronAndRepeat") ); //$NON-NLS-1$
}
String timePart = null;
String strDate = sched.getStartDate();
if ( null != strDate ) {
Date startDate = TimeUtil.getDate( strDate );
if ( sched.isRepeatSchedule() ) {
timePart = TimeUtil.getTimePart( startDate );
scheduleEditor.setStartTime( timePart );
startDate = TimeUtil.zeroTimePart( startDate );
}
scheduleEditor.setStartDate( startDate );
}
// scheduleEditor.getRunOnceEditor().setStartTime(strTime)
// scheduleEditor.getRunOnceEditor().setStartDate(strTime)
strDate = sched.getEndDate();
if ( null != strDate ) {
scheduleEditor.setEndBy();
Date endDate = TimeUtil.getDate( strDate );
if ( sched.isRepeatSchedule() ) {
endDate = TimeUtil.zeroTimePart( endDate );
}
scheduleEditor.setEndDate(endDate);
} else {
scheduleEditor.setNoEndDate();
}
}
private void initSolutionRepositoryActionSequenceEditor( Schedule sched ) {
solRepActionSequenceEditorController.init( sched.getActionsList() );
}
private boolean isNewScheduleCreatorDialogValid() {
ScheduleEditor schedEd = scheduleCreatorDialog.getScheduleEditor();
ScheduleEditorValidator schedEdValidator = new NewScheduleEditorValidator( schedEd, schedulesModel );
return isScheduleCreatorDialogValid( schedEdValidator );
}
private boolean isUpdateScheduleCreatorDialogValid() {
ScheduleEditor schedEd = scheduleCreatorDialog.getScheduleEditor();
ScheduleEditorValidator schedEdValidator = new ScheduleEditorValidator( schedEd, schedulesModel );
return isScheduleCreatorDialogValid( schedEdValidator );
}
private void handleCreateSchedule() {
final SchedulerToolbarController localThis = this;
scheduleCreatorDialog.setTitle( Messages.getString("scheduleCreator") ); //$NON-NLS-1$
scheduleCreatorDialog.reset( new Date() );
if(!loadingInitialized) {
scheduleCreatorDialog.setOkBtnEnabled( false );
}
scheduleCreatorDialog.setOnOkHandler( new ICallback<MessageDialog>() {
public void onHandle(MessageDialog d) {
localThis.createSchedule();
}
});
this.scheduleCreatorDialog.setOnValidateHandler( new IResponseCallback<MessageDialog, Boolean>() {
public Boolean onHandle( MessageDialog schedDlg ) {
return isNewScheduleCreatorDialogValid();
}
});
scheduleCreatorDialog.center();
solRepActionSequenceEditorController.init( null );
scheduleCreatorDialog.getScheduleEditor().setFocus();
}
private void handleUpdateSchedule() {
final SchedulerToolbarController localThis = this;
scheduleCreatorDialog.setTitle( Messages.getString("scheduleEditor") ); //$NON-NLS-1$
final List<Schedule> scheduleList = schedulesListCtrl.getSelectedSchedules();
if(!loadingInitialized) {
scheduleCreatorDialog.setOkBtnEnabled( false );
}
scheduleCreatorDialog.setOnOkHandler( new ICallback<MessageDialog>() {
public void onHandle(MessageDialog d) {
localThis.updateScheduleWithNewScheduleType();
}
});
this.scheduleCreatorDialog.setOnValidateHandler( new IResponseCallback<MessageDialog, Boolean>() {
public Boolean onHandle( MessageDialog schedDlg ) {
return isUpdateScheduleCreatorDialogValid();
}
});
// the update button should be enabled/disabled to guarantee that one and only one schedule is selected
assert scheduleList.size() == 1 : "When clicking update, exactly one schedule should be selected."; //$NON-NLS-1$
Schedule sched = scheduleList.get( 0 );
try {
initScheduleCreatorDialog( sched );
scheduleCreatorDialog.center();
scheduleCreatorDialog.getScheduleEditor().setFocus();
} catch (CronParseException e) {
final MessageDialog errorDialog = new MessageDialog( Messages.getString("error"), //$NON-NLS-1$
Messages.getString("invalidCronInInitOfRecurrenceDialog", sched.getCronString(), e.getMessage() ) ); //$NON-NLS-1$
errorDialog.setOnOkHandler( new ICallback<MessageDialog>() {
public void onHandle(MessageDialog messageDialog ) {
errorDialog.hide();
scheduleCreatorDialog.center();
}
});
errorDialog.center();
}
}
private void handleLoadingComplete() {
scheduleCreatorDialog.setOkBtnEnabled( true );
loadingInitialized = true;
}
private void handleDeleteSchedules() {
final SchedulerToolbarController localThis = this;
final ConfirmDialog confirm = new ConfirmDialog( Messages.getString("confirmDelete"), //$NON-NLS-1$
Messages.getString("confirmDeleteQuestion", Integer.toString( getNumSubscribers() ) ) ); //$NON-NLS-1$
confirm.setOnOkHandler( new ICallback<MessageDialog>() {
public void onHandle( MessageDialog d ) {
confirm.hide();
localThis.deleteSelectedSchedules();
}
});
confirm.center();
}
private int getNumSubscribers() {
List<Schedule> schedList = schedulesListCtrl.getSelectedSchedules();
int numSubscribers = 0;
for ( Schedule sched: schedList ) {
try {
numSubscribers += Integer.parseInt( sched.getSubscriberCount() );
} catch (NumberFormatException ex) {
// Do nothing, we'll return 0.
}
}
return numSubscribers;
}
private void handleResumeSchedules() {
final List<Schedule> selectedScheduleList = schedulesListCtrl.getSelectedSchedules();
AsyncCallback<Object> outerCallback = new AsyncCallback<Object>() {
public void onSuccess(Object result) {
AsyncCallback<Object> innerCallback = new AsyncCallback<Object>() {
public void onSuccess(Object pResult) {
loadJobsTable();
}
public void onFailure(Throwable caught) {
MessageDialogBox messageDialog = new MessageDialogBox(ExceptionParser.getErrorHeader(caught.getMessage()), ExceptionParser.getErrorMessage(caught.getMessage(), caught.getMessage()), false, false, true);
messageDialog.center();
}
}; // end inner callback
final List<Schedule> subscriptionSchedList = getSubscriptionSchedules( selectedScheduleList );
PacServiceFactory.getSubscriptionService().resumeJobs( subscriptionSchedList, innerCallback );
} // end onSuccess
public void onFailure(Throwable caught) {
MessageDialogBox messageDialog = new MessageDialogBox(ExceptionParser.getErrorHeader(caught.getMessage()), ExceptionParser.getErrorMessage(caught.getMessage(), caught.getMessage()), false, false, true);
messageDialog.center();
}
}; // end outer callback -----------
List<Schedule> nonSubscriptionSchedList = getSchedules( selectedScheduleList );
PacServiceFactory.getSchedulerService().resumeJobs( nonSubscriptionSchedList, outerCallback );
}
private void handlePauseSchedules() {
final List<Schedule> selectedScheduleList = schedulesListCtrl.getSelectedSchedules();
AsyncCallback<Object> outerCallback = new AsyncCallback<Object>() {
public void onSuccess(Object result) {
AsyncCallback<Object> innerCallback = new AsyncCallback<Object>() {
public void onSuccess(Object pResult) {
loadJobsTable();
}
public void onFailure(Throwable caught) {
MessageDialogBox messageDialog = new MessageDialogBox(ExceptionParser.getErrorHeader(caught.getMessage()), ExceptionParser.getErrorMessage(caught.getMessage(), caught.getMessage()), false, false, true);
messageDialog.center();
}
}; // end inner callback
final List<Schedule> subscriptionSchedList = getSubscriptionSchedules( selectedScheduleList );
PacServiceFactory.getSubscriptionService().pauseJobs( subscriptionSchedList, innerCallback );
} // end onSuccess
public void onFailure(Throwable caught) {
MessageDialogBox messageDialog = new MessageDialogBox(ExceptionParser.getErrorHeader(caught.getMessage()), ExceptionParser.getErrorMessage(caught.getMessage(), caught.getMessage()), false, false, true);
messageDialog.center();
}
}; // end outer callback -----------
List<Schedule> nonSubscriptionSchedList = getSchedules( selectedScheduleList );
PacServiceFactory.getSchedulerService().pauseJobs( nonSubscriptionSchedList, outerCallback );
}
private void handleRunNowSchedules() {
final List<Schedule> selectedScheduleList = schedulesListCtrl.getSelectedSchedules();
AsyncCallback<Object> outerCallback = new AsyncCallback<Object>() {
public void onSuccess(Object result) {
AsyncCallback<Object> innerCallback = new AsyncCallback<Object>() {
public void onSuccess(Object pResult) {
loadJobsTable();
}
public void onFailure(Throwable caught) {
MessageDialogBox messageDialog = new MessageDialogBox(ExceptionParser.getErrorHeader(caught.getMessage()), ExceptionParser.getErrorMessage(caught.getMessage(), caught.getMessage()), false, false, true);
messageDialog.center();
}
}; // end inner callback
final List<Schedule> subscriptionSchedList = getSubscriptionSchedules( selectedScheduleList );
PacServiceFactory.getSubscriptionService().executeJobs( subscriptionSchedList, innerCallback );
} // end onSuccess
public void onFailure(Throwable caught) {
MessageDialogBox messageDialog = new MessageDialogBox(ExceptionParser.getErrorHeader(caught.getMessage()), ExceptionParser.getErrorMessage(caught.getMessage(), caught.getMessage()), false, false, true);
messageDialog.center();
}
}; // end outer callback -----------
List<Schedule> nonSubscriptionSchedList = getSchedules( selectedScheduleList );
PacServiceFactory.getSchedulerService().executeJobs( nonSubscriptionSchedList, outerCallback );
}
private static List<Schedule> getSchedules( List<Schedule> schedList ) {
List<Schedule> list = new ArrayList<Schedule>();
for ( Schedule sched : schedList ) {
if ( !sched.isSubscriptionSchedule() ) {
list.add( sched);
}
}
return list;
}
private static List<Schedule> getSubscriptionSchedules( List<Schedule> schedList ) {
List<Schedule> list = new ArrayList<Schedule>();
for ( Schedule sched : schedList ) {
if ( sched.isSubscriptionSchedule() ) {
list.add( sched);
}
}
return list;
}
/**
* NOTE: This method should not be called directly except by isNewScheduleCreatorDialogValid and isUpdateScheduleCreatorDialogValid
* NOTE: code in this method must stay in sync with isScheduleEditorValid(), i.e. all error msgs
* that may be cleared in clearScheduleEditorValidationMsgs(), must be set-able here.
*/
private boolean isScheduleCreatorDialogValid( ScheduleEditorValidator schedEdValidator ) {
boolean isValid = true;
boolean isSubscriptionSched = scheduleCreatorDialog.getScheduleEditor().isSubscriptionSchedule();
SolutionRepositoryActionSequenceListEditor solRepPicker = scheduleCreatorDialog.getSolutionRepositoryActionSequenceEditor();
SolutionRepositoryActionSequenceListEditorValidator solRepValidator = new SolutionRepositoryActionSequenceListEditorValidator( solRepPicker, isSubscriptionSched );
scheduleCreatorDialog.clearTabError();
schedEdValidator.clear();
solRepValidator.clear();
/*
* If a tab's controls have errors, change the tab's appearance so that
* the tab-label displays in an error-color (red). If the current tab
* does not have an error, find the first tab that does have an error,
* and set it to the current tab.
*/
TabIndex firstTabWithError = null;
boolean doesSelectedTabHaveError = false;
TabIndex selectedIdx = scheduleCreatorDialog.getSelectedTab();
if ( !schedEdValidator.isValid() ) {
isValid = false ;
scheduleCreatorDialog.setTabError( TabIndex.SCHEDULE );
if ( null == firstTabWithError ) {
firstTabWithError = TabIndex.SCHEDULE;
}
if ( TabIndex.SCHEDULE == selectedIdx ) {
doesSelectedTabHaveError = true;
}
}
if ( !solRepValidator.isValid() ) {
isValid = false ;
scheduleCreatorDialog.setTabError( TabIndex.SCHEDULE_ACTION );
if ( null == firstTabWithError ) {
firstTabWithError = TabIndex.SCHEDULE_ACTION;
}
if ( TabIndex.SCHEDULE_ACTION == selectedIdx ) {
doesSelectedTabHaveError = true;
}
}
if ( false == doesSelectedTabHaveError && firstTabWithError != null ) {
scheduleCreatorDialog.setSelectedTab( firstTabWithError );
}
return isValid;
}
public SchedulesModel getSchedulesModel() {
return schedulesModel;
}
}