Interface TreeTransaction


public interface TreeTransaction
Dedicated interface to handle all stored tree sessions. It is responsible for managing sessions in the API.

With the transaction, the API client can initialize, deactivate, activate, retrieve, or destroy any session.

Structurally, this interface acts as a bridge between TreeManager and the TreeSession, being an inherent part of the session, taking full responsibility for it, leaving the TreeManager interface free to only manipulate the elements inside the session.

An Element represents a node in a tree, and a tree can only exist within a previously created session. But to create a session, an object that represents the session transaction is needed, and this object is an instance of this interface. However, a transaction can only be recovered from within the TreeManager by invoking TreeManager.getTransaction().

There are two ways to create tree sessions:

  1. Create a new empty tree session;
  2. Create a tree session from the API Transformation Process.

The first one happens when the API client wants to create a default empty tree session by invoking initializeSession(String, Class). Here, an empty tree is created by specifying which class type this session will use as a node.

The last one happens when an API client wants to transform a Collection of objects that represents a linear tree structure. This transformation (which is called the API Transformation Process) converts this linear structure into an actual tree structure, where each node is represented by Element objects.

The TreeTransaction can work with only one TreeSession at a time, while the other sessions remain in the background waiting to be checked out again later.

Author:
Diego Madson de Andrade Nóbrega
  • Method Details

    • initializeSession

      <T> void initializeSession(String identifier, Class<T> type) throws TreeException
      Initializes a new empty tree session with the specified identifier. Automatically, after creating the session, it is checked out so it becomes the current session.

      In this method, the API client must create elements one by one until it assembles the desired tree. This is easily done through the TreeManager methods.

      When starting a new standard session, it is necessary to specify the parameterized class type that corresponds to the node class type that each Element will wrap. Then, each element will contain its respective node of this parameterized type.

      The identifier and type parameters cannot be null.

      Type Parameters:
      T - the class type of the session which will store elements with this type of nodes
      Parameters:
      identifier - the session identifier (it must be unique)
      type - class type of the nodes that will be wrapped within their respective elements in this tree session
      Throws:
      TreeException - when there is another session with the same identifier
      IllegalArgumentException - when the identifier or type parameters are null
    • initializeSession

      <T> void initializeSession(String identifier, Collection<T> nodes) throws TreeException
      Initializes a session with a specified identifier and a list of linear objects (with a logical tree structure) to be transformed into an actual tree structure. Automatically, after creating the session, the session is already available as the current session.

      This corresponds to one of the main features of the HappyTree API. When necessary, it converts a linear list of objects that behave as a tree into an actual tree structure. For this, these objects need to follow some requirements for the API Transformation Process to occur successfully.

      This process implements a lifecycle with four general phases:

      1. Pre-Validation
      2. Core Engine (with 3 sub-phases)

      Note: The concept of sub-phase is merely illustrative and serves only to distinguish the phase of validation from the phases of the tree transformation process.

      ATP Lifecycle
      PhaseDescriptionSub-Phases
      Pre-ValidationValidates each input object's requirements.
      Core Engine Processes the tree assembly and transformation from the source objects list into an actual tree structure. Extraction - Initialization - Binding

      Pre-Validation:

      This phase represents the beginning of the API Transformation Process. In this phase, the core API requires that all input aspects to be transformed conform. The following validations are done:

      • Verifies whether the list of objects to be transformed is not null or empty;
      • Verifies whether there is an existing session with the same identifier;
      • Verifies whether the class of the objects to be transformed is annotated with @Tree annotation;
      • Verifies whether the identifier attribute of the object to be transformed has the @Id annotation;
      • Verifies whether the parent attribute of the object to be transformed has the @Parent annotation (for parent attribute with null value, this node will be placed in the first level of the tree - under the root);
      • Verifies whether the class of the objects to be transformed implements Serializable;
      • Verifies whether the identifier attribute of each object is null;
      • Validates whether all source objects have both the @Id and @Parent attributes with the same class type;
      • Checks for duplicate @Id;
      • Verifies whether the class of the objects to be transformed has getters and setters.

      Core Engine:

      Extraction:

      If the input represented by the list of objects to be transformed passes all validations from the previous phase, then the HappyTree API takes them and extracts them in order to separate them from their respective parents. Therefore, as a product for the next phase, there will be the objects and their respective parents separated into two blocks.

      Initialization:

      In this phase, the HappyTree API instantiates an object of type Element for each source object used as input and passes the respective @Id and @Parent attributes of the source object to that element. In addition, the source object itself is automatically wrapped into that element, thus making the source object liable to be a tree node, since the element naturally represents a node in the context of the HappyTree API. After the tree is built, to retrieve the source object just invoke the Element.unwrap() method.

      Binding:

      After obtaining the list of resulting elements from the previous phase, the HappyTree API will now bind each element to its respective parent through the block of separated parent objects from the Extraction phase.

      Therefore, it is in this phase that the tree is actually assembled. Thus, for each node in the tree we have a corresponding element object, where each element has:

      • The @Id attribute value;
      • The @Parent attribute value;
      • The wrappedNode corresponding to the source object used in this process;
      • The collection of children, corresponding to other elements that are children of this one;
      • The tree session to which this element belongs.

      This lifecycle is only triggered in the API Transformation Process by invoking this method, passing a collection of a linear structure (nodes) to be transformed into an actual tree.

      Parameters:
      identifier - the session identifier
      nodes - the Collection of the linear objects to be transformed into an actual tree
      Throws:
      TreeException - when:
      • There is another session with the same identifier;
      • The class of the object to be converted has not been annotated with @Tree;
      • The identifier attribute of the object to be converted has not been annotated with @Id;
      • The parent attribute of the object to be converted has not been annotated with @Parent;
      • The class of the object to be transformed does not implement Serializable;
      • The annotated @Id and @Parent attributes have incompatible types;
      • There are duplicate IDs;
      • The class of the object to be transformed does not have getters & setters.
      IllegalArgumentException - when the identifier or nodes parameters are null or the nodes parameter is empty
    • destroySession

      void destroySession(String identifier)
      Removes the session with the specified identifier.

      The session is permanently removed, as it is not possible to retrieve it anymore. Consequently, the tree and its elements within this session are also removed.

      Parameters:
      identifier - the session identifier to be removed
    • destroySession

      void destroySession()
      Removes the current session previously checked out.

      The session is permanently removed, as it is not possible to retrieve it anymore. Consequently, the tree and its elements within this session are also removed.

      In the case of removing the current session, the API client needs to specify a new session to be checked out right after the removal.

    • destroyAllSessions

      void destroyAllSessions()
      Removes all the registered sessions.

      The removal occurs for both activated and deactivated sessions.

    • sessionCheckout

      TreeSession sessionCheckout(String identifier)
      Selects a tree session to work with it. If there is a session with the specified identifier, then it is returned.

      When the session is selected to be worked on, the current session remains in the background, waiting to be selected at another time, while the checked out session becomes the current session. This occurs because the transaction is only able to work with one session at a time.

      Passing a null or non-existent identifier causes the current session of the transaction to be "canceled". A "canceled" session means that the transaction has no session available to work on, and therefore, it is not possible to execute any operation from TreeManager.

      Parameters:
      identifier - the session identifier to be checked out
      Returns:
      an instance of TreeSession representing the current session
    • activateSession

      void activateSession(String identifier)
      Activates a session by the specified identifier.

      With an active session, its elements can be handled freely within the tree.

      This method just activates a session and does not make it available automatically for the API client to use it as the current session. For this, invoke sessionCheckout(String) before or after activating a session.

      Parameters:
      identifier - the session identifier to be activated
    • activateSession

      void activateSession()
      Activates the current session.

      With an active session, its elements can be handled freely within the tree.

      The current session, if not null, will always be active by invoking this method, regardless of its current state.

    • deactivateSession

      void deactivateSession(String identifier)
      Deactivates a session by the specified identifier.

      Deactivating a session does not remove it from the list of registered sessions, instead, the session is just disabled.

      With a deactivated session, its elements cannot be handled freely within the tree.

      Parameters:
      identifier - the session identifier to be deactivated
    • deactivateSession

      void deactivateSession()
      Deactivates the current session.

      Deactivating the current session does not remove it from the list of registered sessions, instead, the current session is just disabled.

      With a deactivated session, its elements cannot be handled freely within the tree.

    • sessions

      List<TreeSession> sessions()
      Returns the list of all registered sessions.

      The list of all sessions includes both activated and deactivated sessions.

      Returns:
      the list of all registered sessions
    • cloneSession

      TreeSession cloneSession(String from, String to)

      Replicates the tree session defined by the from identifier to the session defined by the to identifier.

      Replicating an existing tree session consists of faithfully reproducing all the elements defined in the source tree for a target tree, whether this is a new or already existing target tree.

      Replicating a session to an already existing session implies replacing the entire tree in the target session defined by to identifier, which causes the total loss of the previous states of the elements that were defined in the target tree.

      Warning: the programmer is responsible for ensuring that the session defined by the to identifier already exists or not.

      In contrast, if the session defined by the to identifier does not exist, then a new session is created with the tree and its elements replicated from the source tree session.

      This method only clones a session and does not make it ready to be worked on. For this, invoke sessionCheckout(String) before or after cloning a session.

      Parameters:
      from - the identifier of the source tree session to be replicated
      to - the identifier of the target tree session
      Returns:
      the cloned session
    • cloneSession

      TreeSession cloneSession(TreeSession from, String to)
      Replicates the tree session defined by from session instance for the session defined by to identifier.

      Replicating an existing tree session consists of faithfully reproducing all the elements defined in the source tree for a target tree, whether this is a new or already existing target tree.

      Replicating a session to an already existing session implies replacing the entire tree in the target session defined by to identifier, which causes the total loss of the previous states of the elements that were defined in the target tree.

      Warning: the programmer is responsible for ensuring that the session defined by the to identifier already exists or not.

      In contrast, if the session defined by the to identifier does not exist, then a new session is created with the tree and its elements replicated from the source tree session.

      This method only clones a session and does not make it ready to be worked on. For this, invoke sessionCheckout(String) before or after cloning a session.

      Parameters:
      from - the instance of the tree session to be replicated
      to - the identifier of the target tree session
      Returns:
      the cloned session
    • currentSession

      TreeSession currentSession()
      Returns the current session of the transaction. The current session implies the session that the transaction is referring to at this very moment.

      Since the transaction can only work with one session at a time, the API client needs to define which session will have the elements handled. To choose the session to be worked on, invoke the method sessionCheckout(String), and to obtain the instance of the session previously chosen, execute this method.

      The programmer is responsible for ensuring that the current session is not null, as it causes errors when trying to execute operations of TreeManager.

      Returns:
      the current session of this transaction