Project

General

Profile

1 1929 brooke
 #
2
 #  '$RCSfile$'
3
 #  Copyright: 2000 Regents of the University of California
4
 #
5
 #   '$Author$'
6
 #     '$Date$'
7
 # '$Revision$'
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 3421 walbridge
use HTTP::Request::Common qw(POST);
35 1929 brooke
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 3421 walbridge
  my($type,$metacatUrl) = @_;
67 1929 brooke
  my $cookie_jar = HTTP::Cookies->new;
68
69 3421 walbridge
  my $self = {
70
    metacatUrl     => $metacatUrl,
71 1929 brooke
    message        => '',
72
    cookies        => \$cookie_jar
73
  };
74
75 3421 walbridge
  bless $self, $type;
76
  return $self;
77 1929 brooke
}
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 1955 jones
  $self->{'message'} = '';
102 1929 brooke
  my $userAgent = new LWP::UserAgent;
103
  $userAgent->agent("MetacatClient/1.0");
104 3421 walbridge
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 1929 brooke
  my $cookie_jar = $self->{'cookies'};
119
  $$cookie_jar->add_cookie_header($request);
120 5029 daigle
  #print "Content_type:text/html\n\n";
121 3421 walbridge
  #print "request: " . $request->as_string();
122 1929 brooke
123
  my $response = $userAgent->request($request);
124 3421 walbridge
  #print "response: " . $response->as_string();
125
126 1929 brooke
  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 2684 sgarg
# 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 1929 brooke
#############################################################
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 2684 sgarg
  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 1929 brooke
  return $returnval;
175
}
176
177
#############################################################
178 9228 leinfelder
# 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
    # clear the cookie
188
    my $cookie_jar = $self->{'cookies'};
189
    $$cookie_jar->clear();
190
191
    return $response->content;
