Project

General

Profile

1
 #
2
 #  '$RCSfile$'
3
 #  Copyright: 2000 Regents of the University of California 
4
 #
5
 #   '$Author: leinfelder $'
6
 #     '$Date: 2015-07-08 17:01:42 -0700 (Wed, 08 Jul 2015) $'
7
 # '$Revision: 9234 $' 
8
 # 
9
 # This program is free software; you can redistribute it and/or modify
10
 # it under the terms of the GNU General Public License as published by
11
 # the Free Software Foundation; either version 2 of the License, or
12
 # (at your option) any later version.
13
 #
14
 # This program is distributed in the hope that it will be useful,
15
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 # GNU General Public License for more details.
18
 #
19
 # You should have received a copy of the GNU General Public License
20
 # along with this program; if not, write to the Free Software
21
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22
 #
23

    
24
package Metacat;
25

    
26
require 5.005_62;
27
use strict;
28
use warnings;
29

    
30
require Exporter;
31
use AutoLoader qw(AUTOLOAD);
32

    
33
use LWP::UserAgent;
34
use HTTP::Request::Common qw(POST);
35
use HTTP::Cookies;
36

    
37
our @ISA = qw(Exporter);
38

    
39
# Items to export into callers namespace by default. Note: do not export
40
# names by default without a very good reason. Use EXPORT_OK instead.
41
# Do not simply export all your public functions/methods/constants.
42

    
43
# This allows declaration	use Metacat ':all';
44
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
45
# will save memory.
46
our %EXPORT_TAGS = ( 'all' => [ qw(
47
	
48
) ] );
49

    
50
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
51

    
52
our @EXPORT = qw(
53
	
54
);
55
our $VERSION = '0.01';
56

    
57

    
58
# Preloaded methods go here.
59

    
60
#############################################################
61
# Constructor creates a new class instance and inits all
62
# of the instance variables to their proper default values,
63
# which can later be changed using "set_options"
64
#############################################################
65
sub new {
66
  my($type,$metacatUrl) = @_;
67
  my $cookie_jar = HTTP::Cookies->new;
68

    
69
  my $self = {
70
    metacatUrl     => $metacatUrl,
71
    message        => '',
72
    cookies        => \$cookie_jar
73
  };
74

    
75
  bless $self, $type; 
76
  return $self;
77
}
78

    
79
#############################################################
80
# subroutine to set options for the class, including the URL 
81
# for the Metacat database to which we would connect
82
#############################################################
83
sub set_options {
84
  my $self = shift;
85
  my %newargs = ( @_ );
86

    
87
  my $arg;
88
  foreach $arg (keys %newargs) {
89
    $self->{$arg} = $newargs{$arg};
90
  }
91
}
92

    
93
#############################################################
94
# subroutine to send data to metacat and get the response
95
# return response from metacat
96
#############################################################
97
sub sendData {
98
  my $self = shift;
99
  my %postData = ( @_ );
100

    
101
  $self->{'message'} = '';
102
  my $userAgent = new LWP::UserAgent;
103
  $userAgent->agent("MetacatClient/1.0");
104

    
105
  # determine encoding type
106
  my $contentType = 'application/x-www-form-urlencoded';
107
  if ($postData{'enctype'}) {
108
      $contentType = $postData{'enctype'};
109
      delete $postData{'enctype'};
110
  }
111

    
112
  my $request = POST("$self->{'metacatUrl'}",
113
                     Content_Type => $contentType,
114
                     Content => \%postData
115
                );
116

    
117
  # set cookies on UA object
118
  my $cookie_jar = $self->{'cookies'};
119
  $$cookie_jar->add_cookie_header($request);
120
  #print "Content_type:text/html\n\n";
121
  #print "request: " . $request->as_string();
122

    
123
  my $response = $userAgent->request($request);
124
  #print "response: " . $response->as_string();
125
   
126
  if ($response->is_success) {
127
    # save the cookies
128
    $$cookie_jar->extract_cookies($response);
129
    # save the metacat response message
130
    $self->{'message'} = $response->content;
131
  } else {
132
    #print "SendData content is: ", $response->content, "\n";
133
    return 0;
134
  } 
135
  return $response;
136
}
137

    
138
#############################################################
139
# subroutine to log into Metacat and save the cookie if the
140
# login is valid.  If not valid, return 0. If valid then send 
141
# following values to indicate user status
142
# 1 - user
143
# 2 - moderator
144
# 3 - administrator
145
# 4 - moderator and administrator
146
#############################################################
147
sub login {
148
  my $self = shift;
149
  my $username = shift;
150
  my $password = shift;
151

    
152
  my $returnval = 0;
153

    
154
  my %postData = ( action => 'login',
155
                   qformat => 'xml',
156
                   username => $username,
157
                   password => $password
158
                 );
159
  my $response = $self->sendData(%postData);
160
  if (($response) && $response->content =~ /<login>/) {
161
    $returnval = 1;
162
  }
163

    
164
  if (($response) && $response->content =~ /<isAdministrator>/) {
165
	if (($response) && $response->content =~ /<isModerator>/) {
166
    		$returnval = 4;
167
	} else {
168
		$returnval = 3;
169
	}
170
  } elsif (($response) && $response->content =~ /<isModerator>/){
171
	$returnval = 2;
172
  }
173

    
174
  return $returnval;
175
}
176

    
177
#############################################################
178
# subroutine to logout of Metacat
179
#############################################################
180
sub logout {
181
    my $self = shift;
182
    
183
    my %postData = (action => 'logout');
184
    
185
    my $response = $self->sendData(%postData);
186
    
187
    my $returnval = 1;
188
    if (($response) && $response->content =~ /<logout>/) {
189
    	$returnval = 0;
190
  	}
191
  	
192
    # clear the cookie
193
    my $cookie_jar = $self->{'cookies'};
194
    $$cookie_jar->clear();
195
    
196
    return $returnval;
197
}
198

    
199
#############################################################
200
# subroutine to log into Metacat and get usr info xml for
201
# a logged in user
202
#############################################################
203
sub getUserInfo {
204
	my $self = shift;
205

    
206
	my %postData = (action => 'getloggedinuserinfo');
207
  
208
	my $response = $self->sendData(%postData);
209

    
210
	return $response->content;
211
}
212

    
213
#############################################################
214
# subroutine to insert an XML document into Metacat
215
# If success, return 1, else return 0
216
#############################################################
217
sub insert {
218
  my $self = shift;
219
  my $docid = shift;
220
  my $xmldocument = shift;
221
  my $dtd = shift;
222

    
223
  my $returnval = 0;
224

    
225
  my %postData = ( action => 'insert',
226
                   docid => $docid,
227
                   doctext => $xmldocument
228
                 );
229
  if ($dtd) {
230
    $postData{'dtdtext'} = $dtd;
231
  }
232

    
233
  my $response = $self->sendData(%postData);
234
  if (($response) && $response->content =~ /<success>/) {
235
    $returnval = 1;
236
  } elsif (($response)) {
237
    $returnval = 0;
238
    #print "Error response from sendData!\n";
239
    #print $response->content, "\n";
240
  } else {
241
    $returnval = 0;
242
    #print "Invalid response from sendData!\n";
243
  }
244

    
245
  return $returnval;
246
}
247

    
248
#############################################################
249
# subroutine to update an XML document in Metacat
250
# If success, return 1, else return 0
251
#############################################################
252
sub update {
253
  my $self = shift;
254
  my $docid = shift;
255
  my $xmldocument = shift;
256
  my $dtd = shift;
257

    
258
  my $returnval = 0;
259

    
260
  my %postData = ( action => 'update',
261
                   docid => $docid,
262
                   doctext => $xmldocument
263
                 );
264
  if ($dtd) {
265
    $postData{'dtdtext'} = $dtd;
266
  }
267

    
268
  my $response = $self->sendData(%postData);
269
  if (($response) && $response->content =~ /<success>/) {
270
    $returnval = 1;
271
  }
272

    
273
  return $returnval;
274
}
275

    
276
############################################################
277
# subroutine to upload an XML document in Metacat
278
# If success, return 1, else return 0
279
#############################################################
280
sub upload {
281
  my $self = shift;
282
  my $docid = shift;
283
  my $datafile = shift;
284
  my $filename = shift;
285

    
286
  my $returnval = 0;
287

    
288
  my %postData = ( action => 'upload',
289
                   docid => $docid,
290
                   datafile => [$datafile, $filename],
291
                   enctype => 'form-data'
292
                 );
293

    
294
  my $response = $self->sendData(%postData);
295
  #print "response is: $response";
296
  # 
297
  if (($response) && $response->content =~ /<success>/) {
298
    $returnval = $response->content;
299
  }
300

    
301
  return $returnval;
302
}
303

    
304

    
305
#############################################################
306
# subroutine to delete an XML document in Metacat
307
# If success, return 1, else return 0
308
#############################################################
309
sub delete {
310
  my $self = shift;
311
  my $docid = shift;
312

    
313
  my $returnval = 0;
314

    
315
  my %postData = ( action => 'delete',
316
                   docid => $docid
317
                 );
318

    
319
  my $response = $self->sendData(%postData);
320
  if (($response) && $response->content =~ /<success>/) {
321
    $returnval = 1;
322
  }
323

    
324
  return $returnval;
325
}
326

    
327
#############################################################
328
# subroutine to set access for an XML document in Metacat
329
# If success, return 1, else return 0
330
#############################################################
331
sub setaccess {
332
  my $self = shift;
333
  my $docid = shift;
334
  my $principal = shift;
335
  my $permission = shift;
336
  my $permType = shift;
337
  my $permOrder = shift;
338

    
339
  my $returnval = 0;
340

    
341
  my %postData = ( action => 'setaccess',
342
                   docid => $docid,
343
		   principal => $principal,
344
		   permission => $permission,
345
		   permType => $permType,
346
		   permOrder => $permOrder
347
                 );
348

    
349
  my $response = $self->sendData(%postData);
350
  if (($response) && $response->content =~ /<success>/) {
351
    $returnval = 1;
352
  }
353

    
354
  return $returnval;
355
}
356

    
357

    
358
#############################################################
359
# subroutine to read an XML document from Metacat
360
# returns the XML from Metacat, which may be an error response
361
#############################################################
362
sub read {
363
  my $self = shift;
364
  my $docid = shift;
365

    
366
  my %postData = ( action => 'read',
367
                   qformat => 'xml',
368
                   docid => $docid
369
                 );
370

    
371
  my $response = $self->sendData(%postData);
372
  
373
  my $returnval = 0;
374
  if ($response) {
375
    $returnval = $response;
376
  } 
377
    
378
  return $returnval;
379
}
380

    
381
#############################################################
382
# subroutine to query metacat using a structured path query
383
# returns the XML from Metacat, which may be an error response
384
#############################################################
385
sub squery {
386
  my $self = shift;
387
  my $query = shift;
388

    
389
  my %postData = ( action => 'squery',
390
                   qformat => 'xml',
391
                   query => $query
392
                 );
393

    
394
  my $response = $self->sendData(%postData);
395

    
396
  my $returnval = 0;
397
  if ($response) {
398
    $returnval = $response;
399
  } 
400
    
401
  return $returnval;
402
}
403

    
404
#############################################################
405
# subroutine to get the maximimum id in a series
406
# If success, return max id, else return 0
407
#############################################################
408
sub getLastId {
409
  my $self = shift;
410
  my $scope = shift;
411

    
412
  my $returnval = 0;
413

    
414
  my %postData = ( action => 'getlastdocid',
415
                   scope => $scope
416
                 );
417

    
418
  my $response = $self->sendData(%postData);
419
  if (($response) && $response->content =~  /<docid>(.*)<\/docid>/s) {
420
      $returnval = "$1";
421
  } elsif (($response)) {
422
    $returnval = 0;
423
    #print "Error response from sendData!\n";
424
    #print $response->content, "\n";
425
  } else {
426
    $returnval = 0;
427
    #print "Invalid response from sendData!\n";
428
  }
429

    
430
  return $returnval;
431
}
432

    
433
#############################################################
434
# subroutine to get the maximimum id in a series
435
# If success, return max id, else return 0
436
#############################################################
437
sub getLastRevision {
438
  my $self = shift;
439
  my $docid = shift;
440

    
441
  my $returnval = 0;
442

    
443
  my %postData = ( action => 'getrevisionanddoctype',
444
                   docid => $docid
445
                 );
446

    
447
  my $response = $self->sendData(%postData);
448
  if (($response) && $response->content =~ /(.*);(.*)/s)  {
449
      $returnval = "$1";
450
  } elsif (($response)) {
451
    $returnval = 0;
452
    #print "Error response from sendData!\n";
453
    #print $response->content, "\n";
454
  } else {
455
    $returnval = 0;
456
    #print "Invalid response from sendData!\n";
457
  }
458

    
459
  return $returnval;
460
}
461

    
462
#############################################################
463
# subroutine to get the docid for a given PID
464
# If success, return docid, else return -1
465
#############################################################
466
sub getDocid {
467
  my $self = shift;
468
  my $pid = shift;
469

    
470
  my $returnval = 0;
471

    
472
  my %postData = ( action => 'getdocid',
473
                   pid => $pid
474
                 );
475

    
476
  my $response = $self->sendData(%postData);
477
  if (($response) && $response->content =~  /<docid>(.*)<\/docid>/s) {
478
      $returnval = "$1";
479
  } elsif (($response)) {
480
    $returnval = -1;
481
    #print "Error response from sendData!\n";
482
    #print $response->content, "\n";
483
  } else {
484
    $returnval = -1;
485
    #print "Invalid response from sendData!\n";
486
  }
487

    
488
  return $returnval;
489
}
490

    
491
#############################################################
492
# subroutine to get the message returned from the last executed
493
# metacat action.  These are generally XML formatted messages.
494
#############################################################
495
sub getMessage {
496
  my $self = shift;
497

    
498
  return $self->{'message'};
499
}
500

    
501
#############################################################
502
# subroutine to get the cookies returned from the metacat 
503
# server to establish (and pass on) session info (JSESSIONID).
504
#############################################################
505
sub getCookies {
506
  my $self = shift;
507

    
508
  return $self->{'cookies'};
509
}
510

    
511
# Autoload methods go after =cut, and are processed by the autosplit program.
512

    
513
1;
514
__END__
515
# Below is stub documentation for your module. You better edit it!
516

    
517
=head1 NAME
518

    
519
Metacat - Perl extension for communicating with the Metacat XML database
520

    
521
=head1 SYNOPSIS
522

    
523
  use Metacat;
