/* 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.editor.ui; import java.io.ByteArrayInputStream; import java.io.File; import java.util.logging.Level; import java.util.logging.Logger; import org.activiti.bpmn.converter.BpmnXMLConverter; import org.activiti.bpmn.model.BpmnModel; import org.activiti.editor.language.json.converter.BpmnJsonConverter; import org.activiti.engine.ProcessEngines; import org.activiti.engine.RepositoryService; import org.activiti.engine.repository.Deployment; import org.activiti.engine.repository.Model; import org.activiti.explorer.ExplorerApp; import org.activiti.explorer.I18nManager; import org.activiti.explorer.Messages; import org.activiti.explorer.ui.Images; import org.activiti.explorer.ui.custom.DetailPanel; import org.activiti.explorer.ui.form.FormPropertiesForm; import org.activiti.explorer.ui.mainlayout.ExplorerLayout; import org.activiti.explorer.ui.process.listener.EditModelClickListener; import org.activiti.explorer.ui.process.listener.ImportModelClickListener; import org.activiti.explorer.ui.process.listener.NewModelClickListener; import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.node.ObjectNode; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; import com.vaadin.terminal.DownloadStream; import com.vaadin.terminal.FileResource; import com.vaadin.ui.AbstractSelect.Filtering; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.ComponentContainer; import com.vaadin.ui.Embedded; import com.vaadin.ui.GridLayout; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.Select; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.themes.Reindeer; /** * Panel showing model detail. * * @author Tijs Rademakers */ public class EditorProcessDefinitionDetailPanel extends DetailPanel { private static final long serialVersionUID = 1L; protected static final Logger LOGGER = Logger.getLogger(EditorProcessDefinitionDetailPanel.class.getName()); // Members protected Model modelData; protected EditorProcessDefinitionPage processDefinitionPage; // Services protected I18nManager i18nManager; // UI protected VerticalLayout detailPanelLayout; protected HorizontalLayout detailContainer; protected HorizontalLayout actionsContainer; protected Label nameLabel; protected Button newModelButton; protected Button importModelButton; protected Button editModelButton; protected Label actionLabel; protected Select actionSelect; protected FormPropertiesForm processDefinitionStartForm; protected EditorProcessDefinitionInfoComponent definitionInfoComponent; protected RepositoryService repositoryService = ProcessEngines.getDefaultProcessEngine().getRepositoryService(); public EditorProcessDefinitionDetailPanel(String modelId, EditorProcessDefinitionPage processDefinitionPage) { this.i18nManager = ExplorerApp.get().getI18nManager(); this.processDefinitionPage = processDefinitionPage; this.modelData = repositoryService.getModel(modelId); initUi(); } protected void initUi() { setSizeFull(); addStyleName(Reindeer.LAYOUT_WHITE); detailPanelLayout = new VerticalLayout(); detailPanelLayout.setWidth(100, UNITS_PERCENTAGE); detailPanelLayout.setMargin(true); setDetailContainer(detailPanelLayout); // All details about the process definition initHeader(); detailContainer = new HorizontalLayout(); detailContainer.addStyleName(Reindeer.PANEL_LIGHT); detailPanelLayout.addComponent(detailContainer); detailContainer.setSizeFull(); initActions(); initProcessDefinitionInfo(); } protected void initActions() { newModelButton = new Button(i18nManager.getMessage(Messages.PROCESS_NEW)); newModelButton.addListener(new NewModelClickListener()); importModelButton = new Button(i18nManager.getMessage(Messages.PROCESS_IMPORT)); importModelButton.addListener(new ImportModelClickListener()); editModelButton = new Button(i18nManager.getMessage(Messages.PROCESS_EDIT)); editModelButton.addListener(new EditModelClickListener(modelData.getId())); actionLabel = new Label(i18nManager.getMessage(Messages.MODEL_ACTION)); actionLabel.setSizeUndefined(); actionSelect = new Select(); actionSelect.addItem(i18nManager.getMessage(Messages.PROCESS_COPY)); actionSelect.addItem(i18nManager.getMessage(Messages.PROCESS_DELETE)); actionSelect.addItem(i18nManager.getMessage(Messages.PROCESS_DEPLOY)); actionSelect.addItem(i18nManager.getMessage(Messages.PROCESS_EXPORT)); actionSelect.setWidth("100px"); actionSelect.setFilteringMode(Filtering.FILTERINGMODE_OFF); actionSelect.setImmediate(true); actionSelect.addListener(new ValueChangeListener() { private static final long serialVersionUID = 1L; @Override public void valueChange(ValueChangeEvent event) { if (i18nManager.getMessage(Messages.PROCESS_COPY).equals(event.getProperty().getValue())) { ExplorerApp.get().getViewManager().showPopupWindow(new CopyModelPopupWindow(modelData)); } else if (i18nManager.getMessage(Messages.PROCESS_DELETE).equals(event.getProperty().getValue())) { ExplorerApp.get().getViewManager().showPopupWindow(new DeleteModelPopupWindow(modelData)); } else if (i18nManager.getMessage(Messages.PROCESS_DEPLOY).equals(event.getProperty().getValue())) { deployModel(); } else if (i18nManager.getMessage(Messages.PROCESS_EXPORT).equals(event.getProperty().getValue())) { exportModel(); } } }); // Clear toolbar and add 'start' button processDefinitionPage.getToolBar().removeAllButtons(); processDefinitionPage.getToolBar().removeAllAdditionalComponents(); processDefinitionPage.getToolBar().addButton(newModelButton); processDefinitionPage.getToolBar().addButton(importModelButton); processDefinitionPage.getToolBar().addButton(editModelButton); processDefinitionPage.getToolBar().addAdditionalComponent(actionLabel); processDefinitionPage.getToolBar().setComponentAlignment(actionLabel, Alignment.MIDDLE_LEFT); processDefinitionPage.getToolBar().addAdditionalComponent(actionSelect); processDefinitionPage.getToolBar().setComponentAlignment(actionSelect, Alignment.MIDDLE_RIGHT); } public void initProcessDefinitionInfo() { if(definitionInfoComponent == null) { definitionInfoComponent = new EditorProcessDefinitionInfoComponent(modelData); } detailContainer.removeAllComponents(); detailContainer.addComponent(definitionInfoComponent); } protected void initHeader() { GridLayout details = new GridLayout(2, 2); details.setWidth(100, UNITS_PERCENTAGE); details.addStyleName(ExplorerLayout.STYLE_TITLE_BLOCK); details.setSpacing(true); details.setMargin(false, false, true, false); details.setColumnExpandRatio(1, 1.0f); detailPanelLayout.addComponent(details); // Image Embedded image = new Embedded(null, Images.PROCESS_50); details.addComponent(image, 0, 0, 0, 1); // Name Label nameLabel = new Label(modelData.getName()); nameLabel.addStyleName(Reindeer.LABEL_H2); details.addComponent(nameLabel, 1, 0); // Properties HorizontalLayout propertiesLayout = new HorizontalLayout(); propertiesLayout.setSpacing(true); details.addComponent(propertiesLayout); // Version String versionString = i18nManager.getMessage(Messages.PROCESS_VERSION, modelData.getVersion()); Label versionLabel = new Label(versionString); versionLabel.addStyleName(ExplorerLayout.STYLE_PROCESS_HEADER_VERSION); propertiesLayout.addComponent(versionLabel); } protected void addEmptySpace(ComponentContainer container) { Label emptySpace = new Label(" ", Label.CONTENT_XHTML); emptySpace.setSizeUndefined(); container.addComponent(emptySpace); } protected void exportModel() { final FileResource stream = new FileResource(new File(""), ExplorerApp.get()) { private static final long serialVersionUID = 1L; @Override public DownloadStream getStream() { DownloadStream ds = null; try { BpmnJsonConverter jsonConverter = new BpmnJsonConverter(); JsonNode editorNode = new ObjectMapper().readTree(repositoryService.getModelEditorSource(modelData.getId())); BpmnModel bpmnModel = jsonConverter.convertToBpmnModel(editorNode); BpmnXMLConverter xmlConverter = new BpmnXMLConverter(); byte[] bpmnBytes = xmlConverter.convertToXML(bpmnModel); ByteArrayInputStream in = new ByteArrayInputStream(bpmnBytes); String filename = bpmnModel.getMainProcess().getId() + ".bpmn20.xml"; ds = new DownloadStream(in, "application/xml", filename); // Need a file download POPUP ds.setParameter("Content-Disposition", "attachment; filename=" + filename); } catch(Exception e) { LOGGER.log(Level.SEVERE, "failed to export model to BPMN XML", e); ExplorerApp.get().getNotificationManager().showErrorNotification(Messages.PROCESS_TOXML_FAILED, e); } return ds; } }; stream.setCacheTime(0); ExplorerApp.get().getMainWindow().open(stream); } protected void deployModel() { try { ObjectNode modelNode = (ObjectNode) new ObjectMapper().readTree(repositoryService.getModelEditorSource(modelData.getId())); BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode); byte[] bpmnBytes = new BpmnXMLConverter().convertToXML(model); Deployment deployment = repositoryService.createDeployment().name(modelData.getName()) .addString(modelData.getName() + ".bpmn20.xml", new String(bpmnBytes)).deploy(); ExplorerApp.get().getViewManager().showDeploymentPage(deployment.getId()); } catch(Exception e) { ExplorerApp.get().getNotificationManager().showErrorNotification(Messages.PROCESS_TOXML_FAILED, e); } } }