[Jifty-commit] r4738 - in jifty/trunk: lib/Jifty lib/Jifty/Plugin/REST

jifty-commit at lists.jifty.org jifty-commit at lists.jifty.org
Tue Dec 18 19:30:23 EST 2007


Author: sartak
Date: Tue Dec 18 19:30:22 2007
New Revision: 4738

Modified:
   jifty/trunk/   (props changed)
   jifty/trunk/lib/Jifty/Plugin/REST/Dispatcher.pm
   jifty/trunk/lib/Jifty/Result.pm
   jifty/trunk/lib/Jifty/Util.pm

Log:
 r49193 at onn:  sartak | 2007-12-18 19:27:52 -0500
 Move the REST object walking into Jifty::Result so that it may be reused


Modified: jifty/trunk/lib/Jifty/Plugin/REST/Dispatcher.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Plugin/REST/Dispatcher.pm	(original)
+++ jifty/trunk/lib/Jifty/Plugin/REST/Dispatcher.pm	Tue Dec 18 19:30:22 2007
@@ -87,142 +87,6 @@
 }
 
 
-=head2 stringify LIST
-
-Takes a list of values and forces them into strings.  Right now all it does
-is concatenate them to an empty string, but future versions might be more
-magical.
-
-=cut
-
-sub stringify {
-    # XXX: allow configuration to specify model fields that are to be
-    # expanded
-    my @r;
-
-    for (@_) {
-        if (UNIVERSAL::isa($_, 'Jifty::Record')) {
-            push @r, reference_to_data($_);
-        }
-        elsif (UNIVERSAL::isa($_, 'Jifty::DateTime')) {
-            push @r, _datetime_to_data($_);
-        }
-        elsif (defined $_) {
-            push @r, '' . $_; # force stringification
-        }
-        else {
-            push @r, undef;
-        }
-    }
-
-    return wantarray ? @r : $r[-1];
-}
-
-=head2 reference_to_data
-
-provides a saner output format for models than MyApp::Model::Foo=HASH(0x1800568)
-
-=cut
-
-sub reference_to_data {
-    my $obj = shift;
-    my ($model) = map { s/::/./g; $_ } ref($obj);
-    return { jifty_model_reference => 1, id => $obj->id, model => $model };
-}
-
-=head2 object_to_data OBJ
-
-Takes an object and converts the known types into simple data structures.
-
-Current known types:
-
-  Jifty::DBI::Collection
-  Jifty::DBI::Record
-  Jifty::DateTime
-
-=cut
-
-sub object_to_data {
-    my $obj = shift;
-    
-    my %types = (
-        'Jifty::DBI::Collection' => \&_collection_to_data,
-        'Jifty::DBI::Record'     => \&_record_to_data,
-        'Jifty::DateTime'        => \&_datetime_to_data,
-    );
-
-    for my $type ( keys %types ) {
-        if ( UNIVERSAL::isa( $obj, $type ) ) {
-            return $types{$type}->( $obj );
-        }
-    }
-
-    # As the last resort, return the object itself and expect the $accept-specific
-    # renderer to format the object as e.g. YAML or JSON data.
-    return $obj;
-}
-
-sub _collection_to_data {
-    my $records = shift->items_array_ref;
-    return [ map { _record_to_data( $_ ) } @$records ];
-}
-
-sub _record_to_data {
-    my $record = shift;
-    # We could use ->as_hash but this method avoids transforming refers_to
-    # columns into JDBI objects
-
-    # XXX: maybe just test ->virtual?
-    my %data   = map {
-                    $_ => (UNIVERSAL::isa( $record->column( $_ )->refers_to,
-                                           'Jifty::DBI::Collection' ) ||
-                           $record->column($_)->container
-                             ? undef
-                             : stringify( $record->_value( $_ ) ) )
-                 } $record->readable_attributes;
-    return \%data;
-}
-
-sub _datetime_to_data {
-    my $dt = shift;
-
-    # if it looks like just a date, then return just the date portion
-    return $dt->ymd
-        if lc($dt->time_zone->name) eq 'floating'
-        && $dt->hms('') eq '000000';
-
-    # otherwise let stringification take care of it
-    return $dt;
-}
-
-=head2 recurse_object_to_data REF
-
-Takes a reference, and calls C<object_to_data> on it if that is
-meaningful.  If it is an arrayref, or recurses on each element.  If it
-is a hashref, recurses on each value.  Returns the new datastructure.
-
-=cut
-
-sub recurse_object_to_data {
-    my $o = shift;
-    return $o unless ref $o;
-
-    my $updated = object_to_data($o);
-    if ($o ne $updated) {
-        return $updated;
-    } elsif (ref $o eq "ARRAY") {
-        my @a = map {recurse_object_to_data($_)} @{$o};
-        return \@a;
-    } elsif (ref $o eq "HASH") {
-        my %h;
-        $h{$_} = recurse_object_to_data($o->{$_}) for keys %{$o};
-        return \%h;
-    } else {
-        return $o;
-    }
-}
-
-
 =head2 list PREFIX items
 
 Takes a URL prefix and a set of items to render. passes them on.
