org.obeonetwork.graal.design.services.actor.ActorUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.obeonetwork.graal.design.services.actor.ActorUtils.java

Source

/*******************************************************************************
 * Copyright (c) 2011 Obeo.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     Obeo - initial API and implementation
 *******************************************************************************/
package org.obeonetwork.graal.design.services.actor;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.emf.ecore.EObject;
import org.obeonetwork.graal.AbstractTask;
import org.obeonetwork.graal.Actor;
import org.obeonetwork.graal.GraalObject;
import org.obeonetwork.graal.System;
import org.obeonetwork.graal.Task;
import org.obeonetwork.graal.TasksGroup;
import org.obeonetwork.graal.UseCase;

import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;

/**
 * Utilities services concerning Actors
 * @author Stephane Thibaudeau <stephane.thibaudeau@obeo.fr>
 *
 */
public class ActorUtils {

    /**
     * Get the list of actors that should be visually connected to a task or group
     * The list depends on inherited actors and already visible tasks on diagram 
     * @param abstractTask The AbstractTask for which we want the actors list
     * @param tasksOnDiagram List of visible tasks on diagram
     * @return List of Actors
     */
    public Collection<Actor> getVisibleLinksToActors(AbstractTask abstractTask, List<Task> tasksOnDiagram) {
        if (abstractTask instanceof Task) {
            return getVisibleLinksToActorsFromTask((Task) abstractTask, tasksOnDiagram);
        } else if (abstractTask instanceof TasksGroup) {
            return ((TasksGroup) abstractTask).getRelatedActors();
        }
        return Collections.emptyList();
    }

    /**
     * Get the list of actors that should be visually connected to a task
     * The list depends on inherited actors and already visible tasks on diagram 
     * @param task The task for which we want the actors list
     * @param tasksOnDiagram List of visible tasks on diagram
     * @return List of Actors
     */
    private Collection<Actor> getVisibleLinksToActorsFromTask(Task task, final List<Task> tasksOnDiagram) {
        if (task.getActors().isEmpty()) {
            // Get using tasks that are displayed on diagram
            List<Task> usingTasksOnDiagram = Lists.newArrayList(task.getUsedBy());
            Iterables.retainAll(usingTasksOnDiagram, tasksOnDiagram);

            // Filter the related actors to keep those not already associated with a displayed using task
            List<Actor> relatedActors = Lists.newArrayList(task.getRelatedActors());
            for (Task usingTask : usingTasksOnDiagram) {
                if (!relatedActors.isEmpty()) {
                    Iterables.removeAll(relatedActors, usingTask.getRelatedActors());
                } else {
                    break;
                }
            }
            // If some of the actors are not linked to displayed tasks
            // we then have to display the whole actors list to prevent from misunderstanding
            if (!relatedActors.isEmpty()) {
                return task.getRelatedActors();
            } else {
                return Collections.emptyList();
            }
        } else {
            return task.getActors();
        }
    }

    /**
     * Returns the visible actors for an object
     * Delegates to the service corresponding to the object's type
     * @param object
     * @return
     */
    public List<Actor> getVisibleActors(GraalObject object) {
        if (object instanceof System) {
            return ((System) object).getRelatedActors();
        } else if (object instanceof TasksGroup) {
            return ((TasksGroup) object).getRelatedActors();
        } else if (object instanceof UseCase) {
            return getVisibleActorsForUseCase((UseCase) object);
        }
        return null;
    }

    /**
     * Returns the visible actors for a use case
     * @param useCase
     * @return
     */
    private List<Actor> getVisibleActorsForUseCase(UseCase useCase) {
        List<Actor> actors = new ArrayList<Actor>();

        for (AbstractTask abstractTask : useCase.getTasks()) {
            if (abstractTask instanceof Task) {
                actors.addAll(((Task) abstractTask).getRelatedActors());
            } else if (abstractTask instanceof TasksGroup) {
                actors.addAll(((TasksGroup) abstractTask).getRelatedActors());
            }
        }
        return actors;
    }

