Package jease.cmf.service

Source Code of jease.cmf.service.Nodes

/*
    Copyright (C) 2011 maik.jablonski@jease.org

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package jease.cmf.service;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import jease.cmf.domain.Node;
import jease.cmf.domain.NodeException;
import jfix.db4o.Database;
import jfix.functor.Command;
import jfix.functor.Predicate;
import jfix.functor.Procedure;
import jfix.functor.Supplier;
import jfix.util.Arrays;

/**
* Static utility to ease the persistence-handling of Nodes.
*
* Each Jease-Repository has one special Node called "root". The root is the
* only Node in a repository which doesn't have a parent node. All Nodes which
* are not the root and don't have a parent, are deleted when a persistence
* operation is performed.
*/
public class Nodes {

  private static Node root = queryRoot();

  private static Supplier<Long> lastChange = new Supplier<Long>() {
    public Long get() {
      return System.currentTimeMillis();
    }
  };

  private static Supplier<Map<String, Node>> nodesByPath = new Supplier<Map<String, Node>>() {
    public Map<String, Node> get() {
      return new ConcurrentHashMap<String, Node>();
    }
  };

  /**
   * Returns the root node derived by a database-query.
   */
  public static Node queryRoot() {
    return Database.queryUnique(Node.class, new Predicate<Node>() {
      public boolean test(Node node) {
        return node.getParent() == null;
      }
    });
  }

  /**
   * Sets the root-node for a repository. This method should only be called
   * once to initialize a repository.
   */
  public static void setRoot(Node rootNode) {
    root = rootNode;
  }

  /**
   * Returns the root-node of the repository. A root node is the only node in
   * a repository which doesn't have a parent.
   */
  public static Node getRoot() {
    return root;
  }

  /**
   * Returns the system time (milliseconds) of the last change in database.
   */
  public static long queryLastChange() {
    return Database.query(lastChange);
  }

  /**
   * Returns true if given node is root or attached to a parent.
   */
  public static boolean isRooted(Node node) {
    return node == root || Arrays.contains(node.getParents(), root);
  }

  /**
   * Returns node from root by given path.
   */
  public static Node getByPath(String path) {
    if (root == null) {
      return null;
    }
    Map<String, Node> cache = Database.query(nodesByPath);
    if (!cache.containsKey(path)) {
      Node node = root.getChild(path);
      if (node != null) {
        cache.put(path, node);
      }
    }
    return cache.get(path);
  }

  /**
   * Appends given child to given node and saves changes to database.
   *
   * Please note: appending a child to a node automatically removes the child
   * from the former container.
   */
  public static void append(Node node, Node child) throws NodeException {
    node.validateChild(child, child.getId());
    node.appendChild(child);
    Nodes.save(node);
  }

  /**
   * Appends given children to given node and save changes to database.
   *
   * Please note: appending a child to a node automatically removes the child
   * from the former container.
   */
  public static void append(Node node, Node[] children) throws NodeException {
    for (Node child : children) {
      node.validateChild(child, child.getId());
    }
    node.appendChildren(children);
    Nodes.save(node);
  }

  /**
   * Saves all changes of a given node to database.
   */
  public static void save(final Node node) {
    Database.write(new Command() {
      public void run() {
        node.markChanged();
        persistChanges();
      }
    });
  }

  /**
   * Deletes given node from repository.
   */
  public static void delete(final Node node) {
    Database.write(new Command() {
      public void run() {
        node.detach();
        persistChanges();
      }
    });
  }

  private static void persistChanges() {
    root.processChangedNodes(new Procedure<Node>() {
      public void execute(Node node) {
        if (isRooted(node)) {
          Database.save(node);
        } else {
          Database.ext().deleteDeliberately(node);
        }
      }
    });
  }
}
TOP

Related Classes of jease.cmf.service.Nodes

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.