#============================================================= -*-perl-*- # # XML::Schema::Type::Provider # # DESCRIPTION # Module implementing a mixin object class for providing type # management facilities within a particular scope. # # AUTHOR # Andy Wardley # # COPYRIGHT # Copyright (C) 2001 Canon Research Centre Europe Ltd. # All Rights Reserved. # # This module is free software; you can redistribute it and/or # modify it under the same terms as Perl itself. # # REVISION # $Id: Provider.pm,v 1.1.1.1 2001/08/29 14:30:17 abw Exp $ # #======================================================================== package XML::Schema::Type::Provider; use strict; use XML::Schema; use base qw( XML::Schema::Base ); use vars qw( $VERSION $DEBUG $ERROR @OPTIONAL ); $VERSION = sprintf("%d.%02d", q$Revision: 1.1.1.1 $ =~ /(\d+)\.(\d+)/); $DEBUG = 0 unless defined $DEBUG; $ERROR = ''; @OPTIONAL = qw( parent ); #------------------------------------------------------------------------ # init_types(\%config) # # Initialiser method called by base class new() constructor method. #------------------------------------------------------------------------ sub init_types { my ($self, $config) = @_; my $types; $self->{ _FACTORY } = $config->{ FACTORY } || $XML::Schema::FACTORY; $self->{ _TYPES } = { }; return $self; } #------------------------------------------------------------------------ # types() # # Return reference to hash array of internal type definitions. #------------------------------------------------------------------------ sub types { my $self = shift; return $self->{ _TYPES }; } #------------------------------------------------------------------------ # type($name) # type($name, $type_obj) # # Direct way to fetch/store types against names. #------------------------------------------------------------------------ sub type { my $self = shift; my $name = shift; my ($type, $scope, $factory, $simple, $class); return ($self->{ _TYPES }->{ $name } = shift) if @_; return $type if ($type = $self->{ _TYPES }->{ $name }); # delegate to any defined 'scope' if type not found if ($scope = $self->{ scope }) { $self->TRACE("delegating $name to $scope") if $DEBUG; return $scope->type($name) || $self->error($scope->error()); } # otherwise look for it as a builtin simple type $factory = $self->{ _FACTORY } || return $self->error("no factory defined"); $simple = $factory->module('simple') || return $self->error($factory->error()); if ($class = $simple->builtin($name)) { return $class->new() || $self->error($class->error()); } else { return $self->error("no such type: $name"); } } #------------------------------------------------------------------------ # simpleType(\%type_options) # # Method for creating a simpleType object and adding it to the internal # type definition facility. #------------------------------------------------------------------------ sub simpleType { my $self = shift; my $factory = $self->{ _FACTORY }; my ($name, $args, $type); if (ref $_[0]) { # hash array or simple type object $args = shift; } elsif (scalar @_ == 1) { # name requesting specific type $name = shift; return $self->type($name); } else { $args = { @_ }; } if ($factory->isa( simple => $args )) { $type = $args; } else { $type = $factory->create( simple => $args ) || return $self->error( $factory->error() ); } defined ($name = $type->name()) || return $self->error('no name specified for simpleType'); $self->TRACE("name => ", $type->ID) if $DEBUG; return $self->type($name => $type); } #------------------------------------------------------------------------ # complexType(\%type_options) # # Method for creating a complexType object and adding it to the internal # type definition facility. #------------------------------------------------------------------------ sub complexType { my $self = shift; my $factory = $self->{ _FACTORY }; my ($name, $args, $type); if (ref $_[0]) { # hash array or complex type object $args = shift; } elsif (scalar @_ == 1) { # name requesting specific type $name = shift; return $self->type->{ $name }; } else { $args = { @_ }; } if ($factory->isa( complex => $args )) { $type = $args; # define scope of complex type unless already set $type->scope($self) unless defined $type->scope(); } else { # define scope of complex type unless already set $args->{ scope } = $self if UNIVERSAL::isa($args, 'HASH') && ! exists $args->{ scope }; $type = $factory->create( complex => $args ) || return $self->error( $factory->error() ); } defined ($name = $type->name()) || return $self->error('no name specified for complexType'); $self->TRACE("name => ", $type->ID) if $DEBUG; return $self->type($name => $type); } 1;