192
}
193
194
#############################################################
195 5311 daigle
# subroutine to log into Metacat and get usr info xml for
196
# a logged in user
197
#############################################################
198
sub getUserInfo {
199
	my $self = shift;
200
201
	my %postData = (action => 'getloggedinuserinfo');
202
203
	my $response = $self->sendData(%postData);
204
205
	return $response->content;
206
}
207
208
#############################################################
209 1929 brooke
# subroutine to insert an XML document into Metacat
210
# If success, return 1, else return 0
211
#############################################################
212
sub insert {
213
  my $self = shift;
214
  my $docid = shift;
215
  my $xmldocument = shift;
216
  my $dtd = shift;
217
218
  my $returnval = 0;
219
220
  my %postData = ( action => 'insert',
221
                   docid => $docid,
222
                   doctext => $xmldocument
223
                 );
224
  if ($dtd) {
225
    $postData{'dtdtext'} = $dtd;
226
  }
227
228
  my $response = $self->sendData(%postData);
229
  if (($response) && $response->content =~ /<success>/) {
230
    $returnval = 1;
231
  } elsif (($response)) {
232
    $returnval = 0;
233
    #print "Error response from sendData!\n";
234
    #print $response->content, "\n";
235
  } else {
236
    $returnval = 0;
237
    #print "Invalid response from sendData!\n";
238
  }
239
240
  return $returnval;
241
}
242
243
#############################################################
244
# subroutine to update an XML document in Metacat
245
# If success, return 1, else return 0
246
#############################################################
247
sub update {
248
  my $self = shift;
249
  my $docid = shift;
250
  my $xmldocument = shift;
251
  my $dtd = shift;
252
253
  my $returnval = 0;
254
255
  my %postData = ( action => 'update',
256
                   docid => $docid,
257
                   doctext => $xmldocument
258
                 );
259
  if ($dtd) {
260
    $postData{'dtdtext'} = $dtd;
261
  }
262
263
  my $response = $self->sendData(%postData);
264
  if (($response) && $response->content =~ /<success>/) {
265
    $returnval = 1;
266
  }
267
268
  return $returnval;
269
}
270
271 3421 walbridge
############################################################
272
# subroutine to upload an XML document in Metacat
273
# If success, return 1, else return 0
274 1929 brooke
#############################################################
275 3421 walbridge
sub upload {
276
  my $self = shift;
277
  my $docid = shift;
278
  my $datafile = shift;
279 7820 leinfelder
  my $filename = shift;
280 3421 walbridge
281
  my $returnval = 0;
282
283
  my %postData = ( action => 'upload',
284
                   docid => $docid,
285 7821 leinfelder
                   datafile => [$datafile, $filename],
286 3421 walbridge
                   enctype => 'form-data'
287
                 );
288
289
  my $response = $self->sendData(%postData);
290
  #print "response is: $response";
291
  #
292
  if (($response) && $response->content =~ /<success>/) {
293
    $returnval = $response->content;
294
  }
295
296
  return $returnval;
297
}
298
299
300
#############################################################
301 1929 brooke
# subroutine to delete an XML document in Metacat
302
# If success, return 1, else return 0
303
#############################################################
304
sub delete {
305
  my $self = shift;
306
  my $docid = shift;
307
308
  my $returnval = 0;
309
310
  my %postData = ( action => 'delete',
311
                   docid => $docid
312
                 );
313
314
  my $response = $self->sendData(%postData);
315
  if (($response) && $response->content =~ /<success>/) {
316
    $returnval = 1;
317
  }
318
319
  return $returnval;
320
}
321
322
#############################################################
323 2846 sgarg
# subroutine to set access for an XML document in Metacat
324
# If success, return 1, else return 0
325
#############################################################
326
sub setaccess {
327
  my $self = shift;
328
  my $docid = shift;
329
  my $principal = shift;
330
  my $permission = shift;
331
  my $permType = shift;
332
  my $permOrder = shift;
333
334
  my $returnval = 0;
335
336
  my %postData = ( action => 'setaccess',
337
                   docid => $docid,
338
		   principal => $principal,
339
		   permission => $permission,
340
		   permType => $permType,
341
		   permOrder => $permOrder
342
                 );
343
344
  my $response = $self->sendData(%postData);
345
  if (($response) && $response->content =~ /<success>/) {
346
    $returnval = 1;
347
  }
348
349
  return $returnval;
350
}
351
352
353
#############################################################
354 1929 brooke
# subroutine to read an XML document from Metacat
355
# returns the XML from Metacat, which may be an error response
356
#############################################################
357
sub read {
358
  my $self = shift;
359
  my $docid = shift;
360
361
  my %postData = ( action => 'read',
362
                   qformat => 'xml',
363
                   docid => $docid
364
                 );
365
366
  my $response = $self->sendData(%postData);
367
368
  my $returnval = 0;
369
  if ($response) {
370
    $returnval = $response;
371
  }
372
373
  return $returnval;
374
}
375
376
#############################################################
377
# subroutine to query metacat using a structured path query
378
# returns the XML from Metacat, which may be an error response
379
#############################################################
380
sub squery {
381
  my $self = shift;
382
  my $query = shift;
383
384
  my %postData = ( action => 'squery',
385
                   qformat => 'xml',
386
                   query => $query
387
                 );
388
389
  my $response = $self->sendData(%postData);
390
391
  my $returnval = 0;
392
  if ($response) {
393
    $returnval = $response;
394
  }
395
396
  return $returnval;
397
}
398
399
#############################################################
400 1953 jones
# subroutine to get the maximimum id in a series
401
# If success, return max id, else return 0
402
#############################################################
403
sub getLastId {
404
  my $self = shift;
405
  my $scope = shift;
406
407
  my $returnval = 0;
408
409
  my %postData = ( action => 'getlastdocid',
410
                   scope => $scope
411
                 );
412
413
  my $response = $self->sendData(%postData);
414 5201 daigle
  if (($response) && $response->content =~  /<docid>(.*)<\/docid>/s) {
415 1953 jones
      $returnval = "$1";
416
  } elsif (($response)) {
417
    $returnval = 0;
418
    #print "Error response from sendData!\n";
419
    #print $response->content, "\n";
420
  } else {
421
    $returnval = 0;
422
    #print "Invalid response from sendData!\n";
423
  }
424
425
  return $returnval;
426
}
427 5201 daigle
428 1953 jones
#############################################################
429 5201 daigle
# subroutine to get the maximimum id in a series
430
# If success, return max id, else return 0
431
#############################################################
432
sub getLastRevision {
433
  my $self = shift;
434
  my $docid = shift;
435
436
  my $returnval = 0;
437
438
  my %postData = ( action => 'getrevisionanddoctype',
439
                   docid => $docid
440
                 );
441
442
  my $response = $self->sendData(%postData);
443
  if (($response) && $response->content =~ /(.*);(.*)/s)  {
444
      $returnval = "$1";
445
  } elsif (($response)) {
446
    $returnval = 0;
447
    #print "Error response from sendData!\n";
448
    #print $response->content, "\n";
449
  } else {
450
    $returnval = 0;
451
    #print "Invalid response from sendData!\n";
452
  }
453
454
  return $returnval;
455
}
456
457
#############################################################
458 7695 leinfelder
# subroutine to get the docid for a given PID
459
# If success, return docid, else return -1
460
#############################################################
461
sub getDocid {
462
  my $self = shift;
463
  my $pid = shift;
464
465
  my $returnval = 0;
466
467
  my %postData = ( action => 'getdocid',
468
                   pid => $pid
469
                 );
470
471
  my $response = $self->sendData(%postData);
472
  if (($response) && $response->content =~  /<docid>(.*)<\/docid>/s) {
473
      $returnval = "$1";
474
  } elsif (($response)) {
475
    $returnval = -1;
476
    #print "Error response from sendData!\n";
477
    #print $response->content, "\n";
478
  } else {
479
    $returnval = -1;
480
    #print "Invalid response from sendData!\n";
481
  }
482
483
  return $returnval;
484
}
485
486
#############################################################
487 1929 brooke
# subroutine to get the message returned from the last executed
488
# metacat action.  These are generally XML formatted messages.
489
#############################################################
490
sub getMessage {
491
  my $self = shift;
492
493
  return $self->{'message'};
494
}
495
496
#############################################################
497
# subroutine to get the cookies returned from the metacat
498
# server to establish (and pass on) session info (JSESSIONID).
499
#############################################################
500
sub getCookies {
501
  my $self = shift;
502
503
  return $self->{'cookies'};
504
}
505
506
# Autoload methods go after =cut, and are processed by the autosplit program.
507
508
1;
509
__END__
510
# Below is stub documentation for your module. You better edit it!
511
512
=head1 NAME
513
514
Metacat - Perl extension for communicating with the Metacat XML database
515
516
=head1 SYNOPSIS
517
518
  use Metacat;
