Mercurial > pub > Impl
view Lib/IMPL/DOM/Navigator/Builder.pm @ 140:fb896377389f
to_json and escape_string functions for the templates
minor changes
author | wizard |
---|---|
date | Mon, 05 Jul 2010 02:22:42 +0400 (2010-07-04) |
parents | 7b14e0122b79 |
children | e6447ad85cb4 |
line wrap: on
line source
package IMPL::DOM::Navigator::Builder; use strict; use warnings; use base qw(IMPL::DOM::Navigator); use IMPL::Class::Property; use IMPL::Class::Property::Direct; require IMPL::DOM::Navigator::SchemaNavigator; require IMPL::DOM::Schema::ValidationError; use IMPL::DOM::Document; BEGIN { private _direct property _schemaNavi => prop_all; private _direct property _docClass => prop_all; public _direct property BuildErrors => prop_get | prop_list; public _direct property Document => prop_get | owner_set; } our %CTOR = ( 'IMPL::DOM::Navigator' => sub { IMPL::DOM::Document->Empty; } ); sub CTOR { my ($this,$docClass,$schema) = @_; $this->{$_docClass} = $docClass; $this->{$_schemaNavi} = $schema ? IMPL::DOM::Navigator::SchemaNavigator->new($schema) : undef; } sub NavigateCreate { my ($this,$nodeName,%props) = @_; if (my $schemaNode = $this->{$_schemaNavi}->NavigateName($nodeName)) { my $class = $schemaNode->can('nativeType') ? $schemaNode->nativeType || 'IMPL::DOM::Node' : 'IMPL::DOM::Node'; my @errors = $this->inflateProperties($schemaNode,\%props); my $node; if (! $this->{$Document}) { $node = $this->{$Document} = $this->{$_docClass}->new(nodeName => $nodeName,%props); $this->_initNavigator($node); } else { die new IMPL::InvalidOperationException('Can\t create a second top level element') unless $this->Current; $node = $this->{$Document}->Create($nodeName,$class,\%props); $this->Current->appendChild($node); $this->internalNavigateNodeSet($node); } if (@errors) { $this->BuildErrors->Append( map { IMPL::DOM::Schema::ValidationError->new( Node => $node, Source => $this->{$_schemaNavi}->SourceSchemaNode, Schema => $schemaNode, Message => $schemaNode->messageInflateError, Error => $_ ) } @errors ); } return $node; } else { die new IMPL::InvalidOperationException("The specified node is undefined", $nodeName); } } sub inflateProperties { my ($this,$schemaNode,$refProps) = @_; my @errors; foreach my $schemaProp ( $schemaNode->selectNodes('Property') ) { next if not exists $refProps->{$schemaProp->name}; my $result = eval {$schemaProp->inflateValue($refProps->{$schemaProp->name}) }; if (my $e = $@) { push @errors, $e; } else { $refProps->{$schemaProp->name} = $result; } } return @errors; } sub inflateValue { my ($this,$value,$node) = @_; $node ||= $this->Current; my $nodeSchema = $this->{$_schemaNavi}->Current; my $result = eval { $nodeSchema->inflateValue($value) }; if (my $e=$@) { $this->BuildErrors->Append(new IMPL::DOM::Schema::ValidationError( Schema => $nodeSchema, Node => $node, Error => $e, Message => $nodeSchema->messageInflateError, Source => $this->{$_schemaNavi}->SourceSchemaNode )); return $value; } else { return $result; } } sub Back { my ($this) = @_; $this->{$_schemaNavi}->SchemaBack(); $this->SUPER::Back(); } sub saveState { my ($this) = @_; $this->{$_schemaNavi}->saveState; $this->SUPER::saveState; } sub restoreState { my ($this) = @_; $this->{$_schemaNavi}->restoreState; $this->SUPER::restoreState; } 1; __END__ =pod =head1 NAME C< IMPL::DOM::Navigator::Builder > - ���������, �������� �������� �� ��������� �����. =head1 SYNOPSIS =begin code my $builder = new IMPL::DOM::Navigator::Builder(new MyApp::Document,$schema); my $reader = new IMPL::DOM::XMLReader(Navigator => $builder); $reader->ParseFile("document.xml"); my @errors = $schema->Validate($builder->Document); =end code =head1 DESCRIPTION ����������� DOM ���������� �� ��������� �����. ������ ������������ � ������ � ��������� ��� ������ ������ ��� C<IMPL::DOM::XMLReader>. =head1 METHODS =over =item C< CTOR($classDocument,$schema) > ������� ����� ������, ��������� �� ���� ����� ��������� (��� �������, �������� L<IMPL::Object::Factory>) � �����. � �������� ��������� ���������� ��������� ����� ������ ������ ���������. =item C< NavigateCreate($nodeName,\%props) > ������� ����� ���� � ��������� ������ � ��������� � ����. � ������ ���� � ����� ���������� ���� �� ������, �� ���������� ����������. ��� ���� �� ����� ���� ������ ��� �����, ����� ���� ������������ ����� ��� �������� ���������� � ��������� ���� ���������� � ��������. ��� �������� ������ ���� ������������ ����� ��������� C<< IMPL::DOM::Document->Create >> �������� ���� ���������� ��� �������� ����� �������� C<props>, �� ��� ������������ ���� �� ����� ���� �������������� ��������� C<nodeName>, ��� ����� ���������������. =item C< Document > ��������, ������� �������� �������� �� ��������� ��������� ����������. =back =cut