/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * Copyright (c) 2013, MPL CodeInside http://codeinside.ru */ package ru.codeinside.gses.webui.actions.deployment; import com.google.common.collect.Lists; import com.vaadin.ui.Upload.SucceededEvent; import com.vaadin.ui.Window; import com.vaadin.ui.Window.Notification; import org.activiti.engine.ActivitiException; import org.activiti.engine.ProcessEngine; import org.activiti.engine.delegate.Expression; import org.activiti.engine.impl.RepositoryServiceImpl; import org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior; import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity; import org.activiti.engine.impl.pvm.process.ActivityImpl; import org.activiti.engine.repository.Deployment; import org.activiti.engine.repository.ProcessDefinition; import ru.codeinside.adm.ui.LazyLoadingContainer2; import ru.codeinside.gses.beans.ActivitiBean; import ru.codeinside.gses.manager.ManagerService; import ru.codeinside.gses.manager.SandboxEngine; import ru.codeinside.gses.service.Functions; import ru.codeinside.gses.service.PF; import javax.ejb.EJBException; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.List; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; public class DeploymentSucceededListener implements com.vaadin.ui.Upload.SucceededListener { private static final long serialVersionUID = 8870696618119836644L; private final DeploymentUploadReceiver receiver; private final String procedureId; private final String processDefId; private List<LazyLoadingContainer2> loadingContainers = Lists.newArrayList(); public void addLoadingContainer(LazyLoadingContainer2 loadingContainer) { this.loadingContainers.add(loadingContainer); } public DeploymentSucceededListener(DeploymentUploadReceiver receiver, String procedureId, String processDefId) { this.receiver = receiver; this.procedureId = procedureId; this.processDefId = processDefId; } @Override public void uploadSucceeded(SucceededEvent event) { try { validateDeployment(); } catch (EJBException e) { Throwable th = e.getCause() != null ? e.getCause() : e; String message = th.getMessage() != null ? th.getMessage() : th.getClass().toString(); showMessage(event, "Ошибка в маршруте", message, Notification.TYPE_ERROR_MESSAGE); return; } catch (ActivitiException e) { showMessage(event, "Ошибка в маршруте", e.getMessage(), Notification.TYPE_ERROR_MESSAGE); return; } Deployment deploy = ActivitiBean.get().deploy(receiver.fileName, receiver.getBytes()); String user = event.getUpload().getApplication().getUser().toString(); ProcessDefinition pd = ActivitiBean.get().getProcessDefinitionByDeployment(deploy.getId(), user); ManagerService.get().createProcessDefination(procedureId, pd, user, processDefId); event.getUpload().setData(null); for (LazyLoadingContainer2 loadingContainer : loadingContainers) { loadingContainer.fireItemSetChange(); } showMessage(event, "Новая версия", "Загружен описатель маршрута №" + pd.getDeploymentId() + ", с ключём " + pd.getKey(), Notification.TYPE_HUMANIZED_MESSAGE); } private void validateDeployment() { Boolean isOk = !Functions.withEngine(new PF<Boolean>() { private static final long serialVersionUID = 1L; public Boolean apply(ProcessEngine realEngine) { ProcessEngine sandbox = SandboxEngine.create(); try { ProcessDefinition processDefinition = createProcessDefinition(sandbox); if (processDefinition == null) { throw new ActivitiException("Маршрут не загружен. Проверьте суффикс имени файла"); } RepositoryServiceImpl impl = (RepositoryServiceImpl) sandbox.getRepositoryService(); ProcessDefinitionEntity pdEntity = (ProcessDefinitionEntity) impl.getDeployedProcessDefinition(processDefinition.getId()); for (ActivityImpl ac : pdEntity.getActivities()) { if (ac.getActivityBehavior() instanceof UserTaskActivityBehavior) { UserTaskActivityBehavior utab = (UserTaskActivityBehavior) ac.getActivityBehavior(); Set<Expression> candidateUsers = utab.getTaskDefinition().getCandidateUserIdExpressions(); Set<Expression> candidateGroups = utab.getTaskDefinition().getCandidateGroupIdExpressions(); if (candidateUsers.isEmpty() && candidateGroups.isEmpty()) { throw new ActivitiException("В " + utab.getTaskDefinition().getKey() + " не указаны кандидаты исполнения"); } } } return ManagerService.get().existProcessDefinitionWithKeyOtherProcedure(procedureId, processDefinition.getKey()); } finally { try { sandbox.close(); } catch (Throwable e) { Logger.getAnonymousLogger().log(Level.WARNING, "cleanup", e); } } } private ProcessDefinition createProcessDefinition(ProcessEngine sandbox) { InputStream is = new ByteArrayInputStream(receiver.getBytes()); Deployment tempDeployment = sandbox.getRepositoryService().createDeployment().name(receiver.fileName) .addInputStream(receiver.fileName, is).deploy(); ProcessDefinition tempProcessDefinition = sandbox.getRepositoryService().createProcessDefinitionQuery() .deploymentId(tempDeployment.getId()).singleResult(); return tempProcessDefinition; } }); if (!isOk) { throw new ActivitiException("'Key' маршрута задействован в другой процедуре"); } } private void showMessage(SucceededEvent event, String title, String message, int type) { Window window = currentWindow(event); if (window != null) { window.showNotification(title, message, type); } } private Window currentWindow(SucceededEvent event) { return event.getUpload().getWindow(); } }