Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *  Copyright: 2000 Regents of the University of California and the
4
 *              National Center for Ecological Analysis and Synthesis
5
 *
6
 *   '$Author: sgarg $'
7
 *     '$Date: 2005-10-20 11:39:24 -0700 (Thu, 20 Oct 2005) $'
8
 * '$Revision: 2683 $'
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
import java.io.BufferedReader;
28
import java.io.InputStream;
29
import java.io.InputStreamReader;
30
import java.io.PushbackReader;
31
import java.io.IOException;
32
import java.io.StringWriter;
33
import java.io.Reader;
34
import java.net.URL;
35
import java.util.Properties;
36

    
37
import edu.ucsb.nceas.utilities.HttpMessage;
38
import edu.ucsb.nceas.utilities.IOUtil;
39
import java.io.File;
40

    
41

    
42
/**
43
 *  This interface provides methods for initializing and logging in to a
44
 *  Metacat server, and then querying, reading, transforming, inserting,
45
 *  updating and deleting documents from that server.
46
 */
47
public class MetacatClient implements Metacat
48
{
49
    /** The URL string for the metacat server */
50
    private String metacatUrl;
51

    
52
    /** The session identifier for the session */
53
    private String sessionId;
54

    
55
    /**
56
     * Constructor to create a new instance. Protected because instances
57
     * should only be created by the factory MetacatFactory.
58
     */
59
    protected MetacatClient()
60
    {
61
        this.metacatUrl = null;
62
        this.sessionId = null;
63
    }
64

    
65
    /**
66
     *  Method used to log in to a metacat server. Implementations will need
67
     *  to cache a cookie value to make the session persistent.  Each time a
68
     *  call is made to one of the other methods (e.g., read), the cookie will
69
     *  need to be passed back to the metacat server along with the request.
70
     *
71
     *  @param username   the username of the user, like an LDAP DN
72
     *  @param password   the password for that user for authentication
73
     *  @return the response string from metacat in XML format
74
     *  @throws MetacatAuthException when the username/password could
75
     *                    not be authenticated
76
     */
77
    public String login(String username, String password)
78
           throws MetacatAuthException, MetacatInaccessibleException
79
    {
80
        Properties prop = new Properties();
81
        prop.put("action", "login");
82
        prop.put("qformat", "xml");
83
        prop.put("username", username);
84
        prop.put("password", password);
85

    
86
        String response = null;
87
        try {
88
            response = sendDataForString(prop, null, null, 0);
89
        } catch (Exception e) {
90
            throw new MetacatInaccessibleException(e.getMessage());
91
        }
92

    
93
        if (response.indexOf("<login>") == -1) {
94
            setSessionId("");
95
            throw new MetacatAuthException(response);
96
        } else {
97
            int start = response.indexOf("<sessionId>") + 11;
98
            int end = response.indexOf("</sessionId>");
99
            if ((start != -1) && (end != -1)) {
100
                setSessionId(response.substring(start,end));
101
            }
102
        }
103
        return response;
104
    }
105
    
106
    /**
107
     *  Method used to log in to a metacat server. Implementations will need
108
     *  to cache a cookie value to make the session persistent.  Each time a
109
     *  call is made to one of the other methods (e.g., read), the cookie will
110
     *  need to be passed back to the metacat server along with the request.
111
     *
112
     *  @param username   the username of the user, like an LDAP DN
113
     *  @param password   the password for that user for authentication
114
     *  @return the response string from metacat in XML format
115
     *  @throws MetacatAuthException when the username/password could
116
     *                    not be authenticated
117
     */
118
    public String getloggedinuserinfo() throws MetacatInaccessibleException
119
    {
120
        Properties prop = new Properties();
121
        prop.put("action", "getloggedinuserinfo");
122
        prop.put("qformat", "xml");
123

    
124
        String response = null;
125
        try {
126
            response = sendDataForString(prop, null, null, 0);
127
        } catch (Exception e) {
128
            throw new MetacatInaccessibleException(e.getMessage());
129
        }
130

    
131
        return response;
132
    }
133

    
134
    /**
135
     *  Method used to log out a metacat server. The Metacat server will end
136
     *  the session when this call is invoked.
137
     *
138
     *  @return the response string from metacat in XML format
139
     *  @throws MetacatInaccessibleException when the metacat server can not be
140
     *                                    reached or does not respond
141
     */
142
    public String logout() throws MetacatInaccessibleException, MetacatException
143
    {
144
        Properties prop = new Properties();
145
        prop.put("action", "logout");
146
        prop.put("qformat", "xml");
147

    
148
        String response = null;
149
        try {
150
            response = sendDataForString(prop, null, null, 0);
151
        } catch (Exception e) {
152
            throw new MetacatInaccessibleException(e.getMessage());
153
        }
154

    
155
        if (response.indexOf("<logout>") == -1) {
156
            throw new MetacatException(response);
157
        }
158
        setSessionId("");
159
        return response;
160
    }
161

    
162
    /**
163
     * Read an XML document from the metacat server session, accessed by docid,
164
     * and returned as a Reader.
165
     *
166
     * @param docid the identifier of the document to be read
167
     * @return a Reader for accessing the document
168
     * @throws InsufficientKarmaException when the user has insufficent rights
169
     *                                    for the operation
170
     * @throws MetacatInaccessibleException when the metacat server can not be
171
     *                                    reached or does not respond
172
     * @throws MetacatException when the metacat server generates another error
173
     */
174
    public Reader read(String docid) throws InsufficientKarmaException,
175
        MetacatInaccessibleException, MetacatException
176
    {
177
        PushbackReader pbr = null;
178

    
179
        Properties prop = new Properties();
180
        prop.put("action", "read");
181
        prop.put("qformat", "xml");
182
        prop.put("docid", docid);
183

    
184
        InputStream response = null;
185
        try {
186
            response = sendData(prop, null, null, 0);
187
        } catch (Exception e) {
188
            throw new MetacatInaccessibleException(e.getMessage());
189
        }
190

    
191
        pbr = new PushbackReader(new InputStreamReader(response), 512);
192
        try {
193
            char[] characters = new char[512];
194
            int len = pbr.read(characters, 0, 512);
195
            StringWriter sw = new StringWriter();
196
            sw.write(characters, 0, len);
197
            String message = sw.toString();
198
            sw.close();
199
            pbr.unread(characters, 0, len);
200

    
201
            if (message.indexOf("<error>") != -1) {
202
                if (message.indexOf("does not have permission") != -1) {
203
                    throw new InsufficientKarmaException(message);
204
                } else {
205
                    throw new MetacatException(message);
206
                }
207
            }
208
        } catch (IOException ioe) {
209
            throw new MetacatException(
210
                    "MetacatClient: Error converting Reader to String."
211
                    + ioe.getMessage());
212
        }
213

    
214
        return pbr;
215
    }
216

    
217

    
218
    /**
219
        * Read inline data from the metacat server session, accessed by
220
        * inlinedataid and returned as a Reader.
221
        *
222
        * @param inlinedataid the identifier of the data to be read
223
        * @return a Reader for accessing the document
224
        * @throws InsufficientKarmaException when the user has insufficent rights
225
        *                                    for the operation
226
        * @throws MetacatInaccessibleException when the metacat server can not be
227
        *                                    reached or does not respond
228
        * @throws MetacatException when the metacat server generates another error
229
        */
230
       public Reader readInlineData(String inlinedataid)
231
           throws InsufficientKarmaException,
232
           MetacatInaccessibleException, MetacatException
233
       {
234
           PushbackReader pbr = null;
235

    
236
           Properties prop = new Properties();
237
           prop.put("action", "readinlinedata");
238
           prop.put("inlinedataid", inlinedataid);
239

    
240
           InputStream response = null;
241
           try {
242
               response = sendData(prop, null, null, 0);
243
           } catch (Exception e) {
244
               throw new MetacatInaccessibleException(e.getMessage());
245
           }
246

    
247
           pbr = new PushbackReader(new InputStreamReader(response), 512);
248
           try {
249
               char[] characters = new char[512];
250
               int len = pbr.read(characters, 0, 512);
251
               StringWriter sw = new StringWriter();
252
               sw.write(characters, 0, len);
253
               String message = sw.toString();
254
               sw.close();
255
               pbr.unread(characters, 0, len);
256

    
257
               if (message.indexOf("<error>") != -1) {
258
                   if (message.indexOf("does not have permission") != -1) {
259
                       throw new InsufficientKarmaException(message);
260
                   } else {
261
                       throw new MetacatException(message);
262
                   }
263
               }
264
           } catch (IOException ioe) {
265
               throw new MetacatException(
266
                       "MetacatClient: Error converting Reader to String."
267
                       + ioe.getMessage());
268
           }
269

    
270
           return pbr;
271
       }
272

    
273
    /**
274
     * Query the metacat document store with the given metacat-compatible
275
     * query document, and return the result set as a Reader.
276
     *
277
     * @param xmlQuery a Reader for accessing the XML version of the query
278
     * @return a Reader for accessing the result set
279
     */
280
    public Reader query(Reader xmlQuery) throws MetacatInaccessibleException,
281
                                                IOException
282
    {
283
        Reader reader = null;
284
        String query = null;
285
        try {
286
          query = IOUtil.getAsString(xmlQuery, true);
287
        } catch (IOException ioE) {
288
          throw ioE;
289
        }
290

    
291
        //set up properties
292
        Properties prop = new Properties();
293
        prop.put("action", "squery");
294
        prop.put("qformat", "xml");
295
        prop.put("query", query);
296

    
297
        InputStream response = null;
298
        try {
299
            response = sendData(prop, null, null, 0);
300
        } catch (Exception e) {
301
            throw new MetacatInaccessibleException(e.getMessage());
302
        }
303
        reader = new InputStreamReader(response);
304
        return reader;
305
    }
306

    
307
    /**
308
     * Insert an XML document into the repository.
309
     *
310
     * @param docid the docid to insert the document
311
     * @param xmlDocument a Reader for accessing the XML document to be inserted
312
     * @param schema a Reader for accessing the DTD or XML Schema for
313
     *               the document
314
     * @return the metacat response message
315
     * @throws InsufficientKarmaException when the user has insufficent rights
316
     *                                    for the operation
317
     * @throws MetacatInaccessibleException when the metacat server can not be
318
     *                                    reached or does not respond
319
     * @throws MetacatException when the metacat server generates another error
320
     * @throws IOException when there is an error reading the xml document
321
     */
322
    public String insert(String docid, Reader xmlDocument, Reader schema)
323
        throws InsufficientKarmaException, MetacatException, IOException,
324
        MetacatInaccessibleException
325
    {
326
        Reader reader = null;
327
        String doctext = null;
328
        String schematext = null;
329
        try {
330
          doctext = IOUtil.getAsString(xmlDocument, true);
331
          if (schema != null) {
332
              schematext = IOUtil.getAsString(schema, true);
333
          }
334
        } catch (IOException ioE) {
335
          throw ioE;
336
        }
337

    
338
        //set up properties
339
        Properties prop = new Properties();
340
        prop.put("action", "insert");
341
        prop.put("docid", docid);
342
        prop.put("doctext", doctext);
343
        if (schematext != null) {
344
            prop.put("dtdtext", schematext);
345
        }
346

    
347
        String response = null;
348
        try {
349
            response = sendDataForString(prop, null, null, 0);
350
        } catch (Exception e) {
351
            throw new MetacatInaccessibleException(e.getMessage());
352
        }
353

    
354
        // Check for an error condition
355
        if (response.indexOf("<error>") != -1) {
356
            if (response.indexOf("does not have permission") != -1) {
357
                throw new InsufficientKarmaException(response);
358
            } else {
359
                throw new MetacatException(response);
360
            }
361
        }
362

    
363
        return response;
364
    }
365

    
366
    /**
367
     * Update an XML document in the repository.
368
     *
369
     * @param docid the docid to update
370
     * @param xmlDocument a Reader for accessing the XML text to be updated
371
     * @param schema a Reader for accessing the DTD or XML Schema for
372
     *               the document
373
     * @return the metacat response message
374
     * @throws InsufficientKarmaException when the user has insufficent rights
375
     *                                    for the operation
376
     * @throws MetacatInaccessibleException when the metacat server can not be
377
     *                                    reached or does not respond
378
     * @throws MetacatException when the metacat server generates another error
379
     * @throws IOException when there is an error reading the xml document
380
     */
381
    public String update(String docid, Reader xmlDocument, Reader schema)
382
        throws InsufficientKarmaException, MetacatException, IOException,
383
        MetacatInaccessibleException
384
    {
385
        Reader reader = null;
386
        String doctext = null;
387
        String schematext = null;
388
        try {
389
          doctext = IOUtil.getAsString(xmlDocument, true);
390
          if (schema != null) {
391
              schematext = IOUtil.getAsString(schema, true);
392
          }
393
        } catch (IOException ioE) {
394
          throw ioE;
395
        }
396

    
397
        //set up properties
398
        Properties prop = new Properties();
399
        prop.put("action", "update");
400
        prop.put("docid", docid);
401
        prop.put("doctext", doctext);
402
        if (schematext != null) {
403
            prop.put("dtdtext", schematext);
404
        }
405

    
406
        String response = null;
407
        try {
408
            response = sendDataForString(prop, null, null, 0);
409
        } catch (Exception e) {
410
            throw new MetacatInaccessibleException(e.getMessage());
411
        }
412

    
413
        // Check for an error condition
414
        if (response.indexOf("<error>") != -1) {
415
            if (response.indexOf("does not have permission") != -1) {
416
                throw new InsufficientKarmaException(response);
417
            } else {
418
                throw new MetacatException(response);
419
            }
420
        }
421

    
422
        return response;
423
    }
424

    
425
    /**
426
       * Upload a data document into the repository.
427
       *
428
       * @param docid the docid to insert the document
429
       * @param document a Reader for accessing the document to be uploaded
430
       * @return the metacat response message
431
       * @throws InsufficientKarmaException when the user has insufficent rights
432
       *                                    for the operation
433
       * @throws MetacatInaccessibleException when the metacat server can not be
434
       *                                    reached or does not respond
435
       * @throws MetacatException when the metacat server generates another error
436
       * @throws IOException when there is an error reading the xml document
437
       */
438
      public String upload(String docid, File file)
439
          throws InsufficientKarmaException, MetacatException, IOException,
440
          MetacatInaccessibleException
441
      {
442

    
443
          URL url = new URL(metacatUrl.trim());
444
          HttpMessage msg = new HttpMessage(url);
445
          //set up properties
446
          Properties arg = new Properties();
447
          arg.put("action", "upload");
448
          arg.put("docid", docid);
449

    
450
          Properties filenames = new Properties();
451
          String filename = file.getAbsolutePath();
452
          filenames.put("datafile", filename);
453

    
454
          String response = null;
455
          try {
456
            response = sendDataForString(arg, filenames, null, 0);
457
          } catch (Exception e) {
458
            throw new MetacatInaccessibleException(e.getMessage());
459
          }
460

    
461
          // Check for an error condition
462
          if (response.indexOf("<error>") != -1) {
463
            if (response.indexOf("does not have permission") != -1) {
464
              throw new InsufficientKarmaException(response);
465
            } else {
466
              throw new MetacatException(response);
467
            }
468
          }
469

    
470
          return response;
471
      }
472

    
473
        /**
474
          * Upload a data document into the repository.
475
          *
476
          * @param docid the docid to insert the document
477
          * @param document a Reader for accessing the document to be uploaded
478
          * @return the metacat response message
479
          * @throws InsufficientKarmaException when the user has insufficent rights
480
          *                                    for the operation
481
          * @throws MetacatInaccessibleException when the metacat server can not be
482
          *                                    reached or does not respond
483
          * @throws MetacatException when the metacat server generates another error
484
          * @throws IOException when there is an error reading the xml document
485
          */
486

    
487

    
488
      public String upload(String docid, String filename, InputStream fileData,
489
                           int size)
490
          throws InsufficientKarmaException, MetacatException, IOException,
491
          MetacatInaccessibleException {
492

    
493
          URL url = new URL(metacatUrl.trim());
494
          HttpMessage msg = new HttpMessage(url);
495
          //set up properties
496
          Properties arg = new Properties();
497
          arg.put("action", "upload");
498
          arg.put("docid", docid);
499

    
500
          Properties filenames = new Properties();
501
          filenames.put("datafile", filename);
502

    
503
          String response = null;
504
          try {
505
            response = sendDataForString(arg, filenames, fileData, size);
506
          } catch (Exception e) {
507
            throw new MetacatInaccessibleException(e.getMessage());
508
          }
509

    
510
          // Check for an error condition
511
          if (response.indexOf("<error>") != -1) {
512
            if (response.indexOf("does not have permission") != -1) {
513
              throw new InsufficientKarmaException(response);
514
            } else {
515
              throw new MetacatException(response);
516
            }
517
          }
518

    
519
          return response;
520
      }
521

    
522
    /**
523
     * Delete an XML document in the repository.
524
     *
525
     * @param docid the docid to delete
526
     * @return the metacat response message
527
     * @throws InsufficientKarmaException when the user has insufficent rights
528
     *                                    for the operation
529
     * @throws MetacatInaccessibleException when the metacat server can not be
530
     *                                    reached or does not respond
531
     * @throws MetacatException when the metacat server generates another error
532
     */
533
    public String delete(String docid)
534
        throws InsufficientKarmaException, MetacatException,
535
        MetacatInaccessibleException
536
    {
537
        //set up properties
538
        Properties prop = new Properties();
539
        prop.put("action", "delete");
540
        prop.put("docid", docid);
541

    
542
        String response = null;
543
        try {
544
            response = sendDataForString(prop, null, null, 0);
545
        } catch (Exception e) {
546
            throw new MetacatInaccessibleException(e.getMessage());
547
        }
548

    
549
        // Check for an error condition
550
        if (response.indexOf("<error>") != -1) {
551
            if (response.indexOf("does not have permission") != -1) {
552
                throw new InsufficientKarmaException(response);
553
            } else {
554
                throw new MetacatException(response);
555
            }
556
        }
557
        return response;
558
    }
559

    
560

    
561
    /**
562
     * set the access on an XML document in the repository.
563
     *
564
     * @param _docid the docid of the document for which the access should be applied.
565
     *
566
     * @param _principal the document's principal
567
     *
568
     * @param _permission the access permission to be applied to the docid
569
     *  {e.g. read,write,all}
570
     *
571
     * @param _permType the permission type to be applied to the document
572
     *  {e.g. allow or deny}
573
     *
574
     * @param _permOrder the order that the document's permissions should be
575
     *  processed {e.g. denyFirst or allowFirst}
576
     *
577
     *
578
     * @return the metacat response message
579
     *
580
     * @throws InsufficientKarmaException when the user has insufficent rights
581
     *                                    for the operation
582
     * @throws MetacatInaccessibleException when the metacat server can not be
583
     *                                    reached or does not respond
584
     * @throws MetacatException when the metacat server generates another error
585
     */
586
    public String setAccess(String _docid, String _principal, String
587
                            _permission, String _permType, 
588
                            String _permOrder )
589
        throws InsufficientKarmaException, MetacatException,
590
        MetacatInaccessibleException
591
    {  
592
        //set up properties
593
        Properties prop = new Properties();
594
        prop.put("action", "setaccess");
595
        prop.put("docid", _docid);
596
        prop.put("principal", _principal);
597
        prop.put("permission", _permission);
598
        prop.put("permType", _permType);
599
        prop.put("permOrder", _permOrder);
600

    
601
        String response = null;
602
        try {
603
            response = sendDataForString(prop, null, null, 0);
604
        } catch (Exception e) {
605
            throw new MetacatInaccessibleException(e.getMessage());
606
        }
607

    
608
        // Check for an error condition
609
        if (response.indexOf("<error>") != -1) {
610
            if (response.indexOf("does not have permission") != -1) {
611
                throw new InsufficientKarmaException(response);
612
            } else {
613
                throw new MetacatException(response);
614
            }
615
        }
616
        return response;
617
    }
618

    
619
    /**
620
     * When the MetacatFactory creates an instance it needs to set the
621
     * MetacatUrl to which connections should be made.
622
     *
623
     * @param metacatUrl the URL for the metacat server
624
     */
625
    public void setMetacatUrl(String metacatUrl)
626
    {
627
        this.metacatUrl = metacatUrl;
628
    }
629

    
630
    /**
631
     * Get the session identifier for this session.  This is only valid if
632
     * the login methods has been called successfully for this Metacat object
633
     * beforehand.
634
     *
635
     * @returns the sessionId as a String, or null if the session is invalid
636
     */
637
    public String getSessionId()
638
    {
639
        return this.sessionId;
640
    }
641

    
642
    /**
643
     * Set the session identifier for this session.  This identifier was
644
     * previously established with a call to login.  To continue to use the
645
     * same session, set the session id before making a call to one of the
646
     * metacat access methods (e.g., read, query, insert, etc.).
647
     *
648
     * @param String the sessionId from a previously established session
649
     */
650
    public void setSessionId(String sessionId)
651
    {
652
        this.sessionId = sessionId;
653
    }
654
    
655
    /**
656
     * The method will return the lasted revision in metacat server 
657
     * for a given document id. If some error happent, this method will throw
658
     * a exception.   
659
     * @param docId String  the given docid you want to use. the docid it self
660
     *                      can have or haven't revision number
661
     * @throws MetacatException
662
     */
663
     public int getNewestDocRevision(String docId) throws MetacatException
664
     {
665
       int rev = 0;
666
       //set up properties
667
       Properties prop = new Properties();
668
       prop.put("action", "getrevisionanddoctype");
669
       prop.put("docid", docId);
670
       
671
       String response = null;
672
        try 
673
        {
674
            response = sendDataForString(prop, null, null, 0);
675
            String revStr = parserRevisionResponse(response);
676
            Integer revObj = new Integer(revStr);
677
            rev = revObj.intValue();
678
            // Check for an error condition
679
           if (response.indexOf("<error>") != -1) 
680
           {
681
              throw new MetacatException(response);
682
           }
683

    
684
        } 
685
        catch (Exception e) 
686
        {
687
            throw new MetacatException(e.getMessage());
688
        }
689
        return rev;
690
     }
691

    
692

    
693
    /************************************************************************
694
     * PRIVATE METHODS
695
     ************************************************************************/
696

    
697
    /**
698
     * Send a request to metacat.
699
     *
700
     * @param prop the properties to be URL encoded and sent
701
     * @param filename  the properties to be sent to Metacat
702
     *                  in case of upload, otherwise null
703
     * @param fileData  the inputStream for the file data to be sent to Metacat
704
     *                  in case of upload, otherwise null
705
     * @param size      the size of the data being sent to Metacat
706
     *                  in case of upload, otherwise 0
707
     */
708
    synchronized private InputStream sendDataOnce(Properties args,
709
                                                  Properties filename,
710
                                                  InputStream fileData,
711
                                                  int size)
712
        throws Exception
713
    {
714
        InputStream returnStream = null;
715
        URL url = new URL(metacatUrl);
716
        HttpMessage msg = new HttpMessage(url);
717
        msg.setCookie("JSESSIONID="+this.sessionId);
718
        if (filename == null){
719
            returnStream = msg.sendPostData(args);
720
        } else if (fileData == null){
721
            returnStream = msg.sendPostData(args, filename);
722
        } else if (size > 0) {
723
            returnStream = msg.sendPostData(args, filename, fileData, size);
724
        } else {
725
            throw new MetacatException("Invalid size specified for " +
726
                                       "the input stream being passed");
727
        }
728
        return returnStream;
729
    }
730

    
731
    /**
732
     * Send a request to Metacat
733
     *
734
     * @param args  the properties to be sent to Metacat
735
     * @param filename  the properties to be sent to Metacat
736
     *                  in case of upload, otherwise null
737
     * @param fileData  the inputStream for the file data to be sent to Metacat
738
     *                  in case of upload, otherwise null
739
     * @param size      the size of the data being sent to Metacat
740
     *                  in case of upload, otherwise 0
741
     * @return      InputStream as returned by Metacat
742
     */
743
    synchronized private InputStream sendData(Properties args,
744
                                              Properties filename,
745
                                              InputStream fileData,
746
                                              int size)
747
        throws Exception
748
    {
749
        InputStream returnStream = null;
750

    
751
        /*
752
            Note:  The reason that there are three try statements all executing
753
            the same code is that there is a problem with the initial connection
754
            using the HTTPClient protocol handler.  These try statements make
755
            sure that a connection is made because it gives each connection a
756
            2nd and 3rd chance to work before throwing an error.
757
            THIS IS A TOTAL HACK.  THIS NEEDS TO BE LOOKED INTO AFTER THE BETA1
758
            RELEASE OF MORPHO!!!  cwb (7/24/01)
759
          */
760
        try {
761
           return sendDataOnce(args, filename, fileData, size);
762
        } catch (Exception e) {
763
            try {
764
                return sendDataOnce(args, filename, fileData, size);
765
            } catch (Exception e2) {
766
                try {
767
                    return sendDataOnce(args, filename, fileData, size);
768
                } catch (Exception e3) {
769
                    System.err.println(
770
                            "Failed to send data to metacat 3 times.");
771
                    throw e3;
772
                }
773
            }
774
        }
775
    }
776

    
777
    /**
778
     * Send a request to Metacat
779
     *
780
     * @param args      the properties to be sent to Metacat
781
     * @param filename  the properties to be sent to Metacat
782
     *                  in case of upload, otherwise null
783
     * @param fileData  the inputStream for the file data to be sent to Metacat
784
     *                  in case of upload, otherwise null
785
     * @param size      the size of the data being sent to Metacat
786
     *                  in case of upload, otherwise 0
787
     * @return          a string as returned by Metacat
788
     */
789
    synchronized private String sendDataForString(Properties args,
790
                                                  Properties filename,
791
                                                  InputStream fileData,
792
                                                  int size)
793
        throws Exception
794
    {
795
        String response = null;
796

    
797
        try {
798
            InputStreamReader returnStream =
799
                    new InputStreamReader(sendData(args, filename,
800
                                                   fileData, size));
801
            StringWriter sw = new StringWriter();
802
            int len;
803
            char[] characters = new char[512];
804
            while ((len = returnStream.read(characters, 0, 512)) != -1) {
805
                sw.write(characters, 0, len);
806
            }
807
            returnStream.close();
808
            response = sw.toString();
809
            sw.close();
810
        } catch (Exception e) {
811
            throw e;
812
        }
813
        return response;
814
    }
815
    
816
    /*
817
     * "getversionanddoctype" action will return a string from metacat server.
818
     * The string format is "revision;doctype"(This is bad idea, we should use xml)
819
     * This method will get revision string from the response string
820
     */
821
    private String parserRevisionResponse(String response) throws Exception
822
    {
823
      String revision = null;
824
      if (response != null)
825
      {
826
        int firstSemiCol = response.indexOf(";");
827
        revision = response.substring(0, firstSemiCol);
828
      }
829
      return revision;
830
    }
831
}
(4-4/7)