519
  my $metacat = Metacat->new();
520
  my $response = $metacat->login($username, $password);
521
  print $metacat->getMessage();
522
  $response = $metacat->insert($docid, $xmldoc);
523
  print $metacat->getMessage();
524
  $response = $metacat->insert($docid, $xmldoc, $dtd);
525
  print $metacat->getMessage();
526
  $response = $metacat->update($docid, $xmldoc);
527
  print $metacat->getMessage();
528 3724 jones
  $response = $metacat->upload($docid, $data);
529
  print $metacat->getMessage();
530 1929 brooke
  $htmlResponse = $metacat->read($docid);
531
  $xmldoc = $htmlResponse->content();
532
  print $xmldoc;
533
  $resultset = $metacat->squery($pathquery);
534
  print $resultset;
535
  $response = $metacat->delete($docid);
536 2846 sgarg
  $response = $metacat->setaccess($docid,$principal,$permission,$permType,$permOrder);
537 1953 jones
  my $lastid = $metacat->getLastId("obfs");
538 1929 brooke
  print $metacat->getMessage();
539
  $response = $metacat->getCookies();
540
  print $metacat->getMessage();
541
542
=head1 DESCRIPTION
543
544
This is a client library for accessing the Metacat XML database.  Metacat
545
is a Java servlet that accepts commands over HTTP and returns XML and
546
HTML responses.  See http://knb.ecoinformatics.org for details about
547
Metacat and its interface.
548
549
=head2 EXPORT
550
551
None by default.
552
553
554
=head1 AUTHOR
555
556
Matthew B. Jones, jones@nceas.ucsb.edu
557
558
=head1 SEE ALSO
559
560
perl(1).
561
562
=cut