ru.runa.wfe.ss.cache.SubstitutionCacheImpl.java Source code

Java tutorial

Introduction

Here is the source code for ru.runa.wfe.ss.cache.SubstitutionCacheImpl.java

Source

/*
 * This file is part of the RUNA WFE project.
 * 
 * This program is free software; you can redistribute it and/or 
 * modify it under the terms of the GNU Lesser General Public License 
 * as published by the Free Software Foundation; version 2.1 
 * of the License. 
 * 
 * This program is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
 * GNU Lesser General Public License for more details. 
 * 
 * You should have received a copy of the GNU Lesser General Public License 
 * along with this program; if not, write to the Free Software 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 */
package ru.runa.wfe.ss.cache;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import ru.runa.wfe.commons.ApplicationContextFactory;
import ru.runa.wfe.commons.cache.BaseCacheImpl;
import ru.runa.wfe.commons.cache.Cache;
import ru.runa.wfe.commons.cache.CacheImplementation;
import ru.runa.wfe.commons.cache.Change;
import ru.runa.wfe.commons.cache.ChangedObjectParameter;
import ru.runa.wfe.execution.logic.SwimlaneInitializerHelper;
import ru.runa.wfe.presentation.BatchPresentationFactory;
import ru.runa.wfe.ss.Substitution;
import ru.runa.wfe.ss.TerminatorSubstitution;
import ru.runa.wfe.ss.dao.SubstitutionDao;
import ru.runa.wfe.user.Actor;
import ru.runa.wfe.user.Executor;
import ru.runa.wfe.user.ExecutorDoesNotExistException;
import ru.runa.wfe.user.Group;
import ru.runa.wfe.user.dao.ExecutorDao;

import com.google.common.collect.Maps;

class SubstitutionCacheImpl extends BaseCacheImpl implements ManageableSubstitutionCache {
    private static final Log log = LogFactory.getLog(SubstitutionCacheImpl.class);
    public static final String substitutorsName = "ru.runa.wfe.ss.cache.substitutors";
    public static final String substitutedName = "ru.runa.wfe.ss.cache.substituted";
    private final Cache<Long, TreeMap<Substitution, HashSet<Long>>> actorToSubstitutorsCache;
    private final Cache<Long, HashSet<Long>> actorToSubstitutedCache;
    private final ExecutorDao executorDao = ApplicationContextFactory.getExecutorDAO();
    private final SubstitutionDao substitutionDao = ApplicationContextFactory.getSubstitutionDAO();

    public SubstitutionCacheImpl() {
        actorToSubstitutorsCache = createCache(substitutorsName, true);
        actorToSubstitutedCache = createCache(substitutedName, true);
        Map<Long, TreeMap<Substitution, HashSet<Long>>> actorToSubstitutors = getMapActorToSubstitutors();
        Map<Long, HashSet<Long>> actorToSubstituted = getMapActorToSubstituted(actorToSubstitutors);
        for (Actor actor : executorDao.getAllActors(BatchPresentationFactory.ACTORS.createNonPaged())) {
            if (actorToSubstituted.get(actor.getId()) == null) {
                actorToSubstituted.put(actor.getId(), new HashSet<Long>());
            }
            if (actorToSubstitutors.get(actor.getId()) == null) {
                actorToSubstitutors.put(actor.getId(), new TreeMap<Substitution, HashSet<Long>>());
            }
        }
        actorToSubstitutorsCache.putAll(actorToSubstitutors);
        actorToSubstitutedCache.putAll(actorToSubstituted);
    }

    @Override
    public TreeMap<Substitution, Set<Long>> getSubstitutors(Actor actor, boolean loadIfRequired) {
        if (actor.isActive()) {
            return new TreeMap<Substitution, Set<Long>>();
        }
        TreeMap<Substitution, HashSet<Long>> result = actorToSubstitutorsCache.get(actor.getId());
        if (result != null) {
            return new TreeMap<Substitution, Set<Long>>(result);
        }
        if (!loadIfRequired) {
            return null;
        }
        Map<Long, TreeMap<Substitution, HashSet<Long>>> actorToSubstitutors = getMapActorToSubstitutors();
        result = actorToSubstitutors.get(actor.getId());
        return result != null ? new TreeMap<Substitution, Set<Long>>(result)
                : new TreeMap<Substitution, Set<Long>>();
    }

    @Override
    public TreeMap<Substitution, Set<Long>> tryToGetSubstitutors(Actor actor) {
        return null;
    }

    @Override
    public HashSet<Long> getSubstituted(Actor actor) {
        HashSet<Long> result = actorToSubstitutedCache.get(actor.getId());
        if (result != null) {
            return result;
        }
        Map<Long, HashSet<Long>> actToSubstituted = getMapActorToSubstituted(actorToSubstitutorsCache);
        result = actToSubstituted.get(actor.getId());
        return result != null ? result : new HashSet<Long>();
    }

