File Coverage

lib/XML/Schema/Scoped.pm
Criterion Covered Total %
statement 39 39 100.0
branch 17 26 65.3
condition 10 18 55.5
subroutine 8 8 100.0
pod 1 4 25.0
total 75 95 78.9


line stmt bran cond sub pod time code
1             #============================================================= -*-perl-*-
2             #
3             # XML::Schema::Scoped
4             #
5             # DESCRIPTION
6             # Module implementing a mixin/base class for providing type
7             # management facilities by delegation to an enclosing scope.
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: Scoped.pm,v 1.1.1.1 2001/08/29 14:30:17 abw Exp $
21             #
22             #========================================================================
23              
24             package XML::Schema::Scoped;
25              
26 28     28   163 use strict;
  28         52  
  28         844  
27 28     28   151 use XML::Schema;
  28         49  
  28         744  
28 28     28   137 use base qw( XML::Schema::Base );
  28         51  
  28         19350  
29 28     28   168 use vars qw( $VERSION $DEBUG $ERROR @MANDATORY @OPTIONAL );
  28         47  
  28         17301  
30              
31             $VERSION = sprintf("%d.%02d", q$Revision: 1.1.1.1 $ =~ /(\d+)\.(\d+)/);
32             $DEBUG = 0 unless defined $DEBUG;
33             $ERROR = '';
34              
35             @MANDATORY = qw( type );
36             @OPTIONAL = qw( scope );
37              
38              
39             #------------------------------------------------------------------------
40             # init(\%config)
41             #
42             # Initialiser method called by base class new() constructor method.
43             #------------------------------------------------------------------------
44              
45             sub init {
46 103     103 1 141 my ($self, $config) = @_;
47              
48 103         450 my ($mand, $option)
49 103         115 = @{ $self->_baseargs( qw( @MANDATORY %OPTIONAL ) ) };
50              
51 103 50 100     530 $self->_mandatory($mand, $config)
52             || return if @$mand;
53              
54 98 50       330 $self->_optional($option, $config)
55             || return;
56              
57             $self->{ _FACTORY } = $config->{ FACTORY }
58 98   33     375 || $XML::Schema::FACTORY;
59              
60 98         449 return $self;
61             }
62              
63              
64             #------------------------------------------------------------------------
65             # type($name)
66             #
67             # Return current type object, querying current scope to retrieve
68             # object against a name if necessary. This effectively implements
69             # lazy evaluation of type names. In other words, it allows an element
70             # to specify that it uses type 'fooType' before that type is defined.
71             # The type() method provides the automatic resolution of type names to
72             # type objects by querying the scope object, i.e. the containing schema
73             # or complexType in which the 'fooType' should be defined.
74             #------------------------------------------------------------------------
75              
76             sub type {
77 124     124 0 168 my ($self, $name) = @_;
78 124 50       690 $name = $self->{ type } unless defined $name;
79              
80 124 50       253 $self->TRACE("name => ", $name) if $DEBUG;
81              
82 124 50       214 return $self->error('no type name specified')
83             unless defined $name;
84              
85             # type may already be a type object
86 124 100       284 return $name if ref $name;
87              
88             # delegate to any defined 'scope' if type not found
89 103 100       240 if (my $scope = $self->{ scope }) {
90 94 50       157 $self->TRACE("delegating $name to $scope\n") if $DEBUG;
91              
92 94   66     249 return $scope->type($name)
93             || $self->error($scope->error());
94             }
95              
96             # otherwise look for it as a builtin simple type
97             my $factory = $self->{ _FACTORY }
98 9   50     25 || return $self->error("no factory defined");
99              
100 9   50     37 my $simple = $factory->module('simple')
101             || return $self->error($factory->error());
102            
103 9 100       48 if (my $class = $simple->builtin($name)) {
104 8   33     32 return $class->new()
105             || $self->error($class->error());
106             }
107             else {
108 1         4 return $self->error("no such type: $name");
109             }
110              
111             # otherwise query scope
112             # my $scope = $self->{ scope }
113             # || return $self->error("no type definition scope defined");
114              
115             # return $scope->type($name)
116             # || $self->error($scope->error());
117             }
118              
119              
120             #------------------------------------------------------------------------
121             # typename($name)
122             #
123             # Return name of current type object. If the type is already an object
124             # reference then its name() method is called, otherwise the type name
125             # is returned intact.
126             #------------------------------------------------------------------------
127              
128             sub typename {
129 10     10 0 21 my ($self, $name) = @_;
130 10 50       41 $name = $self->{ type } unless defined $name;
131              
132 10 50       35 return $self->error('no type specified')
133             unless defined $name;
134              
135             # type may be an object ref
136 10 100 66     48 $name = $name->name() if ref $name && UNIVERSAL::can($name, 'name');
137              
138 10         42 return $name;
139             }
140              
141              
142             #------------------------------------------------------------------------
143             # scope($newscope)
144             #
145             # Accessor method to retrieve the current scope object (when called
146             # without arguments) or to define a new scope object. The scope should
147             # be a reference to an object derived from the XML::Schema::Scope base
148             # class, ensuring it implements the facility to store and retrieve
149             # type objects (definitions) against names.
150             #------------------------------------------------------------------------
151              
152             sub scope {
153 3     3 0 5 my $self = shift;
154 3 50       27 return @_ ? ($self->{ scope } = shift) : $self->{ scope };
155             }
156              
157              
158             1;
159              
160             __END__