Revision 3 (by ahitrov@rambler.ru, 2010/03/24 15:19:32) |
The CORE
|
package Contenido::Init;
# ----------------------------------------------------------------------------
# ����� ����� ��������� ��� ���������������� ������ Contenido...
# ��� �� ������, ��� ������ ����� � �����������...
# ----------------------------------------------------------------------------
use strict;
use warnings;
use locale;
use vars qw($VERSION);
$VERSION = '4.1';
# ����������� �������... �����...
use Utils;
use IO::File;
use Image::Size;
use Data::Dumper;
use Convert::Cyrillic;
use POSIX qw(:locale_h);
# ����������� ������� Contenido...
use Contenido::Globals;
use Contenido::Logger;
use Contenido::User;
use Contenido::Project;
use Contenido::Request;
use Contenido::State;
use Contenido::Document;
use Contenido::Link;
use Contenido::Section;
use Contenido::Keeper;
use Contenido::Image;
# ���� ������
use Contenido::Type::File;
# ��������� ���������� ��������� ��������� Contenido/ElTexto/Arte
# �� ���� ������ ��� ������ ���������, ���� ����� �������������� �������������� ����������.
sub module_structure {
return (
['documents', '������ ����������', 'Contenido::Document'],
['sections', '������ ������', 'Contenido::Section'],
['users', '������ �������������', 'Contenido::User'],
['links', '������ ������', 'Contenido::Link'],
);
}
sub init {
warn "Contenido Init: ������������� Contenido\n" if $DEBUG;
my $R = contenido_init();
if ($state->locale) {
setlocale(LC_COLLATE, $state->locale);
setlocale(LC_CTYPE, $state->locale);
}
$keeper = Contenido::Keeper->new($state);
# ���� �� ����� keepalive ����� ����� ����������� � �����, ���� ��� ������������ ��������
unless ($state->db_type eq 'none') {
$keeper->db_connect unless $keeper->is_connected;
}
$log->info("�������� ������� Contenido::Project") if $DEBUG;
$project = Contenido::Project->new($state);
$R += plugins_load();
$R += modules_load();
utils_load();
init_classes();
clear_not_available();
# PREAMBLE_HANDLER stuff - load and initialize
#
if ( $state->{preamble_handler} ) {
my $module = $state->{preamble_handler}; # main preamble hanler
my $path = $state->{preamble_handler_path}; # extra preamble handlers relative path
eval "use $module";
if ( $@ ) {
$R++; $log->error("Cannot load module $module because of '$@'");
}
$state->{preamble_handler_obj} = $module->new( $path ? (load_modules => $path) : () );
}
unless ($state->db_type eq 'none') {
$keeper->shutdown;
}
if ($R) {
$log->error("��� ������������� Contenido ��������� ������ (���������� - $R)") if $DEBUG;
} else {
$log->info("������������� Contenido ������ �������") if $DEBUG;
}
return ($R ? 1 : 0);
}
sub init_classes {
foreach (&module_structure, ['locals', '��������� ������', $keeper->state()->project() ]) {
my $tag = $_->[0];
$state->{'available_'.$tag} ||= [];
if (ref($state->{'available_'.$tag}) eq 'ARRAY') {
foreach my $class (@{$state->{'available_'.$tag}}) {
$class->class_init;
}
} else {
$log->error("Wrong structure in \$state->{available_$tag} (".$state->{'available_'.$tag}."), must be ARRAY REF");
die;
}
}
}
sub clear_not_available {
foreach (&module_structure, ['locals', '��������� ������', $keeper->state()->project() ]) {
my $tag = $_->[0];
next unless ref $state->{'available_'.$tag} eq 'ARRAY';
for (my $i = 0; $i <= $#{$state->{'available_'.$tag}} ; $i++) {
my $class = $state->{'available_'.$tag}->[$i];
unless ($class->contenido_is_available) {
splice(@{$state->{'available_'.$tag}}, $i--, 1);
$log->debug('������ ����� ' . $class . ' �� $state->{available_' . $tag . '}') if $DEBUG;
}
}
}
}
sub load_classes {
shift;
for (@_) {
eval "use $_";
#����� ������ eval ���� �� ��������� ����� $@ ?
$log->error("Cannot load class $_ because of $@") if ($@);
if ($_->can('class_init')) {
eval {$_->class_init};
$log->error("Error on class_init for class $_ because of $@") if ($@);
}
$log->info("�������� ����� $_") if $DEBUG;
}
}
sub plugins_load {
my $LR = 0;
# ----------------------------------------------------------------------------
# ������ ��� ���� ���������� ��� ��������� ������...
for my $plugin ($state->project, split(/\s+/, $state->plugins)) {
my $class = $plugin.'::Init';
eval ("use $class");
$log->error("������ ��� �������� ������.\n$@!") if $@;
{
package HTML::Mason::Commands;
eval ("use $class");
}
if ( $@ ) {
$log->error("�� ���� ���������� ������ $plugin (������������� $class) �� ������� '$@'");
$LR++;
} else {
$log->info("�������� ����� $class ��� ������� $plugin") if $DEBUG;
eval {
$LR += $class->init( $keeper );
};
if ( $@ ) {
$log->error("�� ���� ��������� ������������� ������� $plugin (������������� $class) �� ������� '$@'");
$LR++;
}
}
}
return $LR;
}
sub utils_load {
Utils::load_modules( ['Utils::HTML'] );
}
sub modules_load {
my $path = __FILE__;
$path =~ s|/[^/]*$||;
$path =~ s|/Contenido$||;
my $LR = 0;
my @ms = ();
# ��������� �������� ��������� �������...
push (@ms, ['locals', '��������� ������', $keeper->state()->project() ] );
foreach my $ms (@ms) {
$log->info("���������� ".$ms->[1]) if $DEBUG;
my $pathlib = $path.'/'.$ms->[2];
$pathlib =~ s|::|/|gi;
if (! -s $pathlib) {
$log->warning("���������� ${pathlib} �� ����������. ���������!");
} else {
opendir(DIR, $pathlib) || do { $log->error("�� ���� ������� ���������� ${pathlib} ��� ����������� �������"); die };
my @modules = grep {/\.pm$/} readdir(DIR);
closedir(DIR);
foreach my $module (@modules) {
$module =~ s/\.pm$//;
my $class = $ms->[2]."::".$module;
eval("
package TestPackage::$class;
use $class;
1;
");
if ( $@ ) {
$log->error("�� ���� ���������� ������ $module (����� $class) �� ������� '$@'");
$LR++;
} else {
$log->info("�������� ����� $class") if $DEBUG;
next unless $class->isa('Contenido::Object');
foreach (&module_structure()) {
my ($tag, $name, $proto) = @$_;
if ($class->isa($proto)) {
push (@{ $state->{'available_'.$tag} }, $class);
$log->info("����� $class ���� $name '".$class->class_name()."' (�������� $proto)") if $DEBUG;
}
}
}
}
}
}
# ��� �������� ���������� ��� ������� - Contenido::User, Contenido::Section... ������ ������� �� � ������ ������������
push (@{ $state->{'available_sections'} }, 'Contenido::Section');
push (@{ $state->{'available_users'} }, 'Contenido::User');
push (@{ $state->{'available_links'} }, 'Contenido::Link');
return $LR;
}
# �������� �������� Contenido...
sub contenido_init {
warn "Contenido Init: �������� ������� Contenido::State\n" if $DEBUG;
$state = Contenido::State->new();
$log = Contenido::Logger->new(
log_format => $state->{__debug_format__} || '%d %C:%L (%P) [%l]: "%m"%n',
max_level => $state->{__debug_max_level__} || 'emergency',
min_level => $state->{__debug_min_level__} || 'debug',
stack_trace => $state->{__debug_stack_trace__} || 0,
);
return 1 unless ref $state && ref $log;
$log->info("������ ������ Contenido::Logger") if $DEBUG;
$state->debug($DEBUG);
$state->info() if $DEBUG;
return 0;
}
1;