Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A Class that implements utility methods for a metadata catalog
4
 *  Copyright: 2000 Regents of the University of California and the
5
 *             National Center for Ecological Analysis and Synthesis
6
 *    Authors: Matt Jones, Jivka Bojilova
7
 *    Release: @release@
8
 *
9
 *   '$Author: jones $'
10
 *     '$Date: 2003-12-05 13:21:06 -0800 (Fri, 05 Dec 2003) $'
11
 * '$Revision: 1951 $'
12
 *
13
 * This program is free software; you can redistribute it and/or modify
14
 * it under the terms of the GNU General Public License as published by
15
 * the Free Software Foundation; either version 2 of the License, or
16
 * (at your option) any later version.
17
 *
18
 * This program is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 * GNU General Public License for more details.
22
 *
23
 * You should have received a copy of the GNU General Public License
24
 * along with this program; if not, write to the Free Software
25
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
 */
27

    
28
package edu.ucsb.nceas.metacat;
29

    
30
import java.io.File;
31
import java.net.URL;
32
import java.net.MalformedURLException;
33
import java.sql.Connection;
34
import java.sql.DriverManager;
35
import java.sql.SQLException;
36
import java.util.PropertyResourceBundle;
37
import java.util.Hashtable;
38
import java.util.Enumeration;
39
import java.util.Stack;
40
import java.util.Vector;
41

    
42
import edu.ucsb.nceas.dbadapter.AbstractDatabase;
43
import edu.ucsb.nceas.utilities.Options;
44

    
45
/**
46
 * A suite of utility classes for the metadata catalog server
47
 */
