com.evolveum.midpoint.web.page.admin.server.TaskSchedulingTabPanel.java Source code

Java tutorial

Introduction

Here is the source code for com.evolveum.midpoint.web.page.admin.server.TaskSchedulingTabPanel.java

Source

/*
 * Copyright (c) 2010-2016 Evolveum
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.evolveum.midpoint.web.page.admin.server;

import com.evolveum.midpoint.gui.api.model.LoadableModel;
import com.evolveum.midpoint.gui.api.util.WebComponentUtil;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.web.component.DateInput;
import com.evolveum.midpoint.web.component.form.Form;
import com.evolveum.midpoint.web.component.objectdetails.AbstractObjectTabPanel;
import com.evolveum.midpoint.web.component.prism.ObjectWrapper;
import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour;
import com.evolveum.midpoint.web.page.admin.configuration.component.EmptyOnBlurAjaxFormUpdatingBehaviour;
import com.evolveum.midpoint.web.page.admin.server.dto.ScheduleValidator;
import com.evolveum.midpoint.web.page.admin.server.dto.StartEndDateValidator;
import com.evolveum.midpoint.web.page.admin.server.dto.TaskDto;
import com.evolveum.midpoint.web.util.InfoTooltipBehavior;
import com.evolveum.midpoint.xml.ns._public.common.common_3.MisfireActionType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ThreadStopActionType;
import org.apache.commons.lang.time.DurationFormatUtils;
import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.EnumChoiceRenderer;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.form.validation.IFormValidator;
import org.apache.wicket.model.AbstractReadOnlyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;

import java.util.Collection;
import java.util.Collections;
import java.util.Date;

/**
 * @author semancik
 * @author lazyman
 * @author mserbak
 * @author mederly
 */
public class TaskSchedulingTabPanel extends AbstractObjectTabPanel<TaskType> implements TaskTabPanel {
    private static final long serialVersionUID = 1L;

    private static final Trace LOGGER = TraceManager.getTrace(TaskSchedulingTabPanel.class);

    public static final String ID_LAST_STARTED_CONTAINER = "lastStartedContainer";
    public static final String ID_LAST_STARTED = "lastStarted";
    public static final String ID_LAST_STARTED_AGO = "lastStartedAgo";
    public static final String ID_LAST_FINISHED_CONTAINER = "lastFinishedContainer";
    public static final String ID_LAST_FINISHED = "lastFinished";
    public static final String ID_LAST_FINISHED_AGO = "lastFinishedAgo";
    public static final String ID_NEXT_RUN_CONTAINER = "nextRunContainer";
    public static final String ID_NEXT_RUN = "nextRun";
    public static final String ID_NEXT_RUN_IN = "nextRunIn";

    public static final String ID_SCHEDULING_TABLE = "schedulingTable";
    public static final String ID_RECURRING_CONTAINER = "recurringContainer";
    public static final String ID_RECURRING_CHECK = "recurringCheck";
    public static final String ID_SUSPEND_REQ_RECURRING = "suspendReqRecurring";
    //public static final String ID_RECURRENT_TASKS_CONTAINER = "recurrentTasksContainer";
    public static final String ID_BOUND_CONTAINER = "boundContainer";
    public static final String ID_BOUND_HELP = "boundHelp";
    public static final String ID_BOUND_CHECK = "boundCheck";
    public static final String ID_SUSPEND_REQ_BOUND = "suspendReqBound";
    public static final String ID_INTERVAL_CONTAINER = "intervalContainer";
    public static final String ID_CRON_CONTAINER = "cronContainer";
    public static final String ID_INTERVAL = "interval";
    public static final String ID_CRON = "cron";
    public static final String ID_CRON_HELP = "cronHelp";
    public static final String ID_NOT_START_BEFORE_CONTAINER = "notStartBeforeContainer";
    public static final String ID_NOT_START_BEFORE_FIELD = "notStartBeforeField";
    public static final String ID_NOT_START_AFTER_CONTAINER = "notStartAfterContainer";
    public static final String ID_NOT_START_AFTER_FIELD = "notStartAfterField";
    public static final String ID_MISFIRE_ACTION_CONTAINER = "misfireActionContainer";
    public static final String ID_MISFIRE_ACTION = "misfireAction";
    public static final String ID_THREAD_STOP_CONTAINER = "threadStopContainer";
    public static final String ID_THREAD_STOP = "threadStop";

