ru.codeinside.gses.webui.components.TaskGraph.java Source code

Java tutorial

Introduction

Here is the source code for ru.codeinside.gses.webui.components.TaskGraph.java

Source

/*
 * 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.components;

import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.vaadin.Application;
import com.vaadin.terminal.StreamResource;
import com.vaadin.terminal.StreamResource.StreamSource;
import com.vaadin.ui.Embedded;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.bpmn.diagram.ProcessDiagramGenerator;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.runtime.Execution;
import ru.codeinside.gses.service.F1;
import ru.codeinside.gses.service.Fn;
import ru.codeinside.gses.service.Functions;
import ru.codeinside.gses.webui.Flash;

import java.io.InputStream;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

//TODO:      ,     ????.
final public class TaskGraph extends Embedded {

    final static Joiner ID_JOINER = Joiner.on('/').skipNulls();

    final static Joiner FILE_JOINER = Joiner.on('_').skipNulls();

    final public boolean hasBlocks;

    public TaskGraph(final String processDefinitionId, final String executionId) {
        final List<String> activeActivityIds;
        final String baseName;
        final String appendix;
        if (executionId != null) {
            baseName = executionId;
            activeActivityIds = Fn.withEngine(new ActiveActivityIds(), executionId);
            if (activeActivityIds.isEmpty()) {
                appendix = null;
                hasBlocks = false;
            } else {
                hasBlocks = true;
                appendix = getSHA(ID_JOINER.join(activeActivityIds));
            }
        } else {
            activeActivityIds = Collections.emptyList();
            baseName = processDefinitionId.replace(':', '_');
            appendix = null;
            hasBlocks = false;
        }
        final String filename = FILE_JOINER.join("ex", baseName, appendix) + ".png";

        setMimeType("image/png");
        setSource(new AppCachedStreamSource(
                new GraphStreamSource(new GraphProducer(processDefinitionId, activeActivityIds)), filename,
                Flash.app()));
    }

    final static class AppCachedStreamSource extends StreamResource {

        public AppCachedStreamSource(final StreamSource streamSource, final String filename,
                final Application application) {
            super(streamSource, filename, application);
        }

        @Override
        public int hashCode() {
            return getFilename().hashCode();
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (!(obj instanceof AppCachedStreamSource)) {
                return false;
            }
            return getFilename().equals(((AppCachedStreamSource) obj).getFilename());
        }
    }

    static String getSHA(final String string) {
        try {
            final MessageDigest md = MessageDigest.getInstance("SHA");
            md.update(string.getBytes("UTF8"));
            return new BigInteger(1, md.digest()).toString(16);
        } catch (NoSuchAlgorithmException e) {
            return "" + string.hashCode();
        } catch (UnsupportedEncodingException e) {
            return "" + string.hashCode();
        }
    }

    final static class GraphStreamSource implements StreamSource {

        final private GraphProducer graphProducer;

        public GraphStreamSource(final GraphProducer graphProducer) {
            this.graphProducer = graphProducer;
        }

        public InputStream getStream() {
            return Functions.withRepository(Flash.login(), graphProducer);
        }
    }

    final static class ActiveActivityIds implements F1<List<String>, String> {
        @Override
        public List<String> apply(ProcessEngine engine, final String executionId) {
            //   ??!
            final Execution execution = engine.getRuntimeService().createExecutionQuery().executionId(executionId)
                    .singleResult();
            if (execution == null) {
                return Collections.emptyList();
            }
            List<String> ids = engine.getRuntimeService().getActiveActivityIds(executionId);
            if (!ids.isEmpty()) {
                return ids;
            }
            return Arrays.asList(((ExecutionEntity) execution).getCurrentActivityId());
        }
    }

    final static class GraphProducer implements Function<RepositoryService, InputStream>, Serializable {
        private final String processDefinitionId;
        private final List<String> activeActivityIds;

        public GraphProducer(final String processDefinitionId, final List<String> activeActivityIds) {
            this.processDefinitionId = processDefinitionId;
            this.activeActivityIds = activeActivityIds;
        }

        final public InputStream apply(final RepositoryService repositoryService) {
            final RepositoryServiceImpl impl = (RepositoryServiceImpl) repositoryService;
            final ProcessDefinitionEntity def = (ProcessDefinitionEntity) impl
                    .getDeployedProcessDefinition(processDefinitionId);
            return ProcessDiagramGenerator.generateDiagram(def, "png", activeActivityIds);
        }
    }
}