ru.parallel.octotron.core.persistence.GraphManager.java Source code

Java tutorial

Introduction

Here is the source code for ru.parallel.octotron.core.persistence.GraphManager.java

Source

/*******************************************************************************
 * Copyright (c) 2014 SRCC MSU
 *
 * Distributed under the MIT License - see the accompanying file LICENSE.txt.
 ******************************************************************************/

package ru.parallel.octotron.core.persistence;

import com.google.common.collect.Iterables;
import ru.parallel.octotron.core.attributes.*;
import ru.parallel.octotron.core.graph.impl.GraphEntity;
import ru.parallel.octotron.core.graph.impl.GraphLink;
import ru.parallel.octotron.core.graph.impl.GraphObject;
import ru.parallel.octotron.core.graph.impl.GraphService;
import ru.parallel.octotron.core.logic.Reaction;
import ru.parallel.octotron.core.model.ModelLink;
import ru.parallel.octotron.core.model.ModelObject;
import ru.parallel.octotron.core.primitive.EAttributeType;
import ru.parallel.octotron.core.primitive.IUniqueID;
import ru.parallel.octotron.core.primitive.exception.ExceptionModelFail;
import ru.parallel.octotron.core.primitive.exception.ExceptionSystemError;
import ru.parallel.octotron.exec.services.ModelService;
import ru.parallel.octotron.neo4j.Neo4jGraph;

import java.util.Collection;
import java.util.logging.Level;
import java.util.logging.Logger;

public class GraphManager implements IPersistenceManager {
    private final static Logger LOGGER = Logger.getLogger("octotron");

    final ModelService model_service;

    private Neo4jGraph graph;
    private GraphService graph_service;

    public GraphManager(ModelService model_service, String path) throws ExceptionSystemError {
        this.model_service = model_service;

        if (model_service.GetMode() == ModelService.EMode.CREATION)
            graph = new Neo4jGraph(path, Neo4jGraph.Op.RECREATE, true);
        else
            graph = new Neo4jGraph(path, Neo4jGraph.Op.LOAD, true);

        graph.GetIndex().EnableLinkIndex("AID");
        graph.GetIndex().EnableObjectIndex("AID");

        graph_service = new GraphService(graph);
    }

    private GraphObject GetObject(IUniqueID<?> id) {
        return graph_service.GetObject("AID", id.GetID());
    }

    private GraphObject CheckObject(IUniqueID<?> id, String check_label) {
        GraphObject graph_object = graph_service.GetObject("AID", id.GetID());

        if (!graph_object.TestLabel(check_label))
            throw new ExceptionModelFail("graph check failed, mismatched labels for AID: " + id.GetID()
                    + " required label: " + check_label);

        return graph_object;
    }

    private GraphLink GetLink(IUniqueID<?> id) {
        return graph_service.GetLink("AID", id.GetID());
    }

    private GraphEntity GetEntity(IUniqueID<?> id) {
        Collection<GraphLink> links = graph_service.GetLinks("AID", id.GetID());
        Collection<GraphObject> objects = graph_service.GetObjects("AID", id.GetID());

        if (!links.isEmpty() && !objects.isEmpty())
            throw new ExceptionModelFail("found few entities with the same id: " + id.GetID());

        if (objects.size() == 1)
            return Iterables.get(objects, 0);
        else if (objects.size() > 1)
            throw new ExceptionModelFail("found multiple objects with AID: " + id.GetID());

        if (links.size() == 1)
            return Iterables.get(links, 0);
        else if (links.size() > 1)
            throw new ExceptionModelFail("found multiple links with AID: " + id.GetID());

        throw new ExceptionModelFail("could not get entity for AID: " + id.GetID());
    }

    @Override
    public void RegisterObject(ModelObject object) {
        if (model_service.GetMode() == ModelService.EMode.CREATION) {
            GraphObject graph_object = graph_service.AddObject();
            graph_object.AddLabel(object.GetType().toString());

            graph_object.UpdateAttribute("AID", object.GetID());
        } else if (model_service.GetMode() == ModelService.EMode.LOAD) {
            CheckObject(object, object.GetType().toString());
        } else if (model_service.GetMode() == ModelService.EMode.OPERATION) {
            throw new ExceptionModelFail("no database modification in operational mode");
        }
    }

    @Override
    public void RegisterLink(ModelLink link) {
        if (model_service.GetMode() == ModelService.EMode.CREATION) {
            GraphLink graph_object = graph_service.AddLink(GetObject(link.Source()), GetObject(link.Target()),
                    link.GetType().name());

            graph_object.UpdateAttribute("AID", link.GetID());
        } else if (model_service.GetMode() == ModelService.EMode.LOAD) {
            GetLink(link);
        } else if (model_service.GetMode() == ModelService.EMode.OPERATION) {
            throw new ExceptionModelFail("no database modification in operational mode");
        }
    }

