]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Utils/Fieldmapper.pm
new FM classes and removing cruft
[Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Utils / Fieldmapper.pm
1 package Fieldmapper;
2 use JSON;
3 use Data::Dumper;
4 use base 'OpenSRF::Application';
5
6 use OpenSRF::Utils::Logger;
7 my $log = 'OpenSRF::Utils::Logger';
8
9 use OpenILS::Application::Storage::CDBI;
10 use OpenILS::Application::Storage::CDBI::actor;
11 use OpenILS::Application::Storage::CDBI::action;
12 use OpenILS::Application::Storage::CDBI::asset;
13 use OpenILS::Application::Storage::CDBI::biblio;
14 use OpenILS::Application::Storage::CDBI::config;
15 use OpenILS::Application::Storage::CDBI::metabib;
16
17 use vars qw/$fieldmap $VERSION/;
18
19 _init();
20
21 sub publish_fieldmapper {
22         my ($self,$client,$class) = @_;
23
24         return $fieldmap unless (defined $class);
25         return undef unless (exists($$fieldmap{$class}));
26         return {$class => $$fieldmap{$class}};
27 }
28 __PACKAGE__->register_method(
29         api_name        => 'opensrf.open-ils.system.fieldmapper',
30         api_level       => 1,
31         method          => 'publish_fieldmapper',
32 );
33
34 #
35 # To dump the Javascript version of the fieldmapper struct use the command:
36 #
37 #       PERL5LIB=~/cvs/ILS/OpenSRF/src/perlmods/:~/cvs/ILS/Open-ILS/src/perlmods/ GEN_JS=1 perl -MOpenILS::Utils::Fieldmapper -e 'print "\n";'
38 #
39 # ... adjusted for your CVS sandbox, of course.
40 #
41
42 sub classes {
43         return () unless (defined $fieldmap);
44         return keys %$fieldmap;
45 }
46
47 sub _init {
48         return if (defined $fieldmap);
49
50         $fieldmap = 
51         {
52                 'Fieldmapper::action::survey'                   => { hint               => 'asv',
53                                                                      proto_fields       => { questions  => 1,
54                                                                                              responses  => 1 } },
55                 'Fieldmapper::action::survey_question'          => { hint               => 'asvq',
56                                                                      proto_fields       => { answers    => 1,
57                                                                                              responses  => 1 } },
58                 'Fieldmapper::action::survey_answer'            => { hint               => 'asva',
59                                                                      proto_fields       => { responses => 1 } },
60                 'Fieldmapper::action::survey_response'          => { hint               => 'asvr'  },
61                 'Fieldmapper::actor::user'                      => { hint => 'au'    },
62                 'Fieldmapper::actor::stat_cat'                  => { hint               => 'asc',
63                                                                      proto_fields       => { entries => 1 } },
64                 'Fieldmapper::actor::stat_cat_entry'            => { hint => 'asce'    },
65                 'Fieldmapper::actor::stat_cat_entry_user_map'   => { hint => 'ascecm'  },
66                 'Fieldmapper::actor::org_unit'                  => { hint               => 'aou',
67                                                                      proto_fields       => { children => 1 } },
68                 'Fieldmapper::actor::org_unit_type'             => { hint               => 'aout',
69                                                                      proto_fields       => { children => 1 } },
70                 
71                 'Fieldmapper::biblio::record_node'              => { hint               => 'brn',
72                                                                      virtual            => 1,
73                                                                      proto_fields       => { children           => 1,
74                                                                                              id                 => 1,
75                                                                                              owner_doc          => 1,
76                                                                                              intra_doc_id       => 1,
77                                                                                              parent_node        => 1,
78                                                                                              node_type          => 1,
79                                                                                              namepsace_uri      => 1,
80                                                                                              name               => 1,
81                                                                                              value              => 1,
82                                                                                            } },
83                 'Fieldmapper::biblio::record_entry'             => { hint               => 'bre',
84                                                                      proto_fields       => { call_numbers => 1 } },
85                 'Fieldmapper::biblio::record_marc'              => { hint => 'brx'  },
86
87                 'Fieldmapper::config::identification_type'      => { hint => 'cit'  },
88                 'Fieldmapper::config::bib_source'               => { hint => 'cbs'  },
89                 'Fieldmapper::config::metabib_field'            => { hint => 'cmf'  },
90
91                 'Fieldmapper::metabib::metarecord'              => { hint => 'mmr'  },
92                 'Fieldmapper::metabib::title_field_entry'       => { hint => 'mtfe' },
93                 'Fieldmapper::metabib::author_field_entry'      => { hint => 'mafe' },
94                 'Fieldmapper::metabib::subject_field_entry'     => { hint => 'msfe' },
95                 'Fieldmapper::metabib::keyword_field_entry'     => { hint => 'mkfe' },
96                 'Fieldmapper::metabib::full_rec'                => { hint => 'mfr'  },
97                 'Fieldmapper::metabib::record_descriptor'       => { hint => 'mrd'  },
98
99                 'Fieldmapper::asset::copy'                      => { hint               => 'acp',
100                                                                      proto_fields       => { stat_cat_entries => 1 } },
101                 'Fieldmapper::asset::stat_cat'                  => { hint               => 'asc',
102                                                                      proto_fields       => { entries => 1 } },
103                 'Fieldmapper::asset::stat_cat_entry'            => { hint => 'asce'    },
104                 'Fieldmapper::asset::stat_cat_entry_copy_map'   => { hint => 'ascecm'  },
105                 'Fieldmapper::asset::copy_note'                 => { hint => 'acpn'    },
106                 'Fieldmapper::asset::call_number'               => { hint               => 'acn',
107                                                                      proto_fields       => { copies => 1 } },
108                 'Fieldmapper::asset::call_number_note'          => { hint => 'acnn'    },
109         };
110
111         #-------------------------------------------------------------------------------
112         # Now comes the evil!  Generate classes
113
114         for my $pkg ( keys %$fieldmap ) {
115                 (my $cdbi = $pkg) =~ s/^Fieldmapper:://o;
116
117                 eval <<"                PERL";
118                         package $pkg;
119                         use base 'Fieldmapper';
120                 PERL
121
122                 $$fieldmap{$pkg}{cdbi} = $cdbi;
123
124                 my $pos = 0;
125                 for my $vfield ( qw/isnew ischanged isdeleted/ ) {
126                         $$fieldmap{$pkg}{fields}{$vfield} = { position => $pos, virtual => 1 };
127                         $pos++;
128                 }
129
130                 if (exists $$fieldmap{$pkg}{proto_fields}) {
131                         for my $pfield ( keys %{ $$fieldmap{$pkg}{proto_fields} } ) {
132                                 $$fieldmap{$pkg}{fields}{$pfield} = { position => $pos, virtual => $$fieldmap{$pkg}{proto_fields}{$pfield} };
133                                 $pos++;
134                         }
135                 }
136
137                 unless ( $$fieldmap{$pkg}{virtual} ) {
138                         for my $col ( $cdbi->columns('All') ) {
139                                 $$fieldmap{$pkg}{fields}{$col} = { position => $pos, virtual => 0 };
140                                 $pos++;
141                         }
142                 }
143
144                 JSON->register_class_hint(
145                         hint => $pkg->json_hint,
146                         name => $pkg,
147                         type => 'array',
148                 );
149
150         }
151
152         #print Fieldmapper->javascript() if ($ENV{GEN_JS});
153 }
154
155 sub new {
156         my $self = shift;
157         my $value = shift;
158         $value = [] unless (defined $value);
159         return bless $value => $self->class_name;
160 }
161
162 sub javascript {
163         my $class_name = shift;
164         return 'var fieldmap = ' . JSON->perl2JSON($fieldmap) . ';'
165 }
166
167 sub DESTROY {}
168
169 sub AUTOLOAD {
170         my $obj = shift;
171         my $value = shift;
172         (my $field = $AUTOLOAD) =~ s/^.*://o;
173         my $class_name = $obj->class_name;
174
175         my $pos = $$fieldmap{$class_name}{fields}{$field}{position};
176
177         if ($field =~ /^clear_/o) {
178                 {       no strict 'subs';
179                         *{$obj->class_name."::$field"} = sub {
180                                 my $self = shift;
181                                 $self->[$pos] = undef;
182                                 return 1;
183                         };
184                 }
185                 return $obj->$field();
186         }
187
188         die "No field by the name $field in $class_name!"
189                 unless (exists $$fieldmap{$class_name}{fields}{$field});
190
191
192         {       no strict 'subs';
193                 *{$obj->class_name."::$field"} = sub {
194                         my $self = shift;
195                         my $new_val = shift;
196                         $self->[$pos] = $new_val if (defined $new_val);
197                         return $self->[$pos];
198                 };
199         }
200         return $obj->$field($value);
201 }
202
203 sub class_name {
204         my $class_name = shift;
205         return ref($class_name) || $class_name;
206 }
207
208 sub real_fields {
209         my $self = shift;
210         my $class_name = $self->class_name;
211         my $fields = $$fieldmap{$class_name}{fields};
212
213         my @f = grep {
214                         !$$fields{$_}{virtual}
215                 } sort {$$fields{$a}{position} <=> $$fields{$b}{position}} keys %$fields;
216
217         return @f;
218 }
219
220 sub api_level {
221         my $self = shift;
222         return $fieldmap->{$self->class_name}->{api_level};
223 }
224
225 sub json_hint {
226         my $self = shift;
227         return $fieldmap->{$self->class_name}->{hint};
228 }
229
230
231 1;