package GO::Object::Tool; =head1 NAME GO::Object::Tool - represents a GO::Object::Tool on the GO tools page =cut use strict; use Data::Dumper; use Exporter; use lib '/Users/gwg/go/scratch/tools'; use vars qw(@ISA); use base qw(GO::Object::Generic); #GO::MiniTests); use GO::Object::Developer; use GO::Object::URL; use GO::TestSet qw(dfv_test); use Data::FormValidator::Constraints qw(:closures); sub _specification { my $self = shift; our $list_values = { # license => [ 'free_academic', 'proprietary', ],#'other' ], # tool_type => [ 'online', 'standalone' ], # compatible_os => [ 'win', 'mac', 'unix', 'linux' ], # feature => [ 'ont_view', 'annot_view', 'ont_edit', 'annot_edit', 'godb', 'stat', 'sw', 'textmine', 'data', 'id_map', 'other_feature' ], # go_data_used => [ 'tree', 'term', 'def', 'synonym', 'relationship', # ontology # 'assoc', 'evcode', 'ref', 'qual', 'not' ], # association data ## Compatible OS compatible_os => [ 'win', 'Windows', 'mac', 'Mac OS X', 'linux', 'Linux', 'unix', 'Unix', ], ## Tool features feature => [ 'ont_view', 'ontology viewer / browser', 'annot_view', 'annotation viewer / browser', 'ont_edit', 'ontology editor', 'annot_edit', 'annotation editor', 'godb', 'GO database', 'stat', 'statistical analysis', 'sw', 'software library', 'textmine', 'text mining', 'data', 'data warehouse', 'id_map', 'ID mapping', ], ## license license => [ 'free_academic', 'free for academic use', 'proprietary', 'proprietary software', 'other_license', 'other license', ], ## GO data go_data_used => [ # ontology data 'term', 'GO terms', 'def', 'term definitions', 'synonym', 'term synonyms', 'tree', 'ontology tree', 'relationship', 'relationships between terms', # association data 'assoc', 'association (annotation) data', 'evcode', 'evidence codes for annotations', 'ref', 'references for annotations', 'qual', 'annotation qualifiers (e.g "contributes to")', 'not', 'NOT (negative) annotations', # gene product data 'gp_spp', 'gene product species', 'gp_seq', 'gene product sequences', # other stuff 'mappings', 'mappings to other databases', ], }; sub get_list_values { my $param = shift; return if !$list_values->{$param}; my $n = 0; return [ grep { $_ if ! ( $n++ % 2 ) } @{$list_values->{$param}} ]; } sub get_value_human_name_h { my $param = shift; return if !$list_values->{$param}; my %hash = ( @{$list_values->{$param}} ); return { %hash } } return ( # required { id => 'name', required => 1, test => [ dfv_test('is_a_string_p', { this => 1 }), FV_min_length(2), ], human_name =>'Tool name', }, { id => 'url', required => 1, test => dfv_test('is_an_url_p', { this => 1 }), human_name =>'Tool URL', }, { id => "email", required => 1, test => email(), human_name =>'Contact email for tool', }, { id => "developer", # id => "developer_list", required => 1, allow_multiple => 1, type => 'GO::Object::Developer', test => dfv_test('is_subclass_of_p', { class => 'GO::Object::Developer', this => 1 }, ), human_name =>'Tool developer(s)', }, { id => "license", required => 1, test => dfv_test('is_in_list_p', { list => get_list_values('license'), this => 1 }), human_name =>'License', list_values => get_list_values('license'), list_values_human_name_h => get_value_human_name_h('license'), default => 'free_academic', }, { id => "description", required => 1, test => [ qr/\w{3,}/, FV_min_length(50), ], human_name =>'Tool description', }, # required, booleans { id => "is_online_tool", test => dfv_test('is_true_p'), human_name =>'Web-based tool', }, { id => "is_standalone_tool", test => dfv_test('is_true_p'), human_name =>'Standalone (downloadable) tool', }, { id => "compatible_os", # id => "compatible_os_list", allow_multiple => 1, test => [ dfv_test('is_in_list_p', { list => get_list_values('compatible_os'), this => 1 }) ], # dependencies => [ 'is_standalone_tool' ], human_name =>'Compatible operating systems (for standalone tools)', list_values => get_list_values('compatible_os'), list_values_human_name_h => get_value_human_name_h('compatible_os'), }, { id => "feature", # id => "feature_list", required => 1, allow_multiple => 1, test => [ #qr/ont/, dfv_test('is_in_list_p', { list => get_list_values('feature'), this => 1 }) ], human_name =>'Tool feature list', list_values => get_list_values('feature'), list_values_human_name_h => get_value_human_name_h('feature'), }, # optional, list { id => "publication", # id => "publication_list", allow_multiple => 1, test => [ dfv_test('is_a_string_p', { this => 1 }), FV_min_length(10) ], human_name =>'Publication(s) relating to the tool', # valid_prefixes => [ 'pmid', 'doi' ], }, # optional, boolean { id => "is_open_source", test => dfv_test('is_true_p', { this => 1 }), human_name =>'Open-source tool', }, { id => "url_source", test => dfv_test('is_an_url_p', { this => 1 }), dependencies => [ 'is_open_source' ], human_name =>'URL for tool source code', }, ## what GO data is used { id => "go_data_used", # id => "go_data_used_list", allow_multiple => 1, test => dfv_test('is_in_list_p', { list => get_list_values('go_data_used'), this => 1 }), human_name =>'GO data used by the tool', list_values => get_list_values('go_data_used'), list_values_human_name_h => get_value_human_name_h('go_data_used'), }, ## GO data source { id => "go_data_source", # should this be an URL? test => [ dfv_test('is_a_string_p', { this => 1 }), FV_min_length(5), ], human_name =>'Source of GO data', }, ## GO data update frequency { id => "go_data_update_frequency", test => [ dfv_test('is_a_string_p', { this => 1 }), FV_min_length(5), ], human_name =>'Frequency at which GO data is updated', # daily, weekly, monthly, n_per_week, n_per_month, n_per_year, unknown }, { id => "submission_date", # get this from the CGI test => dfv_test('is_a_date_p', { this => 1 }), }, # generated automatically # { id => "name_lc", # constructor => 'automatic', # }, # { id => "name_acronym", # constructor => 'automatic', # test => dfv_test('is_a_string_p', { this => 1 }), # human_name =>'Acronym', # }, # { id => "name_abbr", # constructor => 'automatic', ## test => dfv_test('is_a_string_p', { this => 1 }), # human_name =>'Abbreviated name', # }, ); } sub _dfv_data { return { 'require_some' => { tool_type_group => [ 1, 'is_standalone_tool', 'is_online_tool' ], }, 'dependency_groups' => { standalone_os_group => [ 'is_standalone_tool', 'compatible_os' ], }, }; } sub transform_parsed_data { my $self = shift; my $arg_h = shift; my $data_h = $arg_h->{data}; my $spec_h; ## do any transformations here # if ($data_h->{developer_list}) if ($data_h->{developer}) { my $temp; if (!$spec_h->{dev_spec}) { $spec_h->{dev_spec} = GO::Object::Developer->get_spec(); $spec_h->{dev_dfv_profile} = GO::Object::Developer->dfv_profile(); } # foreach (@{$data_h->{developer_list}}) foreach (@{$data_h->{developer}}) { my $dev_h; ($dev_h->{url}, $dev_h->{fn}) = split(" ", $_, 2); if ($dev_h->{fn} =~ /^\s*\"(.*)\" ?(.*?)$/) { $dev_h->{fn} = $1; my $rest = $2; # split up 'rest' by ;\s my @rest_parts = split('; ', $rest); foreach (@rest_parts) { if (/^\s?(.*?):\s?(.+)\s?$/) { $dev_h->{$1} = $2; } } } # create a developer object my $results = GO::Object::Developer->new({ data => $dev_h, object_spec => $spec_h->{dev_spec}, dfv_profile => $spec_h->{dev_dfv_profile}, check_input => $arg_h->{check_input} || undef, return_as => 'success_hash', }); if ($results->{SUCCESS}) { # put the object into the temp list push @$temp, $results->{OBJECT}; } if ($results->{ERROR_LIST}) { $self->add_message($results->{ERROR_LIST}); } } delete $data_h->{developer}; $data_h->{developer} = $temp if $temp && @$temp; # delete $data_h->{developer_list}; # $data_h->{developer_list} = $temp if $temp && @$temp; } } sub add_developer { my $self = shift; my $arg_h = shift; if (! ref $arg_h) { # we have a string as the argument $arg_h = { data => { name => $arg_h } }; } my $results = GO::Object::Developer->new({ %$arg_h, return_as => 'success_hash', }); if ($results->{SUCCESS}) { # hurrah! if (!$arg_h->{add_as}) # { $arg_h->{add_as} = 'developer_list'; { $arg_h->{add_as} = 'developer'; } push @{$self->{ $arg_h->{add_as} }}, $results->{OBJECT}; } if ($results->{ERROR_LIST}) { $self->add_message($results->{ERROR_LIST}); } } sub name_lc { my $self = shift; return $self->{name_lc} if $self->{name_lc}; my $name_lc = lc($self->{name}) || return; $name_lc =~ s/\W/_/g; # convert non-alphanum characters into _ $self->{name_lc} = $name_lc; return $self->{name_lc}; } sub email_id { my $self = shift; my $email = $self->email; (my $id = $email) =~ s/\@.+//; return $id; } sub email_place { my $self = shift; my $email = $self->email; (my $place = $email) =~ s/.+\@//; return $place; } 1;