/* 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 org.activiti.explorer.ui.management.job; import org.activiti.engine.ActivitiException; import org.activiti.engine.ManagementService; import org.activiti.engine.ProcessEngines; import org.activiti.engine.impl.jobexecutor.TimerActivateProcessDefinitionHandler; import org.activiti.engine.impl.jobexecutor.TimerSuspendProcessDefinitionHandler; import org.activiti.engine.impl.persistence.entity.JobEntity; import org.activiti.engine.impl.persistence.entity.MessageEntity; import org.activiti.engine.impl.persistence.entity.TimerEntity; import org.activiti.engine.runtime.Job; import org.activiti.explorer.ExplorerApp; import org.activiti.explorer.I18nManager; import org.activiti.explorer.Messages; import org.activiti.explorer.NotificationManager; import org.activiti.explorer.ui.Images; import org.activiti.explorer.ui.custom.DetailPanel; import org.activiti.explorer.ui.custom.PrettyTimeLabel; import org.activiti.explorer.ui.mainlayout.ExplorerLayout; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; import com.vaadin.ui.Embedded; import com.vaadin.ui.GridLayout; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.Panel; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.themes.Reindeer; /** * @author Frederik Heremans * @author Joram Barrez */ public class JobDetailPanel extends DetailPanel { private static final long serialVersionUID = 1L; protected ManagementService managementService; protected I18nManager i18nManager; protected NotificationManager notificationManager; protected Job job; protected JobPage jobPage; public JobDetailPanel(String jobId, JobPage jobPage) { this.managementService = ProcessEngines.getDefaultProcessEngine().getManagementService(); this.i18nManager = ExplorerApp.get().getI18nManager(); this.notificationManager = ExplorerApp.get().getNotificationManager(); this.job = managementService.createJobQuery().jobId(jobId).singleResult(); this.jobPage = jobPage; init(); } protected void init() { addHeader(); addJobState(); addActions(); } protected void addActions() { Button deleteButton = new Button(i18nManager.getMessage(Messages.JOB_DELETE)); deleteButton.setIcon(Images.DELETE); deleteButton.addListener(new ClickListener() { private static final long serialVersionUID = 1L; public void buttonClick(ClickEvent event) { managementService.deleteJob(job.getId()); notificationManager.showInformationNotification(Messages.JOB_DELETED); jobPage.refreshSelectNext(); } }); Button executeButton = new Button(i18nManager.getMessage(Messages.JOB_EXECUTE)); executeButton.setIcon(Images.EXECUTE); executeButton.addListener(new ClickListener() { private static final long serialVersionUID = 1L; public void buttonClick(ClickEvent event) { try { managementService.executeJob(job.getId()); jobPage.refreshSelectNext(); } catch (ActivitiException ae) { String errorMessage = ae.getMessage() + (ae.getCause() != null ? " (" + ae.getCause().getClass().getName() + ")" : ""); notificationManager.showErrorNotification(Messages.JOB_ERROR, errorMessage); // Refresh the current job jobPage.refreshCurrentJobDetails(); } } }); jobPage.getToolBar().removeAllButtons(); jobPage.getToolBar().addButton(executeButton); jobPage.getToolBar().addButton(deleteButton); } protected void addHeader() { GridLayout jobDetails = new GridLayout(3, 2); jobDetails.setWidth(100, UNITS_PERCENTAGE); jobDetails.addStyleName(ExplorerLayout.STYLE_TITLE_BLOCK); jobDetails.setSpacing(true); jobDetails.setMargin(false, false, true, false); // Add image Embedded image = new Embedded(null, Images.JOB_50); jobDetails.addComponent(image, 0, 0, 0, 1); // Add job name Label nameLabel = new Label(getJobLabel(job)); nameLabel.addStyleName(Reindeer.LABEL_H2); jobDetails.addComponent(nameLabel, 1, 0, 2, 0); // Add due date PrettyTimeLabel dueDateLabel = new PrettyTimeLabel(i18nManager.getMessage(Messages.JOB_DUEDATE), job.getDuedate(), i18nManager.getMessage(Messages.JOB_NO_DUEDATE), false); dueDateLabel.addStyleName(ExplorerLayout.STYLE_JOB_HEADER_DUE_DATE); jobDetails.addComponent(dueDateLabel, 1, 1); jobDetails.setColumnExpandRatio(1, 1.0f); jobDetails.setColumnExpandRatio(2, 1.0f); addDetailComponent(jobDetails); } protected String getJobLabel(Job theJob) { // Try figuring out the type if(theJob instanceof TimerEntity) { return i18nManager.getMessage(Messages.JOB_TIMER, theJob.getId()); } else if (theJob instanceof MessageEntity) { return i18nManager.getMessage(Messages.JOB_MESSAGE, theJob.getId()); } else { return i18nManager.getMessage(Messages.JOB_DEFAULT_NAME, theJob.getId()); } } protected void addJobState() { Label processDefinitionHeader = new Label(i18nManager.getMessage(Messages.JOB_HEADER_EXECUTION)); processDefinitionHeader.addStyleName(ExplorerLayout.STYLE_H3); processDefinitionHeader.addStyleName(ExplorerLayout.STYLE_DETAIL_BLOCK); processDefinitionHeader.setWidth(100, UNITS_PERCENTAGE); addComponent(processDefinitionHeader); VerticalLayout layout = new VerticalLayout(); layout.setSpacing(true); layout.setSizeFull(); layout.setMargin(true,false, true, false); addDetailComponent(layout); setDetailExpandRatio(layout, 1.0f); // Exceptions if(job.getExceptionMessage() != null) { // Number of retries Label retrieslabel = new Label(getRetriesLabel(job)); layout.addComponent(retrieslabel); // Exception Label exceptionMessageLabel = new Label(i18nManager.getMessage(Messages.JOB_ERROR) + ": " + job.getExceptionMessage()); exceptionMessageLabel.addStyleName(ExplorerLayout.STYLE_JOB_EXCEPTION_MESSAGE); layout.addComponent(exceptionMessageLabel); // Add Exception stacktrace String stack = managementService.getJobExceptionStacktrace(job.getId()); Label stackTraceLabel = new Label(stack); stackTraceLabel.setContentMode(Label.CONTENT_PREFORMATTED); stackTraceLabel.addStyleName(ExplorerLayout.STYLE_JOB_EXCEPTION_TRACE); stackTraceLabel.setSizeFull(); Panel stackPanel = new Panel(); stackPanel.setWidth(100, UNITS_PERCENTAGE); stackPanel.setSizeFull(); stackPanel.setScrollable(true); stackPanel.addComponent(stackTraceLabel); layout.addComponent(stackPanel); layout.setExpandRatio(stackPanel, 1.0f); } else { if (job.getProcessDefinitionId() != null) { // This is a hack .. need to cleanify this in the engine JobEntity jobEntity = (JobEntity) job; if (jobEntity.getJobHandlerType().equals(TimerSuspendProcessDefinitionHandler.TYPE)) { addLinkToProcessDefinition(layout, i18nManager.getMessage(Messages.JOB_SUSPEND_PROCESSDEFINITION), false); } else if (jobEntity.getJobHandlerType().equals(TimerActivateProcessDefinitionHandler.TYPE)) { addLinkToProcessDefinition(layout, i18nManager.getMessage(Messages.JOB_ACTIVATE_PROCESSDEFINITION), true); } else { addNotYetExecutedLabel(layout); } } else { addNotYetExecutedLabel(layout); } } } protected void addLinkToProcessDefinition(final VerticalLayout verticalLayout, final String labelText, final boolean isSuspendedProcessDefinition) { HorizontalLayout layout = new HorizontalLayout(); verticalLayout.addComponent(layout); Label processDefinitionLabel = new Label(labelText); processDefinitionLabel.setSizeUndefined(); layout.addComponent(processDefinitionLabel); layout.addComponent(new Label(" ", Label.CONTENT_XHTML)); Button showProcessDefinitionLink = new Button(job.getProcessDefinitionId()); showProcessDefinitionLink.addStyleName(Reindeer.BUTTON_LINK); showProcessDefinitionLink.addListener(new ClickListener() { private static final long serialVersionUID = 1L; public void buttonClick(ClickEvent event) { if (isSuspendedProcessDefinition) { ExplorerApp.get().getViewManager().showSuspendedProcessDefinitionsPage(job.getProcessDefinitionId()); } else { ExplorerApp.get().getViewManager().showActiveProcessDefinitionsPage(job.getProcessDefinitionId()); } } }); layout.addComponent(showProcessDefinitionLink); } private void addNotYetExecutedLabel(VerticalLayout layout) { Label noException = new Label(i18nManager.getMessage(Messages.JOB_NOT_EXECUTED)); layout.addComponent(noException); layout.setExpandRatio(noException, 1.0f); } protected String getRetriesLabel(Job theJob) { String retriesString; if(theJob.getRetries() <= 0) { retriesString = i18nManager.getMessage(Messages.JOB_NO_RETRIES); } else { retriesString = i18nManager.getMessage(Messages.JOB_RETRIES, theJob.getRetries()); } return retriesString; } }