RayApp
view release on metacpan or search on metacpan
origlib/RayApp/Source.pm view on Meta::CPAN
return 0;
}
my $parent = $node->parentNode;
my $prev = $node->previousSibling;
my $indent;
if (defined $prev and $prev->nodeType == 3) {
my $v = $prev->nodeValue;
if (defined $v and $v =~ /(\n[ \t]+)/) {
$indent = $1;
}
}
my $numkeys = keys %$data;
if ($numkeys == 0) {
RayApp::removeChildNodeNicely($parent, $node);
}
my $i = 0;
for my $key (sort {
my $r = 0;
if ($spec->{'hashorder'} eq 'num') {
local $^W = 0;
$r = $a <=> $b;
}
if ($r == 0 and $spec->{'hashorder'} eq 'string') {
$r = $a cmp $b;
}
return $r;
} keys %$data) {
my $work = $node;
if ($i < $numkeys - 1) {
# $work = $node->cloneNode(1);
$work = clone_node($node);
$parent->insertBefore($work, $node);
if (defined $indent) {
$parent->insertBefore(
$dom->createTextNode($indent),
$node);
}
}
$i++;
$work->setAttribute($spec->{'idattr'}, $key);
$self->bind_data($dom, $work, $pointer,
$data->{$key}, $showname . "{$key}", 1);
}
} elsif ($spec->{'type'} ne 'hash') {
if (ref $data) {
$self->{errstr} .= "Scalar expected for $showname defined at line $spec->{'ln'}, got @{[ ref $data ]}\n";
RayApp::removeChildNodeNicely($node->parentNode, $node);
return 0;
} elsif ($spec->{'type'} eq 'int'
and not $data =~ /^[+-]?\d+$/) {
$self->{errstr} .= "Value '$data' of $showname is not integer for data element defined at line $spec->{'ln'}\n";
RayApp::removeChildNodeNicely($node->parentNode, $node);
return 0;
} elsif ($spec->{'type'} eq 'num'
and not $data =~ /^[+-]?\d*\.?\d+$/) {
$self->{errstr} .= "Value '$data' of $showname is not numeric for data element defined at line $spec->{'ln'}\n";
RayApp::removeChildNodeNicely($node->parentNode, $node);
return 0;
}
if ($spec->{'cdata'} eq 'yes') {
while ($data =~ s/^(.*\])(?=\]>)//sg) {
$node->appendChild($dom->createCDATASection($1));
}
$node->appendChild($dom->createCDATASection($data));
} else {
$node->appendText($data);
}
return 1;
} elsif ($spec->{'type'} eq 'hash') {
if (not ref $data) {
$self->{errstr} .= "Scalar data '$data' found where structure expected for $showname at line $spec->{'ln'}\n";
RayApp::removeChildNodeNicely($node->parentNode, $node);
return 0;
}
my %done = ();
my $total = 0;
my $i = 0;
my $arrayi = 0;
for my $child ($node->childNodes) {
my $newpointer = "$pointer:$i";
$i++;
next if not defined $self->{'placeholders'}{$newpointer};
if (ref $data eq 'ARRAY') {
$total += $self->bind_data($dom, $child,
$newpointer, $data->[ $arrayi ],
$showname . "[$arrayi]", 0);
$arrayi++;
} else {
my $newname = $self->{'placeholders'}{$newpointer}{'name'};
$total += $self->bind_data($dom, $child,
$newpointer, $data->{ $newname },
$showname . "{$newname}", 0);
$done{$newname} = 1;
}
}
if (ref $data eq 'HASH') {
for my $k (sort keys %$data) {
if (not exists $done{$k}) {
$self->{errstr} .= "Data $showname\{$k} does not match data structure description\n";
}
}
} elsif (ref $data eq 'ARRAY') {
if ($arrayi <= $#$data) {
my $view = $arrayi;
if ($arrayi < $#$data) {
$view .= "..$#$data";
}
$self->{errstr} .= "Data $showname\[$view] does not match data structure description\n";
}
} else {
die "We shouldn't have got here";
}
if ($total or $inmulti) {
return 1;
} else {
RayApp::removeChildNodeNicely($node->parentNode, $node);
return 0;
}
} else {
die "We shouldn't have got here, " . $node->toString;
origlib/RayApp/Source.pm view on Meta::CPAN
Type of the placeholder. Except the scalar types which are the same as
for input parameters, B<hash> or B<struct> values can be used to denote
nested structure.
=item mandatory
By default, no data needs to be returned by the application for the
placeholder. When set to B<yes>, the value will be required.
=item id
An element can be assigned a unique identification which can be then
referenced by B<typeref> from other parts of the same DSD or from
remote DSD's.
=item multiple
When this attribute is specified, the value is expected to be an
aggregate and either the currect DSD element or its child is repeated
for each value.
=over 4
=item list
An array is expected as the value. The placeholder element
will be repeated.
=item listelement
An array is expected, the child of the placeholder will be repeated
for each of the array's element.
=item hash
An associative array is expected and placeholder element will
be repeated for all values of the array. The key of individual values
will be in an attribute B<id> or in an attribute named in DSD with
attribute B<idattr>.
=item hashelement
The same as B<hash>, except that the child of the placeholder will be
repeated.
=back
=item idattr
Specifies the name of attribute which will hold keys of
individual values for multiple values B<hash> and B<hashelement>,
the default is B<id>.
=item hashorder
Order of elements for values binded using multiple values B<hash> or
B<hashelement>. Possible values are B<num>, B<string>, and
(the default) B<natural>.
=item cdata
When set to yes, the scalar content of this element will be
output as a CDATA section.
=back
=head2 Conditions
The non-placeholder elements can have one of the B<if>, B<ifdef>,
B<ifnot> or B<ifnotdef> attributes that specify a top-level value
(from the data hash) that will be checked for presence or its value.
If the condition is not matched, this element with all its children
will be removed from the output stream.
=head2 Attributes
By default, only the special DSD attributes are allowed. However, with
an attribute B<attrs> a list of space separated attribute names can be
specified. These will be preserved on output.
With attribute B<xattrs>, a rename of attributes is possible. The
value is space separated list of space separated pairs of attribute
names.
=head2 Application name
The root element of the DSD can hold an B<application> attribute with
a URL (file name) of the application which should provide the data for
the DSD.
=head1 DESCRIPTION OF INTERNALS
In the previous parts we have seen how to use B<RayApp> to write Web
applications. Changes are that you will want to use B<RayApp>
serializer in other, non-Web projects. This part describes the
internals of the framework.
=head2 RayApp object
To work with B<RayApp> and to have it process data structure description
files, application data, and presentation transformation, you need
a B<RayApp> object first. Use contructor B<new> to create one:
use RayApp ();
my $rayapp = new RayApp;
The constructor takes a couple of optional parameters that affect
B<RayApp>'s behaviour:
=over 4
=item base
The base URI, used for all URI resolutions. By default, the current
directory is used.
=item cache
When set to true value, will cache loaded DSD's and stylesheets.
False by default.
( run in 1.163 second using v1.01-cache-2.11-cpan-2398b32b56e )