| 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__ |