package WebCoso::Resource;
use strict;
use warnings;
use Class::Std;
{
my %values_of :ATTR(:default<{}>);
my %propnames_of :ATTR(:default<{}>);
my %axes_of :ATTR(:default<{}>);
sub get_axes {
my ($self)=@_;
return keys %{$axes_of{ident $self}};
}
sub get_axis_values {
my ($self,$axis_name)=@_;
return keys %{$axes_of{ident $self}->{$axis_name}};
}
sub set_property {
my $self=shift;
my $axes_spec= (ref($_[0]) eq 'HASH') ? (shift) : {};
my ($prop_name,$prop_value)=@_;
$self->_populate_axes_from($axes_spec);
my $key=_genkey($axes_spec);
$propnames_of{ident $self}->{$prop_name}=undef;
$values_of{ident $self}->{$prop_name}->{$key}=$prop_value;
return;
}
sub get_property {
my $self=shift;
my $axes_spec= (ref($_[0]) eq 'HASH') ? (shift) : {};
my ($prop_name)=@_;
my $req_key=_genkey($axes_spec);
my $values_ref=$values_of{ident $self}->{$prop_name};
my @keys=sort {($a=~tr/\001//) <=> ($b=~tr/\001//)} keys %$values_ref;
for my $key (@keys) {
my $key_rx=_genrx_from_key($key);
if ($req_key =~ m{$key_rx}) {
return $values_ref->{$key};
}
}
return;
}
sub _populate_axes_from {
my ($self,$axes_spec)=@_;
while (my ($axis_name,$axis_value)=each %$axes_spec) {
my $axis_value_set=($axes_of{ident $self}->{$axis_name} ||= {});
$axis_value_set->{$axis_value}=undef;
}
return;
}
sub _genkey {
my ($axes_spec)=@_;
my $key="\000";
$key.=join "\000",map {$_."\001".$axes_spec->{$_}} sort keys %$axes_spec;
$key.="\000";
return $key;
}
sub _genrx_from_key {
my ($key)=@_;
my (undef,@axes)=split /\000/,$key;
my $rx="(?:";
$rx.=join "\000).*?(?:",map {quotemeta($_)} @axes;
$rx.=")";
$rx=qr{^\000.*?${rx}(?:\000|$)};
return $rx;
}
}
1;