@@ -528,7 +392,8 @@
     $col->order_by( column => $column );
 
     list( [ 'model', $model, $column ],
-        map { stringify($_->$column()) } @{ $col->items_array_ref || [] } );
+        map { Jifty::Util->stringify($_->$column()) }
+            @{ $col->items_array_ref || [] } );
 }
 
 
@@ -549,7 +414,8 @@
     # Check that the field is actually a column (and not some other method)
     abort(404) if not scalar grep { $_->name eq $field } $rec->columns;
 
-    outs( [ 'model', $model, $column, $key, $field ], stringify($rec->$field()) );
+    outs( [ 'model', $model, $column, $key, $field ],
+          Jifty::Util->stringify($rec->$field()) );
 }
 
 =head2 show_item $model, $column, $key
@@ -565,7 +431,9 @@
     my $rec = $model->new;
     $rec->load_by_cols( $column => $key );
     $rec->id or abort(404);
-    outs( ['model', $model, $column, $key],  { map {$_ => stringify($rec->$_())} map {$_->name} $rec->columns});
+    outs( ['model', $model, $column, $key], 
+        { map { $_ => Jifty::Util->stringify($rec->$_()) }
+              map {$_->name} $rec->columns});
 }
 
 =head2 create_item
@@ -769,24 +637,8 @@
         } 'model', ref($rec), 'id', $rec->id);
         Jifty->handler->apache->header_out('Location' => $url);
     }
-    
-    my $result = $action->result;
 
-    my $out = {};
-    $out->{success} = $result->success;
-    $out->{message} = $result->message;
-    $out->{error} = $result->error;
-    $out->{field_errors} = {$result->field_errors};
-    for (keys %{$out->{field_errors}}) {
-        delete $out->{field_errors}->{$_} unless $out->{field_errors}->{$_};
-    }
-    $out->{field_warnings} = {$result->field_warnings};
-    for (keys %{$out->{field_warnings}}) {
-        delete $out->{field_warnings}->{$_} unless $out->{field_warnings}->{$_};
-    }
-    $out->{content} = recurse_object_to_data($result->content);
-    
-    outs(undef, $out);
+    outs(undef, $action->result->as_hash);
 
     last_rule;
 }

Modified: jifty/trunk/lib/Jifty/Result.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Result.pm	(original)
+++ jifty/trunk/lib/Jifty/Result.pm	Tue Dec 18 19:30:22 2007
@@ -179,4 +179,116 @@
     return $self->_content->{$key};
 }
 
