topology.ActorTopology.java Source code

Java tutorial

Introduction

Here is the source code for topology.ActorTopology.java

Source

/*
 * Copyright (c) 2011-2015, fortiss GmbH.
 * Licensed under the Apache License, Version 2.0.
 *
 * Use, modification and distribution are subject to the terms specified
 * in the accompanying license file LICENSE.txt located at the root directory
 * of this software distribution.
 */

package topology;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import akka.basicActors.ActorOptions;

/**
 *
 * Internal representation of the ActorTopology used in the Simulation. <br>
 * Can be (de-)serialized with the Helper Class: {@link helper.GridTopologyJson}
 * 
 * @author Alex Mack
 * @author Denis Bytschkow
 *
 */
public class ActorTopology {

    public String simulationName;
    private Map<String, ActorOptions> actorTopology = new HashMap<String, ActorOptions>();

    public ActorTopology(String simulationName) {
        this.simulationName = simulationName;
    }

    @Override
    public String toString() {
        return actorTopology.toString();
    }

    /**
     *  This Class adds the Actor to the topology
     *  <br>
     *  Example: addActor("/user/ActorSupervisor/Solar1", new SolarPanelActor()");
     *  <br>
     *  Example2: addActor("Solar1", new SolarPanelActor()"); --> in this case the 
     *  "/user/ActorSupervisor/" will be added automatically by convention
     *  
     *  @param actorPath - contains the path of the Actor in the topology
     *  @param builder - contains the specification of the actor (BasicActor)
     *  
     */

    public void addActor(String actorPath, ActorOptions builder) {

        //System.out.println(actorPath);

        if (actorPath.contains("ActorSupervisor")) {
            if (this.actorTopology.containsKey(actorPath)) {
                System.out.println("actorPath [" + actorPath + "] already exists. --> Exception");
                throw new IllegalArgumentException("actorPath [" + actorPath + "] already exists.");
            }
            actorTopology.put(actorPath, builder);
        } else {
            actorPath = "/user/ActorSupervisor/" + actorPath;
            if (this.actorTopology.containsKey(actorPath)) {
                System.out.println("actorPath [" + actorPath + "] already exists. --> Exception");
                throw new IllegalArgumentException("actorPath [" + actorPath + "] already exists.");
            }
            actorTopology.put(actorPath, builder);
        }
    }

    public void addActorAsChild(String actorPath, ActorOptions actor) {
        String actorName = this.getActorName(actorPath);
        String parentPath = "";

        if (actorPath.contains("/user/ActorSupervisor/")) {
            parentPath = actorPath.substring(0, actorPath.length() - actorName.length() - 1);
        } else {
            parentPath = "/user/ActorSupervisor/"
                    + actorPath.substring(0, actorPath.length() - actorName.length() - 1);
        }

        ActorTopology top = new ActorTopology("");
        top.addActor(actorName, actor);

        //System.out.println(top);
        //System.out.println(parentPath);
        //System.out.println(actorName);

        this.addSubTopology(parentPath, top);
    }

    public void removeActor(String actorPath) {

        if (actorPath.contains("/user/ActorSupervisor/"))
            actorTopology.remove(actorPath);
        else {
            actorPath = "/user/ActorSupervisor/" + actorPath;
        }

        actorTopology.remove(actorPath);
        String parentPath = actorPath.substring(0, actorPath.lastIndexOf("/"));
        String childName = actorPath.substring(actorPath.lastIndexOf("/") + 1, actorPath.length());
        actorTopology.get(parentPath).childrenNameList.remove(childName);

    }

    /**
     * @return HashMap of the Grid. Every <b>unique</b> Actor has its own {@link ActorOptions} Object.
     *  <br></br>
     *  Layout:
     *  <table>
     *      <tr>
     *          <th>ActorPath</th>
     *          <th>{@link ActorOptions}</th>
     *      </tr>
     *      <tr>
     *          <td>"/user/ActorSupervisor/SomeActor"</td>
     *          <td>{@link ActorOptions}</td>
     *      </tr>
     *  </table>
     */
    public Map<String, ActorOptions> getActorTopology() {
        return actorTopology;
    }

    public ActorOptions getActorOptions(String actorPath) {
        if (!actorPath.contains("ActorSupervisor")) {
            actorPath = "/user/ActorSupervisor/" + actorPath;
        }
        if (!actorTopology.containsKey(actorPath))
            throw new NullPointerException(String.format("Actor [%s] does not exist in GridTopology.", actorPath));
        return actorTopology.get(actorPath);
    }

