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 |
