Java tutorial
/*! * 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 (c) 2002-2017 Pentaho Corporation.. All rights reserved. */ package org.pentaho.mantle.client.dialogs.scheduling; import java.util.Date; import java.util.List; import org.pentaho.gwt.widgets.client.dialogs.IDialogCallback; import org.pentaho.gwt.widgets.client.dialogs.MessageDialogBox; import org.pentaho.gwt.widgets.client.dialogs.PromptDialogBox; import org.pentaho.gwt.widgets.client.utils.TimeUtil; import org.pentaho.gwt.widgets.client.utils.TimeUtil.DayOfWeek; import org.pentaho.gwt.widgets.client.utils.TimeUtil.MonthOfYear; import org.pentaho.gwt.widgets.client.utils.TimeUtil.WeekOfMonth; import org.pentaho.gwt.widgets.client.utils.string.StringUtils; import org.pentaho.gwt.widgets.client.wizards.AbstractWizardDialog; import org.pentaho.gwt.widgets.client.wizards.IWizardPanel; import org.pentaho.mantle.client.dialogs.scheduling.RecurrenceEditor.DailyRecurrenceEditor; import org.pentaho.mantle.client.dialogs.scheduling.RecurrenceEditor.MonthlyRecurrenceEditor; import org.pentaho.mantle.client.dialogs.scheduling.RecurrenceEditor.WeeklyRecurrenceEditor; import org.pentaho.mantle.client.dialogs.scheduling.RecurrenceEditor.YearlyRecurrenceEditor; import org.pentaho.mantle.client.dialogs.scheduling.ScheduleEditor.DurationValues; import org.pentaho.mantle.client.dialogs.scheduling.ScheduleEditor.ScheduleType; import org.pentaho.mantle.client.messages.Messages; import org.pentaho.mantle.client.workspace.BlockoutPanel; import org.pentaho.mantle.client.workspace.JsBlockStatus; import org.pentaho.mantle.client.workspace.JsJob; import org.pentaho.mantle.client.workspace.JsJobParam; import org.pentaho.mantle.client.workspace.JsJobTrigger; import org.pentaho.mantle.login.client.MantleLoginDialog; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JsArrayInteger; import com.google.gwt.core.client.JsArrayString; import com.google.gwt.core.client.JsonUtils; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.http.client.Request; import com.google.gwt.http.client.RequestBuilder; import com.google.gwt.http.client.RequestCallback; import com.google.gwt.http.client.RequestException; import com.google.gwt.http.client.Response; import com.google.gwt.i18n.client.DateTimeFormat; import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat; import com.google.gwt.json.client.JSONArray; import com.google.gwt.json.client.JSONNull; import com.google.gwt.json.client.JSONNumber; import com.google.gwt.json.client.JSONObject; import com.google.gwt.json.client.JSONParser; import com.google.gwt.json.client.JSONString; import com.google.gwt.user.client.Random; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.DockPanel; import com.google.gwt.user.client.ui.Widget; /** * @author wseyler * */ public class ScheduleRecurrenceDialog extends AbstractWizardDialog { private static final String HOUR_MINUTE_SECOND = "h:mm:ss a"; private final String moduleBaseURL = GWT.getModuleBaseURL(); private final String moduleName = GWT.getModuleName(); private final String contextURL = moduleBaseURL.substring(0, moduleBaseURL.lastIndexOf(moduleName)); protected String filePath; protected String outputLocation; protected String scheduleName; private IDialogCallback callback; boolean isBlockoutDialog = false; private ScheduleEmailDialog scheduleEmailDialog; private ScheduleParamsDialog scheduleParamsDialog; protected ScheduleEditorWizardPanel scheduleEditorWizardPanel; protected JsJob editJob = null; private Boolean done = false; private boolean hasParams = false; private boolean isEmailConfValid = false; private boolean showSuccessDialog = true; private ScheduleEditor scheduleEditor; private PromptDialogBox parentDialog; private boolean newSchedule = true; public ScheduleRecurrenceDialog(PromptDialogBox parentDialog, JsJob jsJob, IDialogCallback callback, boolean hasParams, boolean isEmailConfValid, final ScheduleDialogType type) { super(type, type != ScheduleDialogType.BLOCKOUT ? Messages.getString("editSchedule") //$NON-NLS-1$ : Messages.getString("editBlockoutSchedule"), null, false, true); //$NON-NLS-1$ isBlockoutDialog = (type == ScheduleDialogType.BLOCKOUT); setCallback(callback); editJob = jsJob; this.parentDialog = parentDialog; newSchedule = false; constructDialog(jsJob.getFullResourceName(), jsJob.getOutputPath(), jsJob.getJobName(), hasParams, isEmailConfValid, jsJob); } public ScheduleRecurrenceDialog(PromptDialogBox parentDialog, String filePath, String outputLocation, String scheduleName, IDialogCallback callback, boolean hasParams, boolean isEmailConfValid) { super(ScheduleDialogType.SCHEDULER, Messages.getString("newSchedule"), null, false, true); //$NON-NLS-1$ isBlockoutDialog = false; setCallback(callback); this.parentDialog = parentDialog; constructDialog(filePath, outputLocation, scheduleName, hasParams, isEmailConfValid, null); } public ScheduleRecurrenceDialog(PromptDialogBox parentDialog, ScheduleDialogType type, String title, String filePath, String outputLocation, String scheduleName, IDialogCallback callback, boolean hasParams, boolean isEmailConfValid) { super(type, title, null, false, true); isBlockoutDialog = (type == ScheduleDialogType.BLOCKOUT); setCallback(callback); this.parentDialog = parentDialog; constructDialog(filePath, outputLocation, scheduleName, hasParams, isEmailConfValid, null); } @Override public boolean onKeyDownPreview(char key, int modifiers) { if (key == KeyCodes.KEY_ESCAPE) { hide(); } return true; } public void setParentDialog(PromptDialogBox parentDialog) { this.parentDialog = parentDialog; } public void addCustomPanel(Widget w, DockPanel.DockLayoutConstant position) { scheduleEditorWizardPanel.add(w, position); } private void constructDialog(String filePath, String outputLocation, String scheduleName, boolean hasParams, boolean isEmailConfValid, JsJob jsJob) { this.hasParams = hasParams; this.filePath = filePath; this.isEmailConfValid = isEmailConfValid; this.outputLocation = outputLocation; this.scheduleName = scheduleName; scheduleEditorWizardPanel = new ScheduleEditorWizardPanel(getDialogType()); scheduleEditor = scheduleEditorWizardPanel.getScheduleEditor(); String url = ScheduleHelper.getFullyQualifiedURL() + "api/scheduler/blockout/hasblockouts?ts=" //$NON-NLS-1$ + System.currentTimeMillis(); RequestBuilder hasBlockoutsRequest = new RequestBuilder(RequestBuilder.GET, url); hasBlockoutsRequest.setHeader("If-Modified-Since", "01 Jan 1970 00:00:00 GMT"); hasBlockoutsRequest.setHeader("accept", "text/plain"); try { hasBlockoutsRequest.sendRequest(url, new RequestCallback() { @Override public void onError(Request request, Throwable exception) { MessageDialogBox dialogBox = new MessageDialogBox(Messages.getString("error"), //$NON-NLS-1$ exception.toString(), false, false, true); dialogBox.center(); } @Override public void onResponseReceived(Request request, Response response) { Boolean hasBlockouts = Boolean.valueOf(response.getText()); if (hasBlockouts) { scheduleEditor.setBlockoutButtonHandler(new ClickHandler() { @Override public void onClick(final ClickEvent clickEvent) { PromptDialogBox box = new PromptDialogBox(Messages.getString("blockoutTimes"), Messages.getString("close"), null, null, false, true, new BlockoutPanel(false)); box.center(); } }); } scheduleEditor.getBlockoutCheckButton().setVisible(hasBlockouts); } }); } catch (RequestException e) { MessageDialogBox dialogBox = new MessageDialogBox(Messages.getString("error"), e.toString(), //$NON-NLS-1$ false, false, true); dialogBox.center(); } IWizardPanel[] wizardPanels = { scheduleEditorWizardPanel }; setWizardPanels(wizardPanels); setPixelSize(475, 465); center(); if ((hasParams || isEmailConfValid) && (isBlockoutDialog == false)) { finishButton.setText(Messages.getString("next")); //$NON-NLS-1$ } else { finishButton.setText(Messages.getString("finish")); //$NON-NLS-1$ } setupExisting(jsJob); wizardDeckPanel.getElement().getParentElement().addClassName("schedule-dialog-content"); wizardDeckPanel.getElement().getParentElement().removeClassName("dialog-content"); //setHeight("100%"); //$NON-NLS-1$ setSize("650px", "450px"); addStyleName("schedule-recurrence-dialog"); } private void setupExisting(JsJob jsJob) { if (jsJob != null && !jsJob.equals("")) { //$NON-NLS-1$ JsJobTrigger jsJobTrigger = jsJob.getJobTrigger(); ScheduleType scheduleType = ScheduleType.valueOf(jsJobTrigger.getScheduleType()); // scheduleEditor.setScheduleName(jsJob.getJobName()); scheduleEditor.setScheduleType(scheduleType); if (scheduleType == ScheduleType.CRON || jsJobTrigger.getType().equals("cronJobTrigger")) { //$NON-NLS-1$ scheduleEditor.getCronEditor().setCronString(jsJobTrigger.getCronString()); } else if (jsJobTrigger.getType().equals("simpleJobTrigger")) { //$NON-NLS-1$ if (jsJobTrigger.getRepeatCount() == -1) { // Recurring simple Trigger int interval = jsJobTrigger.getRepeatInterval(); scheduleEditor.setRepeatInSecs(interval); if (scheduleType == ScheduleType.DAILY) { DailyRecurrenceEditor dailyRecurrenceEditor = scheduleEditor.getRecurrenceEditor() .getDailyEditor(); dailyRecurrenceEditor.setEveryNDays(); } } } else if (jsJobTrigger.getType().equals("complexJobTrigger")) { //$NON-NLS-1$ if (scheduleType == ScheduleType.DAILY) { // Daily DailyRecurrenceEditor dailyRecurrenceEditor = scheduleEditor.getRecurrenceEditor() .getDailyEditor(); if (jsJobTrigger.isWorkDaysInWeek()) { dailyRecurrenceEditor.setEveryWeekday(); } else { dailyRecurrenceEditor.setEveryNDays(); } } else if (scheduleType == ScheduleType.WEEKLY) { int[] daysOfWeek = jsJobTrigger.getDayOfWeekRecurrences(); WeeklyRecurrenceEditor weeklyRecurrenceEditor = scheduleEditor.getRecurrenceEditor() .getWeeklyEditor(); String strDays = ""; //$NON-NLS-1$ for (int element2 : daysOfWeek) { strDays += Integer.toString(element2) + ","; //$NON-NLS-1$ } weeklyRecurrenceEditor.setCheckedDaysAsString(strDays, 1); } else if (scheduleType == ScheduleType.MONTHLY) { MonthlyRecurrenceEditor monthlyRecurrenceEditor = scheduleEditor.getRecurrenceEditor() .getMonthlyEditor(); if (jsJobTrigger.isQualifiedDayOfWeekRecurrence()) { // Run Every on ___day of Nth week every month monthlyRecurrenceEditor .setDayOfWeek(TimeUtil.DayOfWeek.valueOf(jsJobTrigger.getQualifiedDayOfWeek())); monthlyRecurrenceEditor .setWeekOfMonth(TimeUtil.WeekOfMonth.valueOf(jsJobTrigger.getDayOfWeekQualifier())); monthlyRecurrenceEditor.setNthDayNameOfMonth(); } else { // Run on Nth day of the month monthlyRecurrenceEditor .setDayOfMonth(Integer.toString(jsJobTrigger.getDayOfMonthRecurrences()[0])); } } else if (scheduleType == ScheduleType.YEARLY) { YearlyRecurrenceEditor yearlyRecurrenceEditor = scheduleEditor.getRecurrenceEditor() .getYearlyEditor(); if (jsJobTrigger.isQualifiedDayOfWeekRecurrence()) { // Run Every on ___day of Nth week of the month M yearly yearlyRecurrenceEditor .setDayOfWeek(TimeUtil.DayOfWeek.valueOf(jsJobTrigger.getQualifiedDayOfWeek())); yearlyRecurrenceEditor .setWeekOfMonth(TimeUtil.WeekOfMonth.valueOf(jsJobTrigger.getDayOfWeekQualifier())); yearlyRecurrenceEditor.setMonthOfYear1( TimeUtil.MonthOfYear.get(jsJobTrigger.getMonthlyRecurrences()[0] - 1)); yearlyRecurrenceEditor.setNthDayNameOfMonthName(); } else { // Run on Nth day of the month M yearly yearlyRecurrenceEditor .setDayOfMonth(Integer.toString(jsJobTrigger.getDayOfMonthRecurrences()[0])); yearlyRecurrenceEditor.setMonthOfYear0( TimeUtil.MonthOfYear.get(jsJobTrigger.getMonthlyRecurrences()[0] - 1)); yearlyRecurrenceEditor.setEveryMonthOnNthDay(); } } } scheduleEditor.setStartDate(jsJobTrigger.getStartTime()); scheduleEditor .setStartTime(DateTimeFormat.getFormat(HOUR_MINUTE_SECOND).format(jsJobTrigger.getStartTime())); if (jsJobTrigger.getEndTime() == null) { scheduleEditor.setNoEndDate(); } else { scheduleEditor.setEndDate(jsJobTrigger.getEndTime()); scheduleEditor.setEndBy(); } if (isBlockoutDialog) { scheduleEditor.setDurationFields(jsJobTrigger.getBlockDuration()); } } } protected JSONObject getJsonSimpleTrigger(int repeatCount, int interval, Date startDate, Date endDate) { JSONObject trigger = new JSONObject(); trigger.put("uiPassParam", new JSONString(scheduleEditorWizardPanel.getScheduleType().name())); //$NON-NLS-1$ trigger.put("repeatInterval", new JSONNumber(interval)); //$NON-NLS-1$ trigger.put("repeatCount", new JSONNumber(repeatCount)); //$NON-NLS-1$ addJsonStartEnd(trigger, startDate, endDate); return trigger; } protected JSONObject getJsonCronTrigger(String cronString, Date startDate, Date endDate) { JSONObject trigger = new JSONObject(); trigger.put("uiPassParam", new JSONString(scheduleEditorWizardPanel.getScheduleType().name())); //$NON-NLS-1$ trigger.put("cronString", new JSONString(cronString)); //$NON-NLS-1$ addJsonStartEnd(trigger, startDate, endDate); return trigger; } protected JSONObject getJsonComplexTrigger(ScheduleType scheduleType, MonthOfYear month, WeekOfMonth weekOfMonth, List<DayOfWeek> daysOfWeek, Date startDate, Date endDate) { JSONObject trigger = new JSONObject(); trigger.put("uiPassParam", new JSONString(scheduleEditorWizardPanel.getScheduleType().name())); //$NON-NLS-1$ if (month != null) { JSONArray jsonArray = new JSONArray(); jsonArray.set(0, new JSONString(Integer.toString(month.ordinal()))); trigger.put("monthsOfYear", jsonArray); //$NON-NLS-1$ } if (weekOfMonth != null) { JSONArray jsonArray = new JSONArray(); jsonArray.set(0, new JSONString(Integer.toString(weekOfMonth.ordinal()))); trigger.put("weeksOfMonth", jsonArray); //$NON-NLS-1$ } if (daysOfWeek != null) { JSONArray jsonArray = new JSONArray(); int index = 0; for (DayOfWeek dayOfWeek : daysOfWeek) { jsonArray.set(index++, new JSONString(Integer.toString(dayOfWeek.ordinal()))); } trigger.put("daysOfWeek", jsonArray); //$NON-NLS-1$ } addJsonStartEnd(trigger, startDate, endDate); return trigger; } protected JSONObject getJsonComplexTrigger(ScheduleType scheduleType, MonthOfYear month, int dayOfMonth, Date startDate, Date endDate) { JSONObject trigger = new JSONObject(); trigger.put("uiPassParam", new JSONString(scheduleEditorWizardPanel.getScheduleType().name())); //$NON-NLS-1$ if (month != null) { JSONArray jsonArray = new JSONArray(); jsonArray.set(0, new JSONString(Integer.toString(month.ordinal()))); trigger.put("monthsOfYear", jsonArray); //$NON-NLS-1$ } JSONArray jsonArray = new JSONArray(); jsonArray.set(0, new JSONString(Integer.toString(dayOfMonth))); trigger.put("daysOfMonth", jsonArray); //$NON-NLS-1$ addJsonStartEnd(trigger, startDate, endDate); return trigger; } /** * Returns an object suitable for posting into quartz via the the "JOB" rest service. * * @return */ @SuppressWarnings("deprecation") public JSONObject getSchedule() { ScheduleType scheduleType = scheduleEditorWizardPanel.getScheduleType(); Date startDate = scheduleEditorWizardPanel.getStartDate(); String startTime = scheduleEditorWizardPanel.getStartTime(); // For blockout periods, we need the blockout start time. if (isBlockoutDialog) { startTime = scheduleEditorWizardPanel.getBlockoutStartTime(); } int startHour = getStartHour(startTime); int startMin = getStartMin(startTime); int startYear = startDate.getYear(); int startMonth = startDate.getMonth(); int startDay = startDate.getDate(); Date startDateTime = new Date(startYear, startMonth, startDay, startHour, startMin); Date endDate = scheduleEditorWizardPanel.getEndDate(); MonthOfYear monthOfYear = scheduleEditor.getRecurrenceEditor().getSelectedMonth(); List<DayOfWeek> daysOfWeek = scheduleEditor.getRecurrenceEditor().getSelectedDaysOfWeek(); Integer dayOfMonth = scheduleEditor.getRecurrenceEditor().getSelectedDayOfMonth(); WeekOfMonth weekOfMonth = scheduleEditor.getRecurrenceEditor().getSelectedWeekOfMonth(); JSONObject schedule = new JSONObject(); schedule.put("jobName", new JSONString(scheduleName)); //$NON-NLS-1$ if (scheduleType == ScheduleType.RUN_ONCE) { // Run once types schedule.put("simpleJobTrigger", getJsonSimpleTrigger(0, 0, startDateTime, null)); //$NON-NLS-1$ } else if ((scheduleType == ScheduleType.SECONDS) || (scheduleType == ScheduleType.MINUTES) || (scheduleType == ScheduleType.HOURS)) { int repeatInterval = 0; try { // Simple Trigger Types repeatInterval = Integer.parseInt(scheduleEditorWizardPanel.getRepeatInterval()); } catch (Exception e) { // ignored } schedule.put("simpleJobTrigger", getJsonSimpleTrigger(-1, repeatInterval, startDateTime, endDate)); //$NON-NLS-1$ } else if (scheduleType == ScheduleType.DAILY) { if (scheduleEditor.getRecurrenceEditor().isEveryNDays()) { int repeatInterval = 0; try { // Simple Trigger Types repeatInterval = Integer.parseInt(scheduleEditorWizardPanel.getRepeatInterval()); } catch (Exception e) { // ignored } schedule.put("simpleJobTrigger", getJsonSimpleTrigger(-1, repeatInterval, startDateTime, endDate)); //$NON-NLS-1$ } else { schedule.put("complexJobTrigger", getJsonComplexTrigger(scheduleType, null, null, //$NON-NLS-1$ scheduleEditor.getRecurrenceEditor().getSelectedDaysOfWeek(), startDateTime, endDate)); } } else if (scheduleType == ScheduleType.CRON) { // Cron jobs schedule.put("cronJobTrigger", //$NON-NLS-1$ getJsonCronTrigger(scheduleEditor.getCronString(), startDateTime, endDate)); } else if ((scheduleType == ScheduleType.WEEKLY) && (daysOfWeek.size() > 0)) { schedule.put("complexJobTrigger", getJsonComplexTrigger(scheduleType, null, null, //$NON-NLS-1$ scheduleEditor.getRecurrenceEditor().getSelectedDaysOfWeek(), startDateTime, endDate)); } else if ((scheduleType == ScheduleType.MONTHLY) || ((scheduleType == ScheduleType.YEARLY) && (monthOfYear != null))) { if (dayOfMonth != null) { // YEARLY Run on specific day in year or MONTHLY Run on specific day in month schedule.put("complexJobTrigger", getJsonComplexTrigger(scheduleType, monthOfYear, dayOfMonth, startDateTime, endDate)); } else if ((daysOfWeek.size() > 0) && (weekOfMonth != null)) { // YEARLY schedule.put("complexJobTrigger", getJsonComplexTrigger(scheduleType, monthOfYear, weekOfMonth, daysOfWeek, startDateTime, endDate)); } } schedule.put("inputFile", new JSONString(filePath)); //$NON-NLS-1$ schedule.put("outputFile", new JSONString(outputLocation)); //$NON-NLS-1$ return schedule; } @SuppressWarnings("deprecation") private JSONObject addJsonStartEnd(JSONObject trigger, Date startDate, Date endDate) { trigger.put("startTime", //$NON-NLS-1$ new JSONString(DateTimeFormat.getFormat(PredefinedFormat.ISO_8601).format(startDate))); if (endDate != null) { endDate.setHours(23); endDate.setMinutes(59); endDate.setSeconds(59); } trigger.put("endTime", endDate == null ? JSONNull.getInstance() : new JSONString(DateTimeFormat.getFormat(PredefinedFormat.ISO_8601).format(endDate))); return trigger; } private long calculateBlockoutDuration() { long second = 1000; long minute = second * 60; long hour = minute * 60; long day = hour * 24; long durationMilli = -1; if (scheduleEditor.getBlockoutEndsType().equals(ScheduleEditor.ENDS_TYPE.TIME)) { final String startTime = scheduleEditorWizardPanel.getBlockoutStartTime(); final String endTime = scheduleEditorWizardPanel.getBlockoutEndTime(); long start = getStartHour(startTime) * hour + getStartMin(startTime) * minute; long end = getStartHour(endTime) * hour + getStartMin(endTime) * minute; durationMilli = Math.abs(end - start); } else { DurationValues durationValues = scheduleEditor.getDurationValues(); long minutes = durationValues.minutes * minute; long hours = durationValues.hours * hour; long days = durationValues.days * day; durationMilli = minutes + hours + days; } return durationMilli; } @SuppressWarnings("deprecation") public JsJobTrigger getJsJobTrigger() { JsJobTrigger jsJobTrigger = JsJobTrigger.instance(); ScheduleType scheduleType = scheduleEditorWizardPanel.getScheduleType(); Date startDate = scheduleEditorWizardPanel.getStartDate(); String startTime = scheduleEditorWizardPanel.getStartTime(); int startHour = getStartHour(startTime); int startMin = getStartMin(startTime); int startYear = startDate.getYear(); int startMonth = startDate.getMonth(); int startDay = startDate.getDate(); Date startDateTime = new Date(startYear, startMonth, startDay, startHour, startMin); Date endDate = scheduleEditorWizardPanel.getEndDate(); MonthOfYear monthOfYear = scheduleEditor.getRecurrenceEditor().getSelectedMonth(); List<DayOfWeek> daysOfWeek = scheduleEditor.getRecurrenceEditor().getSelectedDaysOfWeek(); Integer dayOfMonth = scheduleEditor.getRecurrenceEditor().getSelectedDayOfMonth(); WeekOfMonth weekOfMonth = scheduleEditor.getRecurrenceEditor().getSelectedWeekOfMonth(); if (isBlockoutDialog) { jsJobTrigger.setBlockDuration(calculateBlockoutDuration()); } else { // blockDuration is only valid for blockouts jsJobTrigger.setBlockDuration(new Long(-1)); } if (scheduleType == ScheduleType.RUN_ONCE) { // Run once types jsJobTrigger.setType("simpleJobTrigger"); //$NON-NLS-1$ jsJobTrigger.setRepeatInterval(0); jsJobTrigger.setRepeatCount(0); jsJobTrigger .setNativeStartTime(DateTimeFormat.getFormat(PredefinedFormat.ISO_8601).format(startDateTime)); } else if ((scheduleType == ScheduleType.SECONDS) || (scheduleType == ScheduleType.MINUTES) || (scheduleType == ScheduleType.HOURS)) { int repeatInterval = 0; try { // Simple Trigger Types repeatInterval = Integer.parseInt(scheduleEditorWizardPanel.getRepeatInterval()); } catch (Exception e) { // ignored } jsJobTrigger.setType("simpleJobTrigger"); //$NON-NLS-1$ jsJobTrigger.setRepeatInterval(repeatInterval); jsJobTrigger.setRepeatCount(-1); jsJobTrigger .setNativeStartTime(DateTimeFormat.getFormat(PredefinedFormat.ISO_8601).format(startDateTime)); if (endDate != null) { jsJobTrigger.setNativeEndTime(DateTimeFormat.getFormat(PredefinedFormat.ISO_8601).format(endDate)); } } else if (scheduleType == ScheduleType.DAILY) { if (scheduleEditor.getRecurrenceEditor().isEveryNDays()) { int repeatInterval = 0; try { // Simple Trigger Types repeatInterval = Integer.parseInt(scheduleEditorWizardPanel.getRepeatInterval()); } catch (Exception e) { // ignored } jsJobTrigger.setType("simpleJobTrigger"); //$NON-NLS-1$ jsJobTrigger.setRepeatInterval(repeatInterval); jsJobTrigger.setRepeatCount(-1); jsJobTrigger.setNativeStartTime( DateTimeFormat.getFormat(PredefinedFormat.ISO_8601).format(startDateTime)); if (endDate != null) { jsJobTrigger .setNativeEndTime(DateTimeFormat.getFormat(PredefinedFormat.ISO_8601).format(endDate)); } } else { JsArrayInteger jsDaysOfWeek = (JsArrayInteger) JavaScriptObject.createArray(); int i = 0; for (DayOfWeek dayOfWeek : daysOfWeek) { jsDaysOfWeek.set(i++, dayOfWeek.ordinal() + 1); } JsArrayInteger hours = (JsArrayInteger) JavaScriptObject.createArray(); hours.set(0, startHour); JsArrayInteger minutes = (JsArrayInteger) JavaScriptObject.createArray(); hours.set(0, startMin); JsArrayInteger seconds = (JsArrayInteger) JavaScriptObject.createArray(); hours.set(0, 0); jsJobTrigger.setType("complexJobTrigger"); //$NON-NLS-1$ jsJobTrigger.setDayOfWeekRecurrences(jsDaysOfWeek); jsJobTrigger.setHourRecurrences(hours); jsJobTrigger.setMinuteRecurrences(minutes); jsJobTrigger.setSecondRecurrences(seconds); jsJobTrigger.setNativeStartTime( DateTimeFormat.getFormat(PredefinedFormat.ISO_8601).format(startDateTime)); if (endDate != null) { jsJobTrigger .setNativeEndTime(DateTimeFormat.getFormat(PredefinedFormat.ISO_8601).format(endDate)); } } } else if (scheduleType == ScheduleType.CRON) { // Cron jobs jsJobTrigger.setType("cronJobTrigger"); //$NON-NLS-1$ } else if ((scheduleType == ScheduleType.WEEKLY) && (daysOfWeek.size() > 0)) { JsArrayInteger jsDaysOfWeek = (JsArrayInteger) JavaScriptObject.createArray(); int i = 0; for (DayOfWeek dayOfWeek : daysOfWeek) { jsDaysOfWeek.set(i++, dayOfWeek.ordinal() + 1); } JsArrayInteger hours = (JsArrayInteger) JavaScriptObject.createArray(); hours.set(0, startHour); JsArrayInteger minutes = (JsArrayInteger) JavaScriptObject.createArray(); hours.set(0, startMin); JsArrayInteger seconds = (JsArrayInteger) JavaScriptObject.createArray(); hours.set(0, 0); jsJobTrigger.setType("complexJobTrigger"); //$NON-NLS-1$ jsJobTrigger.setDayOfWeekRecurrences(jsDaysOfWeek); jsJobTrigger.setHourRecurrences(hours); jsJobTrigger.setMinuteRecurrences(minutes); jsJobTrigger.setSecondRecurrences(seconds); jsJobTrigger .setNativeStartTime(DateTimeFormat.getFormat(PredefinedFormat.ISO_8601).format(startDateTime)); if (endDate != null) { jsJobTrigger.setNativeEndTime(DateTimeFormat.getFormat(PredefinedFormat.ISO_8601).format(endDate)); } } else if ((scheduleType == ScheduleType.MONTHLY) || ((scheduleType == ScheduleType.YEARLY) && (monthOfYear != null))) { jsJobTrigger.setType("complexJobTrigger"); //$NON-NLS-1$ if (dayOfMonth != null) { JsArrayInteger jsDaysOfMonth = (JsArrayInteger) JavaScriptObject.createArray(); jsDaysOfMonth.set(0, dayOfMonth); JsArrayInteger hours = (JsArrayInteger) JavaScriptObject.createArray(); hours.set(0, startHour); JsArrayInteger minutes = (JsArrayInteger) JavaScriptObject.createArray(); hours.set(0, startMin); JsArrayInteger seconds = (JsArrayInteger) JavaScriptObject.createArray(); hours.set(0, 0); jsJobTrigger.setType("complexJobTrigger"); //$NON-NLS-1$ if (monthOfYear != null) { JsArrayInteger jsMonthsOfYear = (JsArrayInteger) JavaScriptObject.createArray(); jsMonthsOfYear.set(0, monthOfYear.ordinal() + 1); jsJobTrigger.setMonthlyRecurrences(jsMonthsOfYear); } jsJobTrigger.setDayOfMonthRecurrences(jsDaysOfMonth); jsJobTrigger.setHourRecurrences(hours); jsJobTrigger.setMinuteRecurrences(minutes); jsJobTrigger.setSecondRecurrences(seconds); jsJobTrigger.setNativeStartTime( DateTimeFormat.getFormat(PredefinedFormat.ISO_8601).format(startDateTime)); if (endDate != null) { jsJobTrigger .setNativeEndTime(DateTimeFormat.getFormat(PredefinedFormat.ISO_8601).format(endDate)); } } else if ((daysOfWeek.size() > 0) && (weekOfMonth != null)) { JsArrayInteger jsDaysOfWeek = (JsArrayInteger) JavaScriptObject.createArray(); int i = 0; for (DayOfWeek dayOfWeek : daysOfWeek) { jsDaysOfWeek.set(i++, dayOfWeek.ordinal() + 1); } JsArrayInteger hours = (JsArrayInteger) JavaScriptObject.createArray(); hours.set(0, startHour); JsArrayInteger minutes = (JsArrayInteger) JavaScriptObject.createArray(); hours.set(0, startMin); JsArrayInteger seconds = (JsArrayInteger) JavaScriptObject.createArray(); hours.set(0, 0); jsJobTrigger.setType("complexJobTrigger"); //$NON-NLS-1$ if (monthOfYear != null) { JsArrayInteger jsMonthsOfYear = (JsArrayInteger) JavaScriptObject.createArray(); jsMonthsOfYear.set(0, monthOfYear.ordinal() + 1); jsJobTrigger.setMonthlyRecurrences(jsMonthsOfYear); } jsJobTrigger.setHourRecurrences(hours); jsJobTrigger.setMinuteRecurrences(minutes); jsJobTrigger.setSecondRecurrences(seconds); jsJobTrigger.setQualifiedDayOfWeek(daysOfWeek.get(0).name()); jsJobTrigger.setDayOfWeekQualifier(weekOfMonth.name()); jsJobTrigger.setNativeStartTime( DateTimeFormat.getFormat(PredefinedFormat.ISO_8601).format(startDateTime)); if (endDate != null) { jsJobTrigger .setNativeEndTime(DateTimeFormat.getFormat(PredefinedFormat.ISO_8601).format(endDate)); } } } return jsJobTrigger; } protected boolean addBlockoutPeriod(final JSONObject schedule, final JsJobTrigger trigger, String urlSuffix) { String url = ScheduleHelper.getFullyQualifiedURL() + "api/scheduler/blockout/" + urlSuffix; //$NON-NLS-1$ RequestBuilder addBlockoutPeriodRequest = new RequestBuilder(RequestBuilder.POST, url); addBlockoutPeriodRequest.setHeader("accept", "text/plain"); //$NON-NLS-1$ //$NON-NLS-2$ addBlockoutPeriodRequest.setHeader("Content-Type", "application/json"); //$NON-NLS-1$ //$NON-NLS-2$ addBlockoutPeriodRequest.setHeader("If-Modified-Since", "01 Jan 1970 00:00:00 GMT"); // Create a unique blockout period name final Long duration = trigger.getBlockDuration(); final String blockoutPeriodName = trigger.getScheduleType() + Random.nextInt() + ":" + //$NON-NLS-1$ /* PentahoSessionHolder.getSession().getName() */"admin" + ":" + duration; //$NON-NLS-1$ //$NON-NLS-2$ // Add blockout specific parameters JSONObject addBlockoutParams = schedule; addBlockoutParams.put("jobName", new JSONString(blockoutPeriodName)); //$NON-NLS-1$ addBlockoutParams.put("duration", new JSONNumber(duration)); //$NON-NLS-1$ addBlockoutParams.put("timeZone", new JSONString(scheduleEditorWizardPanel.getTimeZone())); try { addBlockoutPeriodRequest.sendRequest(addBlockoutParams.toString(), new RequestCallback() { @Override public void onError(Request request, Throwable exception) { MessageDialogBox dialogBox = new MessageDialogBox(Messages.getString("error"), //$NON-NLS-1$ exception.toString(), false, false, true); dialogBox.center(); setDone(false); } @Override public void onResponseReceived(Request request, Response response) { if (response.getStatusCode() == Response.SC_OK) { if (null != callback) { callback.okPressed(); } } } }); } catch (RequestException e) { // ignored } return true; } private void promptDueToBlockoutConflicts(final boolean alwaysConflict, final boolean conflictsSometimes, final JSONObject schedule, final JsJobTrigger trigger) { StringBuffer conflictMessage = new StringBuffer(); final String updateScheduleButtonText = Messages.getString("blockoutUpdateSchedule"); //$NON-NLS-1$ final String continueButtonText = Messages.getString("blockoutContinueSchedule"); //$NON-NLS-1$ boolean showContinueButton = conflictsSometimes; boolean isScheduleConflict = alwaysConflict || conflictsSometimes; if (conflictsSometimes) { conflictMessage.append(Messages.getString("blockoutPartialConflict")); //$NON-NLS-1$ conflictMessage.append("\n"); //$NON-NLS-1$ conflictMessage.append(Messages.getString("blockoutPartialConflictContinue")); //$NON-NLS-1$ } else { conflictMessage.append(Messages.getString("blockoutTotalConflict")); //$NON-NLS-1$ } if (isScheduleConflict) { final MessageDialogBox dialogBox = new MessageDialogBox(Messages.getString("blockoutTimeExists"), //$NON-NLS-1$ conflictMessage.toString(), false, false, true, updateScheduleButtonText, showContinueButton ? continueButtonText : null, null); dialogBox.setCallback(new IDialogCallback() { // If user clicked on 'Continue' we want to add the schedule. Otherwise we dismiss the dialog // and they have to modify the recurrence schedule @Override public void cancelPressed() { // User clicked on continue, so we need to proceed adding the schedule handleWizardPanels(schedule, trigger); } @Override public void okPressed() { // Update Schedule Button pressed dialogBox.setVisible(false); } }); dialogBox.center(); } } /** * Before creating a new schedule, we want to check to see if the schedule that is being created is going to conflict * with any one of the blockout periods if one is provisioned. * * @param schedule * @param trigger */ protected void verifyBlockoutConflict(final JSONObject schedule, final JsJobTrigger trigger) { String url = ScheduleHelper.getFullyQualifiedURL() + "api/scheduler/blockout/blockstatus"; //$NON-NLS-1$ RequestBuilder blockoutConflictRequest = new RequestBuilder(RequestBuilder.POST, url); blockoutConflictRequest.setHeader("accept", "application/json"); //$NON-NLS-1$ //$NON-NLS-2$ blockoutConflictRequest.setHeader("Content-Type", "application/json"); //$NON-NLS-1$ //$NON-NLS-2$ blockoutConflictRequest.setHeader("If-Modified-Since", "01 Jan 1970 00:00:00 GMT"); final JSONObject verifyBlockoutParams = schedule; verifyBlockoutParams.put("jobName", new JSONString(scheduleName)); //$NON-NLS-1$ try { blockoutConflictRequest.sendRequest(verifyBlockoutParams.toString(), new RequestCallback() { @Override public void onError(Request request, Throwable exception) { MessageDialogBox dialogBox = new MessageDialogBox(Messages.getString("error"), //$NON-NLS-1$ exception.toString(), false, false, true); dialogBox.center(); setDone(false); } @Override public void onResponseReceived(Request request, Response response) { if (response.getStatusCode() == Response.SC_OK) { JsBlockStatus statusResponse = (JsBlockStatus) parseJson( JsonUtils.escapeJsonForEval(response.getText())); // Determine if this schedule conflicts all the time or some of the time boolean partiallyBlocked = Boolean.parseBoolean(statusResponse.getPartiallyBlocked()); boolean totallyBlocked = Boolean.parseBoolean(statusResponse.getTotallyBlocked()); if (partiallyBlocked || totallyBlocked) { promptDueToBlockoutConflicts(totallyBlocked, partiallyBlocked, schedule, trigger); } else { // Continue with other panels in the wizard (params, email) handleWizardPanels(schedule, trigger); } } else { handleWizardPanels(schedule, trigger); } } }); } catch (RequestException e) { // ignored } super.nextClicked(); } private void handleWizardPanels(final JSONObject schedule, final JsJobTrigger trigger) { if (hasParams) { showScheduleParamsDialog(trigger, schedule); } else if (isEmailConfValid) { showScheduleEmailDialog(schedule); } else { // submit JSONObject scheduleRequest = (JSONObject) JSONParser.parseStrict(schedule.toString()); if (editJob != null) { JSONArray scheduleParams = new JSONArray(); for (int i = 0; i < editJob.getJobParams().length(); i++) { JsJobParam param = editJob.getJobParams().get(i); JsArrayString paramValue = (JsArrayString) JavaScriptObject.createArray().cast(); paramValue.push(param.getValue()); JsSchedulingParameter p = (JsSchedulingParameter) JavaScriptObject.createObject().cast(); p.setName(param.getName()); p.setType("string"); //$NON-NLS-1$ p.setStringValue(paramValue); scheduleParams.set(i, new JSONObject(p)); } scheduleRequest.put("jobParameters", scheduleParams); //$NON-NLS-1$ String actionClass = editJob.getJobParamValue("ActionAdapterQuartzJob-ActionClass"); //$NON-NLS-1$ if (!StringUtils.isEmpty(actionClass)) { scheduleRequest.put("actionClass", new JSONString(actionClass)); //$NON-NLS-1$ } } RequestBuilder scheduleFileRequestBuilder = ScheduleHelper.buildRequestForJob(editJob, scheduleRequest); try { scheduleFileRequestBuilder.sendRequest(scheduleRequest.toString(), new RequestCallback() { @Override public void onError(Request request, Throwable exception) { MessageDialogBox dialogBox = new MessageDialogBox(Messages.getString("error"), //$NON-NLS-1$ exception.toString(), false, false, true); dialogBox.center(); setDone(false); } @Override public void onResponseReceived(Request request, Response response) { if (response.getStatusCode() == 200) { setDone(true); ScheduleRecurrenceDialog.this.hide(); if (callback != null) { callback.okPressed(); } } else { MessageDialogBox dialogBox = new MessageDialogBox(Messages.getString("error"), //$NON-NLS-1$ Messages.getString("serverErrorColon") + " " + response.getStatusCode(), false, false, true); dialogBox.center(); setDone(false); } } }); } catch (RequestException e) { MessageDialogBox dialogBox = new MessageDialogBox(Messages.getString("error"), e.toString(), //$NON-NLS-1$ false, false, true); dialogBox.center(); setDone(false); } setDone(true); } } private final native JavaScriptObject parseJson(String json) /*-{ if (null == json || "" == json) { return null; } var obj = JSON.parse(json); return obj; }-*/; /* * (non-Javadoc) * * @see org.pentaho.gwt.widgets.client.wizards.AbstractWizardDialog#finish() */ @Override protected boolean onFinish() { if (!super.enableFinish(getIndex())) { return false; } // DO NOT DELETE - verifyBlockoutConflict(schedule, trigger); JsJobTrigger trigger = getJsJobTrigger(); JSONObject schedule = getSchedule(); handleWizardPanels(schedule, trigger); return true; } private void showScheduleEmailDialog(final JSONObject schedule) { try { final String url = ScheduleHelper.getFullyQualifiedURL() + "api/mantle/isAuthenticated"; //$NON-NLS-1$ RequestBuilder requestBuilder = new RequestBuilder(RequestBuilder.GET, url); requestBuilder.setHeader("accept", "text/plain"); //$NON-NLS-1$ //$NON-NLS-2$ requestBuilder.setHeader("If-Modified-Since", "01 Jan 1970 00:00:00 GMT"); requestBuilder.sendRequest(null, new RequestCallback() { @Override public void onError(Request request, Throwable caught) { MantleLoginDialog.performLogin(new AsyncCallback<Boolean>() { @Override public void onFailure(Throwable caught) { } @Override public void onSuccess(Boolean result) { showScheduleEmailDialog(schedule); } }); } @Override public void onResponseReceived(Request request, Response response) { JSONObject scheduleRequest = (JSONObject) JSONParser.parseStrict(schedule.toString()); if (scheduleEmailDialog == null) { scheduleEmailDialog = new ScheduleEmailDialog(ScheduleRecurrenceDialog.this, filePath, scheduleRequest, null, editJob); scheduleEmailDialog.setCallback(callback); } else { scheduleEmailDialog.setJobSchedule(scheduleRequest); } scheduleEmailDialog.setNewSchedule(newSchedule); scheduleEmailDialog.center(); hide(); } }); } catch (RequestException e) { Window.alert(e.getMessage()); } } private void showScheduleParamsDialog(final JsJobTrigger trigger, final JSONObject schedule) { try { final String url = ScheduleHelper.getFullyQualifiedURL() + "api/mantle/isAuthenticated"; //$NON-NLS-1$ RequestBuilder requestBuilder = new RequestBuilder(RequestBuilder.GET, url); requestBuilder.setHeader("accept", "text/plain"); //$NON-NLS-1$ //$NON-NLS-2$ requestBuilder.setHeader("If-Modified-Since", "01 Jan 1970 00:00:00 GMT"); requestBuilder.sendRequest(null, new RequestCallback() { @Override public void onError(Request request, Throwable caught) { MantleLoginDialog.performLogin(new AsyncCallback<Boolean>() { @Override public void onFailure(Throwable caught) { } @Override public void onSuccess(Boolean result) { showScheduleParamsDialog(trigger, schedule); } }); } @Override public void onResponseReceived(Request request, Response response) { if (scheduleParamsDialog == null) { scheduleParamsDialog = new ScheduleParamsDialog(ScheduleRecurrenceDialog.this, isEmailConfValid, editJob); scheduleParamsDialog.setCallback(callback); } else { scheduleParamsDialog.setJobSchedule(schedule); } scheduleParamsDialog.setNewSchedule(newSchedule); scheduleParamsDialog.center(); hide(); } }); } catch (RequestException e) { Window.alert(e.getMessage()); } } /** * @param startTime * @return */ private int getStartMin(String startTime) { if (startTime == null || startTime.length() < 1) { return 0; } int firstSeparator = startTime.indexOf(':'); int secondSeperator = startTime.indexOf(':', firstSeparator + 1); int min = Integer.parseInt(startTime.substring(firstSeparator + 1, secondSeperator)); return min; } /** * @param startTime * @return */ private int getStartHour(String startTime) { if (startTime == null || startTime.length() < 1) { return 0; } int afternoonOffset = startTime.endsWith(TimeUtil.TimeOfDay.PM.toString()) ? 12 : 0; //$NON-NLS-1$ int hour = Integer.parseInt(startTime.substring(0, startTime.indexOf(':'))); hour += afternoonOffset; return hour; } public Boolean getDone() { return done; } public void setDone(Boolean done) { this.done = done; } /* * (non-Javadoc) * * @see org.pentaho.gwt.widgets.client.wizards.AbstractWizardDialog#onNext(org.pentaho.gwt.widgets.client.wizards. * IWizardPanel, org.pentaho.gwt.widgets.client.wizards.IWizardPanel) */ @Override protected boolean onNext(IWizardPanel nextPanel, IWizardPanel previousPanel) { return super.enableNext(getIndex()); } /* * (non-Javadoc) * * @see org.pentaho.gwt.widgets.client.wizards.AbstractWizardDialog#onPrevious(org.pentaho.gwt.widgets.client.wizards * .IWizardPanel, org.pentaho.gwt.widgets.client.wizards.IWizardPanel) */ @Override protected boolean onPrevious(IWizardPanel previousPanel, IWizardPanel currentPanel) { return true; } @Override protected void backClicked() { hide(); if (parentDialog != null) { parentDialog.center(); } } @Override public void center() { super.center(); Timer t = new Timer() { @Override public void run() { if (scheduleEditorWizardPanel.isAttached() && scheduleEditorWizardPanel.isVisible()) { cancel(); } } }; t.scheduleRepeating(250); } @Override protected boolean enableBack(int index) { return parentDialog != null; } @Override protected boolean showBack(int index) { return parentDialog != null; } @Override protected boolean showFinish(int index) { return true; } @Override protected boolean showNext(int index) { return false; } public void setCallback(IDialogCallback callback) { this.callback = callback; } public IDialogCallback getCallback() { return callback; } public boolean isShowSuccessDialog() { return showSuccessDialog; } public void setShowSuccessDialog(boolean showSuccessDialog) { this.showSuccessDialog = showSuccessDialog; } public void setNewSchedule(boolean newSchedule) { this.newSchedule = newSchedule; } }