Skip to content

Commit

Permalink
Item14237: Implemented support for application in Foswiki::Object
Browse files Browse the repository at this point in the history
Merged functionality of extensible and AppObject roles.

Implemented create() on Foswiki::Object. So, any object can now create
new instances by calling $this->create().
  • Loading branch information
vrurg committed Oct 29, 2017
1 parent e115305 commit bcb9970
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 65 deletions.
5 changes: 3 additions & 2 deletions core/lib/Foswiki/App.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1031,7 +1031,8 @@ Before actually create an object this method:
=cut

sub create {
around create => sub {
my $orig = shift;
my $this = shift;
my $class = shift;

Expand All @@ -1056,7 +1057,7 @@ sub create {
}

return $object;
}
};

=begin TML
Expand Down
12 changes: 2 additions & 10 deletions core/lib/Foswiki/AppObject.pm
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,7 @@ use Moo::Role;
---+++ ObjectAttribute app
Reference to the parent application object.
Required.
Modifies %PERLDOC{"Foswiki::Object" attr="app"} attribute, makes it required.
=cut

Expand All @@ -43,15 +41,9 @@ has app => (
predicate => 1,
weak_ref => 1,
isa => Foswiki::Object::isaCLASS( 'app', 'Foswiki::App', noUndef => 1, ),
required => 1,
clearer => 1,
handles => [qw(create)],
clearer => 1,
);

sub _clone_app {
return $_[0]->app;
}

1;
__END__
Foswiki - The Free and Open Source Wiki, http://foswiki.org/
Expand Down
85 changes: 83 additions & 2 deletions core/lib/Foswiki/Object.pm
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ require Carp;
require Foswiki::Exception;
use Try::Tiny;
use Scalar::Util qw(blessed refaddr reftype weaken isweak);
use Foswiki qw<indentInc indentMsg>;

use Foswiki::Class;

Expand All @@ -84,10 +85,26 @@ use Assert;

=begin TML
---++ Attributes
---++ ATTRIBUTES
=cut

=begin TML
---+++ ObjectAttribute app
Reference to the parent application object.
=cut

has app => (
is => 'rwp',
predicate => 1,
weak_ref => 1,
isa => Foswiki::Object::isaCLASS( 'app', 'Foswiki::App', ),
clearer => 1,
);

# Debug-only attributes for recording object's origins; i.e. the location in the
# core where it was created. Useful for tracking down the source of problems.
has __orig_file => ( is => 'rw', clearer => 1, );
Expand Down Expand Up @@ -122,7 +139,7 @@ has __clone_heap =>

=begin TML
---++ Methods
---++ METHODS
=cut

Expand Down Expand Up @@ -190,6 +207,30 @@ sub DEMOLISH {
}
}

=begin TML
---+++ ObjectMethod create( $className, @params ) -> $object
Creates a new object of class =$className=. If application object could be
guessed with %PERLDOC{"Foswiki::Object" method="guessApp"}% then its
%PERLDOC{"Foswiki::App" method="create" text="create()"}% method would be used.
Otherwise the =$object= would be created with =$className='s =new()= method.
=cut

sub create {
my $this = shift;

my $app = $this->guessApp;

if ( defined $app ) {
return $app->create(@_);
}

my $class = shift;
return $class->new(@_);
}

