Project

General

Profile

1 1780 jones
/**
2
 *  '$RCSfile$'
3
 *  Copyright: 2000 Regents of the University of California and the
4
 *              National Center for Ecological Analysis and Synthesis
5
 *
6
 *   '$Author$'
7
 *     '$Date$'
8
 * '$Revision$'
9
 *
10
 * This program is free software; you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation; either version 2 of the License, or
13
 * (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 * GNU General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public License
21
 * along with this program; if not, write to the Free Software
22
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23
 */
24
25
package edu.ucsb.nceas.metacat.client;
26
27 1786 tao
import java.io.BufferedReader;
28 1780 jones
import java.io.InputStream;
29 1783 jones
import java.io.InputStreamReader;
30 1784 jones
import java.io.PushbackReader;
31 2981 jones
import java.io.StringReader;
32 1784 jones
import java.io.IOException;
33 1783 jones
import java.io.StringWriter;
34 1780 jones
import java.io.Reader;
35
import java.net.URL;
36
import java.util.Properties;
37 3141 berkley
import java.util.Vector;
38 1780 jones
39 2981 jones
import org.w3c.dom.Node;
40 3141 berkley
import org.w3c.dom.NodeList;
41 2981 jones
42 1780 jones
import edu.ucsb.nceas.utilities.HttpMessage;
43 1788 jones
import edu.ucsb.nceas.utilities.IOUtil;
44 2981 jones
import edu.ucsb.nceas.utilities.XMLUtilities;
45 2240 sgarg
import java.io.File;
46 1780 jones
47 1788 jones
48 1780 jones
/**
49 2240 sgarg
 *  This interface provides methods for initializing and logging in to a
50
 *  Metacat server, and then querying, reading, transforming, inserting,
51 1780 jones
 *  updating and deleting documents from that server.
52
 */