+=head2 as_hash
+
+This returns the results as a hash to be given directly to the end user
+(usually via REST or webservices). The difference between
+C<< $result->as_hash >> and C<%$result> is that the latter will expand
+everything as deeply as possible. The former won't inflate C<refers_to>
+columns, among other things.
+
+=cut
+
+sub as_hash {
+    my $self = shift;
+
+    my $out = {
+        success        => $self->success,
+        message        => $self->message,
+        error          => $self->error,
+        field_errors   => { $self->field_errors },
+        field_warnings => { $self->field_warnings },
+        content        => $self->_recurse_object_to_data($self->content),
+    };
+
+    for (keys %{$out->{field_errors}}) {
+        delete $out->{field_errors}->{$_} unless $out->{field_errors}->{$_};
+    }
+    for (keys %{$out->{field_warnings}}) {
+        delete $out->{field_warnings}->{$_} unless $out->{field_warnings}->{$_};
+    }
+
+    return $out;
+}
+
+sub _recurse_object_to_data {
+    my $self = shift;
+    my $o = shift;
+
+    return $o if !ref($o);
+
+    if (ref($o) eq 'ARRAY') {
+        return [ map { $self->_recurse_object_to_data($_) } @$o ];
+    }
+    elsif (ref($o) eq 'HASH') {
+        my %h;
+        $h{$_} = $self->_recurse_object_to_data($o->{$_}) for keys %$o;
+        return \%h;
+    }
+
+    return $self->_object_to_data($o);
+}
+
+sub _object_to_data {
+    my $self = shift;
+    my $o = shift;
+
+    my %types = (
+        'Jifty::DBI::Collection' => \&_collection_to_data,
+        'Jifty::DBI::Record'     => \&_record_to_data,
+        'Jifty::DateTime'        => \&_datetime_to_data,
+    );
+
+    for my $type (keys %types) {
+        if (UNIVERSAL::isa($o, $type)) {
+            return $types{$type}->($self, $o);
+        }
+    }
+
+    # As the last resort, return the object itself and expect the
+    # $accept-specific renderer to format the object as e.g. YAML or JSON data.
+    return $o;
+}
+
+# return an arrayref of the records
+sub _collection_to_data {
+    my $self = shift;
+    my $records = shift->items_array_ref;
+
+    return [ map { $self->_record_to_data($_) } @$records ];
+}
+
+# We could use ->as_hash but this method avoids transforming refers_to
+# columns into JDBI objects
+sub _record_to_data {
+    my $self   = shift;
+    my $record = shift;
+    my %data;
+
+    # XXX: maybe just test ->virtual?
+    for ($record->readable_attributes) {
+        next if UNIVERSAL::isa($record->column($_)->refers_to,
+                               'Jifty::DBI::Collection');
+        next if $record->column($_)->container;
+
+        $data{$_} = Jifty::Util->stringify($record->_value($_));
+    }
+
+    return \%data;
+}
+
+# returns a datetime string consistent with the Jifty "date" magic
+sub _datetime_to_data {
+    my $self = shift;
+    my $dt = shift;
+
+    # if it looks like just a date, then return just the date portion
+    return $dt->ymd
+        if lc($dt->time_zone->name) eq 'floating'
+        && $dt->hms('') eq '000000';
+
+    # otherwise let stringification take care of it
+    return $dt;
+}
+
 1;

Modified: jifty/trunk/lib/Jifty/Util.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Util.pm	(original)
+++ jifty/trunk/lib/Jifty/Util.pm	Tue Dec 18 19:30:22 2007
@@ -334,6 +334,47 @@
     })->create_str;
 }
 
+=head2 reference_to_data Object
+
+Provides a saner output format for models than
+C<MyApp::Model::Foo=HASH(0x1800568)>.
+
+=cut
+
+sub reference_to_data {
+    my ($self, $obj) = @_;
+    (my $model = ref($obj)) =~ s/::/./g;
+    return { jifty_model_reference => 1, id => $obj->id, model => $model };
+}
+
+=head2 stringify LIST
+
+Takes a list of values and forces them into strings.  Right now all it does
+is concatenate them to an empty string, but future versions might be more
+magical.
+
+=cut
+
+sub stringify {
+    my $self = shift;
+
+    my @r;
+
+    for (@_) {
+        if (UNIVERSAL::isa($_, 'Jifty::Record')) {
+            push @r, Jifty::Util->reference_to_data($_);
+        }
+        elsif (defined $_) {
+            push @r, '' . $_; # force stringification
+        }
+        else {
+            push @r, undef;
+        }
+    }
+
+    return wantarray ? @r : $r[-1];
+}
+
 =head1 AUTHOR
 
 Various folks at Best Practical Solutions, LLC.


More information about the Jifty-commit mailing list