    /**
     * Returns the visible actors for a tasks group
     * @param group
     * @return
     */
    public Set<Actor> getVisibleActors(TasksGroup group) {
        HashMap<Task, Set<Actor>> cache = new HashMap<Task, Set<Actor>>();
        Set<Actor> actors = new LinkedHashSet<Actor>();
        List<Actor> actorsLeft = getAllActorsInContext(group);
        for (AbstractTask abstractTask : group.getTasks()) {
            actors.addAll(internalGetVisibleActors(abstractTask, cache, actorsLeft));
        }
        return actors;
    }

    /**
     * Returns the visible actors for a task
     * @param task
     * @return
     */
    public Set<Actor> getVisibleActors(Task task) {
        HashMap<Task, Set<Actor>> cache = new HashMap<Task, Set<Actor>>();
        Set<Actor> actors = new LinkedHashSet<Actor>();
        List<Actor> actorsLeft = getAllActorsInContext(task);
        actors.addAll(internalGetVisibleActors(task, cache, actorsLeft));
        return actors;
    }

    /**
     * Returns the visible actors for a use case
     * @param useCase
     * @return
     */
    public Set<Actor> getVisibleActors(UseCase useCase) {
        HashMap<Task, Set<Actor>> cache = new HashMap<Task, Set<Actor>>();
        Set<Actor> actors = new LinkedHashSet<Actor>();
        List<Actor> actorsLeft = getAllActorsInContext(useCase);
        for (AbstractTask abstractTask : useCase.getTasks()) {
            actors.addAll(internalGetVisibleActors(abstractTask, cache, actorsLeft));
        }
        return actors;
    }

    /**
     * Returns the visible actors for a system
     * @param system
     * @return
     */
    public Set<Actor> getVisibleActors(System system) {
        HashMap<Task, Set<Actor>> cache = new HashMap<Task, Set<Actor>>();
        Set<Actor> actors = new LinkedHashSet<Actor>();
        List<Actor> actorsLeft = getAllActorsInContext(system);
        for (AbstractTask abstractTask : system.getTasks()) {
            actors.addAll(internalGetVisibleActors(abstractTask, cache, actorsLeft));
        }
        return actors;
    }

    /**
     * Collect the visible actors for a task, using an internal cache
     * @param abstractTask
     * @param cache Map to store already calculated links between Tasks and Actors
     * @param actorsLeft List of actors not yet in the final list (used to improve performance)
     * @return
     */
    private Set<Actor> internalGetVisibleActors(AbstractTask abstractTask, Map<Task, Set<Actor>> cache,
            List<Actor> actorsLeft) {
        if (!actorsLeft.isEmpty()) {
            if (abstractTask instanceof Task) {
                Task task = (Task) abstractTask;

                if (cache.containsKey(task)) {
                    return cache.get(task);
                } else {
                    Set<Actor> actors = new LinkedHashSet<Actor>();
                    cache.put(task, actors);
                    if (task.getActors().isEmpty()) {
                        for (Task usingTask : task.getUsedBy()) {
                            if (!cache.containsKey(usingTask) && !actorsLeft.isEmpty()) {
                                actors.addAll(internalGetVisibleActors(usingTask, cache, actorsLeft));
                            }
                        }
                    } else {
                        actors.addAll(task.getActors());
                        actorsLeft.removeAll(actors);
                    }
                    cache.put(task, actors);
                    return actors;
                }
            } else if (abstractTask instanceof TasksGroup) {
                Set<Actor> actors = new LinkedHashSet<Actor>();
                TasksGroup group = (TasksGroup) abstractTask;
                for (AbstractTask subTask : group.getTasks()) {
                    if (!actorsLeft.isEmpty()) {
                        actors.addAll(internalGetVisibleActors(subTask, cache, actorsLeft));
                    }
                }
                return actors;
            }
        }
        return new LinkedHashSet<Actor>();
    }

    private List<Actor> getAllActorsInContext(EObject object) {
        System system = getParentSystem(object);
        if (system != null) {
            return new ArrayList<Actor>(system.getActors());
        }
        return null;
    }

    private System getParentSystem(EObject object) {
        if (object instanceof System) {
            return (System) object;
        } else if (object.eContainer() != null) {
            return getParentSystem(object.eContainer());
        }
        return null;
    }
}