Mercurial > pub > Impl
diff Lib/IMPL/DOM/Navigator/Builder.pm @ 34:a8086f85a571
Dom Builder
author | Sergey |
---|---|
date | Mon, 16 Nov 2009 18:39:25 +0300 |
parents | 7f00786f8210 |
children | f25d021780b3 |
line wrap: on
line diff
--- a/Lib/IMPL/DOM/Navigator/Builder.pm Mon Nov 09 16:49:39 2009 +0300 +++ b/Lib/IMPL/DOM/Navigator/Builder.pm Mon Nov 16 18:39:25 2009 +0300 @@ -2,36 +2,55 @@ use strict; use warnings; -use base qw(IMPL::DOM::Navigator); +use base qw(IMPL::Object); use IMPL::Class::Property; use IMPL::Class::Property::Direct; require IMPL::DOM::Navigator::SchemaNavigator; BEGIN { - protected _direct property _schemaNavi => prop_all; + private _direct property _schemaNavi => prop_all; + private _direct property _nodesPath => prop_all; + private _direct property _nodeCurrent => prop_all; + private _direct property _docClass => prop_all public _direct property Document => prop_get | owner_set; } -our %CTOR = ( - 'IMPL::DOM::Navigator' => sub { $_[0] } # IMPL::DOM::Navigator($domDocument) -); - sub CTOR { - my ($this,$domDocument,$schema) = @_; + my ($this,$docClass,$schema) = @_; - $this->{$Document} = $domDocument; - $this->{$_schemaNavi} = $schema; + $this->{$_docClass} = $docClass; + $this->{$_schemaNavi} = IMPL::DOM::Navigator::SchemaNavigator->new($schema); } sub NavigateCreate { my ($this,$nodeName,%props) = @_; - + if (my $schemaNode = $this->{$_schemaNavi}->NavigateName($nodeName)) { + my $class = $schemaNode->can('nativeType') ? $schemaNode->nativeType : 'IMPL::DOM::Node'; + + my $node; + if (! $this->{$Document}) { + $node = $this->{$Document} = $this->{$_docClass}->new(nodeName => $nodeName,%props); + } else { + die new IMPL::InvalidOperationException('Can\t create a second top level element'); + $node = $this->{$Document}->Create($nodeName,$class,\%props); + push @{$this->{$_nodesPath}}, $this->{$_nodeCurrent}; + $this->{$_nodeCurrent}->appendChild($node); + } + + $this->{$_nodeCurrent} = $node; + + return $node; + } else { + die new IMPL::InvalidOperationException("The specified node is undefined", $nodeName); + } } sub Back { my ($this) = @_; + $this->{$_schemaNavi}->SchemaBack(); + $this->{$_nodeCurrent} = pop @{$this->{$_nodesPath}}; } 1; @@ -67,24 +86,11 @@ Создает новый узел с указанным именем и переходит в него. В случае если в схеме подходящий узел не найден, то вызывается исключение. -При этом схема узла производится по имени, после чего определяется класс для -создания узла, по алгоритму - -=over - -=item Проверяется свойство C<type> и если оно есть, то используется оно +При этом по имени узла ищется его схема, после чего определяется класс для +создания экземпляра и созданный узел доавляется в документ. -=item Проверяется свойство C<type> самого элемента схемы, если оно есть, то -используется оно. - -=item В качестве класса берется имя узла - -=back - -Также имя создаваемого узла может быть переопределено свойством C<nodeName>. - -Т.о. узел вида C<< <ComplexNode nodeName="Box" type="Container"> >> приведет -к созданию C<< Container->new(nodeName => 'Box') >>. +Также имя создаваемого узла НЕ может быть переопределено свойством nodeName, оно +будет проигнорировано. =back