comparison Lib/IMPL/DOM/Schema.pm @ 101:d8dc6cad3f55

Schema in progress
author wizard
date Thu, 06 May 2010 17:55:59 +0400
parents df6b4f054957
children cf3b6ef2be22
comparison
equal deleted inserted replaced
100:df6b4f054957 101:d8dc6cad3f55
10 require IMPL::DOM::Schema::AnyNode; 10 require IMPL::DOM::Schema::AnyNode;
11 require IMPL::DOM::Schema::NodeList; 11 require IMPL::DOM::Schema::NodeList;
12 require IMPL::DOM::Schema::NodeSet; 12 require IMPL::DOM::Schema::NodeSet;
13 require IMPL::DOM::Schema::Property; 13 require IMPL::DOM::Schema::Property;
14 require IMPL::DOM::Schema::SwitchNode; 14 require IMPL::DOM::Schema::SwitchNode;
15 require IMPL::DOM::Schema::Validator;
16 require IMPL::DOM::Navigator::Builder;
17 require IMPL::DOM::XMLReader;
15 18
16 use base qw(IMPL::DOM::Document); 19 use base qw(IMPL::DOM::Document);
17 use IMPL::Class::Property; 20 use IMPL::Class::Property;
18 use IMPL::Class::Property::Direct; 21 use IMPL::Class::Property::Direct;
22 use File::Spec;
19 23
20 our %CTOR = ( 24 our %CTOR = (
21 'IMPL::DOM::Document' => sub { nodeName => 'schema' } 25 'IMPL::DOM::Document' => sub { nodeName => 'schema' }
22 ); 26 );
23 27
24 BEGIN { 28 BEGIN {
25 private _direct property _TypesMap => prop_all; 29 private _direct property _TypesMap => prop_all;
30 public _direct property baseDir => prop_all;
26 public _direct property BaseSchemas => prop_get | owner_set; 31 public _direct property BaseSchemas => prop_get | owner_set;
27 private _direct property _Validators => prop_all; 32 private _direct property _Validators => prop_all;
28 } 33 }
29 34
30 sub resolveType { 35 sub resolveType {
34 sub Create { 39 sub Create {
35 my ($this,$nodeName,$class,$refArgs) = @_; 40 my ($this,$nodeName,$class,$refArgs) = @_;
36 41
37 die new IMPL::Exception('Invalid node class') unless $class->isa('IMPL::DOM::Node'); 42 die new IMPL::Exception('Invalid node class') unless $class->isa('IMPL::DOM::Node');
38 43
39 goto &SUPER::Create; 44 if ($class->isa('IMPL::DOM::Schema::Validator')) {
45 $class = "IMPL::DOM::Schema::Validator::$nodeName";
46 local $@;
47 unless (eval {$class->can('new')}) {
48 eval "require $class; 1;";
49 my $e = $@;
50 die new IMPL::Exception("Invalid validator",$class,$e) if $e;
51 }
52 }
53
54 return $this->SUPER::Create($nodeName,$class,$refArgs);
40 } 55 }
41 56
42 sub Process { 57 sub Process {
43 my ($this) = @_; 58 my ($this) = @_;
44 59
60 # process instructions
61 $this->Include($_) foreach map $_->nodeProperty('source'), $this->selectNodes('Include');
62
63 # build types map
45 $this->{$_TypesMap} = { map { $_->type, $_ } $this->selectNodes(sub { $_[0]->nodeName eq 'ComplexType' || $_[0]->nodeName eq 'SimpleType' } ) }; 64 $this->{$_TypesMap} = { map { $_->type, $_ } $this->selectNodes(sub { $_[0]->nodeName eq 'ComplexType' || $_[0]->nodeName eq 'SimpleType' } ) };
65 }
66
67 sub Include {
68 my ($this,$file) = @_;
69
70 my $schema = $this->LoadSchema($file);
71
72 $this->appendRange( $schema->childNodes );
73 }
74
75 sub LoadSchema {
76 my ($this,$file,$base) = @_;
77
78 my $class = ref $this || $this;
79
80 my $reader = new IMPL::DOM::XMLReader(
81 Navigator => new IMPL::DOM::Navigator::Builder(
82 $class,
83 $class->MetaSchema
84 )
85 );
86
87 $reader->ParseFile($file) or die new IMPL::Exception("Failed to load a schema",$file);
88
89 my $schema = $reader->Navigator->Document;
90
91 my ($vol,$dir) = File::Spec->splitpath($file);
92
93 $schema->baseDir($dir);
94
95 my @errors = $class->MetaSchema->Validate($schema);
96
97 die new IMPL::Exception("Schema is invalid",$file,map( $_->Message, @errors ) ) if @errors;
98
99 $schema->Process;
100
101 return $schema;
46 } 102 }
47 103
48 sub Validate { 104 sub Validate {
49 my ($this,$node) = @_; 105 my ($this,$node) = @_;
50 106