package Froody::Repository; use base qw(Froody::Base); use Froody::API::Reflection; use Froody::Invoker::Reflection; use Froody::Dispatch; use Froody::Invoker::Remote; use Froody::Method; use Froody::ErrorType; use strict; use warnings; use Scalar::Util qw(blessed); our $VERSION = 0.01; =head1 NAME Froody::Repository - a repository of Froody::Method objects. =head1 SYNOPSIS use Froody::Repository; my $repository = Froody::Repository->new(); # methods for putting stuff in the repository $repository->register_method($froody_method); $repository->register_errortype($froody_errortype); # methods for getting froody methods out my $method = $repository->get_method('name.of.method'); my @methods = $repository->get_methods; my @methods2 = $repository->get_methods('namespace.of.interest'); my @methods3 = $repository->get_methods(qr/delete/); # methods for getting froody errortype out my $errortype = $repository->get_errortype('name.of.errortype'); my @errortype = $repository->get_errortypes; my @errortype2 = $repository->get_errortypes('errortypes.of.interest'); my @errortype3 = $repository->get_errortypes(qr/delete/); my $errortype2 = $repository->get_closest_errortype('fragment.of.type'); =head1 DESCRIPTION L provides a central location to register and discover L instances. =head1 METHODS =cut sub init { my $self = shift; ### reflection methods and errortypes ### my (@structures) = grep { blessed($_) && $_->isa("Froody::Structure") } Froody::API::Reflection->load(); my $invoker = Froody::Invoker::Reflection->new()->repository($self); foreach (grep { $_->isa("Froody::Method") } @structures) { #Note: Invoker only holds a weak reference to self -- no memory leaks here. Nope. $_->invoker($invoker); $self->register_method($_); } foreach (grep { $_->isa("Froody::ErrorType") } @structures) { $self->register_errortype($_); } ### default error ### $self->register_errortype(Froody::ErrorType->new()->name("")); return $self; } =head2 Methods for dealing with Froody::Method instances =over =item register_method( Froody::Method ) Register a method with the repository. You don't ever normally have to call this method yourself, things like your Froody::Implementation subclasses do it themselves from C. =cut sub register_method { my $self = shift; my $method = shift; Froody::Error->throw("perl.methodcall.param", "you didn't pass a Froody::Method object") unless UNIVERSAL::isa($method, 'Froody::Method'); $self->{method_hash}{$method->full_name} ||= $method; return $self; } =item get_methods() || get_methods( $regex ) || get_methods( "foo.bar.*" ) Return all methods (as Froody::Method objects) if invoked with no arguments, or only the methods matching the query if invoked with an argument. =cut sub get_methods { my $self = shift; # return everything if no arguments unless (@_) { return values %{ $self->{method_hash} } } # what methods are we looking for? Make it a regex if it's not already my $query = ref($_[0]) ? shift : Froody::Method->match_to_regex( shift ); return grep { $_->full_name =~ $query } values %{ $self->{method_hash} }; } =item get_method($name) Return a single method (as a Froody::Method object) matching $name exactly. Throws a Froody::Error of type "froody.invoke.nosuchmethod" if no method matching the $name is registered with this repository. =cut sub get_method { my $self = shift; my $name = shift; my $method = $self->{method_hash}{ $name } or Froody::Error->throw("froody.invoke.nosuchmethod", "Method '$name' not found",101); return $method; } =back =head2 Methods for dealing with Froody::ErrorType instances =over =item register_errortype( Froody::ErrorType ) Register an errortype with the repository. You don't ever normally have to call this method yourself, things like your Froody::Implementation subclasses do it themselves from C. =cut sub register_errortype { my $self = shift; my $errortype = shift; Froody::Error->throw("perl.methodcall.param", "you didn't pass a Froody::ErrorType object") unless UNIVERSAL::isa($errortype, 'Froody::ErrorType'); $self->{errortypes_hash}{ $errortype->name } = $errortype; return $self; } =item get_errortype($name) Return a single errortype (as a Froody::ErrorType object) matching $name exactly. Throws a Froody::Error of type "froody.invoke.nosucherrortype" if no method matching the $name is registered with this repository. =cut sub get_errortype { my $self = shift; my $name = shift; my $errortype = $self->{errortypes_hash}{ $name } or Froody::Error->throw("froody.invoke.nosucherrortype", "ErrorType '$name' not found"); return $errortype; } =item get_errortypes() || get_errortypes( $regex ) || get_errortypes( "foo.bar.*" ) Return all errortypes (as Froody::ErrorTypes objects) if invoked with no arguments, or only the methods matching the query if invoked with an argument. =cut sub get_errortypes { my $self = shift; # return everything if no arguments unless (@_) { return values %{ $self->{errortypes_hash} } } # what methods are we looking for? Make it a regex if it's not already my $query = ref($_[0]) ? shift : Froody::Method->match_to_regex( shift ); return grep { $_->name =~ $query } values %{ $self->{errortypes_hash} }; } =item get_closest_errortype =cut sub get_closest_errortype { my $self = shift; my $code = shift; my @bits = split /\./, $code; foreach (reverse 0..$#bits) { my $string = join '.', @bits[0..$_]; return $self->{errortypes_hash}{ $string } if $self->{errortypes_hash}{ $string }; } # return the default errortype hash which is always there, as it was # created during init. return $self->{errortypes_hash}{""}; } =back =head1 BUGS None known We're using C from Froody::Method, maybe that should be refactored elsewhere Please report any bugs you find via the CPAN RT system. L =head1 AUTHOR Copyright Fotango 2005. All rights reserved. Please see the main L documentation for details of who has worked on this project. This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 SEE ALSO L, L =cut 1;