diff Lib/DOM/Providers/Page.pm @ 49:16ada169ca75

migrating to the Eclipse IDE
author wizard@linux-odin.local
date Fri, 26 Feb 2010 10:49:21 +0300
parents 03e58a454b20
children
line wrap: on
line diff
--- a/Lib/DOM/Providers/Page.pm	Fri Feb 26 01:43:42 2010 +0300
+++ b/Lib/DOM/Providers/Page.pm	Fri Feb 26 10:49:21 2010 +0300
@@ -1,258 +1,258 @@
-use strict;
-
-package DOM::Providers::Page;
-use Template::Provider;
-#use PerfCounter;
-use DOM::Page;
-use Common;
-use Encode;
-
-our @ISA= qw(Object Exporter);
-
-our $UseIndexPage;  #optional
-our $PagesPath;     #required
-our $IncludesPath;  #optional
-our $CacheSize;     #optional
-our $CachePath;     #optional
-our $Encoding;      #optional
-our $AllowExtPath;  #optional
-our $PageResolver;  #optional
-
-
-BEGIN {
-    DeclareProperty('PageResolver');
-    DeclareProperty('PagesBase');
-    DeclareProperty('IndexPage');
-    DeclareProperty('TemplatesProvider');
-    DeclareProperty('PageEnc');
-}
-
-sub as_list {
-    return( map { UNIVERSAL::isa($_,'ARRAY') ? @{$_} : defined $_ ? $_ : () } @_ );
-}
-
-sub GetProviderInfo {
-    return {
-        Name => 'Page',
-        Host => 'DOM::Site',
-        Methods => {
-            LoadPage => \&SiteLoadPage,
-            ReleasePage => \&SiteReleasePage,
-        }
-    }
-}
-
-sub CTOR {
-    my ($this,%args) = @_;
-    
-    $this->{$PageResolver} = $args{'PageResolver'};
-    $this->{$PagesBase} = $args{'TemplatesPath'};
-    $this->{$IndexPage} = $args{'IndexPage'} || 'index.html';
-    $this->{$PageEnc} = $args{'Encoding'};
-    $this->{$TemplatesProvider} = new Template::Provider( INCLUDE_PATH => [$this->{$PagesBase}, as_list($args{'IncludePath'}) ], COMPILE_DIR => $args{'CachePath'}, CACHE_SIZE => $args{'CacheSize'}, ENCODING => $args{'Encoding'}, ABSOLUTE => $AllowExtPath, RELATIVE => $AllowExtPath, INTERPOLATE => 1, PRE_CHOMP => 3);
-}
-
-sub ResolveId {
-    my ($this,$pageId) = @_;
-    
-    if ($this->{$PageResolver} && UNIVERSAL::can($this->{$PageResolver},'ResolveId')) {
-        return $this->{$PageResolver}->ResolveId($pageId);
-    } else {
-        return grep { $_ } split /\//,$pageId;
-    }
-}
-
-sub MakePageId {
-    my ($this,$raPath) = @_;
-    
-    if ($this->{$PageResolver} && UNIVERSAL::can($this->{$PageResolver},'MakeId')) {
-        return $this->{$PageResolver}->MakeId($raPath);
-    } else {
-        return join '/',@$raPath;
-    }
-}
-
-sub PageIdToURL {
-    my ($this,$pageId) = @_;
-    
-    if ($this->{$PageResolver} && UNIVERSAL::can($this->{$PageResolver},'PageIdToURL')) {
-        return $this->{$PageResolver}->PageIdToURL($pageId);
-    } else {
-        return '/'.$pageId;
-    }
-}
-
-sub SiteLoadPage {
-    my ($this,$site,$pageId) = @_;
-    
-    return $site->RegisterObject('Page', $this->LoadPage($pageId, Site => $site));
-}
-sub LoadPage {
-    my ($this,$pageId,%args) = @_;
-    
-    #StartTimeCounter('LoadPageTime');
-
-    my @pathPage = $this->ResolveId($pageId);
-
-    my $pageNode = $this->LoadNode(\@pathPage);
-    
-    pop @pathPage;
-    
-    my @pathNode;
-    
-    # поскольку путь указан относительно корневого контейнера, то нужно его добавить в начало
-    my @NavChain = map { push @pathNode, $_; $this->LoadNode(\@pathNode); } ('.',@pathPage);
-    
-    if ($pageNode->{'Type'} eq 'Section') {
-        push @NavChain,$pageNode;
-        $pageNode = $this->LoadNode($pageNode->{'pathIndexPage'});
-    }
-    
-    # формируем меню страницы
-    my %PageMenus;
-    foreach my $MenuSet (map { $_->{'Menus'}} @NavChain, $pageNode->{'Menus'} ) {
-        foreach my $menuName (keys %$MenuSet) {
-            if ($PageMenus{$menuName}) {
-                $PageMenus{$menuName}->Merge($MenuSet->{$menuName});
-            } else {
-                $PageMenus{$menuName} = $MenuSet->{$menuName};
-            }
-        }
-    }
-    
-    # формируем ключевые слова и свойства
-    my @keywords;
-    my %Props;
-    foreach my $PropSet ( (map { $_->{'Props'}} @NavChain), $pageNode->{'Props'} ) {
-        if(ref $PropSet->{'Keywords'} eq 'ARRAY') {
-            push @keywords, @{$PropSet->{'Keywords'}};
-        } elsif (not ref $PropSet->{'Keywords'} and exists $PropSet->{'Keywords'}) {
-            push @keywords, $PropSet->{'Keywords'};
-        }
-        
-        while (my ($prop,$value) = each %$PropSet) {
-            next if $prop eq 'Keywords';
-            $Props{$prop} = $value;
-        }
-    }
-        
-    #StopTimeCounter('LoadPageTime');
-    # загружаем шаблон
-    
-    #StartTimeCounter('FetchTime');
-    my ($Template,$error) = $this->{$TemplatesProvider}->fetch($pageNode->{'TemplateFileName'});
-    die new Exception("Failed to load page $pageId",$Template ? $Template->as_string : 'Failed to parse') if $error;
-    #StopTimeCounter('FetchTime');
-    
-    my $page = new DOM::Page(TemplatesProvider => $this->{$TemplatesProvider}, Properties => \%Props, Menus => \%PageMenus, NavChain => \@NavChain, Template => $Template, %args);
-    $page->Properties->{url} = $this->PageIdToURL($pageId);
-    return $page;
-}
-
-sub LoadNode {
-    my ($this,$refNodePath) = @_;
-    
-    my $fileNameNode = $this->{$PagesBase} . join('/',grep $_, @$refNodePath);
-    my $fileNameMenus;
-    my $fileNameProps; 
-    
-    my %Node;
-
-    if ( -d $fileNameNode ) {
-        $Node{'Type'} = 'Section';
-        $fileNameMenus = $fileNameNode . '/.menu.pl';
-        $fileNameProps = $fileNameNode . '/.prop.pl';
-    } elsif ( -e $fileNameNode ) {
-        $Node{'Type'} = 'Page';
-        $Node{'TemplateFileName'} = join('/',@$refNodePath);;
-        $fileNameMenus = $fileNameNode . '.menu.pl';
-        $fileNameProps = $fileNameNode . '.prop.pl';
-    } else {
-        die new Exception("Page not found: $fileNameNode");
-    }
-    
-    if ( -f $fileNameProps ) {
-        local ${^ENCODING};
-        my $dummy = '';
-        open my $hnull,'>>',\$dummy;
-        local (*STDOUT,*STDIN) = ($hnull,$hnull);
-        $Node{'Props'} = do $fileNameProps or warn "can't parse $fileNameProps: $@";
-    }
-    
-    if ( -f $fileNameMenus ) {
-        local ${^ENCODING};
-        my $dummy = '';
-        open my $hnull,'>>',\$dummy;
-        local (*STDOUT,*STDIN) = ($hnull,$hnull);
-        $Node{'Menus'} = do $fileNameMenus or warn "can't parse $fileNameMenus: $@";
-    }
-    
-    if ($Node{'Menus'}) {
-        my %Menus;
-        foreach my $menu (keys %{$Node{'Menus'}}) {
-            $Menus{$menu} = new DOM::PageMenu( DATA => $Node{'Menus'}->{$menu} );
-        }
-        $Node{'Menus'} = \%Menus;
-    }
-    
-    $Node{'pathIndexPage'} = [@$refNodePath, $Node{'Props'}->{'IndexPage'} || $this->{$IndexPage}] if $Node{'Type'} eq 'Section';
-    
-    return \%Node;
-}
-
-sub SiteReleasePage {
-    my ($this,$site) = @_;
-    
-    my $page = $site->Objects()->{'Page'};
-    $page->Release() if $page;
-    
-    return 1;
-}
-
-sub construct {
-    my $self = shift;
-    
-    return new DOM::Providers::Page(TemplatesPath => $PagesPath, IncludePath => $IncludesPath, IndexPage => $UseIndexPage, CachePath => $CachePath, CacheSize => $CacheSize, Encoding => $Encoding);
-}
-
-sub DecodeData {
-    my ($Encoding, $data) = @_;
-    
-    if (ref $data) {
-        if (ref $data eq 'SCALAR') {
-            my $decoded = Encode::decode($Encoding,$$data,Encode::LEAVE_SRC);
-            return \$decoded;
-        } elsif (UNIVERSAL::isa($data, 'HASH')) {
-            return {map {Encode::decode($Encoding,$_,Encode::LEAVE_SRC),DecodeData($Encoding,$data->{$_})} keys %$data };
-        } elsif (UNIVERSAL::isa($data, 'ARRAY')) {
-            return [map {DecodeData($Encoding,$_)} @$data];
-        } elsif (ref $data eq 'REF') {
-            my $decoded = DecodeData($Encoding,$$data);
-            return \$decoded;
-        } else {
-            die new Exception('Cant decode data type', ref $data);
-        }
-    } else {
-        return Encode::decode($Encoding,$data,Encode::LEAVE_SRC);
-    }
-}
-
-1;
-
-=pod
-Хранилище шаблонов на основе файловой системы.
-
-Хранилище состоит из разделов, каждый раздел имеет набор свойств и меню
-Специальны свойства разделов
-    Keywords Ключевые слова
-    Name Название
-    IndexPage страница по умолчанию
-
-В разделах находятся страницы, каждая страница имеет набор свойств и меню
-
-При загрузке страницы полностью загружаются все родительские контейнеры,
-При этом одноименные меню сливаются,
-Свойства keywords объеъединяются,
-Если имя страницы не задано, то используется имя раздела
-
-=cut
\ No newline at end of file
+use strict;
+
+package DOM::Providers::Page;
+use Template::Provider;
+#use PerfCounter;
+use DOM::Page;
+use Common;
+use Encode;
+
+our @ISA= qw(Object Exporter);
+
+our $UseIndexPage;  #optional
+our $PagesPath;     #required
+our $IncludesPath;  #optional
+our $CacheSize;     #optional
+our $CachePath;     #optional
+our $Encoding;      #optional
+our $AllowExtPath;  #optional
+our $PageResolver;  #optional
+
+
+BEGIN {
+    DeclareProperty('PageResolver');
+    DeclareProperty('PagesBase');
+    DeclareProperty('IndexPage');
+    DeclareProperty('TemplatesProvider');
+    DeclareProperty('PageEnc');
+}
+
+sub as_list {
+    return( map { UNIVERSAL::isa($_,'ARRAY') ? @{$_} : defined $_ ? $_ : () } @_ );
+}
+
+sub GetProviderInfo {
+    return {
+        Name => 'Page',
+        Host => 'DOM::Site',
+        Methods => {
+            LoadPage => \&SiteLoadPage,
+            ReleasePage => \&SiteReleasePage,
+        }
+    }
+}
+
+sub CTOR {
+    my ($this,%args) = @_;
+    
+    $this->{$PageResolver} = $args{'PageResolver'};
+    $this->{$PagesBase} = $args{'TemplatesPath'};
+    $this->{$IndexPage} = $args{'IndexPage'} || 'index.html';
+    $this->{$PageEnc} = $args{'Encoding'};
+    $this->{$TemplatesProvider} = new Template::Provider( INCLUDE_PATH => [$this->{$PagesBase}, as_list($args{'IncludePath'}) ], COMPILE_DIR => $args{'CachePath'}, CACHE_SIZE => $args{'CacheSize'}, ENCODING => $args{'Encoding'}, ABSOLUTE => $AllowExtPath, RELATIVE => $AllowExtPath, INTERPOLATE => 1, PRE_CHOMP => 3);
+}
+
+sub ResolveId {
+    my ($this,$pageId) = @_;
+    
+    if ($this->{$PageResolver} && UNIVERSAL::can($this->{$PageResolver},'ResolveId')) {
+        return $this->{$PageResolver}->ResolveId($pageId);
+    } else {
+        return grep { $_ } split /\//,$pageId;
+    }
+}
+
+sub MakePageId {
+    my ($this,$raPath) = @_;
+    
+    if ($this->{$PageResolver} && UNIVERSAL::can($this->{$PageResolver},'MakeId')) {
+        return $this->{$PageResolver}->MakeId($raPath);
+    } else {
+        return join '/',@$raPath;
+    }
+}
+
+sub PageIdToURL {
+    my ($this,$pageId) = @_;
+    
+    if ($this->{$PageResolver} && UNIVERSAL::can($this->{$PageResolver},'PageIdToURL')) {
+        return $this->{$PageResolver}->PageIdToURL($pageId);
+    } else {
+        return '/'.$pageId;
+    }
+}
+
+sub SiteLoadPage {
+    my ($this,$site,$pageId) = @_;
+    
+    return $site->RegisterObject('Page', $this->LoadPage($pageId, Site => $site));
+}
+sub LoadPage {
+    my ($this,$pageId,%args) = @_;
+    
+    #StartTimeCounter('LoadPageTime');
+
+    my @pathPage = $this->ResolveId($pageId);
+
+    my $pageNode = $this->LoadNode(\@pathPage);
+    
+    pop @pathPage;
+    
+    my @pathNode;
+    
+    # поскольку путь указан относительно корневого контейнера, то нужно его добавить в начало
+    my @NavChain = map { push @pathNode, $_; $this->LoadNode(\@pathNode); } ('.',@pathPage);
+    
+    if ($pageNode->{'Type'} eq 'Section') {
+        push @NavChain,$pageNode;
+        $pageNode = $this->LoadNode($pageNode->{'pathIndexPage'});
+    }
+    
+    # формируем меню страницы
+    my %PageMenus;
+    foreach my $MenuSet (map { $_->{'Menus'}} @NavChain, $pageNode->{'Menus'} ) {
+        foreach my $menuName (keys %$MenuSet) {
+            if ($PageMenus{$menuName}) {
+                $PageMenus{$menuName}->Merge($MenuSet->{$menuName});
+            } else {
+                $PageMenus{$menuName} = $MenuSet->{$menuName};
+            }
+        }
+    }
+    
+    # формируем ключевые слова и свойства
+    my @keywords;
+    my %Props;
+    foreach my $PropSet ( (map { $_->{'Props'}} @NavChain), $pageNode->{'Props'} ) {
+        if(ref $PropSet->{'Keywords'} eq 'ARRAY') {
+            push @keywords, @{$PropSet->{'Keywords'}};
+        } elsif (not ref $PropSet->{'Keywords'} and exists $PropSet->{'Keywords'}) {
+            push @keywords, $PropSet->{'Keywords'};
+        }
+        
+        while (my ($prop,$value) = each %$PropSet) {
+            next if $prop eq 'Keywords';
+            $Props{$prop} = $value;
+        }
+    }
+        
+    #StopTimeCounter('LoadPageTime');
+    # загружаем шаблон
+    
+    #StartTimeCounter('FetchTime');
+    my ($Template,$error) = $this->{$TemplatesProvider}->fetch($pageNode->{'TemplateFileName'});
+    die new Exception("Failed to load page $pageId",$Template ? $Template->as_string : 'Failed to parse') if $error;
+    #StopTimeCounter('FetchTime');
+    
+    my $page = new DOM::Page(TemplatesProvider => $this->{$TemplatesProvider}, Properties => \%Props, Menus => \%PageMenus, NavChain => \@NavChain, Template => $Template, %args);
+    $page->Properties->{url} = $this->PageIdToURL($pageId);
+    return $page;
+}
+
+sub LoadNode {
+    my ($this,$refNodePath) = @_;
+    
+    my $fileNameNode = $this->{$PagesBase} . join('/',grep $_, @$refNodePath);
+    my $fileNameMenus;
+    my $fileNameProps; 
+    
+    my %Node;
+
+    if ( -d $fileNameNode ) {
+        $Node{'Type'} = 'Section';
+        $fileNameMenus = $fileNameNode . '/.menu.pl';
+        $fileNameProps = $fileNameNode . '/.prop.pl';
+    } elsif ( -e $fileNameNode ) {
+        $Node{'Type'} = 'Page';
+        $Node{'TemplateFileName'} = join('/',@$refNodePath);;
+        $fileNameMenus = $fileNameNode . '.menu.pl';
+        $fileNameProps = $fileNameNode . '.prop.pl';
+    } else {
+        die new Exception("Page not found: $fileNameNode");
+    }
+    
+    if ( -f $fileNameProps ) {
+        local ${^ENCODING};
+        my $dummy = '';
+        open my $hnull,'>>',\$dummy;
+        local (*STDOUT,*STDIN) = ($hnull,$hnull);
+        $Node{'Props'} = do $fileNameProps or warn "can't parse $fileNameProps: $@";
+    }
+    
+    if ( -f $fileNameMenus ) {
+        local ${^ENCODING};
+        my $dummy = '';
+        open my $hnull,'>>',\$dummy;
+        local (*STDOUT,*STDIN) = ($hnull,$hnull);
+        $Node{'Menus'} = do $fileNameMenus or warn "can't parse $fileNameMenus: $@";
+    }
+    
+    if ($Node{'Menus'}) {
+        my %Menus;
+        foreach my $menu (keys %{$Node{'Menus'}}) {
+            $Menus{$menu} = new DOM::PageMenu( DATA => $Node{'Menus'}->{$menu} );
+        }
+        $Node{'Menus'} = \%Menus;
+    }
+    
+    $Node{'pathIndexPage'} = [@$refNodePath, $Node{'Props'}->{'IndexPage'} || $this->{$IndexPage}] if $Node{'Type'} eq 'Section';
+    
+    return \%Node;
+}
+
+sub SiteReleasePage {
+    my ($this,$site) = @_;
+    
+    my $page = $site->Objects()->{'Page'};
+    $page->Release() if $page;
+    
+    return 1;
+}
+
+sub construct {
+    my $self = shift;
+    
+    return new DOM::Providers::Page(TemplatesPath => $PagesPath, IncludePath => $IncludesPath, IndexPage => $UseIndexPage, CachePath => $CachePath, CacheSize => $CacheSize, Encoding => $Encoding);
+}
+
+sub DecodeData {
+    my ($Encoding, $data) = @_;
+    
+    if (ref $data) {
+        if (ref $data eq 'SCALAR') {
+            my $decoded = Encode::decode($Encoding,$$data,Encode::LEAVE_SRC);
+            return \$decoded;
+        } elsif (UNIVERSAL::isa($data, 'HASH')) {
+            return {map {Encode::decode($Encoding,$_,Encode::LEAVE_SRC),DecodeData($Encoding,$data->{$_})} keys %$data };
+        } elsif (UNIVERSAL::isa($data, 'ARRAY')) {
+            return [map {DecodeData($Encoding,$_)} @$data];
+        } elsif (ref $data eq 'REF') {
+            my $decoded = DecodeData($Encoding,$$data);
+            return \$decoded;
+        } else {
+            die new Exception('Cant decode data type', ref $data);
+        }
+    } else {
+        return Encode::decode($Encoding,$data,Encode::LEAVE_SRC);
+    }
+}
+
+1;
+
+=pod
+Хранилище шаблонов на основе файловой системы.
+
+Хранилище состоит из разделов, каждый раздел имеет набор свойств и меню
+Специальны свойства разделов
+    Keywords Ключевые слова
+    Name Название
+    IndexPage страница по умолчанию
+
+В разделах находятся страницы, каждая страница имеет набор свойств и меню
+
+При загрузке страницы полностью загружаются все родительские контейнеры,
+При этом одноименные меню сливаются,
+Свойства keywords объеъединяются,
+Если имя страницы не задано, то используется имя раздела
+
+=cut