    private PageTaskEdit parentPage;
    private IModel<TaskDto> taskDtoModel;

    public TaskSchedulingTabPanel(String id, Form mainForm, LoadableModel<ObjectWrapper<TaskType>> taskWrapperModel,
            IModel<TaskDto> taskDtoModel, PageTaskEdit parentPage) {
        super(id, mainForm, taskWrapperModel, parentPage);
        this.taskDtoModel = taskDtoModel;
        this.parentPage = parentPage;
        initLayoutForInfoPanel();
        initLayoutForSchedulingTable();
        setOutputMarkupId(true);
    }

    private void initLayoutForInfoPanel() {

        // last start
        WebMarkupContainer lastStartedContainer = new WebMarkupContainer(ID_LAST_STARTED_CONTAINER);
        Label lastStart = new Label(ID_LAST_STARTED, new AbstractReadOnlyModel<String>() {
            @Override
            public String getObject() {
                TaskDto dto = taskDtoModel.getObject();
                if (dto.getLastRunStartTimestampLong() == null) {
                    return "-";
                } else {
                    return WebComponentUtil.formatDate(new Date(dto.getLastRunStartTimestampLong()));
                }
            }
        });
        lastStartedContainer.add(lastStart);

        Label lastStartAgo = new Label(ID_LAST_STARTED_AGO, new AbstractReadOnlyModel<String>() {
            @Override
            public String getObject() {
                TaskDto dto = taskDtoModel.getObject();
                if (dto.getLastRunStartTimestampLong() == null) {
                    return "";
                } else {
                    final long ago = System.currentTimeMillis() - dto.getLastRunStartTimestampLong();
                    return createStringResource("TaskStatePanel.message.ago",
                            DurationFormatUtils.formatDurationWords(ago, true, true)).getString();
                }
            }
        });
        lastStartedContainer.add(lastStartAgo);
        lastStartedContainer.add(parentPage.createVisibleIfAccessible(TaskType.F_LAST_RUN_START_TIMESTAMP));
        add(lastStartedContainer);

        // last finish
        WebMarkupContainer lastFinishedContainer = new WebMarkupContainer(ID_LAST_FINISHED_CONTAINER);
        Label lastFinished = new Label(ID_LAST_FINISHED, new AbstractReadOnlyModel<String>() {
            @Override
            public String getObject() {
                TaskDto dto = taskDtoModel.getObject();
                if (dto.getLastRunFinishTimestampLong() == null) {
                    return "-";
                } else {
                    return WebComponentUtil.formatDate(new Date(dto.getLastRunFinishTimestampLong()));
                }
            }
        });
        lastFinishedContainer.add(lastFinished);

        Label lastFinishedAgo = new Label(ID_LAST_FINISHED_AGO, new AbstractReadOnlyModel<String>() {
            @Override
            public String getObject() {
                TaskDto dto = taskDtoModel.getObject();
                if (dto.getLastRunFinishTimestampLong() == null) {
                    return "";
                } else {
                    Long duration;
                    if (dto.getLastRunStartTimestampLong() == null
                            || dto.getLastRunFinishTimestampLong() < dto.getLastRunStartTimestampLong()) {
                        duration = null;
                    } else {
                        duration = dto.getLastRunFinishTimestampLong() - dto.getLastRunStartTimestampLong();
                    }
                    long ago = System.currentTimeMillis() - dto.getLastRunFinishTimestampLong();
                    if (duration != null) {
                        return getString("TaskStatePanel.message.durationAndAgo",
                                DurationFormatUtils.formatDurationWords(ago, true, true), duration);
                    } else {
                        return getString("TaskStatePanel.message.ago",
                                DurationFormatUtils.formatDurationWords(ago, true, true));
                    }
                }
            }
        });
        lastFinishedContainer.add(lastFinishedAgo);
        lastFinishedContainer.add(parentPage.createVisibleIfAccessible(TaskType.F_LAST_RUN_FINISH_TIMESTAMP));
        add(lastFinishedContainer);

        WebMarkupContainer nextRunContainer = new WebMarkupContainer(ID_NEXT_RUN_CONTAINER);
        Label nextRun = new Label(ID_NEXT_RUN, new AbstractReadOnlyModel<String>() {
            @Override
            public String getObject() {
                TaskDto dto = taskDtoModel.getObject();
                if (dto.isRecurring() && dto.isBound() && dto.isRunning()) {
                    return getString("pageTasks.runsContinually");
                } else if (dto.getNextRunStartTimeLong() == null) {
                    return "-";
                } else {
                    return WebComponentUtil.formatDate(new Date(dto.getNextRunStartTimeLong()));
                }
            }
        });
        nextRunContainer.add(nextRun);

        Label nextRunIn = new Label(ID_NEXT_RUN_IN, new AbstractReadOnlyModel<String>() {
            @Override
            public String getObject() {
                TaskDto dto = taskDtoModel.getObject();
                if (dto.getNextRunStartTimeLong() == null
                        || (dto.isRecurring() && dto.isBound() && dto.isRunning())) {
                    return "";
                } else {
                    long currentTime = System.currentTimeMillis();
                    final long in = dto.getNextRunStartTimeLong() - currentTime;
                    if (in >= 0) {
                        return getString("TaskStatePanel.message.in",
                                DurationFormatUtils.formatDurationWords(in, true, true));
                    } else {
                        return "";
                    }
                }
            }
        });
        nextRunContainer.add(nextRunIn);
        nextRunContainer.add(parentPage.createVisibleIfAccessible(TaskType.F_NEXT_RUN_START_TIMESTAMP));
        add(nextRunContainer);
    }