524
  my $metacat = Metacat->new();
525
  my $response = $metacat->login($username, $password); 
526
  print $metacat->getMessage();
527
  $response = $metacat->insert($docid, $xmldoc); 
528
  print $metacat->getMessage();
529
  $response = $metacat->insert($docid, $xmldoc, $dtd); 
530
  print $metacat->getMessage();
531
  $response = $metacat->update($docid, $xmldoc); 
532
  print $metacat->getMessage();
533
  $response = $metacat->upload($docid, $data); 
534
  print $metacat->getMessage();
535
  $htmlResponse = $metacat->read($docid); 
536
  $xmldoc = $htmlResponse->content();
537
  print $xmldoc;
538
  $resultset = $metacat->squery($pathquery); 
539
  print $resultset;
540
  $response = $metacat->delete($docid); 
541
  $response = $metacat->setaccess($docid,$principal,$permission,$permType,$permOrder); 
542
  my $lastid = $metacat->getLastId("obfs");
543
  print $metacat->getMessage();
544
  $response = $metacat->getCookies(); 
545
  print $metacat->getMessage();
546

    
547
=head1 DESCRIPTION
548

    
549
This is a client library for accessing the Metacat XML database.  Metacat
550
is a Java servlet that accepts commands over HTTP and returns XML and
551
HTML responses.  See http://knb.ecoinformatics.org for details about
552
Metacat and its interface.
553

    
554
=head2 EXPORT
555

    
556
None by default.
557

    
558

    
559
=head1 AUTHOR
560

    
561
Matthew B. Jones, jones@nceas.ucsb.edu
562

    
563
=head1 SEE ALSO
564

    
565
perl(1).
566

    
567
=cut
(5-5/7)