comparison Lib/Schema/DataSource.pm @ 0:03e58a454b20

Создан репозитарий
author Sergey
date Tue, 14 Jul 2009 12:54:37 +0400
parents
children 16ada169ca75
comparison
equal deleted inserted replaced
-1:000000000000 0:03e58a454b20
1 package Configuration;
2 our $DataDir;
3 package Schema::DataSource;
4 use Common;
5 use strict;
6 use base qw(Object);
7
8 use BNFCompiler;
9 use Schema::DB;
10 use Schema;
11 use URI::file;
12
13 BEGIN {
14 DeclareProperty ProcessedSchemas => ACCESS_NONE; #{ uri => schema }
15 DeclareProperty Types => ACCESS_READ; # Schema
16 DeclareProperty DataSourceBuilder => ACCESS_READ;
17 DeclareProperty Compiler => ACCESS_NONE;
18 }
19
20 sub CTOR {
21 my ($this,%args) = @_;
22
23 $this->{$DataSourceBuilder} = $args{'DataSourceBuilder'} or die new Exception('A data source builder is required');
24 $this->{$Types} = new Schema;
25 $this->{$Compiler} = new BNFCompiler(SchemaCache => "${DataDir}Cache/",Transform => sub { BNFCompiler::DOM::TransformDOMToHash(@_,{skip_spaces => 1})} );
26 $this->{$Compiler}->LoadBNFSchema(file => 'Schema/schema.def');
27 }
28
29 sub as_list {
30 return( map { UNIVERSAL::isa($_,'ARRAY') ? @{$_} : defined $_ ? $_ : () } @_ );
31 }
32
33 sub ProcessSchema {
34 my ($this,$uriFile) = @_;
35
36 return 1 if $this->{$ProcessedSchemas}{$uriFile->as_string};
37
38 my $uriDir = URI::file->new('./')->abs($uriFile);
39 $this->{$ProcessedSchemas}->{$uriFile->as_string} = 1;
40
41 my $Schema = $this->ParseSchema($uriFile);
42
43 foreach my $item (as_list($Schema->{'header'}{'include_item'})) {
44 my $uriItem = URI::file->new($item->{'file_name'})->abs($uriDir);
45 $this->ProcessSchema($uriItem);
46 }
47
48 $this->ConstructTypes($Schema);
49
50 }
51
52 sub ParseSchema {
53 my ($this,$fileUri) = @_;
54
55 my $fileName = $fileUri->file;
56 open my $hfile,"$fileName" or die new Exception('Failed to read the file',$fileName,$!);
57 local $/ = undef;
58 my $Schema = $this->{$Compiler}->Parse(<$hfile>);
59
60 return $Schema;
61 }
62
63 sub ConstructTypes {
64 my ($this,$schema) = @_;
65 return if not $schema->{'class'};
66
67 foreach my $class (as_list($schema->{'class'})){
68 # îáúÿâëåíèå òèïà
69 my $type;
70 my $builder;
71 if ($class->{'type_definition'}{'args_list'}) {
72 $type = $this->{$Types}->CreateTemplate($class->{'type_definition'}{'name'},as_list($class->{'type_definition'}{'args_list'}{'name'}));
73 } else {
74 $type = $this->{$Types}->CreateType($class->{'type_definition'}{'name'});
75 }
76
77 $type->SetAttributes(ValueType => 1) if $class->{'value_type'};
78
79 my $mappingTip = $this->{$DataSourceBuilder}->GetClassMapping($type);
80
81
82 # îáðàáàòûâàåì ñïèñîê áàçîâûõ êëàññîâ
83
84 if ($class->{'base_types'}) {
85 foreach my $typename (as_list($class->{'base_types'}{'type'})) {
86 $type->AddBase(MakeTypeName($typename));
87 }
88 }
89
90 # îáðàáàòûâàåì ñïèñîê ñâîéñòâ
91 if ($class->{'property_list'}) {
92 foreach my $property (as_list($class->{'property_list'}{'property'})) {
93 $type->InsertProperty($property->{'name'},MakeTypeName($property->{'type'}));
94 if (my $mapping = $property->{'mapping'}) {
95 $mappingTip->PropertyMapping($property->{'name'},Column => $mapping->{'column_name'},DBType => $mapping->{'db_type'});
96 }
97 }
98 }
99 }
100 }
101
102 sub MakeTypeName {
103 my ($typename) = @_;
104
105 return new Schema::TypeName(
106 $typename->{'name'},
107 (
108 $typename->{'template_list'} ?
109 map { MakeTypeName($_) } as_list($typename->{'template_list'}{'type'})
110 :
111 ()
112 )
113 );
114 }
115
116 sub BuildSchema {
117 my ($this,$fileName) = @_;
118
119 my $uriFile = URI::file->new_abs($fileName);
120
121 $this->ProcessSchema($uriFile);
122
123 $this->{$Types}->Close();
124
125 foreach my $type ($this->{$Types}->EnumTypes(skip_templates => 1)) {
126 $this->{$DataSourceBuilder}->AddType($type);
127 }
128 }
129
130 sub DESTROY {
131 my ($this) = @_;
132
133 $this->{$Compiler}->Dispose;
134 $this->{$DataSourceBuilder}->Dispose;
135 $this->{$Types}->Dispose;
136 }
137
138 1;