view Lib/IMPL/DOM/Document.pm @ 388:648dfaf642e0

DOM refactoring, removed inflators from DOM Schema, DOM validation - in progress
author cin
date Tue, 11 Feb 2014 20:22:01 +0400
parents 010ceafd0c5a
children
line wrap: on
line source

package IMPL::DOM::Document;
use strict;
use warnings;

use IMPL::lang;
use IMPL::Const qw(:prop);
use IMPL::declare {
    require => {
        DOMNode => 'IMPL::DOM::Node'
    },
    base => [
        DOMNode => '@_'
    ],
    props => [
    	schemaDocument => PROP_RW
    ]
};

sub document {
    return $_[0];
}

sub Create {
    my ($this,$nodeName,$class,$refProps) = @_;
    
    if ( ref $class eq 'HASH' ) {
        $refProps = $class;
        $class = undef;
    }
    
    $class ||= DOMNode;
    $refProps ||= {};
    
    delete $refProps->{nodeName};
    
    die new IMPL::Exception("class is not specified") unless $class;
    return $class->new(
        nodeName => $nodeName,
        document => $this,
        %$refProps
    );
}

sub save {
    my ($this,$writer) = @_;
    
    $writer->xmlDecl(undef,'yes');
    $this->SUPER::save($writer);
    $writer->end();
}

{
    my $empty;
    sub Empty() {
        return $empty ? $empty : ($empty = __PACKAGE__->new(nodeName => 'Empty'));
    }
}

1;
__END__

=pod

=head1 NAME

C<IMPL::DOM::Document> DOM документ.

=head1 DESCRIPTION

Документ, позволяет создавать узлы определенных типов, что позволяет абстрагироваться
от механизмов реального создания объектов. Т.о. например C<IMPL::DOM::Navigator::Builder>
может формировать произвольные документы.

=head1 SYNOPSIS

=begin code

package MyDocument;
use parent qw(IMPL::DOM::Document);

sub Create {
    my $this = shift;
    my ($name,$class,$hashProps) = @_;
    
    if ($class eq 'Info') {
        return MyInfo->new($name,$hashProps->{date},$hashProps->{description});
    } else {
        # leave as it is
        return $this->SUPER::Create(@_);
    }
}

=end code

=head1 METHODS

=over

=item C< Create($nodeName,$class,$hashProps) >

Реализация по умолчанию. Создает узел определеннго типа с определенным именем и свойствами.

=begin code

sub Create {
    my ($this,$nodeName,$class,$hashProps) = @_;
    
    return $class->new (
        nodeName => $nodeName,
        document => $this,
        %$hashProps
    );
}

=end code

=item C< save($writer) >

Сохраняет документ в виде XML узла и вызывает C<< $writer->end() >>.

=over

=item C<$writer>

Объект с интерфейсом C<XML::Writer> который будет использован для записи
содержимого документа

=back

=back

=cut