#!/usr/bin/perl
use
vars
qw/$OUT_EXT @IN @OUT/
;
$OUT_EXT
=
'pm'
;
require
'poxargs.pl'
;
my
$domain
=
$ENV
{POP_SYSTEM} or
croak
"Set POP_SYSTEM."
;
my
$pkg
=
"${domain}::"
;
my
$p
= new POP::POX_parser;
for
(
my
$i
;
$i
<
@IN
;
$i
++) {
unless
(
sysopen
(OUT,
$OUT
[
$i
], O_WRONLY|O_CREAT|O_TRUNC, 0660)) {
croak
"Couldn't open [$OUT[$i]] for writing: $!"
;
}
print
STDERR
"Converting $IN[$i] to $OUT[$i]\n"
;
my
$c
;
eval
{
$c
=
$p
->parse(
$IN
[
$i
]);
};
if
($@) {
print
STDERR $@;
next
;
}
&strip_space
(
$c
->{
'comments'
});
print
OUT
<<QQ_PM_QQ;
=head1 CLASS
Title: $c->{'name'}
Desc: $c->{'comments'}
XML: $c->{'version'}
=cut
package $pkg$c->{'name'};
QQ_PM_QQ
print
OUT
q|$VERSION = do{my(@r)=q$|
.
q|Revision: 1.1.1.1 $=~/\d+/g;sprintf '%d.'.'%02d'x$#r,@r};|
;
print
OUT
<<'Q_PM_Q';
use strict;
use vars qw/@ISA $VERSION/;
use Carp;
use POP::Persistent;
Q_PM_Q
my
@isa
=
map
{ s/^(?!
$pkg
)/
$pkg
/o;
$_
}
split
/\s*,\s*/,
$c
->{
'isa'
};
foreach
(
@isa
) {
print
OUT
"use $_;\n"
;
}
print
OUT
"\n\@ISA = qw/"
, (
join
' '
,
'POP::Persistent'
,
@isa
),
"/;\n\n"
;
print
OUT
"# PUBLIC METHODS\n"
;
print
OUT
<<'Q_PM_Q';
sub initialize {
my $this = shift;
Q_PM_Q
foreach
my
$p_name
(
sort
keys
%{
$c
->{
'participants'
}}) {
my
$part
=
$c
->{
'participants'
}{
$p_name
};
print
OUT
" \$this->{'$p_name'} = \\do{my \$a};\n"
;
}
foreach
my
$a_name
(
sort
keys
%{
$c
->{
'attributes'
}}) {
my
$attribute
=
$c
->{
'attributes'
}{
$a_name
};
if
(
$attribute
->{
'hash'
}) {
print
OUT
" \$this->{'$a_name'} = \$this->"
.
"_POP__Persistent_hash_from_db(\n\t'$attribute->{'val_type'}',"
.
" '$a_name', {});\n"
;
}
elsif
(
$attribute
->{
'list'
}) {
print
OUT
" \$this->{'$a_name'} = \$this->"
.
"_POP__Persistent_list_from_db(\n\t'$attribute->{'type'}',"
.
" '$a_name');\n"
;
}
else
{
print
OUT
" \$this->{'$a_name'} = "
,
$attribute
->{
'default'
} ||
(
$attribute
->{
'type'
} =~ /::/ ?
'\do{my $a}'
:
"''"
),
";\n"
;
}
}
print
OUT
"}\n"
;
foreach
my
$c_name
(
sort
keys
%{
$c
->{
'constructors'
}}) {
my
$constructor
=
$c
->{
'constructors'
}{
$c_name
};
&strip_space
(
$constructor
->{
'comments'
});
print
OUT
<<QQ_PM_QQ;
=head2 CONSTRUCTOR
Title: $pkg$c->{'name'}::$c_name
Desc: Constructor - $constructor->{'comments'}
=cut
sub $c_name {
my \$type = shift;
\$type = ref(\$type) || \$type;
QQ_PM_QQ
print
OUT
¶m_list
(
values
%{
$constructor
->{
'params'
}}).
"\n"
;
print
OUT
"\n}\n"
;
}
foreach
my
$cm_name
(
sort
keys
%{
$c
->{
'class-methods'
}}) {
my
$class_method
=
$c
->{
'class-methods'
}{
$cm_name
};
&strip_space
(
$class_method
->{
'comments'
});
print
OUT
<<QQ_PM_QQ;
=head2 CLASS METHOD
Title: $pkg$c->{'name'}::$cm_name
Desc: $class_method->{'comments'}
=cut
sub $cm_name {
my \$type = shift;
\$type = ref(\$type) || \$type;
QQ_PM_QQ
print
OUT
¶m_list
(
values
%{
$class_method
->{
'params'
}}).
"\n"
;
print
OUT
"\n}\n"
;
}
foreach
my
$p_name
(
sort
keys
%{
$c
->{
'participants'
}}) {
my
$part
=
$c
->{
'participants'
}{
$p_name
};
&strip_space
(
$part
->{
'comments'
});
print
OUT
<<QQ_PM_QQ;
=head2 CLASS METHOD
Title: $pkg$c->{'name'}::all_with_$p_name
Desc: Returns list of $c->{'name'} objects that have the given
$part->{'type'} as a $p_name
=cut
sub all_with_$p_name {
my(\$type, \$obj) = \@_;
return map {\$type->new(\$_)}
\$type->all({'where' => [['$p_name', '=', \$obj]]});
}
=head2 PARTICIPANT
Title: $pkg$c->{'name'}::$p_name
Desc: $part->{'comments'}
=cut
sub $p_name {
my \$this = shift;
if (\@_) {
my \$obj = shift;
unless (ref(\$obj) && \$obj->isa('$part->{'type'}')) {
croak "[\$obj] is not a $part->{'type'}";
}
\$this->{'$p_name'} = \\\$obj;
}
\${\$this->{'$p_name'}};
}
QQ_PM_QQ
}
foreach
my
$a_name
(
sort
keys
%{
$c
->{
'attributes'
}}) {
my
$attr
=
$c
->{
'attributes'
}{
$a_name
};
&strip_space
(
$attr
->{
'comments'
});
print
OUT
<<QQ_PM_QQ;
=head2 ACCESSOR
Title: $pkg$c->{'name'}::$a_name
Desc: $attr->{'comments'}
=cut
sub $a_name {
my \$this = shift;
if (\@_) {
QQ_PM_QQ
if
(
$attr
->{
'hash'
}) {
print
OUT
' my %hash = @_;'
,
"\n"
;
if
(
$attr
->{
'val_type'
} =~ /::/) {
print
OUT
' while (my($k,$v) = %hash) {'
,
"\n"
,
' unless (ref($v) && $v->isa(\''
,
$attr
->{
'val_type'
},
'\')) {'
,
"\n"
,
' croak "[$v] is not a '
,
$attr
->{
'val_type'
},
'";'
,
"\n"
,
' }'
,
"\n"
,
' }'
,
"\n"
;
}
print
OUT
" \$this->{'$a_name'} = \\\%hash;\n"
;
print
OUT
<<QQ_PM_QQ;
}
wantarray ? \%{\$this->{'$a_name'}} : \$this->{'$a_name'};
}
QQ_PM_QQ
}
elsif
(
$attr
->{
'list'
}) {
if
(
$attr
->{
'type'
} =~ /::/) {
print
OUT
' foreach (@_) {'
,
"\n"
,
' unless (ref($_) && $_->isa(\''
,
$attr
->{
'type'
},
'\')) {'
,
"\n"
,
' croak "[$_] is not a '
,
$attr
->{
'type'
},
'";'
,
"\n"
,
' }'
,
"\n"
,
' }'
,
"\n"
;
}
print
OUT
" \$this->{'$a_name'} = [\@_];\n"
;
print
OUT
<<QQ_PM_QQ;
}
wantarray ? \@{\$this->{'$a_name'}} : \$this->{'$a_name'};
}
QQ_PM_QQ
}
else
{
print
OUT
' my $obj = shift;'
,
"\n"
;
if
(
$attr
->{
'type'
} =~ /::/) {
print
OUT
' unless (ref($obj) && $obj->isa(\''
,
$attr
->{
'type'
},
'\')) {'
,
"\n"
,
' croak "[$obj] is not a '
,
$attr
->{
'type'
},
'";'
,
"\n"
,
' }'
,
"\n"
;
print
OUT
" \$this->{'$a_name'} = \\\$obj\n"
;
print
OUT
<<QQ_PM_QQ;
}
\${\$this->{'$a_name'}};
}
QQ_PM_QQ
}
else
{
print
OUT
<<QQ_PM_QQ;
\$this->{'$a_name'} = \$obj;
}
\$this->{'$a_name'};
}
QQ_PM_QQ
}
}
}
foreach
my
$m_name
(
sort
keys
%{
$c
->{
'methods'
}}) {
my
$method
=
$c
->{
'methods'
}{
$m_name
};
&strip_space
(
$method
->{
'comments'
});
print
OUT
<<QQ_PM_QQ;
=head2 METHOD
Title: $pkg$c->{'name'}::$m_name
Desc: $method->{'comments'}
=cut
sub $m_name {
my \$this = shift;
QQ_PM_QQ
print
OUT
¶m_list
(
values
%{
$method
->{
'params'
}});
print
OUT
"\n}\n"
;
}
print
OUT
"\n\$VERSION = \$VERSION;\n"
;
}
sub
param_list {
my
@params
=
sort
{
$a
->{
'pos'
} <=>
$b
->{
'pos'
}}
@_
;
my
$param
=
' my('
;
my
$scalar_param_sel
;
my
$scalar_param_cnt
;
my
$scalar_param_idx
;
my
$all_params_are_scalars
= 1;
for
(
my
$i
=0;
$i
<
@params
;
$i
++) {
if
(
$params
[
$i
]->{
'type'
} ne
'array'
) {
$param
.=
"\$$params[$i]->{'name'}, "
;
vec
(
$scalar_param_sel
,
$i
, 1) = 1;
$scalar_param_cnt
++;
$scalar_param_idx
=
$i
;
}
else
{
$all_params_are_scalars
= 0;
}
}
if
(
$scalar_param_cnt
&&
$all_params_are_scalars
) {
substr
(
$param
, -2) =
") = \@_;\n"
;
return
$param
;
}
if
(
$scalar_param_cnt
== 1) {
substr
(
$param
, -2) =
') = $_['
.
$scalar_param_idx
.
"];\n"
;
}
elsif
(
$scalar_param_cnt
) {
my
(
$i
,
$j
) = (0, 0);
substr
(
$param
, -2) =
') = @_['
.
join
(
','
,
grep
{
$_
}
map
{
$i
=
$j
;
$j
+=
length
();
if
(
$_
+0) {
"$i"
.(
$j
>
$i
+1 ?
"-"
.(
$j
-1) :
""
)
}}
split
/(0+)/,
unpack
(
"b*"
,
$scalar_param_sel
)).
"];\n"
;
}
else
{
$param
=
''
;
}
for
(
my
$i
=0;
$i
<
@params
;
$i
++) {
if
(
$params
[
$i
]->{
'list'
}) {
$param
.=
" my \$$params[$i]->{'name'}__ref = \$_[$i]\n"
.
" my \@$params[$i]->{'name'} = \@\$$params[$i]->{'name'}__ref;\n"
;
}
}
return
$param
;
}
sub
strip_space {
$_
[0] =~ s/^\s+//;
$_
[0] =~ s/\s+$//;
$_
[0] =~ s/\s{4,}/\n\t/g;
}