Mercurial > pub > Impl
annotate Lib/IMPL/Web/QueryHandler/JsonFormat.pm @ 138:c5bc900eefd3
IMPL::Web::Application: Fixed file uploading
Minor improvements in the IMPL::Web::TT::Form
author | wizard |
---|---|
date | Thu, 01 Jul 2010 04:25:07 +0400 |
parents | 44977efed303 |
children | fb896377389f |
rev | line source |
---|---|
119 | 1 use strict; |
2 package IMPL::Transform::Json; | |
3 | |
118 | 4 package IMPL::Web::QueryHandler::JsonFormat; |
5 use base qw(IMPL::Web::QueryHandler); | |
6 use Error qw(:try); | |
7 use JSON; | |
8 | |
9 sub Process { | |
10 my ($this,$action,$nextHandler) = @_; | |
11 | |
119 | 12 my $result; |
13 my $t = new IMPL::Transform::Json; | |
118 | 14 |
15 try { | |
16 $result = $nextHandler->(); | |
119 | 17 $result = [$result] unless ref $result; |
118 | 18 } otherwise { |
19 my $err = shift; | |
20 $result = { error => $err }; | |
21 }; | |
22 | |
23 $action->response->contentType('text/javascript'); | |
119 | 24 |
118 | 25 my $hout = $action->response->streamBody; |
119 | 26 print $hout to_json( $t->Transform($result), {pretty => 1} ); |
27 } | |
118 | 28 |
119 | 29 package IMPL::Transform::Json; |
118 | 30 |
31 use base qw(IMPL::Transform); | |
32 use IMPL::Class::Property; | |
134 | 33 use IMPL::Class::Property::Direct; |
34 use Scalar::Util qw(refaddr); | |
35 | |
36 BEGIN { | |
37 private _direct property _visited => prop_none; | |
38 } | |
39 | |
119 | 40 my %propListCache; |
118 | 41 |
42 our %CTOR = ( | |
43 'IMPL::Transform' => sub { | |
119 | 44 ARRAY => sub { |
45 my ($this,$object) = @_; | |
46 | |
47 return [ | |
48 map { $this->Transform($_) } @$object | |
49 ]; | |
50 }, | |
51 HASH => sub { | |
52 my ($this,$object) = @_; | |
53 | |
54 return { | |
55 map { $_, $this->Transform($object->{$_}) } keys %$object | |
56 }; | |
57 }, | |
58 'IMPL::Object::List' => sub { | |
59 my ($this,$object) = @_; | |
60 | |
61 return [ | |
62 map { $this->Transform($_) } @$object | |
63 ]; | |
64 }, | |
65 -plain => sub { | |
66 $_[1]; | |
67 }, | |
68 -default => sub { | |
69 my ($this,$object) = @_; | |
70 | |
71 return "$object" unless $object->isa('IMPL::Object::Abstract'); | |
72 | |
128
08753833173d
Fixed a error handling issue in JSON output: errors are correctly transfered
wizard
parents:
120
diff
changeset
|
73 if ( $object->isa(typeof IMPL::Exception) ) { |
08753833173d
Fixed a error handling issue in JSON output: errors are correctly transfered
wizard
parents:
120
diff
changeset
|
74 return { |
08753833173d
Fixed a error handling issue in JSON output: errors are correctly transfered
wizard
parents:
120
diff
changeset
|
75 type => $object->typeof, |
08753833173d
Fixed a error handling issue in JSON output: errors are correctly transfered
wizard
parents:
120
diff
changeset
|
76 message => $object->Message, |
08753833173d
Fixed a error handling issue in JSON output: errors are correctly transfered
wizard
parents:
120
diff
changeset
|
77 arguments => $this->Transform(scalar $object->Args) |
08753833173d
Fixed a error handling issue in JSON output: errors are correctly transfered
wizard
parents:
120
diff
changeset
|
78 }; |
08753833173d
Fixed a error handling issue in JSON output: errors are correctly transfered
wizard
parents:
120
diff
changeset
|
79 } |
08753833173d
Fixed a error handling issue in JSON output: errors are correctly transfered
wizard
parents:
120
diff
changeset
|
80 |
119 | 81 my $propList = $propListCache{ref $object}; |
82 unless ( $propList ) { | |
83 my %props = map { | |
84 $_->Name, (ref $_->Mutators ? 0 : ($_->Mutators & prop_list)) | |
85 } $object->get_meta('IMPL::Class::PropertyInfo',sub { $_->Access == IMPL::Class::Member::MOD_PUBLIC and $_->Name !~ /^_/}, 1 ); | |
118 | 86 |
119 | 87 $propListCache{ref $object} = $propList = \%props; |
118 | 88 } |
89 | |
90 return { | |
91 map { | |
119 | 92 $_, $propList->{$_} ? $this->Transform([$object->$_()]) : $this->Transform(scalar $object->$_()); |
93 } keys %$propList | |
118 | 94 }; |
95 } | |
96 } | |
97 ); | |
98 | |
134 | 99 sub Transform { |
100 my ($this,$object) = @_; | |
101 | |
102 return $this->SUPER::Transform($object) unless ref $object; | |
103 | |
104 if (exists $this->{$_visited}{refaddr $object}) { | |
105 return $this->{$_visited}{refaddr $object}; | |
106 } else { | |
107 $this->{$_visited}{refaddr $object} = undef; | |
108 return $this->{$_visited}{refaddr $object} = $this->SUPER::Transform($object); | |
109 } | |
110 } | |
111 | |
119 | 112 1; |