    private void initLayoutForSchedulingTable() {

        // models
        final IModel<Boolean> recurringCheckModel = new PropertyModel<>(taskDtoModel, TaskDto.F_RECURRING);
        final IModel<Boolean> boundCheckModel = new PropertyModel<Boolean>(taskDtoModel, TaskDto.F_BOUND);

        // behaviors
        final VisibleEnableBehaviour visibleIfEditAndRunnableOrRunning = new VisibleEnableBehaviour() {
            @Override
            public boolean isVisible() {
                return parentPage.isEdit() && parentPage.getTaskDto().isRunnableOrRunning();
            }
        };
        final VisibleEnableBehaviour visibleIfRecurringAndScheduleIsAccessible = new VisibleEnableBehaviour() {
            @Override
            public boolean isVisible() {
                return recurringCheckModel.getObject() && parentPage.isReadable(new ItemPath(TaskType.F_SCHEDULE));
            }
        };
        final VisibleEnableBehaviour visibleIfRecurringAndLooselyBoundAndScheduleIsAccessible = new VisibleEnableBehaviour() {
            @Override
            public boolean isVisible() {
                return recurringCheckModel.getObject() && !boundCheckModel.getObject()
                        && parentPage.isReadable(new ItemPath(TaskType.F_SCHEDULE));
            }
        };
        final VisibleEnableBehaviour enabledIfEditAndNotRunningRunnableOrLooselyBoundAndScheduleIsEditable = new VisibleEnableBehaviour() {
            @Override
            public boolean isEnabled() {
                return parentPage.isEdit()
                        && (!parentPage.getTaskDto().isRunnableOrRunning() || !boundCheckModel.getObject())
                        && parentPage.isEditable(new ItemPath(TaskType.F_SCHEDULE));
            }
        };
        final VisibleEnableBehaviour enabledIfEditAndNotRunningAndScheduleIsEditable = new VisibleEnableBehaviour() {
            @Override
            public boolean isEnabled() {
                return parentPage.isEdit() && !parentPage.getTaskDto().isRunning()
                        && parentPage.isEditable(new ItemPath(TaskType.F_SCHEDULE));
            }
        };
        final VisibleEnableBehaviour enabledIfEditAndScheduleIsEditable = new VisibleEnableBehaviour() {
            @Override
            public boolean isEnabled() {
                return parentPage.isEdit() && parentPage.isEditable(new ItemPath(TaskType.F_SCHEDULE));
            }
        };
        final VisibleEnableBehaviour enabledIfEditAndThreadStopIsEditable = new VisibleEnableBehaviour() {
            @Override
            public boolean isEnabled() {
                return parentPage.isEdit() && parentPage.isEditable(new ItemPath(TaskType.F_THREAD_STOP_ACTION));
            }
        };

        // components
        final WebMarkupContainer schedulingTable = new WebMarkupContainer(ID_SCHEDULING_TABLE);
        schedulingTable.setOutputMarkupId(true);
        add(schedulingTable);

        WebMarkupContainer recurringContainer = new WebMarkupContainer(ID_RECURRING_CONTAINER);
        AjaxCheckBox recurringCheck = new AjaxCheckBox(ID_RECURRING_CHECK, recurringCheckModel) {
            @Override
            protected void onUpdate(AjaxRequestTarget target) {
                target.add(schedulingTable);
            }
        };
        recurringCheck.setOutputMarkupId(true);
        recurringCheck.add(new VisibleEnableBehaviour() {
            @Override
            public boolean isEnabled() {
                return parentPage.isEdit() && !parentPage.getTaskDto().isRunnableOrRunning()
                        && parentPage.isEditable(TaskType.F_RECURRENCE);
            }
        });
        recurringContainer.add(recurringCheck);

        WebMarkupContainer suspendReqRecurring = new WebMarkupContainer(ID_SUSPEND_REQ_RECURRING);
        suspendReqRecurring.add(visibleIfEditAndRunnableOrRunning);
        recurringContainer.add(suspendReqRecurring);
        recurringContainer.add(parentPage.createVisibleIfAccessible(TaskType.F_RECURRENCE));
        schedulingTable.add(recurringContainer);

        final WebMarkupContainer boundContainer = new WebMarkupContainer(ID_BOUND_CONTAINER);
        boundContainer.setOutputMarkupId(true);

        final AjaxCheckBox bound = new AjaxCheckBox(ID_BOUND_CHECK, boundCheckModel) {
            @Override
            protected void onUpdate(AjaxRequestTarget target) {
                target.add(schedulingTable);
            }
        };
        bound.add(new VisibleEnableBehaviour() {
            @Override
            public boolean isEnabled() {
                return parentPage.isEdit() && !parentPage.getTaskDto().isRunnableOrRunning()
                        && parentPage.isEditable(TaskType.F_BINDING);
            }
        });
        boundContainer.add(bound);

        WebMarkupContainer suspendReqBound = new WebMarkupContainer(ID_SUSPEND_REQ_BOUND);
        suspendReqBound.add(visibleIfEditAndRunnableOrRunning);
        boundContainer.add(suspendReqBound);
        boundContainer.add(new VisibleEnableBehaviour() {
            @Override
            public boolean isVisible() {
                return recurringCheckModel.getObject() && parentPage.isReadable(new ItemPath(TaskType.F_BINDING));
            }
        });
        Label boundHelp = new Label(ID_BOUND_HELP);
        boundHelp.add(new InfoTooltipBehavior());
        boundContainer.add(boundHelp);
        schedulingTable.add(boundContainer);

        WebMarkupContainer intervalContainer = new WebMarkupContainer(ID_INTERVAL_CONTAINER);
        intervalContainer.add(visibleIfRecurringAndScheduleIsAccessible);
        intervalContainer.setOutputMarkupId(true);
        schedulingTable.add(intervalContainer);

        TextField<Integer> interval = new TextField<>(ID_INTERVAL,
                new PropertyModel<Integer>(taskDtoModel, TaskDto.F_INTERVAL));
        interval.add(new EmptyOnBlurAjaxFormUpdatingBehaviour());
        interval.add(enabledIfEditAndNotRunningRunnableOrLooselyBoundAndScheduleIsEditable);
        intervalContainer.add(interval);

        WebMarkupContainer cronContainer = new WebMarkupContainer(ID_CRON_CONTAINER);
        cronContainer.add(visibleIfRecurringAndLooselyBoundAndScheduleIsAccessible);
        cronContainer.setOutputMarkupId(true);
        schedulingTable.add(cronContainer);

        TextField<String> cron = new TextField<>(ID_CRON,
                new PropertyModel<String>(taskDtoModel, TaskDto.F_CRON_SPECIFICATION));
        cron.add(new EmptyOnBlurAjaxFormUpdatingBehaviour());
        cron.add(enabledIfEditAndNotRunningRunnableOrLooselyBoundAndScheduleIsEditable);
        cronContainer.add(cron);

        Label cronHelp = new Label(ID_CRON_HELP);
        cronHelp.add(new InfoTooltipBehavior());
        cronContainer.add(cronHelp);

        WebMarkupContainer notStartBeforeContainer = new WebMarkupContainer(ID_NOT_START_BEFORE_CONTAINER);
        DateInput notStartBefore = new DateInput(ID_NOT_START_BEFORE_FIELD,
                new PropertyModel<Date>(taskDtoModel, TaskDto.F_NOT_START_BEFORE));
        notStartBefore.setOutputMarkupId(true);
        notStartBefore.add(enabledIfEditAndNotRunningAndScheduleIsEditable);
        notStartBeforeContainer.add(notStartBefore);
        notStartBeforeContainer.add(parentPage.createVisibleIfAccessible(TaskType.F_SCHEDULE));
        schedulingTable.add(notStartBeforeContainer);

        WebMarkupContainer notStartAfterContainer = new WebMarkupContainer(ID_NOT_START_AFTER_CONTAINER);
        DateInput notStartAfter = new DateInput(ID_NOT_START_AFTER_FIELD,
                new PropertyModel<Date>(taskDtoModel, TaskDto.F_NOT_START_AFTER));
        notStartAfter.setOutputMarkupId(true);
        notStartAfter.add(enabledIfEditAndNotRunningAndScheduleIsEditable);
        notStartAfterContainer.add(notStartAfter);
        notStartAfterContainer.add(parentPage.createVisibleIfAccessible(TaskType.F_SCHEDULE));
        schedulingTable.add(notStartAfterContainer);

        WebMarkupContainer misfireActionContainer = new WebMarkupContainer(ID_MISFIRE_ACTION_CONTAINER);
        DropDownChoice misfire = new DropDownChoice(ID_MISFIRE_ACTION,
                new PropertyModel<MisfireActionType>(taskDtoModel, TaskDto.F_MISFIRE_ACTION),
                WebComponentUtil.createReadonlyModelFromEnum(MisfireActionType.class),
                new EnumChoiceRenderer<MisfireActionType>(parentPage));
        misfire.add(enabledIfEditAndScheduleIsEditable);
        misfireActionContainer.add(misfire);
        misfireActionContainer.add(parentPage.createVisibleIfAccessible(TaskType.F_SCHEDULE));
        schedulingTable.add(misfireActionContainer);

        WebMarkupContainer threadStopContainer = new WebMarkupContainer(ID_THREAD_STOP_CONTAINER);
        DropDownChoice threadStop = new DropDownChoice<>(ID_THREAD_STOP, new Model<ThreadStopActionType>() {

            @Override
            public ThreadStopActionType getObject() {
                return taskDtoModel.getObject().getThreadStopActionType();
            }

            @Override
            public void setObject(ThreadStopActionType object) {
                taskDtoModel.getObject().setThreadStopActionType(object);
            }
        }, WebComponentUtil.createReadonlyModelFromEnum(ThreadStopActionType.class),
                new EnumChoiceRenderer<ThreadStopActionType>(parentPage));
        threadStop.add(enabledIfEditAndThreadStopIsEditable);
        threadStopContainer.add(threadStop);
        threadStopContainer.add(parentPage.createVisibleIfAccessible(TaskType.F_THREAD_STOP_ACTION));
        schedulingTable.add(threadStopContainer);

        org.apache.wicket.markup.html.form.Form<?> form = parentPage.getForm();
        // if not removed, the validators will accumulate on the form
        // TODO implement more intelligently when other tabs have validators as well
        for (IFormValidator validator : form.getFormValidators()) {
            form.remove(validator);
        }
        form.add(new StartEndDateValidator(notStartBefore, notStartAfter));
        form.add(new ScheduleValidator(parentPage.getTaskManager(), recurringCheck, bound, interval, cron));
    }

    @Override
    public Collection<Component> getComponentsToUpdate() {
        return Collections.<Component>singleton(this);
    }

}