Mercurial > pub > Impl
changeset 14:65a7bb156fb7
Дом модель и схема
author | Sergey |
---|---|
date | Fri, 04 Sep 2009 16:38:15 +0400 |
parents | bb8d67f811ea |
children | 16795016e70b |
files | Lib/IMPL/DOM/Navigator/Builder.pm Lib/IMPL/DOM/Node.pm Lib/IMPL/DOM/XMLReader.pm Lib/IMPL/Test/Unit.pm _test/DOM.t _test/Test/DOM/Node.pm impl.kpf |
diffstat | 7 files changed, 120 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/Lib/IMPL/DOM/Navigator/Builder.pm Wed Sep 02 23:11:14 2009 +0400 +++ b/Lib/IMPL/DOM/Navigator/Builder.pm Fri Sep 04 16:38:15 2009 +0400 @@ -23,8 +23,13 @@ sub NavigateCreate { my ($this,$nodeName,%props) = @_; - if ( my $nodeSchema = $this->{$_navigatorSchema}->Navigate($nodeName) ) { + if ( my $nodeSchema = $this->{$_navigatorSchema}->Navigate(sub { $_[0]->nodeName eq $nodeName or $_[0]->isa('IMPL::DOM::Schema::AnyNode') }) ) { + my $class = $nodeSchema->type; + my $node = $this->{$Document}->Create($nodeName, $class, \%props); + + $this->Current()->appendNode($node); + $this->Current($node); } else { die new IMPL::InvalidOperationException("Requested elemnt not found in the schema");
--- a/Lib/IMPL/DOM/Node.pm Wed Sep 02 23:11:14 2009 +0400 +++ b/Lib/IMPL/DOM/Node.pm Fri Sep 04 16:38:15 2009 +0400 @@ -40,6 +40,20 @@ return $node; } +sub appendNode { + my ($this,$node,$pos) = @_; + + die new IMPL::InvalidOperationException("You can't insert the node to itselft") if $this == $node; + + $node->{$parentNode}->removeNode($node) if ($node->{$parentNode}); + + $this->childNodes->Append($node); + + $node->_setParent( $this ); + + return $node; +} + sub _getChildNodes { my ($this) = @_; @@ -94,9 +108,14 @@ } sub selectNodes { - my ($this,$name) = @_; + my ($this,$query) = @_; + my @result; - my @result = grep $_->nodeName eq $name, @{$this->childNodes}; + if (ref $query eq 'CODE') { + @result = grep &$query($_), @{$this->childNodes}; + } else { + @result = grep $_->nodeName eq $query, @{$this->childNodes}; + } return wantarray ? @result : \@result; } @@ -113,6 +132,7 @@ my ($this,$node) = @_; $this->{$parentNode} = $node; + # prevent from creating cyclicreferences weaken($this->{$parentNode}); }
--- a/Lib/IMPL/DOM/XMLReader.pm Wed Sep 02 23:11:14 2009 +0400 +++ b/Lib/IMPL/DOM/XMLReader.pm Fri Sep 04 16:38:15 2009 +0400 @@ -7,6 +7,8 @@ use IMPL::Class::Property::Direct; use XML::Parser; +__PACKAGE__->PassThroughArgs; + BEGIN { public _direct property Navigator => prop_get | owner_set; private _direct property _current => prop_all; @@ -31,9 +33,9 @@ my $parser = new XML::Parser( Handlers => { - Start => sub {shift; goto &OnStart($this,@_)}, - End => sub {shift; goto &OnEnd($this,@_)}, - Char => sub {shift; goto &OnChar($this,@_)} + Start => sub {shift; goto &_OnStart($this,@_)}, + End => sub {shift; goto &_OnEnd($this,@_)}, + Char => sub {shift; goto &_OnChar($this,@_)} } ); @@ -41,19 +43,19 @@ } -sub OnBegin { +sub _OnBegin { my ($this,$element,%attrs) = @_; $this->{$_current} = $this->Navigator->NavigateCreate($element,%attrs); } -sub OnEnd { +sub _OnEnd { my ($this,$element) = @_; $this->{$_current} = $this->Back; } -sub OnChar { +sub _OnChar { my ($this,$val) = @_; $this->{$_current}->nodeValue($this->{$_current}->nodeValue . $val); @@ -70,11 +72,29 @@ my $reader = new IMPL::DOM::XMLReader(Navigator => $DomBuilder); my $obj = $reader->parsefile("data.xml"); -=head2 DESCRIPTION +=head1 DESCRIPTION , . . C<NavigateCreate> C<Back> +=head1 METHODS + +=over + +=item C<CTOR(Naviagtor => $builder)> + + , + +=item C<$obj->Parse($in)> + + . xml , HANDLE. + +=item C<$obj->ParseFile($fileName)> + + C<$fileName>. + +=back + =cut
--- a/Lib/IMPL/Test/Unit.pm Wed Sep 02 23:11:14 2009 +0400 +++ b/Lib/IMPL/Test/Unit.pm Fri Sep 04 16:38:15 2009 +0400 @@ -36,6 +36,10 @@ } sub Cleanup { + my ($this,$session) = @_; + + $session->{$_} = $this->$_() foreach map $_->DataList, $this->get_meta('IMPL::Test::Unit::SharedData'); + 1; } @@ -81,7 +85,7 @@ $elapsed = tv_interval ( $t0 ); } finally { # we need to call Cleanup anyway - $this->Cleanup; + $this->Cleanup($session); }; return new IMPL::Test::Result(
--- a/_test/DOM.t Wed Sep 02 23:11:14 2009 +0400 +++ b/_test/DOM.t Fri Sep 04 16:38:15 2009 +0400 @@ -8,6 +8,7 @@ my $plan = new IMPL::Test::Plan qw( Test::DOM::Navigator + Test::DOM::Node ); $plan->AddListener(new IMPL::Test::TAPListener);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/_test/Test/DOM/Node.pm Fri Sep 04 16:38:15 2009 +0400 @@ -0,0 +1,33 @@ +package Test::DOM::Node; +use strict; +use warnings; + +use base qw(IMPL::Test::Unit); +use IMPL::Test qw(test shared failed); +use IMPL::Class::Property; + +require IMPL::DOM::Node; + +__PACKAGE__->PassThroughArgs; + +BEGIN { + shared public property Root => prop_all; +} + +test Create => sub { + my ($this) = @_; + + $this->Root(new IMPL::DOM::Node(nodeName => 'Root')) or failed "Failed to create a node"; +}; + +test AppendNode => sub { + my ($this) = @_; + + my $child = $this->Root->appendNode(new IMPL::DOM::Node(nodeName => 'Child')) or failed "Failed to append a child node"; + + my $firstChild = $this->Root->firstChild; + + failed "firstChild returned incorrect results" unless $firstChild == $child; +}; + +1;
--- a/impl.kpf Wed Sep 02 23:11:14 2009 +0400 +++ b/impl.kpf Fri Sep 04 16:38:15 2009 +0400 @@ -248,6 +248,32 @@ </preference-set> <string id="lastInvocation">default</string> </preference-set> +<preference-set idref="66c7d414-175f-45b6-92fe-dbda51c64843/_test/Test/DOM/Node.pm"> +<preference-set id="Invocations"> +<preference-set id="default"> + <string id="cookieparams"></string> + <string id="cwd"></string> + <long id="debugger.io-port">9011</long> + <string id="documentRoot"></string> + <string id="executable-params"></string> + <string relative="path" id="filename">_test/Test/DOM/Node.pm</string> + <string id="getparams"></string> + <string id="language">Perl</string> + <string id="mpostparams"></string> + <string id="params"></string> + <string id="postparams"></string> + <string id="posttype">application/x-www-form-urlencoded</string> + <string id="request-method">GET</string> + <boolean id="show-dialog">1</boolean> + <boolean id="sim-cgi">0</boolean> + <boolean id="use-console">0</boolean> + <string id="userCGIEnvironment"></string> + <string id="userEnvironment"></string> + <string id="warnings">enabled</string> +</preference-set> +</preference-set> + <string id="lastInvocation">default</string> +</preference-set> <preference-set idref="66c7d414-175f-45b6-92fe-dbda51c64843/_test/Web.t"> <preference-set id="Invocations"> <preference-set id="default">