Merge branch 'master' into topic/parent_string
[cxgn-corelibs.git] / lib / MOBY / RDF / InOutArticlesRDF.pm
blobf1bb0ffbfc81ba23e285133f316e391128f73c38
1 package MOBY::RDF::InOutArticlesRDF;
2 use strict;
3 use RDF::Core::NodeFactory;
4 use RDF::Core::Statement;
6 require Exporter;
7 our @ISA = qw(Exporter);
8 our @EXPORT_OK = qw();
10 use RDF::Core::Constants qw(:xml :rdf :rdfs);
11 use constant OBJ => 'http://biomoby.org/RESOURCES/MOBY-S/Objects#';
12 use constant SRV => 'http://biomoby.org/RESOURCES/MOBY-S/Services#';
13 use constant NS => 'http://biomoby.org/RESOURCES/MOBY-S/Namespaces#';
14 use constant MP => 'http://biomoby.org/RESOURCES/MOBY-S/Predicates#';
15 use constant SI => 'http://biomoby.org/RESOURCES/MOBY-S/ServiceInstances#';
16 use constant DC => 'http://purl.org/dc/elements/1.1/';
18 { # these need to be class variables, since this module is loaded multiple times, but the newResouce counter has to increment nevertheless.
20 my $inputfactory ||= new RDF::Core::NodeFactory( GenPrefix => '_:input', GenCounter => 0,BaseURI=>'http://www.biomoby.org/nil');# BaseURI=>'http://www.foo.org/');
21 my $outputfactory ||= new RDF::Core::NodeFactory( GenPrefix => '_:output', GenCounter => 0,BaseURI=>'http://www.biomoby.org/nil');# BaseURI=>'http://www.foo.org/');
22 my $simplefactory ||= new RDF::Core::NodeFactory( GenPrefix => '_:simple', GenCounter => 0,BaseURI=>'http://www.biomoby.org/nil');# BaseURI=>'http://www.foo.org/');
23 my $collectionfactory ||= new RDF::Core::NodeFactory( GenPrefix => '_:collection', GenCounter => 0,BaseURI=>'http://www.biomoby.org/nil');# BaseURI=>'http://www.foo.org/');
24 my $secondaryfactory ||= new RDF::Core::NodeFactory( GenPrefix => '_:secondary', GenCounter => 0,BaseURI=>'http://www.biomoby.org/nil');# BaseURI=>'http://www.foo.org/');
26 sub nextinput {
27 return $inputfactory->newResource
29 sub nextoutput {
30 return $outputfactory->newResource
32 sub nextsimple {
33 return $simplefactory->newResource
35 sub nextcollection {
36 return $collectionfactory->newResource
38 sub nextsecondary {
39 return $secondaryfactory->newResource
46 sub type {
47 my ($self, @args) = @_;
48 $args[0] && ($self->{type} = $args[0]);
49 return $self->{type};
53 sub model {
54 my ($self, @args) = @_;
55 $args[0] && ($self->{model} = $args[0]);
56 return $self->{model};
60 sub subject {
61 my ($self, @args) = @_;
62 $args[0] && ($self->{subject} = $args[0]);
63 return $self->{subject};
67 sub articles {
68 my ($self, @args) = @_;
69 $args[0] && ($self->{articles} = \@args);
70 return @{$self->{articles}};
73 sub new {
74 my ($caller, %args) = @_;
75 return 0 unless $args{'model'} && (ref($args{'model'}) =~ /rdf::core/i);
76 return 0 unless $args{'type'} && ( ($args{'type'} =~ /consumes/i) || ($args{'type'} =~ /produces/i) );
77 return 0 unless $args{'subject'} && (ref($args{'subject'}) =~ /rdf::core/i);
78 return 0 unless $args{'articles'} && (ref($args{'articles'}) =~ /array/i);
79 return 1 unless ${$args{'articles'}}[0]; # if there ARE no articles, this is a valid result!
81 my $caller_is_obj = ref($caller);
82 my $class = $caller_is_obj || $caller;
84 my $self = bless {}, $class;
86 $self->type($args{'type'});
87 $self->subject($args{'subject'});
88 $self->model($args{'model'});
89 $self->articles(@{$args{'articles'}});
90 my $subject = $self->subject;
91 my $model = $self->model;
94 $self->{Bag} = new RDF::Core::Resource(RDF_NS,'Bag');
95 my $Thingy;
96 if ($self->type eq 'consumes'){
97 $Thingy = &nextinput; # create a bnode
98 } else {
99 $Thingy = &nextoutput; # create a bnode
101 my $predicate = $subject->new(MP,$self->type); # 'consumes' or 'produces'
102 my $statement = new RDF::Core::Statement($subject, $predicate, $Thingy);
103 $model->addStmt($statement);
104 #<service consumes bnode1>
106 my $type = $Thingy->new(RDF_NS,'type');
107 $statement = new RDF::Core::Statement($Thingy, $type, $self->{Bag});
108 $model->addStmt($statement);
109 # <type rdf:Bag>
111 $self->build($Thingy);
112 return $self;
117 sub build {
118 my ($self, $Thingy) = @_;
119 my $model = $self->model;
120 my @articles = $self->articles;
121 my $Bag = $self->{Bag};
123 # my $li = 0;
124 foreach my $IN(@articles){
125 my $input = &nextsimple;
126 if ($IN->isSimple){
127 my $LI = $Thingy->new(MP, "SimpleArticle"); # <rdf:li> nodes - need to be numbered :_1, :_2, etc
128 my $statement = new RDF::Core::Statement($Thingy, $LI, $input);
129 $model->addStmt($statement);
130 } elsif ($IN->isCollection){
131 my $LI = $Thingy->new(MP, "CollectionArticle"); # <rdf:li> nodes - need to be numbered :_1, :_2, etc
132 my $statement = new RDF::Core::Statement($Thingy, $LI, $input);
133 $model->addStmt($statement);
134 } elsif ($IN->isSecondary){
135 my $LI = $Thingy->new(MP, "SecondaryArticle"); # <rdf:li> nodes - need to be numbered :_1, :_2, etc
136 my $statement = new RDF::Core::Statement($Thingy, $LI, $input);
137 $model->addStmt($statement);
138 } else {
139 print STDERR "the InOutArticlesRDF got a service instance input or output that was not a simple, collection, nor secondary???\n";
140 return;
142 # ++$li;
143 #my $LI = $Thingy->new(RDF_NS, "_$li"); # <rdf:li> nodes - need to be numbered :_1, :_2, etc
144 #my $statement = new RDF::Core::Statement($Thingy, $LI, $input);
145 #$model->addStmt($statement);
146 #<Description about bnode1>
147 # <rdf:_1 bnode2>
149 if ($IN->isSimple){
150 &_addSimple($model, $input, $IN);
151 } elsif ($IN->isCollection) { # COLLECTION - is just a bag of simples
152 my $type = $input->new(RDF_NS,'type');
153 my $statement = new RDF::Core::Statement($input, $type, $Bag);
154 $model->addStmt($statement);
155 # <type rdf:Bag>
156 _addClassLiteral($model, MP, $input, 'articleName', $IN->articleName) if $IN->articleName; # the bag has an articlename
158 my $simps = $IN->Simples;
159 my $lli=0;
160 foreach my $simp(@{$simps}){
161 ++$lli;
162 my $LI = $input->new(RDF_NS, "_$lli"); # <rdf:li> nodes - need to be numbered :_1, :_2, etc; these connect to the individual simples
163 my $collection_member = &nextcollection;
164 my $statement = new RDF::Core::Statement($input, $LI, $collection_member);
165 $model->addStmt($statement);
168 &_addSimple($model, $collection_member, $simp);
170 } elsif ($IN->isSecondary) {
171 &_addSecondary($model, $input, $IN);
176 sub _addSimple {
177 my ($model, $article, $ART) = @_; # (RDF::COre::Model, $RDF::Core::Resource, $MOBY::Client::SimpleArticle)
178 _addClassLiteral($model, MP, $article, 'article_name', $ART->articleName) if $ART->articleName;
179 my $objecttype = $ART->objectType;
180 $objecttype = ($objecttype =~ /urn:lsid.*:(\S+)$/)?$1:$objecttype;
182 _addResource($model, MP, 'object_type', $article, OBJ, $objecttype);
184 my $namespaces = $ART->namespaces();
185 foreach (@{$namespaces}){
186 my $namespace = _addClassResource($model, NS, "$_", '');
187 my $inNamespace = $article->new(MP, 'namespace_type');
188 my $statement = new RDF::Core::Statement($article, $inNamespace, $namespace);
189 $model->addStmt($statement);
194 #| secondary_input_id | int(10) unsigned | | PRI | NULL | auto_increment |
195 #| default_value | text | YES | | NULL | |
196 #| maximum_value | decimal(10,0) | YES | | NULL | |
197 #| minimum_value | decimal(10,0) | YES | | NULL | |
198 #| enum_value | text | YES | | NULL | |
199 #| datatype | enum('String','Integer','DateTime','Float') | YES | | NULL | |
200 #| article_name | varchar(255) | YES | | NULL | |
201 #| service_instance_id | int(10) unsigned | | | 0 | |
202 sub _addSecondary {
203 my ($model, $article, $ART) = @_; # (RDF::COre::Model, $RDF::Core::Resource, $MOBY::Client::SimpleArticle)
204 _addClassLiteral($model, MP, $article, 'article_name', $ART->articleName) if $ART->articleName;
205 _addClassLiteral($model, MP, $article, 'default_value', $ART->default) if $ART->default;
206 _addClassLiteral($model, MP, $article, 'datatype', $ART->datatype) if $ART->datatype;
207 _addClassLiteral($model, MP, $article, 'max', $ART->max) if $ART->max;
208 _addClassLiteral($model, MP, $article, 'min', $ART->min) if $ART->min;
209 my @enums = @{$ART->enum};
210 foreach my $enum(@enums){
211 _addClassLiteral($model, MP, $article, 'enum', $enum) if defined $enum;
216 sub _addResource {
217 my ($model, $ns, $predicate, $subject, $ons, $object) = @_;
219 $predicate = $subject->new($ns, $predicate);
220 $object = new RDF::Core::Resource($ons, $object);
221 my $statement = new RDF::Core::Statement($subject, $predicate, $object);
222 $model->addStmt($statement);
227 # these should also be stripped out into their own module
228 sub _addClassResource {
229 my ($model, $ns, $thing, $def) = @_;
230 my ($subject, $statement, $class, $label, $type);
232 $label = ($thing =~ /urn:lsid.*:(\S+)$/)?$1:$thing;
234 unless (ref($thing) =~ /RDF/){
235 $subject = new RDF::Core::Resource($ns, $thing);
238 $type = $subject->new(RDF_NS,'type');
239 $class = new RDF::Core::Resource(RDFS_NS,'Class');
240 $statement = new RDF::Core::Statement($subject, $type, $class);
241 $model->addStmt($statement);
243 $type = $subject->new(RDFS_NS,'label');
244 $label = new RDF::Core::Literal($label,"en", "http://www.w3.org/2001/XMLSchema#string");
245 $statement = new RDF::Core::Statement($subject, $type, $label);
246 $model->addStmt($statement);
248 return $subject unless $def;
250 $type = $subject->new(RDFS_NS,'comment');
251 $label = new RDF::Core::Literal($def, "en", "http://www.w3.org/2001/XMLSchema#string");
252 $statement = new RDF::Core::Statement($subject, $type, $label);
253 $model->addStmt($statement);
255 return $subject;
258 sub _addClassLiteral {
259 my ($model, $pns, $subject, $predicate, $value) = @_;
261 $predicate = $subject->new($pns, $predicate);
262 $value = new RDF::Core::Literal($value, "en", "http://www.w3.org/2001/XMLSchema#string");
263 my $statement = new RDF::Core::Statement($subject, $predicate, $value);
264 $model->addStmt($statement);