带验证器的Perl Workflow模块

时间:2015-01-13 12:02:17

标签: perl workflow validation

我正在尝试使用perl Workflow模块 - http://search.cpan.org/~jonasbn/Workflow/

我设法弄清楚它是如何与工作流程,操作,条件和所有工作一起工作的,但我无法让它将验证器类应用于该操作。

来自验证器的我的_init方法加载并打印出我放在那里进行测试的行,但验证方法不会被触发。此外,当从动作类转储$ self-> get_validators()时,我会得到空列表。

我创建了一个简短的示例,如果您发现问题,请尝试并提供帮助。 TNX!

指向代码的链接 - https://github.com/vmcooper/perl_workflow_test

运行程序

程序以

开头
Answer: London
If you answer right the action should change state to 'finished'. Try answering wrong first.
Capital city of England:

如果你回答“伯明翰”它应该写

Your answer is being validated!

再次提问。

当你回答“伦敦”它应该

Correct! Current state of workflow is - finished

编辑现在,无论您的答案是什么,它都会写出“正确!工作流程的当前状态已完成”。

workflow_test.pl

use strict;
use Log::Log4perl     qw( get_logger );
use Workflow::Factory qw( FACTORY );

Log::Log4perl::init( 'log4perl.conf' );
system('clear');

# Stock the factory with the configurations; we can add more later if we want
FACTORY->add_config_from_file(
    workflow   => 'workflow.xml',
    action     => 'action.xml',
    persister  => 'persister.xml',
    validator  => 'validator.xml'
    );

my $workflow = FACTORY->create_workflow( "Workflow1" );
my $context = $workflow->context;

while ( $workflow->state eq "INITIAL" ) {
    print "If you answer right the action should change state to 'finished'. Try answering wrong first.\n";
    my $city = get_response( "Capital city of England: " );
    print "You answered - $city\n";
    $workflow->execute_action( 'action1' );

    if( $workflow->state eq "INITIAL" ) {
        print "Your answer is wrong! try again!\n\n";
    }
}

print "\nCorrect! Current state of workflow is - ".$workflow->state."\n\n";


# Generic routine to read a response from the command-line (defaults,
# etc.) Note that return value has whitespace at the end/beginning of
# the routine trimmed.

sub get_response {
    my ( $msg ) = @_;
    print $msg;
    my $response = <STDIN>;
    chomp $response;
    $response =~ s/^\s+//;
    $response =~ s/\s+$//;
    return $response;
}

workflow.xml

<workflow>
     <type>Workflow1</type>
     <time_zone>local</time_zone>
     <description>This is my workflow.</description>
     <persister>Persister1</persister>

     <state name="INITIAL">
        <action name="action1" resulting_state="finished"/>
     </state>

    <state name="finished" />
 </workflow>

action.xml

<actions>
    <action name="action1" class="App::Action::Action1" >
        <validator name="validator1">
            <arg>$city</arg>
        </validator>
    </action>
</actions>

validator.xml

<validators>
    <validator name="validator1" class="App::Validator::Validator1">
        <param name="answer" value="London" />
    </validator>
</validators>

应用::动作:: Action1.pm

package App::Action::Action1;

use strict;
use base qw( Workflow::Action );
use Workflow::Exception qw( validation_error configuration_error );
use Data::Dumper;

sub new {
    my $class = shift;

    my $self = {};
    bless ($self, $class);

    return $self;
}

sub execute {
    my $self = shift;
    my $wf = shift;
    print "App::Action::Action1::Execute\n";
    print "Validators: ".Dumper($self->get_validators())."\n";
}

1;

应用::验证:: Validator1.pm

package App::Validator::Validator1;

use strict;
use base qw( Workflow::Validator );
use Workflow::Exception qw( validation_error configuration_error );
use Data::Dumper;
use Carp qw(carp);

sub _init {
    my ( $self, $params ) = @_;
     unless ( $params->{answer} ) {
         configuration_error
             "You must define a value for 'answer' in ",
             "declaration of validator ", $self->name;
     }
     if ( ref $params->{answer} ) {
         configuration_error
             "The value for 'answer' must be a simple scalar in ",
             "declaration of validator ", $self->name;
     }
     print "Answer: ".$params->{answer}."\n";
     $self->{ answer => $params->{answer} };
}

sub validate {
    my ( $self, $wf, $city ) = @_;

    print "Your answer is being validated!\n";
    print "Your answer is - ".$city."\n";

    my $check;

    if ( $city eq $self->{answer} ){
        $check = 1;
    } else {
        $check = 0;
    }
    unless ( $check ) {
        validation_error "Validation error!";
    }
}

1;

编辑: 如果我在创建后立即转储工作流对象,并且在执行任何操作之前,我会得到:

Workflow: $VAR1 = bless( {
    '_states' => {
        'INITIAL' => bless( {
            ...,
            '_actions' => {
                'action1' => {
                    'resulting_state' => 'finished',
                    'name' => 'action1'
                }
            },
            '_factory' => bless( {
                ...,
                '_action_config' => {
                    'default' => {
                        'action1' => {
                            'name' => 'action1',
                            'class' => 'App::Action::Action1',
                            'validator' => [
                                {
                                    'arg' => [
                                         '$city'
                                       ],
                                    'name' => 'validator1'
                                }
                            ]
                        }
                    }
                },
                '_validators' => {
                    'validator1' => bless( {
                        'name' => 'validator1',
                        'class' => 'App::Validator::Validator1',
                        'PARAMS' => {}
                    }, 'App::Validator::Validator1' )
                },
                '_validator_config' => {
                    'validator1' => {
                        'answer' => 'London',
                        'name' => 'validator1',
                        'class' => 'App::Validator::Validator1'
                    }
                },
                ...
            }, 'Workflow::Factory' ),
            'type' => 'Workflow1',
            'PARAMS' => {}
        }, 'Workflow::State' ),
        'finished' => $VAR1->{'_states'}{'INITIAL'}{'_factory'}{'_workflow_state'}{'Workflow1'}[1]
    },
    ...
}, 'Workflow' );

正如你所看到的,验证器就在这里,所有东西都已设置好,看起来没问题,但验证器没有应用。

2 个答案:

答案 0 :(得分:0)

看起来我们将不得不等待这一点,或者我们可以参与一个项目来完成这项功能。

滚动到&#34; get_validators&#34;标题,你会看到#TODO&#34;标记。 我不确定这是否意味着文档需要完成或代码,但我确实看了一下代码,看起来代码需要为此功能完成。 http://search.cpan.org/~jonasbn/Workflow-1.41/lib/Workflow/Factory.pm

如果我错了,请纠正我。

答案 1 :(得分:-1)

我在你的例子中找到了几个问题。

Action1.pm有一个构造函数,这会干扰继承,所以应该删除这个动作类,如下所示

package App::Action::Action1;

use strict;
use base qw( Workflow::Action );
use Workflow::Exception qw( validation_error configuration_error );
use Data::Dumper;

sub execute {
    my $self = shift;
    my $wf = shift;
    print "App::Action::Action1::Execute\n";
    print "Validators: ".Dumper($self->get_validators())."\n";
}

1;

您的应用程序收到用户输入的主要问题,但您从未将其提供给工作流程。这可以使用上下文来完成,如下所示:

$context->param( answer => $city );

验证器应如下所示:

package App::Validator::Validator1;

use strict;
use base qw( Workflow::Validator );
use Workflow::Exception qw( validation_error configuration_error );
use Data::Dumper;
use Carp qw(carp);

sub _init {
    my ( $self, $params ) = @_;
     unless ( $params->{answer} ) {
         configuration_error
             "You must define a value for 'answer' in ",
             "declaration of validator ", $self->name;
     }
     if ( ref $params->{answer} ) {
         configuration_error
             "The value for 'answer' must be a simple scalar in ",
             "declaration of validator ", $self->name;
     }
     print "Answer: ".$params->{answer}."\n";
     $self->{answer} = $params->{answer};
}

sub validate {
    my ( $self, $wf ) = @_;

    my $city = $wf->context->param('answer');

    print "Your answer is being validated!\n";
    print "Your answer is - ".$city."\n";

    my $check;

    if ( $city eq $self->{answer} ){
        $check = 1;
    } else {
        $check = 0;
    }
    unless ( $check ) {
        validation_error "Validation error!";
    }
}

1;

您的主要应用程序应类似于以下内容:

use strict;
use Log::Log4perl     qw( get_logger );
use Workflow::Factory qw( FACTORY );
use lib qw(lib);

Log::Log4perl::init( 'log4perl.conf' );
system('clear');

# Stock the factory with the configurations; we can add more later if we want
FACTORY->add_config_from_file(
    workflow   => 'workflow.xml',
    action     => 'action.xml',
    persister  => 'persister.xml',
    validator  => 'validator.xml'
    );

my $workflow = FACTORY->create_workflow( "Workflow1" );
my $context = $workflow->context;

while ( $workflow->state eq "INITIAL" ) {
    print "If you answer right the action should change state to 'finished'. Try answering wrong first.\n";
    my $city = get_response( "Capital city of England: " );
    print "You answered - $city\n";
    $context->param( answer => $city );
    $workflow->execute_action( 'action1' );

    if( $workflow->state eq "INITIAL" ) {
        print "Your answer is wrong! try again!\n\n";
    }
}

print "\nCorrect! Current state of workflow is - ".$workflow->state."\n\n";


# Generic routine to read a response from the command-line (defaults,
# etc.) Note that return value has whitespace at the end/beginning of
# the routine trimmed.

sub get_response {
    my ( $msg ) = @_;
    print $msg;
    my $response = <STDIN>;
    chomp $response;
    $response =~ s/^\s+//;
    $response =~ s/\s+$//;
    return $response;
}

我理解您的困惑,因为文档没有正确反映这一事实,也无法从分发中的示例应用程序中读取。我会相应地更新文档。