PageRenderTime 35ms CodeModel.GetById 7ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/Apache/Voodoo/Loader/Dynamic.pm

http://github.com/maverick/ApacheVoodoo
Perl | 157 lines | 94 code | 37 blank | 26 comment | 11 complexity | 9941e137ce34c7d0bc1c19ddb3a002c4 MD5 | raw file
Possible License(s): LGPL-2.0
  1. package Apache::Voodoo::Loader::Dynamic;
  2. $VERSION = "3.0206";
  3. use strict;
  4. use warnings;
  5. use base("Apache::Voodoo::Loader");
  6. sub new {
  7. my $class = shift;
  8. my $self = {};
  9. bless $self,$class;
  10. $self->{'module'} = shift;
  11. $self->{'bootstrapping'} = 1;
  12. $self->refresh;
  13. $self->{'bootstrapping'} = 0;
  14. $self->{'parents'} = {};
  15. foreach (eval '@{'.$self->{'module'}.'::ISA}') {
  16. $self->{'parents'}->{$_} = $self->get_mtime($_);
  17. }
  18. return $self;
  19. }
  20. sub init {
  21. my $self = shift;
  22. $self->{'config'} = \@_;
  23. $self->{'object'}->init(@_);
  24. }
  25. sub get_mtime {
  26. my $self = shift;
  27. my $file = shift || $self->{'module'};
  28. $file =~ s/::/\//go;
  29. $file .= ".pm";
  30. return 0 unless defined($INC{$file});
  31. my $mtime = (stat($INC{$file}))[9];
  32. return $mtime;
  33. }
  34. sub refresh {
  35. my $self = shift;
  36. $self->{'object'} = $self->load_module;
  37. $self->{'mtime'} = $self->get_mtime;
  38. }
  39. #
  40. # Override the built in 'can' to trigger dynamic reloading of the module as needed
  41. #
  42. sub can {
  43. my $self = shift;
  44. my $method = shift;
  45. # find out if this thing has changed
  46. if ($self->{'mtime'} != $self->get_mtime) {
  47. warn "Reloading $self->{module}\n";
  48. $self->refresh;
  49. $self->{'object'}->init(@{$self->{'config'}});
  50. }
  51. if ($self->{'object'}->isa("Apache::Voodoo::Zombie") || $self->{'object'}->can($method)) {
  52. # Either we have a dead module and the Zombie will answer to whatever was requested,
  53. # or we have a live one and it has the requested method.
  54. return 1;
  55. }
  56. return 0;
  57. }
  58. #
  59. # In scenarios where the caller doesn't know that can has been overloaded, we'll use
  60. # autoload to catch it and call our overloaded can. We unfortunately end up with two
  61. # different ways to do a very similar task because the constraints are slightly different.
  62. # We want the calls from the A::V::Handler to the controllers to be aware of what methods
  63. # actually exist so it can either call them or not. The controllers talking to the models
  64. # shouldn't have to do anything special or even be aware that they're talking to this
  65. # proxy object, thus the need for a autoload variation.
  66. #
  67. sub AUTOLOAD {
  68. return if our $AUTOLOAD =~ /::DESTROY$/;
  69. return unless ref($_[0]);
  70. my $self = shift;
  71. my $method = $AUTOLOAD;
  72. $method =~ s/.*:://;
  73. if ($self->can($method)) {
  74. return $self->_handle($method,@_);
  75. }
  76. return $self->exception("No such method \"$method\"");
  77. }
  78. sub _handle {
  79. my $self = shift;
  80. my $method = shift;
  81. my @params = @_;
  82. # check parent modules for change
  83. foreach my $module (eval '@{'.$self->{'module'}.'::ISA}') {
  84. my $t = $self->get_mtime($module);
  85. if ($self->{'parents'}->{$module} != $t) {
  86. $self->{'parents'}->{$module} = $t;
  87. my $file = $module;
  88. $file =~ s/::/\//go;
  89. $file .= ".pm";
  90. no warnings 'redefine';
  91. delete $INC{$file};
  92. eval {
  93. no warnings 'redefine';
  94. require $file;
  95. };
  96. if ($@) {
  97. my $error= "There was an error loading one of the base classes for this page ($_):\n\n$@\n";
  98. my $link = $self->{'module'};
  99. $link =~ s/::/\//g;
  100. unless ($method eq "handle") {
  101. $link =~ s/([^\/]+)$/$method."_".$1/e;
  102. }
  103. # FIXME replace with a instance of Apache::Voodoo::Zombie
  104. $self->debug("ZOMBIE: $self->{'module'} $method");
  105. return $self->display_error($error,"/$link");
  106. }
  107. }
  108. }
  109. return $self->{'object'}->$method(@params);
  110. }
  111. 1;
  112. ################################################################################
  113. # Copyright (c) 2005-2010 Steven Edwards (maverick@smurfbane.org).
  114. # All rights reserved.
  115. #
  116. # You may use and distribute Apache::Voodoo under the terms described in the
  117. # LICENSE file include in this package. The summary is it's a legalese version
  118. # of the Artistic License :)
  119. #
  120. ################################################################################