The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.
[%# A template for an datatype property.
    ===========================
    Expected/recognized parameters:
    obj ... a SADI::Data::Def::OWLClass object
      
-%]
#-----------------------------------------------------------------
# [% obj.module_name %]
# Generated: [% USE Date (format = '%d-%b-%Y %H:%M:%S %Z') %][% Date.format %]
# Contact: Edward Kawas <edward.kawas+sadi@gmail.com>
#-----------------------------------------------------------------
package [% obj.module_name %];

#use SADI::Base;

[% FOREACH child IN obj.module_parent -%]
use [% child %];
[% END %]

no strict;
use vars qw( @ISA );
@ISA = qw(
 [% obj.module_parent.join("\n ") %] 
);
use strict;

# imports 
use SADI::Data::String;
use SADI::Data::Integer;
use SADI::Data::Float;
use SADI::Data::Boolean;
use SADI::Data::DateTime;

[% FOREACH child IN obj.object_properties %]
use [% child.module_name %];[% END %]
[% FOREACH child IN obj.datatype_properties %]
use [% child.module_name %];[% END %]

{
    my %_allowed = (
    [% FOREACH child IN obj.object_properties %]
        [% child.name %] => {
        	type => 'SADI::Data::OWL::Class',
        	# range checking of classes added 
        	post => sub {
        		my ($self) = shift;
                my $type = @{$self->[% child.name %]}[-1];
                return unless defined $type and $type->type;
                my $range = new [% child.module_name %]->range();
                return unless $range;
                $range = $self->uri2package($range);
                eval {
                	$range = $range->new();
                };
                return if $@;
        		$self->throw("\n" . $type->type() . "\nis not related to\n" . $range->type()) unless $type->isa(ref($range));
        	},
        	is_array => 1, },
    [% END %]
    [% FOREACH child IN obj.datatype_properties %]
        [% child.name %] => {
            type => '[% child.module_name %]',
            is_array => 1, },
    [% END %]
    );

    sub _accessible {
        my ( $self, $attr ) = @_;
        exists $_allowed{$attr} 
[% FOREACH child IN obj.module_parent -%]
          or $self->[%- child -%]::_accessible($attr)
[% END -%]
    }

    sub _attr_prop {
        my ( $self, $attr_name, $prop_name ) = @_;
        my $attr = $_allowed{$attr_name};
        return ref($attr) ? $attr->{$prop_name} : $attr if $attr;
[% FOREACH child IN obj.module_parent -%]
        return $self->[%- child -%]::_attr_prop( $attr_name, $prop_name ) 
            if $self->[%- child -%]::_accessible($attr_name);
[% END %]
    }
}

#-----------------------------------------------------------------
# init
#-----------------------------------------------------------------
sub init {
    my ($self) = shift;
[% FOREACH child IN obj.module_parent -%]
    $self->[%- child -%]::init();
[% END -%]
    $self->type('[% obj.type %]');
    
}

# every generated module implements this ...
sub _get_statements {
    my $self = shift;
    # create a named resource or bnode for this object ....
    my $subject = new RDF::Core::Resource( $self->value ) if defined $self->value and $self->value ne '';
    $subject = 
        new RDF::Core::Resource( "_:a" . sprintf( "%08x%04x", time(), int(rand(0xFFFF))) )
      unless defined $self->value and $self->value ne '';
    
    # set the subject so that this sub graph can be linked to other graphs
    $self->subject($subject);
    my $add_type_statement = undef;
    $add_type_statement = 1 if defined $self->value and $self->value ne '';

    # add a label if one is specified
    if (defined $self->label()) {
    	$self->add_statements(
    	   new RDF::Core::Statement(
            $subject,
            $subject->new( SADI::RDF::Predicates::RDFS->label ),
            new RDF::Core::Literal( $self->label )
           )
        );
    }
    
    # for each attribute, if is array do:
[% FOREACH child IN obj.object_properties -%]
    if (defined $self->[%- child.name -%]){
	    foreach (@{$self->[%- child.name -%]}) {
	        # add all statements from $_
	        my @statements = @{$_->_get_statements};
	        $self->add_statements(@statements) if @statements;
	        # add a statement linking the graphs
	        $self->add_statements(
	          new RDF::Core::Statement(
	              $subject,
	              $subject->new('[%- child.uri -%]'), 
	              $_->subject
	          )
	        );
	    }
	    $add_type_statement = 1;
    }
[% END -%]
[% FOREACH child IN obj.datatype_properties -%]
    if (defined $self->[%- child.name -%]){
	    foreach (@{$self->[%- child.name -%]}) {
	        $self->add_statements(
	          new RDF::Core::Statement(
	              $subject,
	              $subject->new('[%- child.uri -%]'), 
	              new RDF::Core::Literal( 
	                $_->value, undef, (defined $_->range ? $_->range : undef) 
	              ),
	          )
	        );
	    }
	    $add_type_statement = 1;
    }
[% END -%]
    # add parent statements too
[% FOREACH child IN obj.module_parent -%]
    eval {
    	my @statements = @{$self->[%- child -%]::_get_statements()};
    	if (scalar (@statements) > 0) {
    		$self->add_statements(@statements);
    		$add_type_statement ||= undef;
    	}
    };
[% END %]

    # add the type
    $self->add_statements(
        new RDF::Core::Statement(
            $subject,
            $subject->new( SADI::RDF::Predicates::RDF->type ),
            new RDF::Core::Resource( $self->type )
        )
    ) if $add_type_statement; # or scalar (@{ $self->statements }) > 0;
    
    return $self->statements;
}

1;

__END__

=head1 NAME

[% obj.module_name %] - an automatically generated owl class!

=head1 SYNOPSIS

  use [% obj.module_name %];
  my $class = [% obj.module_name %]->new();

  # get the uri for this class
  my $uri = $class->uri;

[% IF obj.datatype_properties -%]
  # add datatype properties 
[% FOREACH child IN obj.datatype_properties -%]
  use [% child.module_name %];
  my $[% child.name %] = new [% child.module_name %]('some value');
  $class->add_[% child.name %]($[% child.name %]);
  # get the [% child.name %] datatype properties
  my $[% child.name %]_property = $class->[% child.name %];
[% END %][% END %]
  
[% IF obj.object_properties -%]
  # add object properties 
[% FOREACH child IN obj.object_properties -%]
  # Make sure to use the appropriate OWL class! 
  # SADI::Data::OWL::Class used as an example
  $class->add_[% child.name %](new SADI::Data::OWL::Class('#someURI'));
  # get the [% child.name %] object properties
  my $[% child.name %]_objects = $class->[% child.name %];
[% END %][% END %]

=head1 DESCRIPTION

I<Inherits from>:
[% FOREACH child IN obj.module_parent -%]
L<[% child %]>
[% END %]

=cut