File Coverage

lib/XML/Schema/Scope.pm
Criterion Covered Total %
statement 74 86 86.0
branch 35 56 62.5
condition 17 31 54.8
subroutine 10 11 90.9
pod 1 7 14.2
total 137 191 71.7


line stmt bran cond sub pod time code
1             #============================================================= -*-perl-*-
2             #
3             # XML::Schema::Scope
4             #
5             # DESCRIPTION
6             # Module implementing a mixin object class for providing type
7             # management within a particular 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: Scope.pm,v 1.2 2001/12/20 13:26:27 abw Exp $
21             #
22             #========================================================================
23              
24             package XML::Schema::Scope;
25              
26 28     28   136 use strict;
  28         44  
  28         1100  
27 28     28   164 use XML::Schema;
  28         55  
  28         591  
28 28     28   236 use base qw( XML::Schema::Base );
  28         45  
  28         2340  
29 28     28   170 use vars qw( $VERSION $DEBUG $ERROR @OPTIONAL );
  28         177  
  28         57166  
30              
31             $VERSION = sprintf("%d.%02d", q$Revision: 1.2 $ =~ /(\d+)\.(\d+)/);
32             $DEBUG = 0 unless defined $DEBUG;
33             $ERROR = '';
34              
35             @OPTIONAL = qw( scope );
36              
37              
38             #------------------------------------------------------------------------
39             # init(\%config)
40             #
41             # Initialiser method called by base class new() constructor method.
42             #------------------------------------------------------------------------
43              
44             sub init {
45 90     90 1 153 my ($self, $config) = @_;
46              
47 90 100       420 $self->init_mandopt($config)
48             || return;
49              
50 88   33     417 $self->{ _FACTORY } ||= $XML::Schema::FACTORY;
51              
52             # need to think about instantiating objects for types?
53 88   50     506 $self->{ _TYPES } = $config->{ types } || { };
54              
55             # ditto for attribute_groups?
56 88         236 $self->{ _ATTRIBUTE_GROUPS } = { };
57              
58 88         412 return $self;
59             }
60              
61              
62              
63             #========================================================================
64             # Type management methods
65             #
66             # * type($name)
67             # type($type_obj)
68             #
69             # * types()
70             #
71             # * simpleType(\%type_options)
72             #
73             # * complexType(\%type_options)
74             #
75             #========================================================================
76              
77             #------------------------------------------------------------------------
78             # type($name)
79             # type($name, $type_obj)
80             #
81             # Direct way to fetch/store types against names.
82             #------------------------------------------------------------------------
83              
84             sub type {
85 147     147 0 191 my $self = shift;
86 147         149 my $name = shift;
87 147         154 my ($type, $scope, $factory, $simple, $class);
88              
89 147 100       362 return ($self->{ _TYPES }->{ $name } = shift)
90             if @_;
91              
92             return $type
93 132 100       344 if ($type = $self->{ _TYPES }->{ $name });
94              
95             # delegate to any defined 'scope' if type not found
96 125 100       240 if ($scope = $self->{ scope }) {
97 34 50       60 $self->TRACE("delegating $name to $scope") if $DEBUG;
98 34   66     75 return $scope->type($name)
99             || $self->error($scope->error());
100             }
101              
102             # otherwise look for it as a builtin simple type
103             $factory = $self->{ _FACTORY }
104 91   50     180 || return $self->error("no factory defined");
105              
106 91   50     236 $simple = $factory->module('simple')
107             || return $self->error($factory->error());
108            
109 91 100       274 if ($class = $simple->builtin($name)) {
110 89   33     254 return $class->new()
111             || $self->error($class->error());
112             }
113             else {
114 2         12 return $self->error("no such type: $name");
115             }
116             }
117              
118              
119             #------------------------------------------------------------------------
120             # types()
121             #
122             # Return reference to hash array of internal type definitions.
123             #------------------------------------------------------------------------
124              
125             sub types {
126 0     0 0 0 my $self = shift;
127 0         0 return $self->{ _TYPES };
128             }
129              
130              
131             #------------------------------------------------------------------------
132             # simpleType(\%type_options)
133             #
134             # Method for creating a simpleType object and adding it to the internal
135             # type definition facility.
136             #------------------------------------------------------------------------
137              
138             sub simpleType {
139 13     13 0 38 my $self = shift;
140 13         29 my $factory = $self->{ _FACTORY };
141 13         17 my ($name, $args, $type);
142              
143 13 50       64 if (ref $_[0]) {
    100          
144             # hash array or simple type object
145 0         0 $args = shift;
146             }
147             elsif (scalar @_ == 1) {
148             # name requesting specific type
149 4         9 $name = shift;
150 4         11 return $self->type($name);
151             }
152             else {
153 9         38 $args = { @_ };
154             }
155              
156 9 50       53 if ($factory->isa( simple => $args )) {
157 0         0 $type = $args;
158             }
159             else {
160 9   100     36 $type = $factory->create( simple => $args )
161             || return $self->error( $factory->error() );
162             }
163 8 50       89 defined ($name = $type->name())
164             || return $self->error('no name specified for simpleType');
165              
166 8 50       50 $self->TRACE("name => ", $type->ID) if $DEBUG;
167              
168 8         40 return $self->type($name => $type);
169             }
170              
171              
172             #------------------------------------------------------------------------
173             # complexType(\%type_options)
174             #
175             # Method for creating a complexType object and adding it to the internal
176             # type definition facility.
177             #------------------------------------------------------------------------
178              
179             sub complexType {
180 5     5 0 16 my $self = shift;
181 5         19 my $factory = $self->{ _FACTORY };
182 5         7 my ($name, $args, $type);
183              
184 5 50       22 if (ref $_[0]) {
    50          
185             # hash array or complex type object
186 0         0 $args = shift;
187             }
188             elsif (scalar @_ == 1) {
189             # name requesting specific type
190 0         0 $name = shift;
191 0         0 return $self->type->{ $name };
192             }
193             else {
194 5         26 $args = { @_ };
195             }
196              
197 5 50       29 if ($factory->isa( complex => $args )) {
198 0         0 $type = $args;
199             # define scope of complex type unless already set
200 0 0       0 $type->scope($self)
201             unless defined $type->scope();
202              
203             }
204             else {
205             # define scope of complex type unless already set
206             $args->{ scope } = $self
207             if UNIVERSAL::isa($args, 'HASH')
208 5 50 33     43 && ! exists $args->{ scope };
209              
210 5   50     27 $type = $factory->create( complex => $args )
211             || return $self->error( $factory->error() );
212             }
213 5 50       43 defined ($name = $type->name())
214             || return $self->error('no name specified for complexType');
215              
216 5 50       19 $self->TRACE("name => ", $type->ID) if $DEBUG;
217              
218 5         28 return $self->type($name => $type);
219              
220             }
221              
222              
223              
224             #========================================================================
225             # Element management methods
226             #========================================================================
227              
228             sub element {
229 3     3 0 6 my $self = shift;
230             my $factory = $self->{ _FACTORY }
231 3   50     8 || return $self->error("no factory defined");
232              
233 3 50       8 if (@_) {
234 3 50       21 if ($factory->isa( element => $_[0] )) {
235 0 0       0 $self->TRACE("returning element") if $DEBUG;
236 0         0 return shift;
237             }
238             else {
239 3 50       23 my $args = UNIVERSAL::isa($_[0], 'HASH') ? shift : { @_ };
240 3 50       13 $args->{ scope } = $self unless exists $args->{ scope };
241 3 50       6 $self->TRACE("creating element") if $DEBUG;
242 3   33     13 return $factory->create( element => $args )
243             || $self->error($factory->error());
244             }
245             }
246             else {
247 0         0 return $self->error("no element arguments");
248             }
249             }
250              
251              
252             #========================================================================
253             # Attribute Group management methods
254             #========================================================================
255              
256              
257             #------------------------------------------------------------------------
258             # attribute_group()
259             # attribute_group($new_group)
260             #------------------------------------------------------------------------
261              
262             sub attribute_group {
263 37     37 0 100 my ($self, $group) = @_;
264 37         120 my $name;
265              
266             # return entire hash if called with no arguments
267             return $self->{ _ATTRIBUTE_GROUPS }
268 37 100       82 unless defined $group;
269              
270             # create and register new attribute group if group is a reference to
271             # a group object or hash of configuration options for an attribute
272             # group, otherwise...
273              
274 36 100       74 if (ref $group) {
275 10         38 my $factory = $self->factory();
276              
277             # coerce into attribute group object, if not already so
278 10 100 100     197 $group = $factory->create( attribute_group => $group )
279             || return $self->error( $factory->error() )
280             unless $factory->isa( attribute_group => $group );
281            
282             # by what name should we reference this group?
283 9         34 $name = $group->name();
284              
285 9 50       25 return $self->error("no name specified for attribute group")
286             unless defined $name;
287              
288             # install it
289 9         25 $self->{ _ATTRIBUTE_GROUPS }->{ $name } = $group;
290             }
291             else {
292 26         26 $name = $group;
293 26   100     82 $group = $self->{ _ATTRIBUTE_GROUPS }->{ $name }
294             || return $self->error("no such attribute group: $name");
295             }
296              
297 34         108 return $group;
298             }
299              
300              
301              
302             1;
303              
304             __END__