[Jifty-commit] r7021 - jifty/branches/webservices-in-td/lib/Jifty/Web
Jifty commits
jifty-commit at lists.jifty.org
Tue May 12 20:43:29 EDT 2009
Author: ruz
Date: Tue May 12 20:43:28 2009
New Revision: 7021
Added:
jifty/branches/webservices-in-td/lib/Jifty/Web/Services.pm
Log:
* add Jifty::Web::Services
Added: jifty/branches/webservices-in-td/lib/Jifty/Web/Services.pm
==============================================================================
--- (empty file)
+++ jifty/branches/webservices-in-td/lib/Jifty/Web/Services.pm Tue May 12 20:43:28 2009
@@ -0,0 +1,175 @@
+package Jifty::Web::Services;
+
+use strict;
+use warnings;
+
+use base qw(Jifty::Object);
+
+use Scalar::Util qw(blessed);
+use XML::Simple;
+use Jifty::JSON;
+use Jifty::YAML;
+
+sub JSON {
+ my $self = shift;
+
+ Jifty->handler->apache->content_type("text/x-json");
+
+ my %results = Jifty->web->response->results;
+ for (values %results) {
+ $_ = $_->as_hash;
+
+ # backwards compatibility :(
+ $_->{_content} = delete $_->{content};
+ }
+ Jifty->web->out( Jifty::JSON::objToJson(\%results) );
+}
+
+sub YAML {
+ my $self = shift;
+
+ Jifty->handler->apache->content_type("text/x-yaml");
+
+ my %results = Jifty->web->response->results;
+ for (values %results) {
+ $_ = $_->as_hash;
+
+ # backwards compatibility :(
+ $_->{_content} = delete $_->{content};
+ }
+ Jifty->web->out( Jifty::YAML::Dump(\%results) );
+}
+
+sub XML {
+ my $self = shift;
+
+ Jifty->handler->apache->content_type('text/xml; charset=utf-8');
+
+ my $output = "";
+ my $writer = XML::Writer->new( OUTPUT => \$output, UNSAFE => 1 );
+ $writer->xmlDecl( "UTF-8", "yes" );
+ $writer->startTag("response");
+
+ if (my $ext = Jifty->web->request->argument('_webservice_external_redirect')) {
+ $writer->startTag("redirect");
+ $writer->cdataElement(url=> $ext);
+ $writer->endTag;
+ $writer->endTag;
+ Jifty->web->out($output);
+ return;
+ }
+
+ FRAGMENT:
+ for my $fragment ( Jifty->web->request->fragments ) {
+ # Set up the form if need be
+ Jifty->web->form->_init;
+ Jifty->web->form->is_open(1) if $fragment->in_form;
+
+ # Set up the region stack
+ local Jifty->web->{'region_stack'} = [];
+ my @regions;
+ do {
+ push @regions, $fragment;
+ } while ($fragment = $fragment->parent);
+
+ for my $current (reverse @regions) {
+ my $new = Jifty->web->get_region( join '-', grep {$_} Jifty->web->qualified_region, $current->name );
+
+ # Arguments can be complex mapped hash values. Get their
+ # real values by mapping.
+ my %defaults = %{$current->arguments || {}};
+ for (keys %defaults) {
+ my ($key, $value) = Jifty::Request::Mapper->map(destination => $_, source => $defaults{$_});
+ delete $defaults{$_};
+ $defaults{$key} = $value;
+ }
+
+ $new ||= Jifty::Web::PageRegion->new(
+ name => $current->name,
+ path => URI::Escape::uri_unescape($current->path),
+ region_wrapper => $current->wrapper,
+ parent => Jifty->web->current_region,
+ defaults => \%defaults,
+ );
+
+ # It's possible that the pageregion creation could fail -- no
+ # name, for instance. In that case, bail on this fragment.
+ next FRAGMENT unless $new;
+
+ $new->enter;
+ }
+
+ # Stuff the rendered region into the XML
+ my $current_region = Jifty->web->current_region;
+ $writer->startTag( "fragment", id => $current_region->qualified_name );
+ my $args = $current_region->arguments;
+ $writer->dataElement( "argument", $args->{$_}, name => $_) for sort keys %$args;
+ if (Jifty->config->framework('ClientTemplate') && $current_region->client_cacheable) {
+ $writer->cdataElement( "cacheable", $current_region->client_cache_content, type => $current_region->client_cacheable );
+ }
+ $writer->cdataElement( "content", $current_region->as_string );
+ $writer->endTag();
+
+ # Clean up region stack and form
+ Jifty->web->current_region->exit while Jifty->web->current_region;
+ Jifty->web->form->is_open(0);
+ }
+
+ my %results = Jifty->web->response->results;
+ for (keys %results) {
+ $writer->startTag("result", moniker => $_, class => $results{$_}->action_class);
+ $writer->dataElement("success", $results{$_}->success);
+
+ $writer->dataElement("message", $results{$_}->message) if $results{$_}->message;
+ $writer->dataElement("error", $results{$_}->error) if $results{$_}->error;
+
+ my %warnings = $results{$_}->field_warnings;
+ my %errors = $results{$_}->field_errors;
+ my %fields; $fields{$_}++ for keys(%warnings), keys(%errors);
+ for (sort keys %fields) {
+ next unless $warnings{$_} or $errors{$_};
+ $writer->startTag("field", name => $_);
+ $writer->dataElement("warning", $warnings{$_}) if $warnings{$_};
+ $writer->dataElement("error", $errors{$_}) if $errors{$_};
+ $writer->endTag();
+ }
+
+ # XXX TODO: Hack because we don't have a good way to serialize
+ # Jifty::DBI::Record's yet, which are technically circular data
+ # structures at some level (current_user of a
+ # current_user->user_object is itself)
+ my $content = stripkids($results{$_}->content);
+ $writer->raw(XML::Simple::XMLout($content, NoAttr => 1, RootName => "content", NoIndent => 1))
+ if keys %{$content};
+
+ $writer->endTag();
+ }
+
+ $writer->endTag();
+ Jifty->handler->apache->content_type('text/xml; charset=UTF-8');
+ Jifty->web->out($output);
+}
+
+sub stripkids {
+ my $top = shift;
+ if ( not ref $top ) {
+ return $top
+ }
+ elsif (
+ blessed($top)
+ and ( $top->isa("Jifty::DBI::Record")
+ or $top->isa("Jifty::DBI::Collection") )
+ )
+ {
+ return undef;
+ }
+ elsif ( ref $top eq 'HASH' ) {
+ $top->{$_} = stripkids( $top->{$_} ) foreach keys %$top;
+ }
+ elsif ( ref $top eq 'ARRAY' ) {
+ push @$top, stripkids( $_ ) foreach splice @$top;
+ }
+ return $top;
+}
+
+1;
More information about the Jifty-commit
mailing list