| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Mojolicious::Plugin::XML::Loy; | 
| 2 | 1 |  |  | 1 |  | 649 | use Mojo::Base 'Mojolicious::Plugin'; | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 10 |  | 
| 3 | 1 |  |  | 1 |  | 186 | use Mojo::Loader qw/load_class/; | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 55 |  | 
| 4 | 1 |  |  | 1 |  | 11 | use Mojo::Util qw!deprecated!; | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 34 |  | 
| 5 | 1 |  |  | 1 |  | 544 | use XML::Loy; | 
|  | 1 |  |  |  |  | 4566 |  | 
|  | 1 |  |  |  |  | 4 |  | 
| 6 |  |  |  |  |  |  |  | 
| 7 |  |  |  |  |  |  | our $VERSION = '0.14'; | 
| 8 |  |  |  |  |  |  |  | 
| 9 |  |  |  |  |  |  | my %base_classes; | 
| 10 |  |  |  |  |  |  |  | 
| 11 |  |  |  |  |  |  | # Register Plugin | 
| 12 |  |  |  |  |  |  | sub register { | 
| 13 | 2 |  |  | 2 | 1 | 6408 | my ($plugin, $mojo, $param) = @_; | 
| 14 |  |  |  |  |  |  |  | 
| 15 | 2 |  |  |  |  | 3 | my $namespace = 'XML::Loy::'; | 
| 16 | 2 |  |  |  |  | 3 | my $max_size = 1024 * 1024; | 
| 17 |  |  |  |  |  |  |  | 
| 18 |  |  |  |  |  |  | # Load parameter from Config file | 
| 19 | 2 | 50 |  |  |  | 10 | if (my $config_param = $mojo->config('XML-Loy')) { | 
| 20 | 0 |  |  |  |  | 0 | $param = { %$param, %$config_param }; | 
| 21 |  |  |  |  |  |  | }; | 
| 22 |  |  |  |  |  |  |  | 
| 23 | 2 | 100 | 66 |  |  | 39 | if (exists $param->{max_size} && $param->{max_size} =~ /^\d+$/) { | 
| 24 | 1 |  |  |  |  | 2 | $max_size = delete $param->{max_size}; | 
| 25 |  |  |  |  |  |  | }; | 
| 26 |  |  |  |  |  |  |  | 
| 27 |  |  |  |  |  |  | # Create new XML helpers | 
| 28 | 2 |  |  |  |  | 6 | foreach my $helper (keys %$param) { | 
| 29 |  |  |  |  |  |  |  | 
| 30 |  |  |  |  |  |  | # Already defined | 
| 31 | 5 | 100 |  |  |  | 82 | if (exists $mojo->renderer->helpers->{$helper}) { | 
| 32 | 1 |  |  |  |  | 11 | $mojo->log->debug("Helper '$helper' already defined"); | 
| 33 | 1 |  |  |  |  | 22 | next; | 
| 34 |  |  |  |  |  |  | }; | 
| 35 |  |  |  |  |  |  |  | 
| 36 | 4 |  |  |  |  | 33 | my @helper = @{ $param->{ $helper } }; | 
|  | 4 |  |  |  |  | 12 |  | 
| 37 | 4 |  |  |  |  | 6 | my $base = shift @helper; | 
| 38 |  |  |  |  |  |  |  | 
| 39 | 4 | 100 |  |  |  | 8 | $base = 'XML::Loy' if $base eq '-Loy'; | 
| 40 |  |  |  |  |  |  |  | 
| 41 | 4 | 100 |  |  |  | 10 | if (index($base, '-') == 0) { | 
| 42 | 3 |  |  |  |  | 10 | $base =~ s/^-//; | 
| 43 | 3 | 50 |  |  |  | 10 | $base = ($base eq 'Loy' ? 'XML::Loy' : $namespace . "$base"); | 
| 44 |  |  |  |  |  |  | }; | 
| 45 |  |  |  |  |  |  |  | 
| 46 |  |  |  |  |  |  | # Load module if not loaded | 
| 47 | 4 | 100 |  |  |  | 7 | unless (exists $base_classes{$base}) { | 
| 48 |  |  |  |  |  |  |  | 
| 49 |  |  |  |  |  |  | # Load base class | 
| 50 | 3 | 50 |  |  |  | 7 | if (my $e = load_class $base) { | 
| 51 | 0 |  |  |  |  | 0 | for ($mojo->log) { | 
| 52 | 0 | 0 |  |  |  | 0 | $_->error("Exception: $e")  if ref $e; | 
| 53 | 0 |  |  |  |  | 0 | $_->error(qq{Unable to load base class "$base"}); | 
| 54 |  |  |  |  |  |  | }; | 
| 55 | 0 |  |  |  |  | 0 | next; | 
| 56 |  |  |  |  |  |  | }; | 
| 57 |  |  |  |  |  |  |  | 
| 58 | 3 |  |  |  |  | 5950 | my $mime   = $base->mime; | 
| 59 | 3 |  |  |  |  | 39 | my $prefix = $base->_prefix; | 
| 60 |  |  |  |  |  |  |  | 
| 61 |  |  |  |  |  |  | # Establish mime types | 
| 62 | 3 | 100 | 66 |  |  | 28 | if ($mime && $prefix) { | 
| 63 |  |  |  |  |  |  |  | 
| 64 |  |  |  |  |  |  | # Apply mime type | 
| 65 | 2 |  |  |  |  | 10 | $mojo->types->type($prefix => $mime); | 
| 66 |  |  |  |  |  |  | }; | 
| 67 |  |  |  |  |  |  |  | 
| 68 |  |  |  |  |  |  | # module loaded | 
| 69 | 3 |  |  |  |  | 84 | $base_classes{$base} = [$prefix => $mime]; | 
| 70 |  |  |  |  |  |  | }; | 
| 71 |  |  |  |  |  |  |  | 
| 72 |  |  |  |  |  |  | # Code generation for ad-hoc helper | 
| 73 | 4 |  |  |  |  | 10 | my $code = 'sub { shift;' . | 
| 74 |  |  |  |  |  |  | ' { use bytes; return if length("@_") > ' . $max_size . '} ' . | 
| 75 |  |  |  |  |  |  | ' my $doc = ' . $base . '->new( @_ );'; | 
| 76 |  |  |  |  |  |  |  | 
| 77 |  |  |  |  |  |  | # Extend base class | 
| 78 | 4 | 100 |  |  |  | 9 | if (@helper) { | 
| 79 | 3 |  |  |  |  | 13 | $code .= '$doc->extension(' . | 
| 80 |  |  |  |  |  |  | join(',', map( '"' . qq{$_"}, @helper)) . | 
| 81 |  |  |  |  |  |  | ");"; | 
| 82 |  |  |  |  |  |  | }; | 
| 83 | 4 |  |  |  |  | 4 | $code .= 'return $doc };'; | 
| 84 |  |  |  |  |  |  |  | 
| 85 |  |  |  |  |  |  | # Eval code | 
| 86 | 1 |  |  | 1 |  | 4 | my $code_ref = eval $code; | 
|  | 1 |  |  | 1 |  | 1 |  | 
|  | 1 |  |  | 1 |  | 7 |  | 
|  | 1 |  |  | 1 |  | 7 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 6 |  | 
|  | 1 |  |  |  |  | 8 |  | 
|  | 1 |  |  |  |  | 3 |  | 
|  | 1 |  |  |  |  | 3 |  | 
|  | 1 |  |  |  |  | 5 |  | 
|  | 1 |  |  |  |  | 1 |  | 
|  | 1 |  |  |  |  | 3 |  | 
|  | 4 |  |  |  |  | 263 |  | 
| 87 |  |  |  |  |  |  |  | 
| 88 |  |  |  |  |  |  | # Evaluation error | 
| 89 | 4 | 50 | 0 |  |  | 17 | $mojo->log->fatal($@ . ': ' . $!) and next if $@; | 
| 90 |  |  |  |  |  |  |  | 
| 91 |  |  |  |  |  |  | # Create helper | 
| 92 | 4 |  |  |  |  | 18 | $mojo->helper($helper => $code_ref); | 
| 93 |  |  |  |  |  |  | }; | 
| 94 |  |  |  |  |  |  |  | 
| 95 |  |  |  |  |  |  | # Plugin wasn't registered before | 
| 96 | 2 | 100 |  |  |  | 19 | unless (exists $mojo->renderer->helpers->{'new_xml'}) { | 
| 97 |  |  |  |  |  |  |  | 
| 98 |  |  |  |  |  |  | # Default 'new_xml' helper | 
| 99 |  |  |  |  |  |  | $mojo->helper( | 
| 100 |  |  |  |  |  |  | new_xml => sub { | 
| 101 | 3 |  |  | 3 |  | 21527 | shift; | 
| 102 | 3 |  |  |  |  | 17 | return XML::Loy->new( @_ ); | 
| 103 | 1 |  |  |  |  | 11 | }); | 
| 104 |  |  |  |  |  |  |  | 
| 105 |  |  |  |  |  |  | my $reply_xml = sub { | 
| 106 | 5 |  |  | 5 |  | 2628 | my ($c, $xml) = @_; | 
| 107 | 5 |  |  |  |  | 11 | my $format = 'xml'; | 
| 108 |  |  |  |  |  |  |  | 
| 109 |  |  |  |  |  |  | # Check format based on mime type | 
| 110 | 5 |  |  |  |  | 8 | my $class = ref $xml; | 
| 111 | 5 | 50 |  |  |  | 20 | if ($base_classes{$class}) { | 
| 112 | 5 | 50 | 66 |  |  | 23 | if ($base_classes{$class}->[0] && $base_classes{$class}->[1]) { | 
| 113 | 2 |  |  |  |  | 4 | $format = $base_classes{$class}->[0]; | 
| 114 |  |  |  |  |  |  | }; | 
| 115 |  |  |  |  |  |  | }; | 
| 116 |  |  |  |  |  |  |  | 
| 117 |  |  |  |  |  |  | # render XML with correct mime type | 
| 118 | 5 |  |  |  |  | 21 | return $c->render( | 
| 119 |  |  |  |  |  |  | 'data'   => $xml->to_pretty_xml, | 
| 120 |  |  |  |  |  |  | 'format' => $format, | 
| 121 |  |  |  |  |  |  | @_ | 
| 122 |  |  |  |  |  |  | ); | 
| 123 | 1 |  |  |  |  | 10 | }; | 
| 124 |  |  |  |  |  |  |  | 
| 125 |  |  |  |  |  |  | # Add 'render_xml' helper | 
| 126 |  |  |  |  |  |  | $mojo->helper( | 
| 127 |  |  |  |  |  |  | render_xml => sub { | 
| 128 | 1 |  |  | 1 |  | 790 | deprecated 'render_xml is deprecated in favor of reply->xml'; | 
| 129 | 1 |  |  |  |  | 306 | $reply_xml->(@_); | 
| 130 |  |  |  |  |  |  | } | 
| 131 | 1 |  |  |  |  | 4 | ); | 
| 132 |  |  |  |  |  |  |  | 
| 133 |  |  |  |  |  |  | # Add 'reply->xml' helper | 
| 134 | 1 |  |  |  |  | 10 | $mojo->helper('reply.xml' => $reply_xml); | 
| 135 |  |  |  |  |  |  | }; | 
| 136 |  |  |  |  |  |  | }; | 
| 137 |  |  |  |  |  |  |  | 
| 138 |  |  |  |  |  |  |  | 
| 139 |  |  |  |  |  |  | 1; | 
| 140 |  |  |  |  |  |  |  | 
| 141 |  |  |  |  |  |  |  | 
| 142 |  |  |  |  |  |  | __END__ |