48
public class MetaCatUtil {
49

    
50
  public static AbstractDatabase dbAdapter;
51
  private static Options options = null;
52
  private static boolean debug = true;
53

    
54
  //private Hashtable connectionPool = new Hashtable();
55

    
56
  /**
57
   * Determine our db adapter class and create an instance of that class
58
   */
59
  static {
60
    try {
61
      dbAdapter = (AbstractDatabase)createObject(getOption("dbAdapter"));
62
    } catch (Exception e) {
63
      System.err.println("Error in MetaCatUtil static block:" + e.getMessage());
64
    }
65
  }
66

    
67

    
68

    
69
  /**
70
   * Instantiate a class using the name of the class at runtime
71
   *
72
   * @param className the fully qualified name of the class to instantiate
73
   */
74
  public static Object createObject(String className) throws Exception {
75

    
76
    Object object = null;
77
    try {
78
      Class classDefinition = Class.forName(className);
79
      object = classDefinition.newInstance();
80
    } catch (InstantiationException e) {
81
      throw e;
82
    } catch (IllegalAccessException e) {
83
      throw e;
84
    } catch (ClassNotFoundException e) {
85
      throw e;
86
    }
87
    return object;
88
  }
89

    
90
  /**
91
   * Utility method to get an option value from the properties file
92
   *
93
   * @param optionName the name of the option requested
94
   * @return the String value for the option, or null if not set
95
   */
96
  public static String getOption(String optionName) {
97
      if (options == null) {
98
        options = Options.getInstance();
99
      }
100
      String value = options.getOption(optionName);
101
      return value;
102
  }
103

    
104
  /** Utility method to convert a file handle into a URL */
105
  public static URL fileToURL(File file)
106
  {
107
     String path = file.getAbsolutePath();
108
     String fSep = System.getProperty("file.separator");
109
     if (fSep != null && fSep.length() == 1)
110
       path = path.replace(fSep.charAt(0), '/');
111
     if (path.length() > 0 && path.charAt(0) != '/')
112
       path = '/' + path;
113
     try {
114
       return new URL("file", null, path);
115
     }
116
     catch (java.net.MalformedURLException e) {
117
       /* According to the spec this could only happen if the file
118
          protocol were not recognized. */
119
       throw new Error("unexpected MalformedURLException");
120
     }
121
  }
122

    
123
  /**
124
   * Utility method to parse the query part of a URL into parameters. This
125
   * method assumes the format of the query par tof the url is an
126
   * ampersand separated list of name/value pairs, with equal signs separating
127
   * the name from the value (e.g., name=tom&zip=99801 ). Returns a
128
   * has of the name value pairs, hashed on name.
129
   */
130
  public static Hashtable parseQuery(String query) throws MalformedURLException
131
  {
132
    String[][] params = new String[200][2];
133
    Hashtable parameters = new Hashtable();
134

    
135
    String temp = "";
136
    boolean ampflag = true;
137
    boolean poundflag = false;
138
    int arrcount = 0;
139

    
140
    if ( query != null ) {
141
      for (int i=0; i < query.length(); i++) {
142

    
143
        // go throught the remainder of the query one character at a time.
144
        if (query.charAt(i) == '=') {
145
          // if the current char is a # then the preceding should be a name
146
          if (!poundflag && ampflag) {
147
            params[arrcount][0] = temp.trim();
148
            temp = "";
149
          } else {
150
            //if there are two #s or &s in a row throw an exception.
151
            throw new MalformedURLException("metacatURL: Two parameter names "+
152
                                            "not allowed in sequence");
153
          }
154
          poundflag = true;
155
          ampflag = false;
156
        } else if (query.charAt(i) == '&' || i == query.length()-1) {
157
          //the text preceding the & should be the param value.
158
          if (i == query.length() - 1) {
159
            //if at the end of the string grab the last value and append it.
160
            if (query.charAt(i) != '=') {
161
            //ignore an extra & on the end of the string
162
              temp += query.charAt(i);
163
            }
164
          }
165

    
166
          if (!ampflag && poundflag) {
167
            params[arrcount][1] = temp.trim();
168
            parameters.put(params[arrcount][0], params[arrcount][1]);
169
            temp = "";
170
            arrcount++; //increment the array to the next row.
171
          } else {
172
            //if there are two =s or &s in a row through an exception
173
            throw new MalformedURLException("metacatURL: Two parameter values "+
174
                                            "not allowed in sequence");
175
          }
176
          poundflag = false;
177
          ampflag = true;
178
        } else {
179
          //get the next character in the string
180
          temp += query.charAt(i);
181
        }
182
      }
183
    }
184
    return parameters;
185
  }
186

    
187
   /**
188
   * Utility method to print debugging messages. User can set debug level
189
   * for this message. The number is fewer, the message is more important
190
   * @param msg, the content of the message
191
   * @param debugLevel, an integer indicating the message debug leve
192
   */
193
  public static void debugMessage(String msg, int debugLevel)
194
  {
195
    if (debug)
196
    {
197
      int limit = 1;
198
      try
199
      {
200
        limit=Integer.parseInt(getOption("debuglevel"));
201

    
202
      }
203
      catch (Exception e)
204
      {
205
        System.out.println(e.getMessage());
206
      }
207
      //don't allow the user set debugLevel less than or equals 0
208
      if (debugLevel<=0)
209
      {
210
        debugLevel=1;
211
      }
212

    
213
      if (debugLevel < limit)
214
      {
215
        System.err.println("@debugprefix@ " +msg);
216
      }
217
    }
218
  }
219

    
220

    
221
  public static Vector getOptionList(String optiontext)
222
  {
223
    Vector optionsVector = new Vector();
224
    if(optiontext.indexOf(",") == -1)
225
    {
226
      optionsVector.addElement(optiontext);
227
      return optionsVector;
228
    }
229

    
230
    while(optiontext.indexOf(",") != -1)
231
    {
232
      String s = optiontext.substring(0, optiontext.indexOf(","));
233
      optionsVector.addElement(s.trim());
234
      optiontext = optiontext.substring(optiontext.indexOf(",") + 1,
235
                                        optiontext.length());
236
      if(optiontext.indexOf(",") == -1)
237
      { //catch the last list entry
238
        optionsVector.addElement(optiontext.trim());
239
      }
240
    }
241
    return optionsVector;
242
  }
243

    
244
  /** Normalizes the given string. Taken from configXML.java*/
245
  public static String normalize(String s)
246
  {
247
    StringBuffer str = new StringBuffer();
248

    
249
    int len = (s != null) ? s.length() : 0;
250
    for (int i = 0; i < len; i++)
251
    {
252
      char ch = s.charAt(i);
253
      switch (ch)
254
      {
255
      case '<':
256
      {
257
        str.append("&lt;");
258
        break;
259
      }
260
        case '>':
261
      {
262
        str.append("&gt;");
263
        break;
264
      }
265
      case '&':
266
      {
267
        str.append("&amp;");
268
        break;
269
      }
270
      case '"':
271
      {
272
        str.append("&quot;");
273
        break;
274
      }
275
      case '\r':
276
      case '\n':
277
      {
278
        // else, default append char
279
      }
280
      default:
281
      {
282
        str.append(ch);
283
      }
284
      }
285
    }
286
    return (str.toString());
287
  }
288
  
289
  /** 
290
   * Get docid from online/url string
291
   */
292
  public static String getDocIdWithRevFromOnlineURL(String url)
293
  {
294
    String docid = null;
295
    String DOCID = "docid";
296
    boolean find = false;
297
    char limited = '&';
298
    int  count = 0; //keep track how many & was found
299
    Vector list = new Vector();// keep index number for &
300
    if (url == null)
301
    {
302
      MetaCatUtil.debugMessage("url is null and null will be returned", 30);
303
      return docid;
304
    }
305
    // the first element in list is 0
306
    list.add(new Integer(0));
307
    for (int i=0; i< url.length(); i++)
308
    {
309
      if (url.charAt(i) == limited)
310
      {
311
        // count plus 1
312
        count++;
313
        list.add(new Integer(i));
314
        // get substring beween two &
315
        String str = url.substring(((Integer)list.elementAt(count-1)).intValue(), i);
316
        MetaCatUtil.debugMessage("substring between two & is: " + str, 30);
317
        //if the subString contains docid, we got it
318
        if (str.indexOf(DOCID) != -1)
319
        { 
320
          //get index of '="
321
          int start = getIndexForGivenChar(str, '=')+1;
322
          int end   = str.length();
323
          docid = str.substring(start, end);
324
          find = true;
325
        }//if
326
      }//if
327
    }//for
328
    //if not find, we need check the subtring between the index of last & and 
329
    // the end of string
330
    if (!find)
331
    {
332
      MetaCatUtil.debugMessage("Checking the last substring", 35);
333
      String str = url.substring(((Integer)list.elementAt(count)).intValue() +1, 
334
                                 url.length());
335
      MetaCatUtil.debugMessage("Last substring is: " + str, 30);
336
      if (str.indexOf(DOCID) != -1)
337
      { 
338
          //get index of '="
339
          int start = getIndexForGivenChar(str, '=')+1;
340
          int end   = str.length();
341
          docid = str.substring(start, end);
342
          find = true;
343
      }//if
344
    }//if
345
    MetaCatUtil.debugMessage("The docid from online url is:"+ docid, 30);
346
    return docid.trim();
347
  }
348
  
349
  private static int getIndexForGivenChar(String str, char character)
350
  {
351
    int index = -1;
352
    // make sure str is not null
353
    if(str == null)
354
    {
355
      MetaCatUtil.debugMessage("The given str is null and -1 will be returned",
356
                                30);
357
      return index;
358
    }
359
    // got though the string
360
    for (int i=0; i<str.length(); i++)
361
    {
362
      // find the first one then break the loop
363
      if (str.charAt(i) == character)
364
      {
365
        index = i;
366
        break;
367
      }//if
368
    }//for
369
    MetaCatUtil.debugMessage("the index for char "+ character +
370
                             " is: "+index, 30);
371
    return index;
372
  }
373
  
374
  /**
375
   * Utility method to get docid from a given string
376
   * @param string, the given string should be these two format:
377
   *              1) str1.str2  in this case docid= str1.str2
378
   *              2) str1.str2.str3, in this case docid =str1.str2
379
   * @param the sperator char
380
   */
381
  public static String getDocIdFromString(String str)
382
  {
383
    String docId = null;
384
    if (str == null)
385
    {
386
      MetaCatUtil.debugMessage("The given str is null and null will be returned"
387
                                +" in getDocIdfromString", 30);
388
      return docId;
389
    } //make sure docid is not null
390
    int dotNumber = 0;//count how many dots in given string
391
    int indexOfLastDot = 0;
392

    
393
    //assume that seperator is one charactor string
394
    char seperator=getOption("accNumSeparator").charAt(0);
395

    
396
    for (int i=0; i<str.length(); i++)
397
    {
398
      if ( str.charAt(i)==seperator)
399
      {
400
        dotNumber++;//count how many dots
401
        indexOfLastDot=i;//keep the last dot postion
402
      }
403
    }//for
404

    
405
    //The string formatt is wrong, because it has more than two or less than
406
    //one seperator
407
    if ( dotNumber>2 || dotNumber < 1)
408
    {
409
      docId=null;
410
    }
411
    else if (dotNumber == 2) //the case for str1.str2.str3
412
    {
413
       docId=str.substring(0, indexOfLastDot);
414
    }
415
    else if (dotNumber == 1) //the case for str1.str2
416
    {
417
      docId=str;
418
    }
419

    
420
    return docId;
421
  }//getDocIdFromString
422

    
423
  /**
424
   * Utility method to get version number from a given string
425
   * @param string, the given string should be these two format:
426
   *              1) str1.str2(no version)  version =-1;
427
   *              2) str1.str2.str3, in this case version = str3;
428
   *              3) other, vresion =-2
429
   */
430
  public static int getVersionFromString(String str)
431
                                throws NumberFormatException
432
  {
433
    int version=-1;
434
    String versionString=null;
435
    int dotNumber = 0;//count how many dots in given string
436
    int indexOfLastDot = 0;
437

    
438
    //assume that seperator is one charactor string
439
    char seperator=getOption("accNumSeparator").charAt(0);
440

    
441
    for (int i=0; i<str.length(); i++)
442
    {
443
      if ( str.charAt(i)==seperator)
444
      {
445
        dotNumber++;//count how many dots
446
        indexOfLastDot=i;//keep the last dot postion
447
      }
448
    }//for
449

    
450
    //The string formatt is wrong, because it has more than two or less than
451
    //one seperator
452
    if ( dotNumber>2 || dotNumber < 1)
453
    {
454
      version=-2;
455
    }
456
    else if (dotNumber == 2 && (indexOfLastDot != (str.length() -1)))
457
     //the case for str1.str2.str3
458
    {
459
       versionString=str.substring((indexOfLastDot+1), str.length());
460
       version=Integer.parseInt(versionString);
461
    }
462
    else if (dotNumber == 1) //the case for str1.str2
463
    {
464
      version=-1;
465
    }
466

    
467
    return version;
468
  }//getVersionFromString
469

    
470

    
471
  /**
472
   * Utility method to get version string from a given string
473
   * @param string, the given string should be these two format:
474
   *              1) str1.str2(no version)  version=null;
475
   *              2) str1.str2.str3, in this case version = str3;
476
   *              3) other, vresion =null;
477
   */
478
  public static String getRevisionStringFromString(String str)
479
                                throws NumberFormatException
480
  {
481
    // String to store the version
482
    String versionString=null;
483
    int dotNumber = 0;//count how many dots in given string
484
    int indexOfLastDot = 0;
485

    
486
    //assume that seperator is one charactor string
487
    char seperator=getOption("accNumSeparator").charAt(0);
488

    
489
    for (int i=0; i<str.length(); i++)
490
    {
491
      if ( str.charAt(i)==seperator)
492
      {
493
        dotNumber++;//count how many dots
494
        indexOfLastDot=i;//keep the last dot postion
495
      }
496
    }//for
497

    
498
    //The string formatt is wrong, because it has more than two or less than
499
    //one seperator
500
    if ( dotNumber>2 || dotNumber < 1)
501
    {
502
      versionString = null;
503
    }
504
    else if (dotNumber == 2 && (indexOfLastDot != (str.length() -1)))
505
    {
506
      //the case for str1.str2.str3
507
      // indexOfLastDot != (str.length() -1) means get rid of str1.str2.
508
      versionString=str.substring((indexOfLastDot+1), str.length());
509
    }
510
    else if (dotNumber == 1) //the case for str1.str2 or str1.str2.
511
    {
512
      versionString=null;
513
    }
514

    
515
    return versionString;
516
  }//getVersionFromString
517

    
518
  /**
519
   * Method to get the name of local replication server
520
   */
521
   public static String getLocalReplicationServerName()
522
   {
523
     String replicationServerName=null;
524
     String serverHost=null;
525
     serverHost=getOption("server");
526
     // append "context/servelet/replication" to the host name
527
     replicationServerName=serverHost+getOption("replicationpath");
528
     return replicationServerName;
529

    
530
   }
531

    
532
   /**
533
    * Method to get docidwithrev from eml2 inline data id
534
    * The eml inline data id would look like eml.200.2.3
535
    */
536
   public static String getDocIdWithoutRevFromInlineDataID(String inlineDataID)
537
   {
538
     String docidWithoutRev = null;
539
     if ( inlineDataID == null)
540
     {
541
       return docidWithoutRev;
542
     }
543
     String seperator = MetaCatUtil.getOption("accNumSeparator");
544
     char charSeperator = seperator.charAt(0);
545
     int targetNumberOfSeperator = 2;// we  want to know his index
546
     int numberOfSeperator = 0;
547
     for (int i = 0; i< inlineDataID.length(); i++)
548
     {
549
       // meet seperator, increase number of seperator
550
       if (inlineDataID.charAt(i) == charSeperator)
551
       {
552
         numberOfSeperator++;
553
       }
554
       // if number of seperator reach the target one, record the index(i)
555
       // and get substring and terminate the loop
556
       if ( numberOfSeperator == targetNumberOfSeperator)
557
       {
558
         docidWithoutRev = inlineDataID.substring(0, i);
559
         break;
560
       }
561
     }
562

    
563
     MetaCatUtil.debugMessage("Docid without rev from inlinedata id: " +
564
                               docidWithoutRev, 35);
565
     return docidWithoutRev;
566

    
567
   }
568
   
569
   /**
570
    * Revise stack change a stack to opposite order 
571
    */
572
   public static Stack reviseStack(Stack stack)
573
   {
574
     Stack result = new Stack();
575
     // make sure the parameter is correct
576
     if (stack == null || stack.isEmpty())
577
     {
578
       result = stack;
579
       return result;
580
     }
581
     
582
     while (!stack.isEmpty())
583
     {
584
       Object obj = stack.pop();
585
       result.push(obj);
586
     }
587
     return result;
588
   }
589
  
590
  /** A method to replace whitespace in url*/
591
  public static String replaceWhiteSpaceForURL(String urlHasWhiteSpace)
592
  {
593
    StringBuffer newUrl = new StringBuffer();
594
    String whiteSpaceReplace ="%20";
595
    if (urlHasWhiteSpace == null || urlHasWhiteSpace.trim().equals(""))
596
    {
597
      return null;
598
    }
599

    
600
    for (int i=0; i<urlHasWhiteSpace.length(); i++)
601
    {
602
       char ch = urlHasWhiteSpace.charAt(i);
603
       if ( !Character.isWhitespace(ch))
604
       {
605
          newUrl.append(ch);
606
       }
607
       else
608
       {
609
         //it is white sapce, replace it by %20
610
         newUrl = newUrl.append(whiteSpaceReplace);
611
       }
612

    
613
   }//for
614
   MetaCatUtil.debugMessage("The new string without space is:"+ 
615
                             newUrl.toString(), 35);
616
   return newUrl.toString();
617

    
618
  }// replaceWhiteSpaceForUR
619

    
620
}
(40-40/58)