generate methods after loading the IDL
[Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / PermaCrud.pm
index 7ef4e15..14bc8c4 100644 (file)
@@ -1,3 +1,5 @@
+# vim:et:ts=4:sw=4:
+
 package OpenILS::Application::PermaCrud;
 use OpenILS::Application;
 use base qw/OpenILS::Application/;
@@ -44,6 +46,8 @@ sub initialize {
     $idl = $parser->parse_file( $idl_file );
 
     $log->debug( 'IDL XML file loaded' );
+
+    generate_methods();
 }
 sub child_init {}
 
@@ -63,15 +67,23 @@ sub CRUD_action_object_permcheck {
         );
     }
 
-    my $action = $self->api_name =~ s/^open-ils\.admin\.([^\.])\..+$/$1/o;
-    my $o_type = $obj->cdbi =~ s/::/./go;
-
     my ($class_node) = $xpc->findnodes( "//idl:class[\@id='$self->{class_hint}']", $idl->documentElement );
     my ($action_node) = $xpc->findnodes( "perm:permacrud/perm:actions/perm:$action", $class_node );
+    my $all_perms = $xpc->getAttribute( 'all_perms', $action_node );
+
+    if (!ref($obj)) {
+        my $retrieve_method = 'retrieve_' . $xpc->findvalue( '@oils_obj:fieldmapper', $class_node );
+        $retrieve_method =~ s/::/_/go;
+        $obj = $e->retrieve_method( $obj )->gather(1);
+    }
+
+    my $action = $self->api_name =~ s/^open-ils\.admin\.([^\.])\..+$/$1/o;
+    my $o_type = $obj->cdbi =~ s/::/./go;
+    my $id_field = $obj->Identity;
 
     my $perm_field_value = $aciton_node->getAttribute('permission');
 
-    if (defined($perm_field_value)) 
+    if (defined($perm_field_value)) {
         my @perms = split '|', $aciton_node->getAttribute('permission');
 
         my @context_ous;
@@ -88,57 +100,103 @@ sub CRUD_action_object_permcheck {
                     my $context_field = $context_node->getAttribute('field');
                     my $link_field = $context_node->getAttribute('link');
 
-                    my ($link_node) = $xpc->findnodes( "idl:links/idl:link[\@field='$link_field']", $class_node );
-                    my $link_class_hint = $link_node->getAttribute('class');
-                    my $remote_field = $link_node->getAttribute('key');
+                    if ($link_field) {
 
-                    my ($remote_class_node) = $xpc->findnodes( "//idl:class[\@id='$self->{class_hint}']", $idl->documentElement );
-                    my $search_method = 'search_' . $xpc->findvalue( '@oils_obj:fieldmapper', $remote_class_node );
-                    $search_method =~ s/::/_/go;
+                        my ($link_node) = $xpc->findnodes( "idl:links/idl:link[\@field='$link_field']", $class_node );
+                        my $link_class_hint = $link_node->getAttribute('class');
+                        my $remote_field = $link_node->getAttribute('key');
 
-                    for my $remote_object ( @{$e->$search_method( { $key => $obj->$link_field } )} ) {
-                        push @context_ous, $remote_object->$context_field;
+                        my ($remote_class_node) = $xpc->findnodes( "//idl:class[\@id='$self->{class_hint}']", $idl->documentElement );
+                        my $search_method = 'search_' . $xpc->findvalue( '@oils_obj:fieldmapper', $remote_class_node );
+                        $search_method =~ s/::/_/go;
+
+                        for my $remote_object ( @{$e->$search_method( { $key => $obj->$link_field } )} ) {
+                            push @context_ous, $remote_object->$context_field;
+                        }
+                    } else {
+                        push @context_ous, $obj->$_ for ( split '|', $context_field );
                     }
                 }
             }
         }
 
-        my ($pok, $cok) = (0, 0);
+        my $pok = 0;
         for my $perm (@perms) {
-            for my $c_ou (@context_ous) {
-                if ($e->allowed($perm => $c_ou => $obj)) {
-                    $cok++;
-                    last;
+            if (@context_ous) {
+                for my $c_ou (@context_ous) {
+                    if ($e->allowed($perm => $c_ou => $obj)) {
+                        $pok++;
+                        last;
+                    }
                 }
+            } else {
+                $pok++ if ($e->allowed($perm => undef => $obj));
             }
-            $pok++ if ($cok);
-            $cok = 0;
         }
 
-        unless (@perms == $pok) {
+        if ((lc($all_perms) eq 'true' && @perms != $pok) or !$pok) {
             throw OpenSRF::DomainObject::oilsException->new(
                 statusCode => 500,
                 status => "Perm failure -- action: $action, object type: $self->{json_hint}",
             );
         }
     }
+
+    return $obj if ($action eq 'retrieve');
+
+    return $e->session->request("open-ils.cstore.direct.$o_type.$action" => $obj )->gather(1);
 }
 
-for my $class_node ( $xpc->findnodes( "perm:permacrud/perm:actions/perm:$action", $class_node ) ) {
-    my $hint = $class_node->getAttribute('id');
+sub search_permacrud {
+    my $self = shift;
+    my $client = shift;
+    my $auth = shift;
+    my @args = @_;
 
-    for my $action_node ( $xpc->findnodes( "perm:permacrud/perm:actions/perm:*", $class_node ) ) {
-        my $method = $action_node->localname =~ s/^.+:(.+)$/$1/o;
+    my $e = new_editor(authtoken => $auth);
+    return $e->event unless $e->checkauth;
+    my ($class_node) = $xpc->findnodes( "//idl:class[\@id='$self->{class_hint}']", $idl->documentElement );
+    my $search_method = 'search_' . $xpc->findvalue( '@oils_obj:fieldmapper', $remote_class_node );
+    $search_method =~ s/::/_/go;
 
-        __PACKAGE__->register_method(
-            method      => 'CRUD_action_object_permcheck',
-            api_name    => 'open-ils.permacrud.' . $method . '.' . $hint,
-            class_hint  => $hint,
-        );
+    my $retriever = $self->method_lookup( $self->{retriever} );
+    my $obj_list = $e->$search_method( @args );
 
+    for my $o ( @$obj_list ) {
+        my ($o) = $retriever->run( $o );
+        $client->respond( $o ) if ($o);
     }
+
+    return undef;
 }
+
+sub generate_methods {
+    for my $class_node ( $xpc->findnodes( '//idl:class[perm:permacrud]', $idl->documentElement ) ) {
+        my $hint = $class_node->getAttribute('id');
     
+        for my $action_node ( $xpc->findnodes( "perm:permacrud/perm:actions/perm:*", $class_node ) ) {
+            my $method = $action_node->localname =~ s/^.+:(.+)$/$1/o;
+    
+            __PACKAGE__->register_method(
+                method          => 'CRUD_action_object_permcheck',
+                api_name        => 'open-ils.permacrud.' . $method . '.' . $hint,
+                authoritative   => 1,
+                class_hint      => $hint,
+            );
+    
+            if ($method eq 'retrieve') {
+                __PACKAGE__->register_method(
+                    method      => 'search_permcheck',
+                    api_name    => 'open-ils.permacrud.search.' . $hint,
+                    class_hint  => $hint,
+                    retriever   => 'open-ils.permacrud.retrieve.' . $hint,
+                    stream      => 1
+                );
+            }
+        }
+    }
+}
 
 
 1;