Net::LDAP::Class::MethodMaker - create methods for Net::LDAP::Class classes


Net-LDAP-Class documentation Contained in the Net-LDAP-Class distribution.

Index


Code Index:

NAME

Top

Net::LDAP::Class::MethodMaker - create methods for Net::LDAP::Class classes

SYNOPSIS

Top

 package MyUser;
 use base qw( Net::LDAP::Class::User );
 use Net::LDAP::Class::MethodMaker (
    'scalar --get_set_init' => [qw( foo )],
    'related_objects'       => [qw( bars )],
 );

 __PACKAGE__->metadata->setup(
    base_dn             => 'dc=local',
    attributes          => [qw( foo )],
    unique_attributes   => [qw( foo )],
 );

 # must define a fetch_bars method
 sub fetch_bars {
    my $user = shift;

    # do something to get bar objects.

 }

 1;

 # elsewhere

 my $user = MyUser->new( foo => '1234' )->read or die;
 $user->foo;        # == $user->ldap_entry->get_value('foo');
 $user->foo(5678);  # == $user->ldap_entry->replace( foo => 5678 );
 $user->foo;        # returns '5678'

 my $bars       = $user->bars;  # == $user->fetch_bars;
 push(@$bars, 'new bar');
 $user->bars($bars);
 my $newbars    = $user->bars;  # != $user->fetch_bars;
 $user->clear_bars;
 $newbars       = $user->bars;  # == $user->fetch_bars;

 


DESCRIPTION

Top

Net::LDAP::Class::MethodMaker is a subclass of Rose::Object::MakeMethods::Generic. It extends the base class with two new method types: related_objects and ldap_entry.

METHODS

Top

ldap_entry

The ldap_entry method type supports the 'get_set' interface only.

This method type negotiates the getting and setting of values in the delegate ldap_entry() object.

object_or_class_meta

Similar to the 'scalar --get-set-init' method type but may be called as a class method, in which case it will call through to the class metadata() object.

AUTHOR

Top

Peter Karman, <karman at cpan.org>

BUGS

Top

Please report any bugs or feature requests to bug-net-ldap-class at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Net-LDAP-Class. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

Top

You can find documentation for this module with the perldoc command.

    perldoc Net::LDAP::Class

You can also look for information at:

* AnnoCPAN: Annotated CPAN documentation

http://annocpan.org/dist/Net-LDAP-Class

* CPAN Ratings

http://cpanratings.perl.org/d/Net-LDAP-Class

* RT: CPAN's request tracker

http://rt.cpan.org/NoAuth/Bugs.html?Dist=Net-LDAP-Class

* Search CPAN

http://search.cpan.org/dist/Net-LDAP-Class

ACKNOWLEDGEMENTS

Top

The Minnesota Supercomputing Institute http://www.msi.umn.edu/ sponsored the development of this software.

COPYRIGHT

Top

SEE ALSO

Top

Net::LDAP::Class, Rose::Object::MakeMethods::Generic


Net-LDAP-Class documentation Contained in the Net-LDAP-Class distribution.
package Net::LDAP::Class::MethodMaker;
use strict;
use warnings;
use base qw( Rose::Object::MakeMethods::Generic );
use Carp;
use Data::Dump;

our $VERSION = '0.26';

sub related_objects {
    my ( $class, $name, $args ) = @_;

    my %methods;

    my $key       = $args->{'hash_key'}  || $name;
    my $interface = $args->{'interface'} || 'get_set';

    if ( $interface eq 'get_set_init' ) {
        croak
            "get_set_init interface not supported for related_objects: $name";
    }
    elsif ( $interface eq 'get_set' ) {
        my $fetcher_method = $args->{'fetch_method'} || "fetch_$name";
        $methods{$name} = sub {
            if ( @_ > 1 ) {
                if ( !$_[0]->validate( $key, $_[1] ) ) {
                    croak "validate failed for attribute $key: "
                        . $_[0]->error;
                }
                return $_[0]->{$key} = $_[1];
            }
            return exists $_[0]->{$key}
                ? $_[0]->{$key}
                : $_[0]->$fetcher_method;
        };

        $methods{"clear_$name"} = sub { return delete $_[0]->{$key} };
    }
    else {
        croak "Unknown interface: $interface";
    }

    return \%methods;
}

# get/set attributes on the delegate ldap_entry
sub ldap_entry {
    my ( $class, $name, $args ) = @_;

    if ( $class->can($name) ) {
        carp "class $class already has method for $name";
        return;
    }

    my %methods;

    my $attribute = $args->{'hash_key'}  || $name;
    my $interface = $args->{'interface'} || 'get_set';

    if ( $interface eq 'get_set' ) {

        $methods{$name} = sub {
            my $self = shift;
            my @args = @_;

            # we do not support values of more than one arg
            if ( scalar @args > 1 ) {
                croak "cannot set more than one value at a time";
            }

            # if we haven't yet loaded a Net::LDAP::Entry via read()
            # cache the values and set them when/if we read().
            if ( !defined $self->ldap_entry ) {

                if ( scalar @args ) {
                    $self->{_not_yet_set}->{$attribute} = $args[0];
                }
                return
                    exists $self->{_not_yet_set}->{$attribute}
                    ? $self->{_not_yet_set}->{$attribute}
                    : undef;

            }

# otherwise, delegate to the ldap_entry
#unless ( grep { $_ eq $attribute } @{ $self->attributes } ) {
#                croak
#                    qq[no such attribute or method "$attribute" defined for package "]
#                    . ref($self)
#                    . qq[ -- do you need to add '$attribute' to your setup() call?"];
#            }

            if ( scalar @args ) {

                if ( !$self->validate( $attribute, $args[0] ) ) {
                    croak "validate failed for attribute $attribute: "
                        . $self->error;
                }

                #warn "AUTOLOAD set $attribute -> $args[0]";
                my @old = $self->ldap_entry->get_value($attribute);
                $self->ldap_entry->replace( $attribute, $args[0] );
                $self->{_was_set}->{$attribute}->{new} = $args[0];

       # do not overwrite an existing 'old' value, since we might need to know
       # what was originally in the ldap_entry in order to replace it.
                unless ( exists $self->{_was_set}->{$attribute}->{old} ) {
                    $self->{_was_set}->{$attribute}->{old}
                        = @old > 1 ? \@old : $old[0];
                }
            }

            my (@ret) = ( $self->ldap_entry->get_value($attribute) );
            if (wantarray) {
                return @ret;
            }
            else {
                return @ret > 1 ? \@ret : $ret[0];
            }
        };

    }
    else {
        croak "Unknown interface: $interface";
    }

    return \%methods;
}

sub object_or_class_meta {
    my ( $class, $name, $args ) = @_;

    my %methods;
    my $key         = $args->{'hash_key'}    || $name;
    my $init_method = $args->{'init_method'} || "init_$name";

    $methods{$name} = sub {
        if ( ref( $_[0] ) ) {
            return $_[0]->{$key} = $_[1] if ( @_ > 1 );

            if ( $_[0]->can($init_method) ) {
                return defined $_[0]->{$key}
                    ? $_[0]->{$key}
                    : ( $_[0]->{$key} = $_[0]->$init_method() );
            }
            else {
                return defined $_[0]->{$key}
                    ? $_[0]->{$key}
                    : ( $_[0]->{$key} = $_[0]->metadata->$key );
            }
        }
        else {
            return $_[0]->metadata->$key;
        }
    };

    return \%methods;
}

1;

__END__