package Catalyst::Controller::JMS;
$Catalyst::Controller::JMS::VERSION = '1.3';
  $Catalyst::Controller::JMS::DIST = 'Catalyst-ActionRole-JMS';
use Moose;
use namespace::autoclean;

# ABSTRACT: controller base class to simplify usage of Catalyst::ActionRole::JMS

BEGIN { extends 'Catalyst::Controller' }

    stash_key => 'message',
    default => 'application/json',
    map => {
        'application/json'   => 'JSON',
        'text/x-json'        => 'JSON',

around create_action => sub {
    my ($orig, $self, %args) = @_;

    return $self->$orig(%args)
        if $args{name} =~ /^_(DISPATCH|BEGIN|AUTO|ACTION|END)$/;

    my $type = delete $args{attributes}->{MessageTarget};
    if ($type) {
        $args{attributes}->{Path} = [$self->path_prefix()];
        $args{attributes}->{JMSType} = [$type->[0] || $args{name}];
        $args{attributes}->{Does} = [ 'Catalyst::ActionRole::JMS' ];

    return $self->$orig(%args);

sub begin :ActionClass('Deserialize') { }

sub end :ActionClass('Serialize') {
    my ($self,$c) = @_;

    $c->stash->{message} = [$c->stash->{message}]
        unless ref($c->stash->{message});





=encoding UTF-8

=head1 NAME

Catalyst::Controller::JMS - controller base class to simplify usage of Catalyst::ActionRole::JMS

=head1 VERSION

version 1.3


  package MyApp::Controller::Something;
  use Moose;

  BEGIN { extends 'Catalyst::Controller::JMS' }

    namespace => 'queue/my_queue',

  sub my_message_type :MessageTarget {
    my ($self,$c) = @_;

    my $body = $c->req->data;
    my $headers = $c->req->headers;

    # do something

    $c->res->header('X-Reply-Address' => 'temporary-queue-name');
    $c->stash->{message} = { some => [ 'reply', 'message' ] };



This controller base class makes it easy to handle JMS-style messages
in your Catalyst application. It handles deserialisation and
serialisation transparently (thanks to
L<Catalyst::Action::Deserialize> and L<Catalyst::Action::Serialize>)
and sets up the attributes needed by L<Catalyst::ActionRole::JMS>. It
also sets up some sensible default configuration.


    stash_key => 'message',
    default => 'application/json',
    map => {
      'application/json'   => 'JSON',
      'text/x-json'        => 'JSON',

See L<Catalyst::Action::Deserialize> and
L<Catalyst::Action::Serialize> for what this means.

=head1 ACTIONS

=head2 Your actions

If you set the C<MessageTarget> attribute on an action, it will be
marked for dispatch based on the JMSType of incoming messages. More

  sub my_message_type :MessageTarget { }

is equivalent to:

  sub my_message_type : Does('Catalyst::ActionRole::JMS')
   { }


  sub my_action :MessageTarget('my_type') { }

is equivalent to:

  sub my_action : Does('Catalyst::ActionRole::JMS')
   { }

If you want to have a C<default> action to catch requests not matching
any other action, you have to declare it as:

  sub default :Default { }

otherwise dispatch may not work properly, see for
some attempts at an explanation

=head2 C<begin>

De-serialises the body of the request into C<< $ctx->req->data >>. See
L<Catalyst::Action::Deserialize> for details.

=head2 C<end>

Serialises C<< $ctx->stash->{message} >> into the response body. See
L<Catalyst::Action::Serialize> for details.

B<NOTE>: if C<< $ctx->stash->{message} >> is not a reference, it will
be wrapped in an arrayref. Some L<Catalyst::Action::Serialize> plugins
don't like serialising plain scalars.


You can find examples of use in the tests, or at

=head1 AUTHOR

Gianni Ceccarelli <>


This software is copyright (c) 2011 by

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.