Mercurial > pub > Impl
comparison Lib/IMPL/DOM/Schema.pm @ 230:6d8092d8ce1b
*reworked IMPL::Security
*reworked IMPL::Web::Security
*refactoring
| author | sergey |
|---|---|
| date | Mon, 08 Oct 2012 03:37:37 +0400 |
| parents | 4d0e1962161c |
| children | 5c82eec23bb6 |
comparison
equal
deleted
inserted
replaced
| 229:47f77e6409f7 | 230:6d8092d8ce1b |
|---|---|
| 1 package IMPL::DOM::Schema; | 1 package IMPL::DOM::Schema; |
| 2 use strict; | 2 use strict; |
| 3 use warnings; | 3 use warnings; |
| 4 | 4 |
| 5 require IMPL::DOM::Schema::ComplexNode; | 5 use IMPL::require { |
| 6 require IMPL::DOM::Schema::ComplexType; | 6 ComplexNode => 'IMPL::DOM::Schema::ComplexNode', |
| 7 require IMPL::DOM::Schema::SimpleNode; | 7 ComplexType => 'IMPL::DOM::Schema::ComplexType', |
| 8 require IMPL::DOM::Schema::SimpleType; | 8 SimpleNode => 'IMPL::DOM::Schema::SimpleNode', |
| 9 require IMPL::DOM::Schema::Node; | 9 SimpleType => 'IMPL::DOM::Schema::SimpleType', |
| 10 require IMPL::DOM::Schema::AnyNode; | 10 Node => 'IMPL::DOM::Schema::Node', |
| 11 require IMPL::DOM::Schema::NodeList; | 11 AnyNode => 'IMPL::DOM::Schema::AnyNode', |
| 12 require IMPL::DOM::Schema::NodeSet; | 12 NodeList => 'IMPL::DOM::Schema::NodeList', |
| 13 require IMPL::DOM::Schema::Property; | 13 NodeSet => 'IMPL::DOM::Schema::NodeSet', |
| 14 require IMPL::DOM::Schema::SwitchNode; | 14 Property => 'IMPL::DOM::Schema::Property', |
| 15 require IMPL::DOM::Schema::Validator; | 15 SwitchNode => 'IMPL::DOM::Schema::SwitchNode', |
| 16 require IMPL::DOM::Navigator::Builder; | 16 Validator => 'IMPL::DOM::Schema::Validator', |
| 17 require IMPL::DOM::XMLReader; | 17 Builder => 'IMPL::DOM::Navigator::Builder', |
| 18 require IMPL::DOM::Schema::InflateFactory; | 18 XMLReader => 'IMPL::DOM::XMLReader', |
| 19 InflateFactory => 'IMPL::DOM::Schema::InflateFactory', | |
| 20 Loader => 'Code::Loader' | |
| 21 }; | |
| 19 | 22 |
| 20 use parent qw(IMPL::DOM::Document); | 23 use parent qw(IMPL::DOM::Document); |
| 21 use IMPL::Class::Property; | 24 use IMPL::Class::Property; |
| 22 use IMPL::Class::Property::Direct; | 25 use IMPL::Class::Property::Direct; |
| 23 use File::Spec; | 26 use File::Spec; |
| 30 private _direct property _TypesMap => prop_all; | 33 private _direct property _TypesMap => prop_all; |
| 31 public _direct property baseDir => prop_all; | 34 public _direct property baseDir => prop_all; |
| 32 public _direct property BaseSchemas => prop_get | owner_set; | 35 public _direct property BaseSchemas => prop_get | owner_set; |
| 33 } | 36 } |
| 34 | 37 |
| 38 my $validatorLoader = Loader->new(prefix => Validator, verifyNames => 1); | |
| 39 | |
| 35 sub resolveType { | 40 sub resolveType { |
| 36 $_[0]->{$_TypesMap}->{$_[1]}; | 41 $_[0]->{$_TypesMap}->{$_[1]}; |
| 37 } | 42 } |
| 38 | 43 |
| 39 sub CTOR { | 44 sub CTOR { |
| 46 my ($this,$nodeName,$class,$refArgs) = @_; | 51 my ($this,$nodeName,$class,$refArgs) = @_; |
| 47 | 52 |
| 48 die new IMPL::Exception('Invalid node class') unless $class->isa('IMPL::DOM::Node'); | 53 die new IMPL::Exception('Invalid node class') unless $class->isa('IMPL::DOM::Node'); |
| 49 | 54 |
| 50 if ($class->isa('IMPL::DOM::Schema::Validator')) { | 55 if ($class->isa('IMPL::DOM::Schema::Validator')) { |
| 51 $class = "IMPL::DOM::Schema::Validator::$nodeName"; | 56 $class = $validatorLoader->GetFullName($nodeName); |
| 52 unless (eval {$class->can('new')}) { | 57 unless (eval {$class->can('new')}) { |
| 53 eval "require $class; 1;"; | 58 $validatorLoader->Require($nodeName); |
| 54 my $e = $@; | |
| 55 die new IMPL::Exception("Invalid validator",$class,$e) if $e; | 59 die new IMPL::Exception("Invalid validator",$class,$e) if $e; |
| 56 } | 60 } |
| 57 } | 61 } |
| 58 | 62 |
| 59 return $this->SUPER::Create($nodeName,$class,$refArgs); | 63 return $this->SUPER::Create($nodeName,$class,$refArgs); |
| 82 | 86 |
| 83 $file = File::Spec->rel2abs($file); | 87 $file = File::Spec->rel2abs($file); |
| 84 | 88 |
| 85 my $class = ref $this || $this; | 89 my $class = ref $this || $this; |
| 86 | 90 |
| 87 my $reader = new IMPL::DOM::XMLReader( | 91 my $reader = Reader->( |
| 88 Navigator => new IMPL::DOM::Navigator::Builder( | 92 Navigator => Builder->new( |
| 89 $class, | 93 $class, |
| 90 $class->MetaSchema | 94 $class->MetaSchema |
| 91 ), | 95 ), |
| 92 SkipWhitespace => 1 | 96 SkipWhitespace => 1 |
| 93 ); | 97 ); |
| 110 } | 114 } |
| 111 | 115 |
| 112 sub Validate { | 116 sub Validate { |
| 113 my ($this,$node) = @_; | 117 my ($this,$node) = @_; |
| 114 | 118 |
| 115 if ( my ($schemaNode) = $this->selectNodes(sub { $_->isa('IMPL::DOM::Schema::Node') and $_[0]->name eq $node->nodeName })) { | 119 if ( my ($schemaNode) = $this->selectNodes(sub { $_->isa(Node) and $_[0]->name eq $node->nodeName })) { |
| 116 $schemaNode->Validate($node); | 120 $schemaNode->Validate($node); |
| 117 } else { | 121 } else { |
| 118 return new IMPL::DOM::Schema::ValidationError(Node => $node, Message=> "A specified document (%Node.nodeName%) doesn't match the schema"); | 122 return new IMPL::DOM::Schema::ValidationError(Node => $node, Message=> "A specified document (%Node.nodeName%) doesn't match the schema"); |
| 119 } | 123 } |
| 120 } | 124 } |
| 123 | 127 |
| 124 sub MetaSchema { | 128 sub MetaSchema { |
| 125 | 129 |
| 126 return $schema if $schema; | 130 return $schema if $schema; |
| 127 | 131 |
| 128 $schema = new IMPL::DOM::Schema; | 132 $schema = Schema->new(); |
| 129 | 133 |
| 130 $schema->appendRange( | 134 $schema->appendRange( |
| 131 IMPL::DOM::Schema::ComplexNode->new(name => 'schema')->appendRange( | 135 ComplexNode->new(name => 'schema')->appendRange( |
| 132 IMPL::DOM::Schema::NodeSet->new()->appendRange( | 136 NodeSet->new()->appendRange( |
| 133 IMPL::DOM::Schema::Node->new(name => 'ComplexNode', type => 'ComplexNode', minOccur => 0, maxOccur=>'unbounded'), | 137 Node->new(name => 'ComplexNode', type => 'ComplexNode', minOccur => 0, maxOccur=>'unbounded'), |
| 134 IMPL::DOM::Schema::Node->new(name => 'ComplexType', type => 'ComplexType', minOccur => 0, maxOccur=>'unbounded'), | 138 Node->new(name => 'ComplexType', type => 'ComplexType', minOccur => 0, maxOccur=>'unbounded'), |
| 135 IMPL::DOM::Schema::Node->new(name => 'SimpleNode', type => 'SimpleNode', minOccur => 0, maxOccur=>'unbounded'), | 139 Node->new(name => 'SimpleNode', type => 'SimpleNode', minOccur => 0, maxOccur=>'unbounded'), |
| 136 IMPL::DOM::Schema::Node->new(name => 'SimpleType', type => 'SimpleType', minOccur => 0, maxOccur=>'unbounded'), | 140 Node->new(name => 'SimpleType', type => 'SimpleType', minOccur => 0, maxOccur=>'unbounded'), |
| 137 IMPL::DOM::Schema::Node->new(name => 'Node', type => 'Node', minOccur => 0, maxOccur=>'unbounded'), | 141 Node->new(name => 'Node', type => 'Node', minOccur => 0, maxOccur=>'unbounded'), |
| 138 IMPL::DOM::Schema::SimpleNode->new(name => 'Include', minOccur => 0, maxOccur=>'unbounded')->appendRange( | 142 SimpleNode->new(name => 'Include', minOccur => 0, maxOccur=>'unbounded')->appendRange( |
| 139 IMPL::DOM::Schema::Property->new(name => 'source') | 143 Property->new(name => 'source') |
| 140 ) | 144 ) |
| 141 ), | 145 ), |
| 142 ), | 146 ), |
| 143 IMPL::DOM::Schema::ComplexType->new(type => 'NodeSet', nativeType => 'IMPL::DOM::Schema::NodeSet')->appendRange( | 147 ComplexType->new(type => 'NodeSet', nativeType => 'IMPL::DOM::Schema::NodeSet')->appendRange( |
| 144 IMPL::DOM::Schema::NodeSet->new()->appendRange( | 148 NodeSet->new()->appendRange( |
| 145 IMPL::DOM::Schema::Node->new(name => 'ComplexNode', type => 'ComplexNode', minOccur => 0, maxOccur=>'unbounded'), | 149 Node->new(name => 'ComplexNode', type => 'ComplexNode', minOccur => 0, maxOccur=>'unbounded'), |
| 146 IMPL::DOM::Schema::Node->new(name => 'SimpleNode', type => 'SimpleNode', minOccur => 0, maxOccur=>'unbounded'), | 150 Node->new(name => 'SimpleNode', type => 'SimpleNode', minOccur => 0, maxOccur=>'unbounded'), |
| 147 IMPL::DOM::Schema::Node->new(name => 'Node', type=>'Node', minOccur => 0, maxOccur=>'unbounded'), | 151 Node->new(name => 'Node', type=>'Node', minOccur => 0, maxOccur=>'unbounded'), |
| 148 IMPL::DOM::Schema::SwitchNode->new(minOccur => 0, maxOccur => 1)->appendRange( | 152 SwitchNode->new(minOccur => 0, maxOccur => 1)->appendRange( |
| 149 IMPL::DOM::Schema::Node->new(name => 'AnyNode', type => 'AnyNode'), | 153 Node->new(name => 'AnyNode', type => 'AnyNode'), |
| 150 IMPL::DOM::Schema::Node->new(name => 'SwitchNode',type => 'SwitchNode') | 154 Node->new(name => 'SwitchNode',type => 'SwitchNode') |
| 151 ) | 155 ) |
| 152 ) | 156 ) |
| 153 ), | 157 ), |
| 154 IMPL::DOM::Schema::ComplexType->new(type => 'SwitchNode', nativeType => 'IMPL::DOM::Schema::SwitchNode')->appendRange( | 158 ComplexType->new(type => 'SwitchNode', nativeType => 'IMPL::DOM::Schema::SwitchNode')->appendRange( |
| 155 IMPL::DOM::Schema::NodeSet->new()->appendRange( | 159 NodeSet->new()->appendRange( |
| 156 IMPL::DOM::Schema::Node->new(name => 'ComplexNode', type=>'ComplexNode', minOccur => 0, maxOccur=>'unbounded'), | 160 Node->new(name => 'ComplexNode', type=>'ComplexNode', minOccur => 0, maxOccur=>'unbounded'), |
| 157 IMPL::DOM::Schema::Node->new(name => 'SimpleNode', type=>'SimpleNode', minOccur => 0, maxOccur=>'unbounded'), | 161 Node->new(name => 'SimpleNode', type=>'SimpleNode', minOccur => 0, maxOccur=>'unbounded'), |
| 158 IMPL::DOM::Schema::Node->new(name => 'Node', type=>'Node', minOccur => 0, maxOccur=>'unbounded'), | 162 Node->new(name => 'Node', type=>'Node', minOccur => 0, maxOccur=>'unbounded'), |
| 159 ) | 163 ) |
| 160 ), | 164 ), |
| 161 IMPL::DOM::Schema::ComplexType->new(type => 'NodeList', nativeType => 'IMPL::DOM::Schema::NodeList')->appendRange( | 165 ComplexType->new(type => 'NodeList', nativeType => 'IMPL::DOM::Schema::NodeList')->appendRange( |
| 162 IMPL::DOM::Schema::NodeSet->new()->appendRange( | 166 NodeSet->new()->appendRange( |
| 163 IMPL::DOM::Schema::Node->new(name => 'ComplexNode', type => 'ComplexNode', minOccur => 0, maxOccur=>'unbounded'), | 167 Node->new(name => 'ComplexNode', type => 'ComplexNode', minOccur => 0, maxOccur=>'unbounded'), |
| 164 IMPL::DOM::Schema::Node->new(name => 'SimpleNode', type => 'SimpleNode', minOccur => 0, maxOccur=>'unbounded'), | 168 Node->new(name => 'SimpleNode', type => 'SimpleNode', minOccur => 0, maxOccur=>'unbounded'), |
| 165 IMPL::DOM::Schema::Node->new(name => 'SwitchNode',type => 'SwitchNode', minOccur => 0, maxOccur=>'unbounded'), | 169 Node->new(name => 'SwitchNode',type => 'SwitchNode', minOccur => 0, maxOccur=>'unbounded'), |
| 166 IMPL::DOM::Schema::Node->new(name => 'Node', type => 'Node', minOccur => 0, maxOccur=>'unbounded'), | 170 Node->new(name => 'Node', type => 'Node', minOccur => 0, maxOccur=>'unbounded'), |
| 167 IMPL::DOM::Schema::Node->new(name => 'AnyNode', type => 'AnyNode', minOccur => 0, maxOccur=>'unbounded'), | 171 Node->new(name => 'AnyNode', type => 'AnyNode', minOccur => 0, maxOccur=>'unbounded'), |
| 168 ) | 172 ) |
| 169 ), | 173 ), |
| 170 IMPL::DOM::Schema::ComplexType->new(type => 'ComplexType', nativeType => 'IMPL::DOM::Schema::ComplexType')->appendRange( | 174 ComplexType->new(type => 'ComplexType', nativeType => 'IMPL::DOM::Schema::ComplexType')->appendRange( |
| 171 IMPL::DOM::Schema::NodeList->new()->appendRange( | 175 NodeList->new()->appendRange( |
| 172 IMPL::DOM::Schema::SwitchNode->new()->appendRange( | 176 SwitchNode->new()->appendRange( |
| 173 IMPL::DOM::Schema::Node->new(name => 'NodeSet', type => 'NodeSet'), | 177 Node->new(name => 'NodeSet', type => 'NodeSet'), |
| 174 IMPL::DOM::Schema::Node->new(name => 'NodeList',type => 'NodeList'), | 178 Node->new(name => 'NodeList',type => 'NodeList'), |
| 175 ), | 179 ), |
| 176 IMPL::DOM::Schema::Node->new(name => 'Property', type=>'Property', maxOccur=>'unbounded', minOccur=>0), | 180 Node->new(name => 'Property', type=>'Property', maxOccur=>'unbounded', minOccur=>0), |
| 177 IMPL::DOM::Schema::AnyNode->new(maxOccur => 'unbounded', minOccur => 0, type=>'Validator') | 181 AnyNode->new(maxOccur => 'unbounded', minOccur => 0, type=>'Validator') |
| 178 ), | 182 ), |
| 179 new IMPL::DOM::Schema::Property(name => 'type') | 183 Property->new(name => 'type') |
| 180 ), | 184 ), |
| 181 IMPL::DOM::Schema::ComplexType->new(type => 'ComplexNode', nativeType => 'IMPL::DOM::Schema::ComplexNode')->appendRange( | 185 ComplexType->new(type => 'ComplexNode', nativeType => 'IMPL::DOM::Schema::ComplexNode')->appendRange( |
| 182 IMPL::DOM::Schema::NodeList->new()->appendRange( | 186 NodeList->new()->appendRange( |
| 183 IMPL::DOM::Schema::SwitchNode->new()->appendRange( | 187 SwitchNode->new()->appendRange( |
| 184 IMPL::DOM::Schema::Node->new(name => 'NodeSet', type => 'NodeSet'), | 188 Node->new(name => 'NodeSet', type => 'NodeSet'), |
| 185 IMPL::DOM::Schema::Node->new(name => 'NodeList',type => 'NodeList'), | 189 Node->new(name => 'NodeList',type => 'NodeList'), |
| 186 ), | 190 ), |
| 187 IMPL::DOM::Schema::Node->new(name => 'Property', type=>'Property', maxOccur=>'unbounded', minOccur=>0), | 191 Node->new(name => 'Property', type=>'Property', maxOccur=>'unbounded', minOccur=>0), |
| 188 IMPL::DOM::Schema::AnyNode->new(maxOccur => 'unbounded', minOccur => 0, type=>'Validator') | 192 AnyNode->new(maxOccur => 'unbounded', minOccur => 0, type=>'Validator') |
| 189 ), | 193 ), |
| 190 new IMPL::DOM::Schema::Property(name => 'name') | 194 Property->new(name => 'name') |
| 191 ), | 195 ), |
| 192 IMPL::DOM::Schema::ComplexType->new(type => 'SimpleType', nativeType => 'IMPL::DOM::Schema::SimpleType')->appendRange( | 196 ComplexType->new(type => 'SimpleType', nativeType => 'IMPL::DOM::Schema::SimpleType')->appendRange( |
| 193 IMPL::DOM::Schema::NodeList->new()->appendRange( | 197 NodeList->new()->appendRange( |
| 194 IMPL::DOM::Schema::Node->new(name => 'Property', type=>'Property', maxOccur=>'unbounded', minOccur=>0), | 198 Node->new(name => 'Property', type=>'Property', maxOccur=>'unbounded', minOccur=>0), |
| 195 IMPL::DOM::Schema::AnyNode->new(maxOccur => 'unbounded', minOccur => 0, type=>'Validator') | 199 AnyNode->new(maxOccur => 'unbounded', minOccur => 0, type=>'Validator') |
| 196 ), | 200 ), |
| 197 new IMPL::DOM::Schema::Property(name => 'type'), | 201 Property->new(name => 'type'), |
| 198 new IMPL::DOM::Schema::Property(name => 'inflator', optional => 1, inflator => 'IMPL::DOM::Schema::InflateFactory') | 202 Property->(name => 'inflator', optional => 1, inflator => 'IMPL::DOM::Schema::InflateFactory') |
| 199 ), | 203 ), |
| 200 IMPL::DOM::Schema::ComplexType->new(type => 'SimpleNode', nativeType => 'IMPL::DOM::Schema::SimpleNode')->appendRange( | 204 ComplexType->new(type => 'SimpleNode', nativeType => 'IMPL::DOM::Schema::SimpleNode')->appendRange( |
| 201 IMPL::DOM::Schema::NodeList->new()->appendRange( | 205 NodeList->new()->appendRange( |
| 202 IMPL::DOM::Schema::Node->new(name => 'Property', type=>'Property', maxOccur=>'unbounded', minOccur=>0), | 206 Node->new(name => 'Property', type=>'Property', maxOccur=>'unbounded', minOccur=>0), |
| 203 IMPL::DOM::Schema::AnyNode->new(maxOccur => 'unbounded', minOccur => 0, type=>'Validator') | 207 AnyNode->new(maxOccur => 'unbounded', minOccur => 0, type=>'Validator') |
| 204 ), | 208 ), |
| 205 new IMPL::DOM::Schema::Property(name => 'name'), | 209 Property->new(name => 'name'), |
| 206 new IMPL::DOM::Schema::Property(name => 'inflator', optional => 1, inflator => 'IMPL::DOM::Schema::InflateFactory') | 210 Property->new(name => 'inflator', optional => 1, inflator => 'IMPL::DOM::Schema::InflateFactory') |
| 207 ), | 211 ), |
| 208 IMPL::DOM::Schema::ComplexType->new(type => 'Validator', nativeType => 'IMPL::DOM::Schema::Validator')->appendRange( | 212 ComplexType->new(type => 'Validator', nativeType => 'IMPL::DOM::Schema::Validator')->appendRange( |
| 209 IMPL::DOM::Schema::NodeList->new()->appendRange( | 213 NodeList->new()->appendRange( |
| 210 IMPL::DOM::Schema::AnyNode->new(maxOccur => 'unbounded', minOccur => 0) | 214 AnyNode->new(maxOccur => 'unbounded', minOccur => 0) |
| 211 ) | 215 ) |
| 212 ), | 216 ), |
| 213 IMPL::DOM::Schema::ComplexType->new(type => 'Property', nativeType => 'IMPL::DOM::Schema::Property' )->appendRange( | 217 ComplexType->new(type => 'Property', nativeType => 'IMPL::DOM::Schema::Property' )->appendRange( |
| 214 IMPL::DOM::Schema::NodeList->new()->appendRange( | 218 NodeList->new()->appendRange( |
| 215 IMPL::DOM::Schema::AnyNode->new(maxOccur => 'unbounded', minOccur => 0) | 219 AnyNode->new(maxOccur => 'unbounded', minOccur => 0) |
| 216 ), | 220 ), |
| 217 IMPL::DOM::Schema::Property->new(name => 'name'), | 221 Property->new(name => 'name'), |
| 218 new IMPL::DOM::Schema::Property(name => 'inflator', optional => 1, inflator => 'IMPL::DOM::Schema::InflateFactory') | 222 Property->new(name => 'inflator', optional => 1, inflator => 'IMPL::DOM::Schema::InflateFactory') |
| 219 ), | 223 ), |
| 220 IMPL::DOM::Schema::SimpleType->new(type => 'Node', nativeType => 'IMPL::DOM::Schema::Node')->appendRange( | 224 SimpleType->new(type => 'Node', nativeType => 'IMPL::DOM::Schema::Node')->appendRange( |
| 221 IMPL::DOM::Schema::Property->new(name => 'name'), | 225 Property->new(name => 'name'), |
| 222 IMPL::DOM::Schema::Property->new(name => 'type') | 226 Property->new(name => 'type') |
| 223 ), | 227 ), |
| 224 IMPL::DOM::Schema::SimpleType->new(type => 'AnyNode', nativeType => 'IMPL::DOM::Schema::AnyNode') | 228 SimpleType->new(type => 'AnyNode', nativeType => 'IMPL::DOM::Schema::AnyNode') |
| 225 ); | 229 ); |
| 226 | 230 |
| 227 $schema->Process; | 231 $schema->Process; |
| 228 | 232 |
| 229 return $schema; | 233 return $schema; |
