Bio::Phylo::Mediators::NodeMediator - Mediator for links between tree nodes


NAME

Bio::Phylo::Mediators::NodeMediator - Mediator for links between tree nodes


SYNOPSIS

 # no direct usage


DESCRIPTION

This module manages links between node objects. It is an implementation of the Mediator design pattern (e.g. see http://www.atug.com/andypatterns/RM.htm, http://home.earthlink.net/~huston2/dp/mediator.html, http://sern.ucalgary.ca/courses/SENG/443/W02/assignments/Mediator/).

Methods defined in this module are meant only for internal usage by Bio::Phylo.


METHODS

CONSTRUCTOR

new()

NodeMediator constructor.

 Type    : Constructor
 Title   : new
 Usage   : my $mediator = Bio::Phylo::Taxa::NodeMediator->new;
 Function: Instantiates a Bio::Phylo::Taxa::NodeMediator
           object.
 Returns : A Bio::Phylo::Taxa::NodeMediator object (singleton).
 Args    : None.

METHODS

register()

Stores an object in mediator's cache.

 Type    : Method
 Title   : register
 Usage   : $mediator->register( $obj );
 Function: Stores an object in mediator's cache
 Returns : $self
 Args    : An object, $obj
 Comments: This method is called every time a node is instantiated.
unregister()

Removes argument from mediator's cache.

 Type    : Method
 Title   : unregister
 Usage   : $mediator->unregister( $obj );
 Function: Cleans up mediator's cache of $obj and $obj's relations
 Returns : $self
 Args    : An object, $obj
 Comments: This method is called every time a node ($obj) is destroyed.
set_link()

Creates link between arguments.

 Type    : Method
 Title   : set_link
 Usage   : $mediator->set_link( node => $obj1, $connection => $obj2 );
 Function: Creates link between objects
 Returns : $self
 Args    : node => a $node object
                   $connection => another $node object, where $connection is
                   *    parent
                   *    first_daughter
                   *    last_daughter
                   *    next_sister
                   *    previous_sister
 Comments: This method is called from within, for example, set_parent
           method calls. A call like $node1->set_parent( $node2 ),
           is internally rerouted to:
           $mediator->set_link( 
                node   => $node1,
                parent => $node2, 
           );
update_tree()

Updates tree membership.

 Type    : Method
 Title   : update_tree
 Usage   : $mediator->update_tree( 
               keep   => $node1, 
               update => $node2,
           );
 Function: updates tree membership
 Returns : Linked object
 Args    : keep   => $node1 (node whose tree membership to retain)
           update => $node2 (node whose tree membership 
           is moved to that of $node1)
 Comments: This method is called so that $node2 and its descendants
                   becomes member of the same tree as $node1
get_link()

Retrieves relative of argument.

 Type    : Method
 Title   : get_link
 Usage   : $mediator->get_link( $connection => $node );
 Function: Retrieves relative of $node
 Returns : Relative of $node
 Args    : $connection => $node, where $connection can be:
                   *    parent_of
                   *    next_sister_of
                   *    previous_sister_of
                   *    first_daughter_of
                   *    last_daughter_of
 =cut
 
        sub get_link {
                my $self = shift;
                my %args = @_;
                $logger->debug( "getting link between nodes" );
                my $node;
                # get_parent
                if ( $node = $args{'parent_of'} ) {
                        my $id       = $$node;
                        my $tree_id  = $tree_id_for_node{$id};
                        my $function = $ancestor_function{$tree_id};
                        for my $tuple ( @{$function} ) {
                                if ( $tuple->[0] == $id ) {
                                        return $node_object_for_id{ $tuple->[1] };
                                }
                        }
                        return;
                }
                # get_first_daughter
                elsif ( $node = $args{'first_daughter_of'} ) {
                        my $id       = $$node;
                        my $tree_id  = $tree_id_for_node{$id};
                        my $function = $ancestor_function{$tree_id};
                        for ( my $i = 0 ; $i <= $#{$function} ; $i++ ) {
                                if ( $function->[$i]->[1] == $id ) {
                                        return $node_object_for_id{ $function->[$i]->[0] };
                                }
                        }
                        return;
                }
                # get_last_daughter
                elsif ( $node = $args{'last_daughter_of'} ) {
                        my $id       = $$node;
                        my $tree_id  = $tree_id_for_node{$id};
                        my $function = $ancestor_function{$tree_id};
                        for ( my $i = $#{$function} ; $i >= 0 ; $i-- ) {
                                if ( $function->[$i]->[1] == $id ) {
                                        return $node_object_for_id{ $function->[$i]->[0] };
                                }
                        }
                        return;
                }
                # get_next_sister
                elsif ( $node = $args{'next_sister_of'} ) {
                        my $id       = $$node;
                        my $tree_id  = $tree_id_for_node{$id};
                        my $function = $ancestor_function{$tree_id};
                        my $parent_id;
                  GET_NEXT_SISTER: for ( my $i = 0 ; $i <= $#{$function} ; $i++ ) {
                                if ( $function->[$i]->[0] == $id ) {
                                        $parent_id = $function->[$i]->[1];
                                        next GET_NEXT_SISTER;
                                }
                                if (   defined $parent_id
                                        && $function->[$i]->[0] != $id
                                        && $function->[$i]->[1] == $parent_id )
                                {
                                        return $node_object_for_id{ $function->[$i]->[0] };
                                }
                        }
                        return;
                }
                # get_previous_sister
                elsif ( $node = $args{'previous_sister_of'} ) {
                        my $id       = $$node;
                        my $tree_id  = $tree_id_for_node{$id};
                        my $function = $ancestor_function{$tree_id};
                        my $parent_id;
                  GET_PREVIOUS_SISTER:
                        for ( my $i = $#{$function} ; $i >= 0 ; $i-- ) {
                                if ( $function->[$i]->[0] == $id ) {
                                        $parent_id = $function->[$i]->[1];
                                        next GET_PREVIOUS_SISTER;
                                }
                                if (   defined $parent_id
                                        && $function->[$i]->[0] != $id
                                        && $function->[$i]->[1] == $parent_id )
                                {
                                        return $node_object_for_id{ $function->[$i]->[0] };
                                }
                        }
                        return;
                }
                        }
        # $logger is apparently already cleaned up when we reach the destructor, so call as static
        sub DESTROY { Bio::Phylo::Util::Logger->debug( "calling empty destructor for '@_'" ) }

}


SEE ALSO

the Bio::Phylo::Manual manpage

Also see the manual: the Bio::Phylo::Manual manpage and http://rutgervos.blogspot.com.


REVISION

 $Id: NodeMediator.pm 841 2009-03-04 23:07:30Z rvos $
 Bio::Phylo::Mediators::NodeMediator - Mediator for links between tree nodes