    @Override
    public void RegisterReaction(Reaction reaction) {
        if (model_service.GetMode() == ModelService.EMode.CREATION) {
            GraphObject graph_object = graph_service.AddObject();
            graph_object.AddLabel(reaction.GetType().toString());

            graph_object.UpdateAttribute("AID", reaction.GetID());

            graph_object.UpdateAttribute("state", reaction.GetState().toString());
            graph_object.UpdateAttribute("stat", reaction.GetGlobalStat());

            graph_object.UpdateAttribute("suppress", reaction.GetSuppress());
            graph_object.UpdateAttribute("descr", reaction.GetDescription());

            // info
            graph_object.UpdateAttribute("name", reaction.GetAttribute().GetName());

            graph_service.AddLink(GetObject(reaction.GetAttribute()), graph_object, reaction.GetType().name());
        } else if (model_service.GetMode() == ModelService.EMode.LOAD) {
            GraphObject graph_object = CheckObject(reaction, reaction.GetType().toString());

            reaction.SetState(Reaction.State.valueOf((String) graph_object.GetAttribute("state")));
            reaction.SetGlobalStat((Long) graph_object.GetAttribute("stat"));
            reaction.SetSuppress((Boolean) graph_object.GetAttribute("suppress"));
            reaction.SetDescription((String) graph_object.GetAttribute("descr"));
        } else if (model_service.GetMode() == ModelService.EMode.OPERATION) {
            GraphObject graph_object = GetObject(reaction);

            graph_object.UpdateAttribute("state", reaction.GetState().toString());
            graph_object.UpdateAttribute("stat", reaction.GetGlobalStat());

            graph_object.UpdateAttribute("suppress", reaction.GetSuppress());
            graph_object.UpdateAttribute("descr", reaction.GetDescription());
        }
    }

    @Override
    public void RegisterConst(ConstAttribute attribute) {
        if (model_service.GetMode() == ModelService.EMode.CREATION) {
            GraphEntity graph_entity = GetEntity(attribute.GetParent());

            graph_entity.UpdateAttribute(attribute.GetName(), attribute.GetValue().GetRaw());
        } else if (model_service.GetMode() == ModelService.EMode.LOAD) {
            GraphEntity graph_entity = GetEntity(attribute.GetParent());

            Object new_value = graph_entity.GetAttribute(attribute.GetName());

            attribute.GetBuilder(model_service).ModifyValue(Value.Construct(new_value));
        } else if (model_service.GetMode() == ModelService.EMode.OPERATION) {
            throw new ExceptionModelFail("no database modification in operational mode");
        }
    }

    private void RegisterMod(AbstractModAttribute attribute) {
        if (model_service.GetMode() == ModelService.EMode.CREATION) {
            GraphObject graph_object = graph_service.AddObject();
            graph_object.AddLabel(attribute.GetType().toString());

            graph_object.UpdateAttribute("AID", attribute.GetID());

            graph_object.UpdateAttribute("ctime", attribute.GetCTime());

            if (attribute.GetValue().IsComputable())
                graph_object.UpdateAttribute("value", attribute.GetValue().GetRaw());

            // info
            graph_object.UpdateAttribute("name", attribute.GetName());

            graph_service.AddLink(GetObject(attribute.GetParent()), graph_object, attribute.GetType().name());
        } else if (model_service.GetMode() == ModelService.EMode.LOAD) {
            GraphObject graph_object = CheckObject(attribute, attribute.GetType().toString());

            attribute.GetBuilder(model_service).SetCTime((Long) graph_object.GetAttribute("ctime"));

            if (graph_object.TestAttribute("value"))
                attribute.GetBuilder(model_service).SetValue(Value.Construct(graph_object.GetAttribute("value")));
            else
                attribute.GetBuilder(model_service).SetValue(Value.undefined);
        } else if (model_service.GetMode() == ModelService.EMode.OPERATION) {
            GraphObject graph_object = GetObject(attribute);

            graph_object.UpdateAttribute("ctime", attribute.GetCTime());

            if (attribute.GetValue().IsComputable())
                graph_object.UpdateAttribute("value", attribute.GetValue().GetRaw());
        }
    }

    public void RegisterSensor(SensorAttribute attribute) {
        RegisterMod(attribute);

        if (model_service.GetMode() == ModelService.EMode.CREATION) {
            GraphObject graph_object = GetObject(attribute);
            graph_object.UpdateAttribute("is_valid", attribute.IsUserValid());
        } else if (model_service.GetMode() == ModelService.EMode.LOAD) {
            GraphObject graph_object = GetObject(attribute);

            attribute.GetBuilder(model_service).SetValid((Boolean) graph_object.GetAttribute("is_valid"));
        } else if (model_service.GetMode() == ModelService.EMode.OPERATION) {
            GraphObject graph_object = GetObject(attribute);

            graph_object.UpdateAttribute("is_valid", attribute.IsUserValid());
        }
    }

    @Override
    public void RegisterVar(VarAttribute attribute) {
        RegisterMod(attribute);
    }

    private static final String DEPENDS = "DEPENDS";

    @Override
    public void MakeRuleDependency(VarAttribute attribute) {
        GraphObject object = GetObject(attribute);

        for (IModelAttribute i_depend_from : attribute.GetIDependOn()) {
            if (i_depend_from.GetType() == EAttributeType.CONST)
                continue;

            GraphObject dependency_object = GetObject(i_depend_from);

            graph_service.AddLink(object, dependency_object, DEPENDS);
        }
    }

    @Override
    public void Finish() {
        graph.GetTransaction().ForceWrite(); // TODO: not needed?

        graph.Shutdown();
    }

    @Override
    public void Wipe() {
        graph.Shutdown();

        try {
            graph.Delete();
        } catch (ExceptionSystemError e) {
            LOGGER.log(Level.SEVERE, "could not wipe Neo4j folder", e);
        }

        LOGGER.log(Level.INFO, "Neo4j folder wiped");
    }
}