view release on metacpan or search on metacpan
x App::Context::HTTP - add support for RPC and REST (in addition to web app support)
x App::Context::service_exists() - detect if a service exists in the config/session (generalizes session_object_exists())
VERSION 0.9661
x updated the dependencies so that the CPAN tests don't fail
VERSION 0.966
x add SharedDatastore as a useful service (with a Repository-based implementation)
x improved support for "temporary" services (named "temporary" or with the {temporary} arg)
(a "temporary service" is akin to a stateless session bean in Java)
x add support for including/overlaying additional config files based on values present in
the %$options hash or when a particular named service is instantiated
x App::Context::POE::Server
x App::Context::POE::ClusterController, App::Context::POE::ClusterNode
VERSION 0.965
x add UI timing log, activated by "app.Context.timer" option
VERSION 0.964
x mostly documentation updates
x moved Apache::Framework::App to Apache::App
x add permissions to widget display from URL and method calls, also {open_widget_urls} option
x add App::Service::substitute()
x default dates can be {today}+6
VERSION 0.95
x Widget containership is defined in the widget name by dashes ("-") instead of dots (".") (better for CSS)
x Removed dependency on App::Repository in t/ServiceRemote.t
VERSION 0.93
x Initial release (first one I started keeping this change log, anyway)
x Implemented App::Reference->overlay() more completely
lib/App/Conf.pod view on Meta::CPAN
$config = App::Conf->new();
$config = App::Conf->new("file" => $file);
$config = App::Conf->new("file" => $file, "configClass" => "App::Conf::XML");
print $config->dump(), "\n"; # use Data::Dumper to spit out the Perl representation
# accessors
$property_value = $config->get($property_name);
$branch = $config->get_branch($branch_name); # get hashref of properties
# on-demand loading helper methods (private methods)
$config->overlay($config2); # merge the two config structures using overlay rules
$config->overlay($config1, $config2); # merge $config2 onto $config1
$config->graft($branch_name, $config2); # graft new config structure onto branch
# By convention, the configurations for each App-Context service will be located
# two levels under the hash ref as shown.
$config->{Conf} # config settings for all Conf services
$config->{Conf}{default} # config settings for the default Conf service
$config->{Security} # config settings for all Security services
$config->{Security}{default} # config settings for the default Security service
$config->{TemplateEngine}{tt} # config settings for the Template service named "tt"
lib/App/Conf.pod view on Meta::CPAN
# PRIVATE METHODS
#############################################################################
=head1 Private Methods:
The following methods are intended to be called only within this class.
=cut
#############################################################################
# overlay()
#############################################################################
=head2 overlay()
* Signature: $config->overlay($config2);
* Signature: $config->overlay($config1, $config2);
* Param: $config1 {}
* Param: $config2 {}
* Return: void
* Throws: App::Exception::Conf
* Since: 0.01
Sample Usage:
# merge the two config structures using overlay rules
$config->overlay($config2);
# merge $config2 onto $config1
$config->overlay($config1, $config2);
=cut
#############################################################################
# graft()
#############################################################################
=head2 graft()
* Signature: $config->graft($branch_name, $config2);
lib/App/Conf/File.pm view on Meta::CPAN
else {
App::Exception::Conf->throw(
error => "create(): [$conf_file] config text doesn't match '\$var = {...};'\n"
);
}
}
}
}
if ($options->{conf} && ref($options->{conf}) eq "HASH") {
App::Reference->overlay($conf, $options->{conf});
}
$conf;
}
1;
lib/App/Conf/File.pod view on Meta::CPAN
$config = App::Conf->new();
$config = App::Conf->new(configFile => $file);
print $config->dump(), "\n"; # use Data::Dumper to spit out the Perl representation
# accessors
$property_value = $config->get($property_name);
$branch = $config->get_branch($branch_name); # get hashref of properties
# on-demand loading helper methods (private methods)
$config->overlay($config2); # merge the two config structures using overlay rules
$config->overlay($config1, $config2); # merge $config2 onto $config1
$config->graft($branch_name, $config2); # graft new config structure onto branch
# By convention, the configurations for each App-Context service will be located
# two levels under the hash ref as shown.
$config->{Conf} # config settings for all Conf services
$config->{Conf}{default} # config settings for the default Conf service
$config->{Security} # config settings for all Security services
$config->{Security}{default} # config settings for the default Security service
$config->{Template}{tt} # config settings for the Template service named "tt"
lib/App/Context.pm view on Meta::CPAN
}
foreach my $conf_file (@include_files) {
$conf_file = "$prefix/etc/app/$conf_file" if ($conf_file !~ m!^/!);
if ($self->{conf_included}{$conf_file}) {
print STDERR "Conf global include: [$cond][$conf_file] already included\n" if ($options{debug_conf});
next;
}
if (-r $conf_file) {
$options{conf_file} = $conf_file;
my $aux_conf = $conf_class->create({ %options });
$conf->overlay($aux_conf);
print STDERR "Conf global include: [$cond][$conf_file] included (overlayed)\n" if ($options{debug_conf});
}
else {
print STDERR "Conf global include: [$cond][$conf_file] not readable\n" if ($options{debug_conf});
}
$self->{conf_included}{$conf_file} = 1;
}
}
print STDERR "Conf global include: [$cond] did not match options\n" if (!$matches && $options{debug_conf});
}
}
lib/App/Context.pm view on Meta::CPAN
##############################################################
# Load extra conf on demand
##############################################################
if (!$service_initialized && !$service_conf && $name !~ /-/) { # if it's not a contained widget, try the file system
my $prefix = $options->{prefix};
my $conf_type = $options->{conf_type} || "pl";
my $conf_file = "$prefix/etc/app/$type.$name.$conf_type";
if (!$self->{conf_included}{$conf_file} && -r $conf_file) {
$options->{conf_file} = $conf_file;
my $aux_conf = App::Conf::File->create({ %$options });
$conf->overlay($aux_conf);
$service_conf = $conf->{$type}{$name};
}
$self->{conf_included}{$conf_file} = 1;
}
##############################################################
# conf includes
##############################################################
if (!$service_initialized && $service_conf && $service_conf->{include}) {
my $prefix = $options->{prefix};
lib/App/Context.pm view on Meta::CPAN
}
elsif (ref($include_files) eq "") {
@include_files = ( $include_files );
}
foreach my $conf_file (@include_files) {
$conf_file = "$prefix/etc/app/$conf_file" if ($conf_file !~ m!^/!);
next if ($self->{conf_included}{$conf_file});
if (-r $conf_file) {
$options->{conf_file} = $conf_file;
my $aux_conf = App::Conf::File->create({ %$options });
$conf->overlay($aux_conf);
}
$self->{conf_included}{$conf_file} = 1;
}
}
##############################################################
# Detect Deprecated Services
##############################################################
if (!$service_initialized && $service_conf) {
if ($service_conf->{deprecated}) {
lib/App/Context.pm view on Meta::CPAN
################################################################
if ($service_store) {
foreach $attrib (keys %$service_store) {
if (!defined $service->{$attrib}) {
$service->{$attrib} = $service_store->{$attrib};
}
}
}
################################################################
# overlay with attributes from the conf file
################################################################
if ($service_conf) {
foreach $attrib (keys %$service_conf) {
# include conf attributes only if not set already
if (!defined $service->{$attrib}) {
$service->{$attrib} = $service_conf->{$attrib};
}
}
}
################################################################
# overlay with attributes from the "service_type"
################################################################
$service_type = $service->{type}; # i.e. "session_object_type"
if ($service_type) {
$service_type_conf = $conf->{"${type}Type"}{$service_type};
if ($service_type_conf) {
foreach $attrib (keys %$service_type_conf) {
# include service_type confs only if not set already
if (!defined $service->{$attrib}) {
$service->{$attrib} = $service_type_conf->{$attrib};
}
lib/App/Reference.pm view on Meta::CPAN
$ref = App::Reference->new();
$ref = App::Reference->new("file" => $file);
print $ref->dump(), "\n"; # use Data::Dumper to spit out the Perl representation
# accessors
$property_value = $ref->get($property_name);
$branch = $ref->get_branch($branch_name,$create_flag); # get hashref
$ref->set($property_name, $property_value);
# on-demand loading helper methods (private methods)
$ref->overlay($ref2); # merge the two structures using overlay rules
$ref->overlay($ref1, $ref2); # merge $ref2 onto $ref1
$ref->graft($branch_name, $ref2); # graft new structure onto branch
=head1 DESCRIPTION
App::Reference is a very thin class which wraps a few simple
methods around a perl reference which may contain a multi-level data
structure.
=cut
lib/App/Reference.pm view on Meta::CPAN
if (ref($branch) eq "ARRAY") {
$branch->[$attrib] = $property_value;
}
else {
$branch->{$attrib} = $property_value;
}
}
#############################################################################
# overlay()
#############################################################################
=head2 overlay()
* Signature: $ref->overlay($ref2);
* Signature: $ref->overlay($ref1, $ref2);
* Param: $ref1 {}
* Param: $ref2 {}
* Return: void
* Throws: App::Exception
* Since: 0.01
Sample Usage:
# merge the two config structures using overlay rules
$ref->overlay($ref2);
# merge $ref2 onto $ref1
$ref->overlay($ref1, $ref2);
NOTE: right now, this just copies top-level keys of a hash reference
from one hash to the other.
TODO: needs to nested/recursive overlaying
=cut
sub overlay {
&App::sub_entry if ($App::trace);
my ($self, $ref1, $ref2) = @_;
if (!defined $ref2) {
$ref2 = $ref1;
$ref1 = $self;
}
my $ref1type = ref($ref1);
my $ref2type = ref($ref2);
if ($ref1type eq "" || $ref2type eq "") {
# scalar: nothing to do
lib/App/Reference.pm view on Meta::CPAN
else { # assume they are both hashes
foreach my $key (keys %$ref2) {
if (!exists $ref1->{$key}) {
$ref1->{$key} = $ref2->{$key};
}
else {
$ref1type = ref($ref1->{$key});
if ($ref1type && $ref1type ne "ARRAY") {
$ref2type = ref($ref2->{$key});
if ($ref2type && $ref2type ne "ARRAY") {
$self->overlay($ref1->{$key}, $ref2->{$key});
}
}
}
}
}
&App::sub_exit() if ($App::trace);
}
#############################################################################
# graft()
t/Reference.t view on Meta::CPAN
label => "hello",
},
bar => {
class => "App::Widget::Label",
label => "world",
columns => ["global","destruction"],
},
},
};
$ref->overlay($ref1, $ref2);
is($ref1->{SessionObject}{foo}{class}, "App::Widget::Label", "overlay(): foo.class not overwritten");
is($ref1->{SessionObject}{foo}{label}, "hello", "overlay(): foo.label set");
is($ref1->{SessionObject}{bar}{class}, "App::Widget::Label", "overlay(): bar.class set");
is($ref1->{SessionObject}{bar}{label}, "world", "overlay(): bar.label set");
ok($ref1->{SessionObject}{foo} ne $ref2->{SessionObject}{foo}, "overlay(): foo was not a deep link from ref1 to ref2");
ok($ref1->{SessionObject}{bar} eq $ref2->{SessionObject}{bar}, "overlay(): bar was a deep link from ref1 to ref2");
ok($ref1->{SessionObject}{bar}{columns} eq $ref2->{SessionObject}{bar}{columns}, "overlay(): bar.columns was a deep link from ref1 to ref2");
exit 0;