sub _cloneData {
my $this = shift;
my ( $val, $attr ) = @_;
Expand Down Expand Up @@ -441,6 +482,42 @@ sub clone {

=begin TML
---+++ ObjectMethod getApp -> $app
Returns application object depending on current object's status:
1 for a %PERLDOC{"Foswiki::App"}% object returns itself
1 if =app= attribute is set then returns its value.
1 otherwise returns undef
=cut

sub getApp {
my $this = shift;
return (
$this->isa('Foswiki::App')
? $this
: ( $this->has_app ? $this->app : undef )
);
}

=begin TML
---+++ ObjectMethod guessApp -> $app
Similar to the =getApp()= method above but tries harder and returns
=$Foswiki::app= when getApp() returns undef. Note that in some cases this
could be _undef_ too.
=cut

sub guessApp {
my $this = shift;
return $this->getApp // $Foswiki::app;
}

=begin TML
---++ ObjectMethod to_str => $string
This method is used to overload stringification operator "" (see
Expand Down Expand Up @@ -670,6 +747,10 @@ sub _traceMsg {
}
}

sub _clone_app {
return $_[0]->app;
}

1;
__END__
Foswiki - The Free and Open Source Wiki, http://foswiki.org/
Expand Down
22 changes: 4 additions & 18 deletions core/lib/Foswiki/Util/Callbacks.pm
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ before DEMOLISH => sub {

# Cleanup all callbacks registed by this object.
unless ($in_global) {
my $app = $this->_getApp;
my $app = $this->guessApp;

# The application object could have been already destroyed at this
# moment. This is normal for auto-destruction.
Expand All @@ -270,20 +270,6 @@ sub _splitCBName {
return ( $1, $2 );
}

# Returns currently active Foswiki::App object.
sub _getApp {
my $this = shift;

return (
$this->isa('Foswiki::App') ? $this
: (
$this->does('Foswiki::AppObject') ? $this->app
: ( $this->does('Foswiki::Util::_ExtensibleRole')
&& $this->_has__appObj ? $this->__appObj : $Foswiki::app )
)
);
}

# Normilizes callback name to it's full form of 'namespace::cbName'. If cbName
# is short (i.e. doesn't contain ::) then namespace if fetched from index. If
# more than one namespace registered a callback with the same name then assert
Expand Down Expand Up @@ -348,7 +334,7 @@ sub registerCallback {
obj => $this->__id,
};

my $app = $this->_getApp;
my $app = $this->guessApp;

ASSERT( defined $app,
"Callback cannot be registered without an active application object" );
Expand Down Expand Up @@ -379,7 +365,7 @@ sub deregisterCallback {
ASSERT( $_registeredCBNames{$name}, "unknown callback '$name'" );

my $objId = $this->__id;
my $appHeap = $this->_getApp->heap;
my $appHeap = $this->guessApp->heap;
my $oldList = $appHeap->{_aux_registered_callbacks}{$name};
my $newList = [];

Expand Down Expand Up @@ -414,7 +400,7 @@ sub callback {
ASSERT( ref($params) eq 'HASH', "callback params must be a hashref" );

my $lastException;
my $cbList = $this->_getApp->heap->{_aux_registered_callbacks}{$name};
my $cbList = $this->guessApp->heap->{_aux_registered_callbacks}{$name};

return unless $cbList;

Expand Down
4 changes: 2 additions & 2 deletions core/lib/Foswiki/Util/Localize.pm
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ use v5.14;

use Foswiki::Util::Holder ();

use Moo::Role;

use Try::Tiny;

use Moo::Role;

# _dataStack is a storage for configurations active upon localize() method
# calls.
has _dataStack => ( is => 'rw', lazy => 1, default => sub { [] }, );
Expand Down
31 changes: 0 additions & 31 deletions core/lib/Foswiki/Util/_ExtensibleRole.pm
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,6 @@ use Moo::Role;

# This role is not to be applied manually but by Foswiki::Class only!

# Though this attribute is seemingly duplicating Foswiki::AppObject app
# attribute but it's purpose to be optional and apply cleanly to classes which
# are not Foswiki::App-dependant.
has __appObj => (
is => 'rw',
lazy => 1,
predicate => 1,
isa => Foswiki::Object::isaCLASS( '__appObj', 'Foswiki::App' ),
weak_ref => 1,
);

around BUILD => sub {
my $orig = shift;
my $this = shift;
my ($params) = @_;

#$this->_traceMsg("Storing app for extensible objet");

if ( defined $params->{app} && $params->{app}->isa('Foswiki::App') ) {
$this->__appObj( $params->{app} );
}

return $orig->( $this, @_ );
};

# Foswiki::Object::clone support.
# Avoid full app cloning.
sub _clone__appObj {
return $_[0]->__appObj;
}

1;
__END__
Foswiki - The Free and Open Source Wiki, http://foswiki.org/
Expand Down

0 comments on commit bcb9970

Please sign in to comment.