[open-ils-commits] r13013 - trunk/Open-ILS/src/perlmods/OpenILS/Utils (scottmk)
svn at svn.open-ils.org
svn at svn.open-ils.org
Wed Apr 29 09:45:13 EDT 2009
Author: scottmk
Date: 2009-04-29 09:45:11 -0400 (Wed, 29 Apr 2009)
New Revision: 13013
Modified:
trunk/Open-ILS/src/perlmods/OpenILS/Utils/Fieldmapper.pm
Log:
Fix the links in the Fieldmapper, which were borked whenever a
class had only one link.
This fix entailed a complete rewrite of the code that builds the
fieldmapper structure, using XML::LibXML instead of XML::Simple.
Modified: trunk/Open-ILS/src/perlmods/OpenILS/Utils/Fieldmapper.pm
===================================================================
--- trunk/Open-ILS/src/perlmods/OpenILS/Utils/Fieldmapper.pm 2009-04-29 01:08:21 UTC (rev 13012)
+++ trunk/Open-ILS/src/perlmods/OpenILS/Utils/Fieldmapper.pm 2009-04-29 13:45:11 UTC (rev 13013)
@@ -5,7 +5,7 @@
use OpenSRF::Utils::Logger;
use OpenSRF::Utils::SettingsClient;
use OpenSRF::System;
-use XML::Simple;
+use XML::LibXML;
my $log = 'OpenSRF::Utils::Logger';
@@ -37,53 +37,155 @@
return keys %$fieldmap;
}
-import();
-sub import {
- my $class = shift;
- my %args = @_;
+sub get_attribute {
+ my $attr_list = shift;
+ my $attr_name = shift;
- return if (keys %$fieldmap);
- return if (!OpenSRF::System->connected && !$args{IDL});
+ my $attr = $attr_list->getNamedItem( $attr_name );
+ if( defined( $attr ) ) {
+ return $attr->getValue();
+ }
+ return undef;
+}
- # parse the IDL ...
- my $file = $args{IDL} || OpenSRF::Utils::SettingsClient->new->config_value( 'IDL' );
- #my $idl = XMLin( $file, ForceArray => 0, KeyAttr => ['name', 'id'], ValueAttr => {link =>'key'} )->{class};
- my $idl = XMLin( $file, ForceArray => 0, KeyAttr => ['name', 'id', 'field'] )->{class};
+sub load_fields {
+ my $field_list = shift;
+ my $fm = shift;
- for my $c ( keys %$idl ) {
- next unless ($idl->{$c}{'oils_obj:fieldmapper'});
- my $n = 'Fieldmapper::'.$idl->{$c}{'oils_obj:fieldmapper'};
+ # Get attributes of the field list. Since there is only one
+ # <field> per class, these attributes logically belong to the
+ # enclosing class, and that's where we load them.
- $log->debug("Building Fieldmapper class for [$n] from IDL");
+ my $field_attr_list = $field_list->attributes();
- $$fieldmap{$n}{hint} = $c;
- $$fieldmap{$n}{virtual} = ($idl->{$c}{'oils_persist:virtual'} && $idl->{$c}{'oils_persist:virtual'} eq 'true') ? 1 : 0;
- $$fieldmap{$n}{table} = $idl->{$c}{'oils_persist:tablename'};
- $$fieldmap{$n}{controller} = [ split ' ', $idl->{$c}{'controller'} ];
- $$fieldmap{$n}{restrict_primary} = $idl->{$c}{'oils_persist:restrict_primary'};
- $$fieldmap{$n}{sequence} = $idl->{$c}{fields}{'oils_persist:sequence'};
- $$fieldmap{$n}{identity} = $idl->{$c}{fields}{'oils_persist:primary'};
+ my $sequence = get_attribute( $field_attr_list, 'oils_persist:sequence' );
+ if( ! defined( $sequence ) ) {
+ $sequence = '';
+ }
+ my $primary = get_attribute( $field_attr_list, 'oils_persist:primary' );
- for my $f ( keys %{ $idl->{$c}{fields}{field} } ) {
- $$fieldmap{$n}{fields}{$f} =
- { virtual => ($idl->{$c}{fields}{field}{$f}{'oils_persist:virtual'} eq 'true') ? 1 : 0,
- position => $idl->{$c}{fields}{field}{$f}{'oils_obj:array_position'},
+ # Load attributes into the Fieldmapper ----------------------
+
+ $$fieldmap{$fm}{ sequence } = $sequence;
+ $$fieldmap{$fm}{ identity } = $primary;
+
+ # Load each field -------------------------------------------
+
+ for my $field ( $field_list->childNodes() ) { # For each <field>
+ if( $field->nodeName eq 'field' ) {
+
+ my $attribute_list = $field->attributes();
+
+ my $name = get_attribute( $attribute_list, 'name' );
+ my $array_position = get_attribute( $attribute_list, 'oils_obj:array_position' );
+ my $virtual = get_attribute( $attribute_list, 'oils_persist:virtual' );
+ if( ! defined( $virtual ) ) {
+ $virtual = "false";
+ }
+ my $selector = get_attribute( $attribute_list, 'reporter:selector' );
+
+ $$fieldmap{$fm}{fields}{ $name } =
+ { virtual => ( $virtual eq 'true' ) ? 1 : 0,
+ position => $array_position,
};
- if ($idl->{$c}{fields}{field}{$f}{'reporter:selector'}) {
- $$fieldmap{$n}{selector} = $idl->{$c}{fields}{field}{$f}{'reporter:selector'};
+ # The selector attribute, if present at all, attaches to only one
+ # of the fields in a given class. So if we see it, we store it at
+ # the level of the enclosing class.
+
+ if( defined( $selector ) ) {
+ $$fieldmap{$fm}{selector} = $selector;
}
}
- for my $f ( keys %{ $idl->{$c}{links}{link} } ) {
- $$fieldmap{$n}{links}{$f} =
- { class => $idl->{$c}{links}{link}{$f}{class},
- reltype => $idl->{$c}{links}{link}{$f}{reltype},
- key => $idl->{$c}{links}{link}{$f}{key},
+ }
+}
+
+sub load_links {
+ my $link_list = shift;
+ my $fm = shift;
+
+ for my $link ( $link_list->childNodes() ) { # For each <link>
+ if( $link->nodeName eq 'link' ) {
+ my $attribute_list = $link->attributes();
+
+ my $field = get_attribute( $attribute_list, 'field' );
+ my $reltype = get_attribute( $attribute_list, 'reltype' );
+ my $key = get_attribute( $attribute_list, 'key' );
+ my $class = get_attribute( $attribute_list, 'class' );
+
+ $$fieldmap{$fm}{links}{ $field } =
+ { class => $class,
+ reltype => $reltype,
+ key => $key,
};
}
}
+}
+sub load_class {
+ my $class_node = shift;
+ # Get attributes ---------------------------------------------
+
+ my $attribute_list = $class_node->attributes();
+
+ my $fm = get_attribute( $attribute_list, 'oils_obj:fieldmapper' );
+ $fm = 'Fieldmapper::' . $fm;
+ my $id = get_attribute( $attribute_list, 'id' );
+ my $controller = get_attribute( $attribute_list, 'controller' );
+ my $virtual = get_attribute( $attribute_list, 'virtual' );
+ if( ! defined( $virtual ) ) {
+ $virtual = 'false';
+ }
+ my $tablename = get_attribute( $attribute_list, 'oils_persist:tablename' );
+ if( ! defined( $tablename ) ) {
+ $tablename = '';
+ }
+ my $restrict_primary = get_attribute( $attribute_list, 'oils_persist:restrict_primary' );
+
+ # Load the attributes into the Fieldmapper --------------------
+
+ $log->debug("Building Fieldmapper class for [$fm] from IDL");
+
+ $$fieldmap{$fm}{ hint } = $id;
+ $$fieldmap{$fm}{ virtual } = ( $virtual eq 'true' ) ? 1 : 0;
+ $$fieldmap{$fm}{ table } = $tablename;
+ $$fieldmap{$fm}{ controller } = [ split ' ', $controller ];
+ $$fieldmap{$fm}{ restrict_primary } = $restrict_primary;
+
+ # Load fields and links
+
+ for my $child ( $class_node->childNodes() ) {
+ my $nodeName = $child->nodeName;
+ if( $nodeName eq 'fields' ) {
+ load_fields( $child, $fm );
+ } elsif( $nodeName eq 'links' ) {
+ load_links( $child, $fm );
+ }
+ }
+}
+
+import();
+sub import {
+ my $class = shift;
+ my %args = @_;
+
+ return if (keys %$fieldmap);
+ return if (!OpenSRF::System->connected && !$args{IDL});
+
+ # parse the IDL ...
+ my $parser = XML::LibXML->new();
+ my $file = $args{IDL} || OpenSRF::Utils::SettingsClient->new->config_value( 'IDL' );
+ my $fmdoc = $parser->parse_file( $file );
+ my $rootnode = $fmdoc->documentElement();
+
+ for my $child ( $rootnode->childNodes() ) { # For each <class>
+ my $nodeName = $child->nodeName;
+ if( $nodeName eq 'class' ) {
+ load_class( $child );
+ }
+ }
+
#-------------------------------------------------------------------------------
# Now comes the evil! Generate classes
More information about the open-ils-commits
mailing list