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