File Coverage

lib/XML/Schema/Scheduler.pm
Criterion Covered Total %
statement 60 62 96.7
branch 22 36 61.1
condition 2 2 100.0
subroutine 9 9 100.0
pod 1 1 100.0
total 94 110 85.4


line stmt bran cond sub pod time code
1             #============================================================= -*-perl-*-
2             #
3             # XML::Schema::Scheduler.pm
4             #
5             # DESCRIPTION
6             # Module implementing an object class for scheduling actions around
7             # an XML Schema.
8             #
9             # AUTHOR
10             # Andy Wardley
11             #
12             # COPYRIGHT
13             # Copyright (C) 2001 Canon Research Centre Europe Ltd.
14             # All Rights Reserved.
15             #
16             # This module is free software; you can redistribute it and/or
17             # modify it under the same terms as Perl itself.
18             #
19             # REVISION
20             # $Id: Scheduler.pm,v 1.1.1.1 2001/08/29 14:30:17 abw Exp $
21             #
22             #========================================================================
23              
24             package XML::Schema::Scheduler;
25              
26 28     28   148 use strict;
  28         44  
  28         1159  
27 28     28   152 use base qw( XML::Schema::Base );
  28         47  
  28         2302  
28 28     28   144 use vars qw( $VERSION $DEBUG $ERROR @SCHEDULES );
  28         51  
  28         11981  
29              
30             $VERSION = sprintf("%d.%02d", q$Revision: 1.1.1.1 $ =~ /(\d+)\.(\d+)/);
31             $DEBUG = 0 unless defined $DEBUG;
32             $ERROR = '';
33              
34             # default schedule lists (can be overridden in a subclass)
35             @SCHEDULES = qw( before after );
36              
37              
38             #use constant TAIL => 0;
39             #use constant HEAD => 1;
40              
41             #------------------------------------------------------------------------
42             # init()
43             #------------------------------------------------------------------------
44              
45             *init_scheduler = \&init;
46              
47             sub init {
48 332     332 1 477 my ($self, $config) = @_;
49 332         416 my ($s, $value, $schedule);
50 332         505 my $class = ref $self;
51              
52 332         335 my ($schedules) = @{ $self->_baseargs( { first => 1 },
  332         1193  
53             qw( @SCHEDULES ) ) };
54              
55 332         877 local $" = ', ';
56 332 50       731 $self->DEBUG("Schedule lists for $class: [ @$schedules ]\n")
57             if $DEBUG;
58              
59 332         500 foreach $s (@$schedules) {
60 28     28   1626 no strict 'refs';
  28         63  
  28         6185  
61 502         484 ($schedule) = @{ $self->_baseargs("\@SCHEDULE_$s") };
  502         1654  
62              
63 502 100       1924 push(@$schedule, UNIVERSAL::isa($value, 'ARRAY') ? @$value : $value)
    100          
64             if defined ($value = $config->{"schedule_$s"});
65              
66 502         1711 $self->{"_SCHEDULE_$s"} = $schedule;
67 502 50       1278 $self->DEBUG("_SCHEDULE_$s => [ @$schedule ]\n")
68             if $DEBUG;
69             }
70 332         1737 $self->_schedule_method_factory(@$schedules);
71              
72 332         2579 return $self;
73             }
74              
75             #------------------------------------------------------------------------
76             # _schedule_method_factory(@methods)
77             #
78             # Iterates $m through each of the method names passed as arguments and
79             # installs two closures as the methods "schedule_$m" and "activate_$m"
80             # in the subclass package. If the "schedule_$m" method is already
81             # defined then it skips this step (assumes that "activate_$m" is also
82             # defined but doesn't actually check). These methods can then be used
83             # to schedule actions and subsequently activate them for each of the
84             # schedule lists defined for a subclass object.
85             #------------------------------------------------------------------------
86              
87             sub _schedule_method_factory {
88 332     332   844 my ($self, @methods) = @_;
89 332         555 my $class = ref $self;
90 332         590 foreach my $m (@methods) {
91 28     28   147 no strict 'refs';
  28         84  
  28         17850  
92 502 100       533 if (defined &{$class . "::schedule_$m"}) {
  502         2536  
93 320 50       1013 $self->DEBUG("schedule_$m method already defined in $class, skipping\n")
94             if $DEBUG;
95             }
96             else {
97 182 50       493 $self->DEBUG("creating schedule/action methods in $class\n")
98             if $DEBUG;
99 182         1663 *{$class . "::schedule_$m"} = sub {
100 6     6   31 my ($self, $action, $at_head) = @_;
101 6   100     28 $at_head ||= 0;
102 6 50       14 $self->DEBUG("schedule_$m($action, $at_head)\n")
103             if $DEBUG;
104 6 100       13 if ($at_head) {
105 1         1 unshift(@{ $self->{"_SCHEDULE_$m"} }, $action);
  1         5  
106             }
107             else {
108 5         9 push(@{ $self->{"_SCHEDULE_$m"} }, $action);
  5         29  
109             }
110 182         1236 };
111 182         1651 *{$class . "::activate_$m"} = sub {
112 425     425   581 my ($self, $infoset) = @_;
113 425 100       1406 $infoset = { result => $infoset } unless UNIVERSAL::isa($infoset, 'HASH');
114 425         452 foreach my $action (@{ $self->{"_SCHEDULE_$m"} }) {
  425         1135  
115             # TODO: check return value for ERROR/STOP/EXPLODE/etc
116 27 100       104 if (ref $action eq 'CODE') {
    50          
117 26 50       46 $self->DEBUG("calling $action($self, $infoset)\n")
118             if $DEBUG;
119 26 50       64 return unless defined &$action($self, $infoset);
120             }
121             elsif (ref $action eq 'ARRAY') {
122 1         4 my ($object, $method, @args) = @$action;
123 1 50       3 $self->DEBUG("calling $object->$method($self, $infoset, @args)\n")
124             if $DEBUG;
125 1 50       5 return unless defined $object->$method($self, $infoset, @args);
126             }
127             else {
128 0 0       0 $self->DEBUG("calling $self->$action($infoset)\n")
129             if $DEBUG;
130 0 0       0 return unless defined $self->$action($infoset);
131             }
132             }
133 425         3191 return $infoset;
134 182         1948 };
135             }
136             }
137             }
138              
139              
140              
141            
142              
143             1;
144              
145             __END__