Mercurial > pub > Impl
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 |