53
public class MetacatClient implements Metacat
54
{
55
    /** The URL string for the metacat server */
56
    private String metacatUrl;
57
58 1822 jones
    /** The session identifier for the session */
59
    private String sessionId;
60
61 1780 jones
    /**
62
     * Constructor to create a new instance. Protected because instances
63
     * should only be created by the factory MetacatFactory.
64
     */
65
    protected MetacatClient()
66
    {
67 1822 jones
        this.metacatUrl = null;
68
        this.sessionId = null;
69 1780 jones
    }
70
71
    /**
72
     *  Method used to log in to a metacat server. Implementations will need
73
     *  to cache a cookie value to make the session persistent.  Each time a
74
     *  call is made to one of the other methods (e.g., read), the cookie will
75
     *  need to be passed back to the metacat server along with the request.
76
     *
77
     *  @param username   the username of the user, like an LDAP DN
78
     *  @param password   the password for that user for authentication
79 1822 jones
     *  @return the response string from metacat in XML format
80 1780 jones
     *  @throws MetacatAuthException when the username/password could
81
     *                    not be authenticated
82
     */
83 2240 sgarg
    public String login(String username, String password)
84 1780 jones
           throws MetacatAuthException, MetacatInaccessibleException
85
    {
86 1783 jones
        Properties prop = new Properties();
87
        prop.put("action", "login");
88
        prop.put("qformat", "xml");
89
        prop.put("username", username);
90
        prop.put("password", password);
91
92
        String response = null;
93
        try {
94 2264 sgarg
            response = sendDataForString(prop, null, null, 0);
95 1783 jones
        } catch (Exception e) {
96
            throw new MetacatInaccessibleException(e.getMessage());
97
        }
98
99
        if (response.indexOf("<login>") == -1) {
100 1828 jones
            setSessionId("");
101 1783 jones
            throw new MetacatAuthException(response);
102 1822 jones
        } else {
103 1825 jones
            int start = response.indexOf("<sessionId>") + 11;
104 1822 jones
            int end = response.indexOf("</sessionId>");
105
            if ((start != -1) && (end != -1)) {
106 1828 jones
                setSessionId(response.substring(start,end));
107 1822 jones
            }
108 1783 jones
        }
109 1822 jones
        return response;
110 1780 jones
    }
111 2683 sgarg
112
    /**
113
     *  Method used to log in to a metacat server. Implementations will need
114
     *  to cache a cookie value to make the session persistent.  Each time a
115
     *  call is made to one of the other methods (e.g., read), the cookie will
116
     *  need to be passed back to the metacat server along with the request.
117
     *
118
     *  @param username   the username of the user, like an LDAP DN
119
     *  @param password   the password for that user for authentication
120
     *  @return the response string from metacat in XML format
121
     *  @throws MetacatAuthException when the username/password could
122
     *                    not be authenticated
123
     */
124
    public String getloggedinuserinfo() throws MetacatInaccessibleException
125
    {
126
        Properties prop = new Properties();
127
        prop.put("action", "getloggedinuserinfo");
128
        prop.put("qformat", "xml");
129 1780 jones
130 2683 sgarg
        String response = null;
131
        try {
132
            response = sendDataForString(prop, null, null, 0);
133
        } catch (Exception e) {
134
            throw new MetacatInaccessibleException(e.getMessage());
135
        }
136
137
        return response;
138
    }
139
140 1780 jones
    /**
141 1822 jones
     *  Method used to log out a metacat server. The Metacat server will end
142
     *  the session when this call is invoked.
143 1798 tao
     *
144 1822 jones
     *  @return the response string from metacat in XML format
145 1798 tao
     *  @throws MetacatInaccessibleException when the metacat server can not be
146
     *                                    reached or does not respond
147
     */
148 1822 jones
    public String logout() throws MetacatInaccessibleException, MetacatException
149 1798 tao
    {
150
        Properties prop = new Properties();
151
        prop.put("action", "logout");
152 2240 sgarg
        prop.put("qformat", "xml");
153
154 1798 tao
        String response = null;
155
        try {
156 2264 sgarg
            response = sendDataForString(prop, null, null, 0);
157 1798 tao
        } catch (Exception e) {
158
            throw new MetacatInaccessibleException(e.getMessage());
159
        }
160 2240 sgarg
161 1798 tao
        if (response.indexOf("<logout>") == -1) {
162
            throw new MetacatException(response);
163
        }
164 1828 jones
        setSessionId("");
165 1822 jones
        return response;
166 1798 tao
    }
167 2240 sgarg
168 1798 tao
    /**
169 1780 jones
     * Read an XML document from the metacat server session, accessed by docid,
170
     * and returned as a Reader.
171
     *
172
     * @param docid the identifier of the document to be read
173
     * @return a Reader for accessing the document
174 2240 sgarg
     * @throws InsufficientKarmaException when the user has insufficent rights
175 1780 jones
     *                                    for the operation
176 1784 jones
     * @throws MetacatInaccessibleException when the metacat server can not be
177
     *                                    reached or does not respond
178
     * @throws MetacatException when the metacat server generates another error
179 1780 jones
     */
180 1784 jones
    public Reader read(String docid) throws InsufficientKarmaException,
181 2989 berkley
        MetacatInaccessibleException, MetacatException, DocumentNotFoundException
182 1780 jones
    {
183 1784 jones
        PushbackReader pbr = null;
184
185
        Properties prop = new Properties();
186
        prop.put("action", "read");
187
        prop.put("qformat", "xml");
188
        prop.put("docid", docid);
189
        InputStream response = null;
190
        try {
191 2264 sgarg
            response = sendData(prop, null, null, 0);
192 1784 jones
        } catch (Exception e) {
193
            throw new MetacatInaccessibleException(e.getMessage());
194
        }
195
        pbr = new PushbackReader(new InputStreamReader(response), 512);
196
        try {
197
            char[] characters = new char[512];
198
            int len = pbr.read(characters, 0, 512);
199
            StringWriter sw = new StringWriter();
200
            sw.write(characters, 0, len);
201
            String message = sw.toString();
202
            sw.close();
203
            pbr.unread(characters, 0, len);
204
            if (message.indexOf("<error>") != -1) {
205
                if (message.indexOf("does not have permission") != -1) {
206
                    throw new InsufficientKarmaException(message);
207 2989 berkley
                } else if(message.indexOf("does not exist") != -1) {
208
                    throw new DocumentNotFoundException(message);
209 1784 jones
                } else {
210
                    throw new MetacatException(message);
211
                }
212
            }
213
        } catch (IOException ioe) {
214
            throw new MetacatException(
215 2240 sgarg
                    "MetacatClient: Error converting Reader to String."
216 1784 jones
                    + ioe.getMessage());
217
        }
218
        return pbr;
219 1780 jones
    }
220
221 2261 sgarg
222 1780 jones
    /**
223 2261 sgarg
        * Read inline data from the metacat server session, accessed by
224
        * inlinedataid and returned as a Reader.
225
        *
226
        * @param inlinedataid the identifier of the data to be read
227
        * @return a Reader for accessing the document
228
        * @throws InsufficientKarmaException when the user has insufficent rights
229
        *                                    for the operation
230
        * @throws MetacatInaccessibleException when the metacat server can not be
231
        *                                    reached or does not respond
232
        * @throws MetacatException when the metacat server generates another error
233
        */
234
       public Reader readInlineData(String inlinedataid)
235
           throws InsufficientKarmaException,
236
           MetacatInaccessibleException, MetacatException
237
       {
238
           PushbackReader pbr = null;
239
240
           Properties prop = new Properties();
241
           prop.put("action", "readinlinedata");
242
           prop.put("inlinedataid", inlinedataid);
243
244
           InputStream response = null;
245
           try {
246 2264 sgarg
               response = sendData(prop, null, null, 0);
247 2261 sgarg
           } catch (Exception e) {
248
               throw new MetacatInaccessibleException(e.getMessage());
249
           }
250
251
           pbr = new PushbackReader(new InputStreamReader(response), 512);
252
           try {
253
               char[] characters = new char[512];
254
               int len = pbr.read(characters, 0, 512);
255
               StringWriter sw = new StringWriter();
256
               sw.write(characters, 0, len);
257
               String message = sw.toString();
258
               sw.close();
259
               pbr.unread(characters, 0, len);
260
261
               if (message.indexOf("<error>") != -1) {
262
                   if (message.indexOf("does not have permission") != -1) {
263
                       throw new InsufficientKarmaException(message);
264
                   } else {
265
                       throw new MetacatException(message);
266
                   }
267
               }
268
           } catch (IOException ioe) {
269
               throw new MetacatException(
270
                       "MetacatClient: Error converting Reader to String."
271
                       + ioe.getMessage());
272
           }
273
274
           return pbr;
275
       }
276
277
    /**
278 2240 sgarg
     * Query the metacat document store with the given metacat-compatible
279 1780 jones
     * query document, and return the result set as a Reader.
280
     *
281
     * @param xmlQuery a Reader for accessing the XML version of the query
282
     * @return a Reader for accessing the result set
283
     */
284 1786 tao
    public Reader query(Reader xmlQuery) throws MetacatInaccessibleException,
285
                                                IOException
286 1780 jones
    {
287 1786 tao
        Reader reader = null;
288
        String query = null;
289 1788 jones
        try {
290
          query = IOUtil.getAsString(xmlQuery, true);
291
        } catch (IOException ioE) {
292 1786 tao
          throw ioE;
293
        }
294
295
        //set up properties
296
        Properties prop = new Properties();
297
        prop.put("action", "squery");
298
        prop.put("qformat", "xml");
299
        prop.put("query", query);
300 2240 sgarg
301 1786 tao
        InputStream response = null;
302
        try {
303 2264 sgarg
            response = sendData(prop, null, null, 0);
304 1786 tao
        } catch (Exception e) {
305
            throw new MetacatInaccessibleException(e.getMessage());
306
        }
307
        reader = new InputStreamReader(response);
308
        return reader;
309 1780 jones
    }
310
311
    /**
312
     * Insert an XML document into the repository.
313
     *
314
     * @param docid the docid to insert the document
315
     * @param xmlDocument a Reader for accessing the XML document to be inserted
316 2240 sgarg
     * @param schema a Reader for accessing the DTD or XML Schema for
317 1780 jones
     *               the document
318 1789 jones
     * @return the metacat response message
319 2240 sgarg
     * @throws InsufficientKarmaException when the user has insufficent rights
320 1780 jones
     *                                    for the operation
321 1789 jones
     * @throws MetacatInaccessibleException when the metacat server can not be
322
     *                                    reached or does not respond
323
     * @throws MetacatException when the metacat server generates another error
324
     * @throws IOException when there is an error reading the xml document
325 1780 jones
     */
326 1789 jones
    public String insert(String docid, Reader xmlDocument, Reader schema)
327
        throws InsufficientKarmaException, MetacatException, IOException,
328
        MetacatInaccessibleException
329 1780 jones
    {
330 1789 jones
        Reader reader = null;
331
        String doctext = null;
332
        String schematext = null;
333
        try {
334
          doctext = IOUtil.getAsString(xmlDocument, true);
335
          if (schema != null) {
336
              schematext = IOUtil.getAsString(schema, true);
337
          }
338
        } catch (IOException ioE) {
339
          throw ioE;
340
        }
341
342
        //set up properties
343
        Properties prop = new Properties();
344
        prop.put("action", "insert");
345
        prop.put("docid", docid);
346
        prop.put("doctext", doctext);
347
        if (schematext != null) {
348
            prop.put("dtdtext", schematext);
349
        }
350 2240 sgarg
351 1789 jones
        String response = null;
352
        try {
353 2264 sgarg
            response = sendDataForString(prop, null, null, 0);
354 1789 jones
        } catch (Exception e) {
355
            throw new MetacatInaccessibleException(e.getMessage());
356
        }
357
358
        // Check for an error condition
359
        if (response.indexOf("<error>") != -1) {
360
            if (response.indexOf("does not have permission") != -1) {
361
                throw new InsufficientKarmaException(response);
362
            } else {
363
                throw new MetacatException(response);
364
            }
365
        }
366
367
        return response;
368 1780 jones
    }
369
370
    /**
371
     * Update an XML document in the repository.
372
     *
373
     * @param docid the docid to update
374
     * @param xmlDocument a Reader for accessing the XML text to be updated
375 2240 sgarg
     * @param schema a Reader for accessing the DTD or XML Schema for
376 1780 jones
     *               the document
377 1795 jones
     * @return the metacat response message
378 2240 sgarg
     * @throws InsufficientKarmaException when the user has insufficent rights
379 1780 jones
     *                                    for the operation
380 1795 jones
     * @throws MetacatInaccessibleException when the metacat server can not be
381
     *                                    reached or does not respond
382
     * @throws MetacatException when the metacat server generates another error
383
     * @throws IOException when there is an error reading the xml document
384 1780 jones
     */
385 1795 jones
    public String update(String docid, Reader xmlDocument, Reader schema)
386
        throws InsufficientKarmaException, MetacatException, IOException,
387
        MetacatInaccessibleException
388 1780 jones
    {
389 1795 jones
        Reader reader = null;
390
        String doctext = null;
391
        String schematext = null;
392
        try {
393
          doctext = IOUtil.getAsString(xmlDocument, true);
394
          if (schema != null) {
395
              schematext = IOUtil.getAsString(schema, true);
396
          }
397
        } catch (IOException ioE) {
398
          throw ioE;
399
        }
400
401
        //set up properties
402
        Properties prop = new Properties();
403
        prop.put("action", "update");
404
        prop.put("docid", docid);
405
        prop.put("doctext", doctext);
406
        if (schematext != null) {
407
            prop.put("dtdtext", schematext);
408
        }
409 2240 sgarg
410 1795 jones
        String response = null;
411
        try {
412 2264 sgarg
            response = sendDataForString(prop, null, null, 0);
413 1795 jones
        } catch (Exception e) {
414
            throw new MetacatInaccessibleException(e.getMessage());
415
        }
416
417
        // Check for an error condition
418
        if (response.indexOf("<error>") != -1) {
419
            if (response.indexOf("does not have permission") != -1) {
420
                throw new InsufficientKarmaException(response);
421
            } else {
422
                throw new MetacatException(response);
423
            }
424
        }
425
426
        return response;
427 1780 jones
    }
428
429
    /**
430 2240 sgarg
       * Upload a data document into the repository.
431
       *
432
       * @param docid the docid to insert the document
433
       * @param document a Reader for accessing the document to be uploaded
434
       * @return the metacat response message
435
       * @throws InsufficientKarmaException when the user has insufficent rights
436
       *                                    for the operation
437
       * @throws MetacatInaccessibleException when the metacat server can not be
438
       *                                    reached or does not respond
439
       * @throws MetacatException when the metacat server generates another error
440
       * @throws IOException when there is an error reading the xml document
441
       */
442
      public String upload(String docid, File file)
443
          throws InsufficientKarmaException, MetacatException, IOException,
444
          MetacatInaccessibleException
445
      {
446
447
          URL url = new URL(metacatUrl.trim());
448
          HttpMessage msg = new HttpMessage(url);
449
          //set up properties
450
          Properties arg = new Properties();
451
          arg.put("action", "upload");
452
          arg.put("docid", docid);
453
454
          Properties filenames = new Properties();
455
          String filename = file.getAbsolutePath();
456
          filenames.put("datafile", filename);
457
458
          String response = null;
459
          try {
460 2264 sgarg
            response = sendDataForString(arg, filenames, null, 0);
461 2240 sgarg
          } catch (Exception e) {
462
            throw new MetacatInaccessibleException(e.getMessage());
463
          }
464
465
          // Check for an error condition
466
          if (response.indexOf("<error>") != -1) {
467
            if (response.indexOf("does not have permission") != -1) {
468
              throw new InsufficientKarmaException(response);
469
            } else {
470
              throw new MetacatException(response);
471
            }
472
          }
473
474 2264 sgarg
          return response;
475
      }
476 2240 sgarg
477 2326 harris
        /**
478 2264 sgarg
          * Upload a data document into the repository.
479
          *
480
          * @param docid the docid to insert the document
481
          * @param document a Reader for accessing the document to be uploaded
482
          * @return the metacat response message
483
          * @throws InsufficientKarmaException when the user has insufficent rights
484
          *                                    for the operation
485
          * @throws MetacatInaccessibleException when the metacat server can not be
486
          *                                    reached or does not respond
487
          * @throws MetacatException when the metacat server generates another error
488
          * @throws IOException when there is an error reading the xml document
489
          */
490
491
492
      public String upload(String docid, String filename, InputStream fileData,
493
                           int size)
494
          throws InsufficientKarmaException, MetacatException, IOException,
495
          MetacatInaccessibleException {
496
497
          URL url = new URL(metacatUrl.trim());
498
          HttpMessage msg = new HttpMessage(url);
499
          //set up properties
500
          Properties arg = new Properties();
501
          arg.put("action", "upload");
502
          arg.put("docid", docid);
503
504
          Properties filenames = new Properties();
505
          filenames.put("datafile", filename);
506
507
          String response = null;
508
          try {
509
            response = sendDataForString(arg, filenames, fileData, size);
510
          } catch (Exception e) {
511
            throw new MetacatInaccessibleException(e.getMessage());
512
          }
513
514
          // Check for an error condition
515
          if (response.indexOf("<error>") != -1) {
516
            if (response.indexOf("does not have permission") != -1) {
517
              throw new InsufficientKarmaException(response);
518
            } else {
519
              throw new MetacatException(response);
520
            }
521
          }
522
523
          return response;
524 2240 sgarg
      }
525
526
    /**
527 1780 jones
     * Delete an XML document in the repository.
528
     *
529
     * @param docid the docid to delete
530 1795 jones
     * @return the metacat response message
531 2240 sgarg
     * @throws InsufficientKarmaException when the user has insufficent rights
532 1780 jones
     *                                    for the operation
533 1795 jones
     * @throws MetacatInaccessibleException when the metacat server can not be
534
     *                                    reached or does not respond
535
     * @throws MetacatException when the metacat server generates another error
536 1780 jones
     */
537 1795 jones
    public String delete(String docid)
538
        throws InsufficientKarmaException, MetacatException,
539
        MetacatInaccessibleException
540 1780 jones
    {
541 1795 jones
        //set up properties
542
        Properties prop = new Properties();
543
        prop.put("action", "delete");
544
        prop.put("docid", docid);
545 2240 sgarg
546 1795 jones
        String response = null;
547
        try {
548 2264 sgarg
            response = sendDataForString(prop, null, null, 0);
549 1795 jones
        } catch (Exception e) {
550
            throw new MetacatInaccessibleException(e.getMessage());
551
        }
552
553
        // Check for an error condition
554
        if (response.indexOf("<error>") != -1) {
555
            if (response.indexOf("does not have permission") != -1) {
556
                throw new InsufficientKarmaException(response);
557
            } else {
558
                throw new MetacatException(response);
559
            }
560
        }
561 2326 harris
        return response;
562
    }
563 1795 jones
564 2326 harris
565
    /**
566
     * set the access on an XML document in the repository.
567
     *
568 2327 harris
     * @param _docid the docid of the document for which the access should be applied.
569 2326 harris
     *
570
     * @param _principal the document's principal
571
     *
572
     * @param _permission the access permission to be applied to the docid
573
     *  {e.g. read,write,all}
574
     *
575
     * @param _permType the permission type to be applied to the document
576
     *  {e.g. allow or deny}
577
     *
578
     * @param _permOrder the order that the document's permissions should be
579
     *  processed {e.g. denyFirst or allowFirst}
580
     *
581
     *
582
     * @return the metacat response message
583
     *
584
     * @throws InsufficientKarmaException when the user has insufficent rights
585
     *                                    for the operation
586
     * @throws MetacatInaccessibleException when the metacat server can not be
587
     *                                    reached or does not respond
588
     * @throws MetacatException when the metacat server generates another error
589
     */
590
    public String setAccess(String _docid, String _principal, String
591
                            _permission, String _permType,
592
                            String _permOrder )
593
        throws InsufficientKarmaException, MetacatException,
594
        MetacatInaccessibleException
595
    {
596
        //set up properties
597
        Properties prop = new Properties();
598
        prop.put("action", "setaccess");
599
        prop.put("docid", _docid);
600
        prop.put("principal", _principal);
601
        prop.put("permission", _permission);
602
        prop.put("permType", _permType);
603
        prop.put("permOrder", _permOrder);
604
605
        String response = null;
606
        try {
607
            response = sendDataForString(prop, null, null, 0);
608
        } catch (Exception e) {
609
            throw new MetacatInaccessibleException(e.getMessage());
610
        }
611
612
        // Check for an error condition
613
        if (response.indexOf("<error>") != -1) {
614
            if (response.indexOf("does not have permission") != -1) {
615
                throw new InsufficientKarmaException(response);
616
            } else {
617
                throw new MetacatException(response);
618
            }
619
        }
620 1795 jones
        return response;
621 1780 jones
    }
622
623
    /**
624
     * When the MetacatFactory creates an instance it needs to set the
625
     * MetacatUrl to which connections should be made.
626
     *
627
     * @param metacatUrl the URL for the metacat server
628
     */
629
    public void setMetacatUrl(String metacatUrl)
630
    {
631 1783 jones
        this.metacatUrl = metacatUrl;
632 1780 jones
    }
633
634 1822 jones
    /**
635
     * Get the session identifier for this session.  This is only valid if
636
     * the login methods has been called successfully for this Metacat object
637
     * beforehand.
638
     *
639
     * @returns the sessionId as a String, or null if the session is invalid
640
     */
641
    public String getSessionId()
642
    {
643
        return this.sessionId;
644
    }
645
646 1826 jones
    /**
647 2240 sgarg
     * Set the session identifier for this session.  This identifier was
648
     * previously established with a call to login.  To continue to use the
649 1826 jones
     * same session, set the session id before making a call to one of the
650
     * metacat access methods (e.g., read, query, insert, etc.).
651
     *
652
     * @param String the sessionId from a previously established session
653
     */
654
    public void setSessionId(String sessionId)
655
    {
656
        this.sessionId = sessionId;
657
    }
658 2337 tao
659
    /**
660 2981 jones
     * The method will return the latest revision in metacat server
661
     * for a given document id. If some error happens, this method will throw
662
     * an exception.
663 2337 tao
     * @param docId String  the given docid you want to use. the docid it self
664
     *                      can have or haven't revision number
665
     * @throws MetacatException
666
     */
667
     public int getNewestDocRevision(String docId) throws MetacatException
668
     {
669 2981 jones
         int rev = 0;
670
         //set up properties
671
         Properties prop = new Properties();
672
         prop.put("action", "getrevisionanddoctype");
673
         prop.put("docid", docId);
674
675
         String response = null;
676
         try {
677
             response = sendDataForString(prop, null, null, 0);
678 2992 berkley
             //parseRevisionResponse will return null if there is an
679
             //error that it can't handle
680 2981 jones
             String revStr = parserRevisionResponse(response);
681
             Integer revObj = new Integer(revStr);
682
             rev = revObj.intValue();
683
             // Check for an error condition
684 2992 berkley
             if (response.indexOf("<error>") != -1 && revStr == null) {
685 2981 jones
                 throw new MetacatException(response);
686
             }
687
         } catch (Exception e) {
688
             throw new MetacatException(e.getMessage());
689
         }
690
         return rev;
691
     }
692
693
    /**
694
     * Return the highest document id for a given scope.  This is used by
695
     * clients to make it easier to determine the next free identifier in a
696
     * sequence for a given scope.
697
     * @param scope String  the scope to use for looking up the latest id
698
     * @throws MetacatException when an error occurs
699
     */
700
    public String getLastDocid(String scope) throws MetacatException {
701
        String lastIdentifier = "";
702
        //set up properties
703
        Properties prop = new Properties();
704
        prop.put("action", "getlastdocid");
705
        prop.put("scope", scope);
706
707
        String response = null;
708
        try {
709 2337 tao
            response = sendDataForString(prop, null, null, 0);
710
            // Check for an error condition
711 2981 jones
            if (response.indexOf("<error>") != -1) {
712
               throw new MetacatException(response);
713
            } else {
714
                Reader responseReader = new StringReader(response);
715
                Node root =
716
                    XMLUtilities.getXMLReaderAsDOMTreeRootNode(responseReader);
717
                Node docidNode =
718
                    XMLUtilities.getNodeWithXPath(root, "/lastDocid/docid");
719 2986 jones
                lastIdentifier = docidNode.getFirstChild().getNodeValue();
720 2981 jones
            }
721
        } catch (Exception e) {
722 2337 tao
            throw new MetacatException(e.getMessage());
723
        }
724 2981 jones
        return lastIdentifier;
725
    }
726 3141 berkley
727
    /**
728
     * return a list of all docids that match a given scope.  if scope is null
729
     * return all docids registered in the system
730
     * @param scope String  the scope to use to limit the docid query
731
     * @throws MetacatException when an error occurs
732
     */
733
    public Vector getAllDocids(String scope) throws MetacatException {
734
        Vector resultVec = new Vector();
735
        //set up properties
736
        Properties prop = new Properties();
737
        prop.put("action", "getalldocids");
738
        if(scope != null)
739
        {
740
          prop.put("scope", scope);
741
        }
742
743
        String response = null;
744
        try {
745
            response = sendDataForString(prop, null, null, 0);
746
            // Check for an error condition
747
            if (response.indexOf("<error>") != -1) {
748
               throw new MetacatException(response);
749
            } else {
750
                Reader responseReader = new StringReader(response);
751
                Node root =
752
                    XMLUtilities.getXMLReaderAsDOMTreeRootNode(responseReader);
753
                NodeList nlist = root.getChildNodes();
754
                for(int i=0; i<nlist.getLength(); i++)
755
                {
756
                  Node n = nlist.item(i);
757
                  if(n.getNodeName().equals("docid"))
758
                  {
759
                    //add the content to the return vector
760 3142 berkley
                    String nodeVal = n.getFirstChild().getNodeValue();
761 3141 berkley
                    resultVec.addElement(nodeVal);
762
                  }
763
                }
764
765
            }
766
        } catch (Exception e) {
767
            throw new MetacatException(e.getMessage());
768
        }
769
        return resultVec;
770
    }
771 2337 tao
772 1780 jones
    /************************************************************************
773
     * PRIVATE METHODS
774
     ************************************************************************/
775
776 1783 jones
    /**
777
     * Send a request to metacat.
778
     *
779
     * @param prop the properties to be URL encoded and sent
780 2264 sgarg
     * @param filename  the properties to be sent to Metacat
781
     *                  in case of upload, otherwise null
782
     * @param fileData  the inputStream for the file data to be sent to Metacat
783
     *                  in case of upload, otherwise null
784
     * @param size      the size of the data being sent to Metacat
785
     *                  in case of upload, otherwise 0
786 1783 jones
     */
787 2240 sgarg
    synchronized private InputStream sendDataOnce(Properties args,
788 2264 sgarg
                                                  Properties filename,
789
                                                  InputStream fileData,
790
                                                  int size)
791 1780 jones
        throws Exception
792
    {
793
        InputStream returnStream = null;
794
        URL url = new URL(metacatUrl);
795
        HttpMessage msg = new HttpMessage(url);
796 1828 jones
        msg.setCookie("JSESSIONID="+this.sessionId);
797 2264 sgarg
        if (filename == null){
798
            returnStream = msg.sendPostData(args);
799
        } else if (fileData == null){
800
            returnStream = msg.sendPostData(args, filename);
801
        } else if (size > 0) {
802
            returnStream = msg.sendPostData(args, filename, fileData, size);
803 2240 sgarg
        } else {
804 2264 sgarg
            throw new MetacatException("Invalid size specified for " +
805
                                       "the input stream being passed");
806 2240 sgarg
        }
807 1780 jones
        return returnStream;
808
    }
809
810
    /**
811
     * Send a request to Metacat
812
     *
813 2264 sgarg
     * @param args  the properties to be sent to Metacat
814
     * @param filename  the properties to be sent to Metacat
815
     *                  in case of upload, otherwise null
816
     * @param fileData  the inputStream for the file data to be sent to Metacat
817
     *                  in case of upload, otherwise null
818
     * @param size      the size of the data being sent to Metacat
819
     *                  in case of upload, otherwise 0
820 1780 jones
     * @return      InputStream as returned by Metacat
821
     */
822 2240 sgarg
    synchronized private InputStream sendData(Properties args,
823 2264 sgarg
                                              Properties filename,
824
                                              InputStream fileData,
825
                                              int size)
826 2240 sgarg
        throws Exception
827
    {
828 1780 jones
        InputStream returnStream = null;
829
        /*
830
            Note:  The reason that there are three try statements all executing
831
            the same code is that there is a problem with the initial connection
832 2240 sgarg
            using the HTTPClient protocol handler.  These try statements make
833
            sure that a connection is made because it gives each connection a
834 1780 jones
            2nd and 3rd chance to work before throwing an error.
835
            THIS IS A TOTAL HACK.  THIS NEEDS TO BE LOOKED INTO AFTER THE BETA1
836
            RELEASE OF MORPHO!!!  cwb (7/24/01)
837
          */
838
        try {
839 2264 sgarg
           return sendDataOnce(args, filename, fileData, size);
840 1780 jones
        } catch (Exception e) {
841
            try {
842 2264 sgarg
                return sendDataOnce(args, filename, fileData, size);
843 1780 jones
            } catch (Exception e2) {
844
                try {
845 2264 sgarg
                    return sendDataOnce(args, filename, fileData, size);
846 1780 jones
                } catch (Exception e3) {
847
                    System.err.println(
848
                            "Failed to send data to metacat 3 times.");
849
                    throw e3;
850
                }
851
            }
852
        }
853
    }
854 1783 jones
855
    /**
856
     * Send a request to Metacat
857
     *
858 2264 sgarg
     * @param args      the properties to be sent to Metacat
859
     * @param filename  the properties to be sent to Metacat
860
     *                  in case of upload, otherwise null
861
     * @param fileData  the inputStream for the file data to be sent to Metacat
862
     *                  in case of upload, otherwise null
863
     * @param size      the size of the data being sent to Metacat
864
     *                  in case of upload, otherwise 0
865
     * @return          a string as returned by Metacat
866 1783 jones
     */
867 2240 sgarg
    synchronized private String sendDataForString(Properties args,
868 2264 sgarg
                                                  Properties filename,
869
                                                  InputStream fileData,
870
                                                  int size)
871 1783 jones
        throws Exception
872
    {
873
        String response = null;
874
875
        try {
876
            InputStreamReader returnStream =
877 2264 sgarg
                    new InputStreamReader(sendData(args, filename,
878
                                                   fileData, size));
879 1783 jones
            StringWriter sw = new StringWriter();
880
            int len;
881
            char[] characters = new char[512];
882
            while ((len = returnStream.read(characters, 0, 512)) != -1) {
883
                sw.write(characters, 0, len);
884
            }
885
            returnStream.close();
886
            response = sw.toString();
887
            sw.close();
888
        } catch (Exception e) {
889
            throw e;
890
        }
891
        return response;
892
    }
893 2337 tao
894
    /*
895
     * "getversionanddoctype" action will return a string from metacat server.
896
     * The string format is "revision;doctype"(This is bad idea, we should use xml)
897
     * This method will get revision string from the response string
898
     */
899
    private String parserRevisionResponse(String response) throws Exception
900
    {
901
      String revision = null;
902
      if (response != null)
903
      {
904 2992 berkley
        if(response.indexOf("<error>") != -1)
905
        {
906
          if(response.indexOf("There is not record") != -1)
907
          {
908
            return "0";
909
          }
910
          else
911
          {
912
            return null;
913
          }
914
        }
915
        else
916
        {
917
          int firstSemiCol = response.indexOf(";");
918
          revision = response.substring(0, firstSemiCol);
919
        }
920
      }
921 2337 tao
      return revision;
922
    }
923 1780 jones
}