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