    /**
     * Adds <b>topologyToAdd</b> as Children to the Actor specified by <b>parentPath</b>.
     * <br><br>
     * Example:  <br>
     * <b>{Grid_1}</b> has 2 Actors: <b>/user/ActorSupervisor/Actor_1</b> and <b>/user/ActorSupervisor/Actor_2</b>.   <br>
     * <b>{Grid_2}</b> has 1 Actor: <b>/user/ActorSupervisor/OtherActor</b>                                  <br>
     * <b>{Grid_1}.addSubGrid("/user/ActorSupervisor/Actor_2", {Grid_2})</b> will add <b>/user/ActorSupervisor/OtherActor</b>.<br>
     * <b>{Grid_1}</b> has then 3 Actors:    <br>
     *  - <b>/user/ActorSupervisor/Actor_1</b>
     *  - <b>/user/ActorSupervisor/Actor_2</b>
     *  - <b>/user/ActorSupervisor/Actor_2/OtherActor</b>
     *
     * @param parentPath Unique path of the Actor (in {@link #actorTopology}) that serves as the Anchor of <b>topologyToAdd</b>.
     * @param topInput SubGrid to be added.
     *
     * @throws NullPointerException if <b>parentPath</b> does not exist in {@link #actorTopology}
     * @throws IllegalArgumentException if the Actor specified by <b>parentPath</b> has a Child of the same Name as the Root Actors of <b>topologyToAdd</b>
     */
    public void addSubTopology(String parentPath, ActorTopology topInput) {

        //System.out.println(topInput);
        //System.out.println(parentPath);        
        List<String> rootActorNames = this.getRootActorNames(topInput);

        for (String actorPath : topInput.actorTopology.keySet()) {
            //System.out.println("TOP vorher: " + topInput);
            String newPath = this.replaceActorPathForSubGridAddition(parentPath, actorPath);
            //System.out.println("newPath:" + newPath);
            //System.out.println(topInput.getActorBuildOptions(actorPath));
            this.addActor(newPath, topInput.getActorOptions(actorPath));
        }

        ActorOptions parentOptions = this.getActorOptions(parentPath);
        this.appendChildrenList(parentPath, parentOptions, rootActorNames);
    }

    /**
     * Stores all RootActor names of a given Topology in a List. </br>
     * A RootActor is an Actor on the first Level (/user/ActorSupervisor/Level1/Level2...) of a GridTopology: </br>
     * <b>/user/ActorSupervisor/RootActor</b>
     *
     * @param topology GridTopology to be analysed.
     * @return List of RootActor names.
     */
    private List<String> getRootActorNames(ActorTopology topology) {
        //System.out.println(topology);
        List<String> rootActorNames = new ArrayList<>();
        for (String actorPath : topology.actorTopology.keySet()) {
            if (this.isRootActor(actorPath))
                rootActorNames.add(this.getActorName(actorPath));
        }
        //System.out.println(rootActorNames); 
        return rootActorNames;
    }

    /**
     * Appends <b>childrenNameList</b> to {@link ActorOptions#childrenNameList}
     *
     * @param parentPath the full path of the parent
     * @param options ActorOptions to be modified.
     * @param childrenNameList List of ChildrenNames to be added.
     *
     * @throws IllegalArgumentException if ChildName is not unique.
     */
    protected void appendChildrenList(String parentPath, ActorOptions options, List<String> childrenNameList) {

        // System.out.println(childrenNameList);       
        boolean securityCheck = true;

        for (String child : childrenNameList) {
            if (securityCheck && options.childrenNameList.contains(child)) {
                System.out.println("ActorOptions.childrenNameList already contains " + child);
                throw new IllegalArgumentException("ActorOptions.childrenNameList already contains " + child);
            }
        }
        options.childrenNameList.addAll(childrenNameList);
        // add also the paths

        for (String child : childrenNameList) {
            options.childrenPathList.add(parentPath + "/" + child);
        }

        // System.out.println(options.childrenPathList);

    }

    /**
     * Replaces the "/user/ActorSupervisor" part of the given <b>actorPath</b> with <b>parentPath</b>.
     * <br>
     * Example: <br>
     * replaceActorPathForSubGridAddition("/user/ActorSupervisor/Parent", "/user/ActorSupervisor/Child") -> <b>"/user/ActorSupervisor/Parent/Child"</b>
     * @param parentPath Path of the Anchor Actor.
     * @param actorPath Path to be modified.
     *
     * @return Modified ActorPath.
     */
    protected String replaceActorPathForSubGridAddition(String parentPath, String actorPath) {
        // System.out.println(actorPath.replace("/user/ActorSupervisor", parentPath));
        return actorPath.replace("/user/ActorSupervisor", parentPath);
    }

    /**
     * Checks if an Actor is located on Level 1 on the Grid hierarchy. (/user/ActorSupervisor/Level_1/Level_2)
     *
     * @param actorPath
     * @return True if Actor is located on Level 1.
     */
    protected boolean isRootActor(String actorPath) {
        return StringUtils.countMatches(actorPath, "/") == 3;
    }

    /**
     * Returns the name of the Actor specified by <b>actorPath</b>. <br>
     * Example: <br>
     * getActorName("/user/ActorSupervisor/Some/Actor/Stuff") -> "Stuff"
     *
     * @param actorPath ActorPath (/user/ActorSupervisor/Some/Actor)
     * @return ActorName
     */
    protected String getActorName(String actorPath) {
        int indexOfLastSlash = StringUtils.lastIndexOf(actorPath, "/");
        return actorPath.substring(indexOfLastSlash + 1);
    }

    /**
     * Replaces all occurrences of <b>oldPath</b> in {@link #actorTopology} with <b>newPath</b>.
     *
     * @param oldPath ActorPath to be replaced.
     * @param newPath New Path.
     */
    public void replaceActorPath(String oldPath, String newPath) {
        ActorTopology replacedTopology = new ActorTopology(this.simulationName);
        for (String currentPath : this.actorTopology.keySet()) {
            if (currentPath.contains(oldPath)) {
                String replaced = currentPath.replace(oldPath, newPath);
                replacedTopology.addActor(replaced, this.getActorOptions(currentPath));
            } else
                replacedTopology.addActor(currentPath, this.getActorOptions(currentPath));
        }
        this.actorTopology = replacedTopology.getActorTopology();
    }
}