    public void onActorStatusChange(Actor actor, Change change) {
        log.debug("onActorStatusChange: " + actor);
        TreeMap<Substitution, HashSet<Long>> substitutions = actorToSubstitutorsCache.get(actor.getId());
        if (substitutions == null) {
            return;
        }
        for (HashSet<Long> substitutors : substitutions.values()) {
            if (substitutors != null) {
                for (Long substitutor : substitutors) {
                    actorToSubstitutedCache.remove(substitutor);
                }
            }
        }
    }

    private Map<Long, TreeMap<Substitution, HashSet<Long>>> getMapActorToSubstitutors() {
        Map<Long, TreeMap<Substitution, HashSet<Long>>> result = Maps.newHashMap();
        try {
            for (Substitution substitution : substitutionDao.getAll()) {
                try {
                    Long actorId;
                    try {
                        actorId = executorDao.getActor(substitution.getActorId()).getId();
                    } catch (ExecutorDoesNotExistException e) {
                        log.error("in " + substitution + ": " + e);
                        continue;
                    }
                    if (!substitution.isEnabled()) {
                        continue;
                    }
                    TreeMap<Substitution, HashSet<Long>> subDescr = result.get(actorId);
                    if (subDescr == null) {
                        subDescr = new TreeMap<Substitution, HashSet<Long>>();
                        result.put(actorId, subDescr);
                    }
                    if (substitution instanceof TerminatorSubstitution) {
                        subDescr.put(substitution, null);
                        continue;
                    }
                    List<? extends Executor> executors = SwimlaneInitializerHelper
                            .evaluate(substitution.getOrgFunction(), null);
                    HashSet<Long> substitutors = new HashSet<Long>();
                    for (Executor sub : executors) {
                        if (sub instanceof Actor) {
                            substitutors.add(sub.getId());
                        } else {
                            for (Actor groupActor : executorDao.getGroupActors((Group) sub)) {
                                substitutors.add(groupActor.getId());
                            }
                        }
                    }
                    subDescr.put(substitution, substitutors);
                } catch (Exception e) {
                    log.error("Error in " + substitution, e);
                }
            }
        } catch (Throwable th) {
            log.error("in substitution", th);
        }
        return result;
    }

    private Map<Long, HashSet<Long>> getMapActorToSubstituted(
            Cache<Long, TreeMap<Substitution, HashSet<Long>>> mapActorToSubstitutors) {
        Map<Long, HashSet<Long>> result = new HashMap<Long, HashSet<Long>>();
        for (Long substituted : mapActorToSubstitutors.keySet()) {
            try {
                Actor substitutedActor = executorDao.getActor(substituted);
                if (substitutedActor.isActive()) {
                    continue;
                }
                for (HashSet<Long> substitutors : mapActorToSubstitutors.get(substituted).values()) {
                    if (substitutors == null) {
                        continue;
                    }
                    for (Long substitutor : substitutors) {
                        HashSet<Long> set = result.get(substitutor);
                        if (set == null) {
                            set = new HashSet<Long>();
                            result.put(substitutor, set);
                        }
                        set.add(substitutedActor.getId());
                    }
                }
            } catch (ExecutorDoesNotExistException e) {
            }
        }
        return result;
    }

    private Map<Long, HashSet<Long>> getMapActorToSubstituted(
            Map<Long, TreeMap<Substitution, HashSet<Long>>> mapActorToSubstitutors) {
        Map<Long, HashSet<Long>> result = new HashMap<Long, HashSet<Long>>();
        for (Map.Entry<Long, TreeMap<Substitution, HashSet<Long>>> entry1 : mapActorToSubstitutors.entrySet()) {
            final Long substitutedId = entry1.getKey();
            try {
                Actor substitutedActor = executorDao.getActor(substitutedId);
                if (substitutedActor.isActive()) {
                    continue;
                }
                for (HashSet<Long> substitutors : entry1.getValue().values()) {
                    if (substitutors == null) {
                        continue;
                    }
                    for (Long substitutor : substitutors) {
                        HashSet<Long> set = result.get(substitutor);
                        if (set == null) {
                            set = new HashSet<>();
                            result.put(substitutor, set);
                        }
                        set.add(substitutedActor.getId());
                    }
                }
            } catch (ExecutorDoesNotExistException e) {
            }
        }
        return result;
    }

    @Override
    public CacheImplementation unlock() {
        return null;
    }

    @Override
    public boolean onChange(ChangedObjectParameter changedObject) {
        return false;
    }
}