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; |