diff Lib/IMPL/DOM/Transform/ObjectToDOM.pm @ 236:2904da230022

DOM refactoring
author sergey
date Mon, 15 Oct 2012 04:23:01 +0400
parents
children 61db68166c37
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Lib/IMPL/DOM/Transform/ObjectToDOM.pm	Mon Oct 15 04:23:01 2012 +0400
@@ -0,0 +1,134 @@
+package IMPL::DOM::Transform::ObjectToDOM;
+use strict;
+
+use IMPL::Const qw(:prop :access);
+use IMPL::declare {
+    require => {
+        PropertyInfo => 'IMPL::Class::PropertyInfo',
+        Builder => 'IMPL::DOM::Navigator::Builder',
+        Exception => 'IMPL::Exception',
+        ArgumentException => '-IMPL::InvalidArgumentException',
+        OperationException => '-IMPL::InvalidOperationException'
+    },
+    base => [
+        'IMPL::Transform' => sub {
+            -plain => \&TransformPlain,
+            HASH => \&TransformHash,
+            -default => \&TransformDefault
+        }
+    ],
+    props => [
+        documentSchema => PROP_RO,
+        _schema => PROP_RW,
+        _navi => PROP_RW
+    ]
+};
+
+sub CTOR {
+    my ($this,$docName,$docSchema) = @_;
+    
+    my $docNodeSchema = $docSchema->selectSingleNode(sub { $_->name eq $docName })
+        or die OperationException->new("Can't find a node schema for the document '$docName'");
+       
+    my $docClass = ($docNodeSchema->can('nativeType') ? $docNodeSchema->nativeType : undef) || 'IMPL::DOM::Document';
+    
+    $this->documentSchema($docNodeSchema);
+    
+    $this->_navi(
+        Builder->new(
+            $docClass,
+            $docSchema,
+            ignoreUndefined => 1
+        )
+    );
+    $this->_schema($docSchema);
+    
+    $this->_navi->NavigateCreate($docName);
+}
+
+sub TransformPlain {
+    my ($this,$data) = @_;
+    
+    $this->_navi->Current->nodeValue( $this->_navi->inflateValue($data) );
+    return $this->_navi->Current;
+}
+
+sub TransformHash {
+    my ($this,$data) = @_;
+    
+    die ArgumentException->new(data => 'A HASH reference is required')
+        unless ref $data eq 'HASH';
+
+    KEYLOOP: foreach my $key (keys %$data) {
+        my $value = $data->{$key};
+        
+        if (ref $value eq 'ARRAY') {
+            foreach my $subval (@$value) {
+                
+                my $node = $this->_navi->NavigateCreate($key);
+                
+                unless(defined $node) {
+                    $this->_navi->Back();
+                    next KEYLOOP;
+                }
+                
+                $this->Transform($subval);
+                
+                $this->_navi->Back();
+            }
+        } else {
+            my $node = $this->_navi->NavigateCreate($key);
+                
+            unless(defined $node) {
+                $this->_navi->Back();
+                next KEYLOOP;
+            }
+            
+            $this->Transform($value);
+            
+            $this->_navi->Back();            
+        }
+    }
+    return $this->_navi->Current;
+}
+
+sub TransformDefault {
+    my ($this,$data) = @_;
+    
+    if ( ref $data and eval { $data->can('GetMeta') } ) {
+        my %props = map {
+            $_->name, 1
+        } $data->GetMeta(PropertyInfo, sub { $_->access == ACCESS_PUBLIC }, 1 );
+        
+        my %values = map {
+            $_,
+            $data->$_();
+        } keys %props;
+        
+        return $this->Transform(\%values);
+    } else {
+        die OperationException->new("Don't know how to transform $data");
+    }
+    
+    return $this->_navi->Current;
+}
+
+sub buildErrors {
+    my ($this) = @_;
+    
+    return $this->_navi->buildErrors;
+}
+
+1;
+
+__END__
+
+=pod
+
+=head1 NAME
+
+C<IMPL::DOM::Transform::ObjectToDOM> -преобразование объекта  
+
+=head1 SYNOPSIS 
+
+=cut
\ No newline at end of file