我正在尝试使用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' );
正如你所看到的,验证器就在这里,所有东西都已设置好,看起来没问题,但验证器没有应用。
答案 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;
}
我理解您的困惑,因为文档没有正确反映这一事实,也无法从分发中的示例应用程序中读取。我会相应地更新文档。