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: sgarg $'
10
 *     '$Date: 2005-09-06 08:45:43 -0700 (Tue, 06 Sep 2005) $'
11
 * '$Revision: 2557 $'
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.MalformedURLException;
32
import java.net.URL;
33
import java.util.Hashtable;
34
import java.util.Stack;
35
import java.util.Vector;
36

    
37
import edu.ucsb.nceas.dbadapter.AbstractDatabase;
38
import edu.ucsb.nceas.utilities.Options;
39

    
40
/**
41
 * A suite of utility classes for the metadata catalog server
42
 */
43
public class MetaCatUtil
44
{
45

    
46
    public static AbstractDatabase dbAdapter;
47

    
48
    public static Vector pathsForIndexing;
49

    
50
    private static Options options = null;
51

    
52
    private static boolean debug = true;
53

    
54

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

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

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

    
89
    /**
90
     * Utility method to get an option value from the properties file
91
     *
92
     * @param optionName the name of the option requested
93
     * @return the String value for the option, or null if not set
94
     */
95
    public static String getOption(String optionName)
96
    {
97
        if (options == null) {
98
            options = Options.getInstance();
99
        }
100
        String value = options.getOption(optionName);
101
        return value;
102
    }
103
    
104
    /**
105
     * Utility method to set an option value from the properties file
106
     *
107
     * @param optionName the name of the option requested
108
     */
109
    public static void setOption(String optionName, String newValue)
110
    {
111
        if (options == null) {
112
            options = Options.getInstance();
113
        }
114
        options.setOption(optionName, newValue);
115
        
116
    }
117

    
118
    /** Utility method to convert a file handle into a URL */
119
    public static URL fileToURL(File file)
120
    {
121
        String path = file.getAbsolutePath();
122
        String fSep = System.getProperty("file.separator");
123
        if (fSep != null && fSep.length() == 1)
124
                path = path.replace(fSep.charAt(0), '/');
125
        if (path.length() > 0 && path.charAt(0) != '/') path = '/' + path;
126
        try {
127
            return new URL("file", null, path);
128
        } catch (java.net.MalformedURLException e) {
129
            /*
130
             * According to the spec this could only happen if the file
131
             */
132
            throw new Error("unexpected MalformedURLException");
133
        }
134
    }
135

    
136
    /**
137
     * Utility method to parse the query part of a URL into parameters. This
138
     * method assumes the format of the query par tof the url is an ampersand
139
     * separated list of name/value pairs, with equal signs separating the name
140
     * from the value (e.g., name=tom&zip=99801 ). Returns a has of the name
141
     * value pairs, hashed on name.
142
     */
143
    public static Hashtable parseQuery(String query)
144
            throws MalformedURLException
145
    {
146
        String[][] params = new String[200][2];
147
        Hashtable parameters = new Hashtable();
148

    
149
        String temp = "";
150
        boolean ampflag = true;
151
        boolean poundflag = false;
152
        int arrcount = 0;
153

    
154
        if (query != null) {
155
            for (int i = 0; i < query.length(); i++) {
156

    
157
                // go throught the remainder of the query one character at a
158
                // time.
159
                if (query.charAt(i) == '=') {
160
                    // if the current char is a # then the preceding should be
161
                    // a name
162
                    if (!poundflag && ampflag) {
163
                        params[arrcount][0] = temp.trim();
164
                        temp = "";
165
                    } else {
166
                        //if there are two #s or &s in a row throw an
167
                        // exception.
168
                        throw new MalformedURLException(
169
                                "metacatURL: Two parameter names "
170
                                        + "not allowed in sequence");
171
                    }
172
                    poundflag = true;
173
                    ampflag = false;
174
                } else if (query.charAt(i) == '&' || i == query.length() - 1) {
175
                    //the text preceding the & should be the param value.
176
                    if (i == query.length() - 1) {
177
                        //if at the end of the string grab the last value and
178
                        // append it.
179
                        if (query.charAt(i) != '=') {
180
                            //ignore an extra & on the end of the string
181
                            temp += query.charAt(i);
182
                        }
183
                    }
184

    
185
                    if (!ampflag && poundflag) {
186
                        params[arrcount][1] = temp.trim();
187
                        parameters
188
                                .put(params[arrcount][0], params[arrcount][1]);
189
                        temp = "";
190
                        arrcount++; //increment the array to the next row.
191
                    } else {
192
                        //if there are two =s or &s in a row through an
193
                        // exception
194
                        throw new MalformedURLException(
195
                                "metacatURL: Two parameter values "
196
                                        + "not allowed in sequence");
197
                    }
198
                    poundflag = false;
199
                    ampflag = true;
200
                } else {
201
                    //get the next character in the string
202
                    temp += query.charAt(i);
203
                }
204
            }
205
        }
206
        return parameters;
207
    }
208

    
209
    /**
210
     * Utility method to print debugging messages. User can set debug level for
211
     * this message. The number is fewer, the message is more important
212
     *
213
     * @param msg, the content of the message
214
     * @param debugLevel, an integer indicating the message debug leve
215
     */
216
    public static void debugMessage(String msg, int debugLevel)
217
    {
218
        if (debug) {
219
            int limit = 1;
220
            try {
221
                limit = Integer.parseInt(getOption("debuglevel"));
222

    
223
            } catch (Exception e) {
224
                System.out.println(e.getMessage());
225
            }
226
            //don't allow the user set debugLevel less than or equals 0
227
            if (debugLevel <= 0) {
228
                debugLevel = 1;
229
            }
230

    
231
            if (debugLevel < limit) {
232
                System.err.println("@debugprefix@ " + msg);
233
            }
234
        }
235
    }
236

    
237

    
238
    /**
239
     * Utility method to print debugging messages. User can set debug level for
240
     * this message. The number is fewer, the message is more important. Can be
241
     * used to control if the carriage return and debugPrefix are printed
242
     *
243
     * @param msg, the content of the message
244
     * @param debugLevel, an integer indicating the message debug level
245
     * @param debugPrefix, a boolean indicating whether debugprefix
246
     *                    should be printed or not
247
     */
248
    public static void formattedDebugMessage(String msg, int debugLevel,
249
                                      boolean carriageReturn,
250
                                      boolean debugPrefix)
251
    {
252
        if (debug) {
253
            int limit = 1;
254
            try {
255
                limit = Integer.parseInt(getOption("debuglevel"));
256

    
257
            } catch (Exception e) {
258
                System.out.println(e.getMessage());
259
            }
260
            //don't allow the user set debugLevel less than or equals 0
261
            if (debugLevel <= 0) {
262
                debugLevel = 1;
263
            }
264

    
265
            if (debugLevel < limit) {
266
                if(debugPrefix) {
267
                    if(carriageReturn)
268
                        System.err.println("@debugprefix@ " + msg);
269
                    else
270
                        System.err.print("@debugprefix@ " + msg);
271
                } else {
272
                    if(carriageReturn)
273
                        System.err.println(msg);
274
                    else
275
                        System.err.print(msg);
276
                }
277
            }
278
        }
279
    }
280

    
281

    
282
    public static Vector getOptionList(String optiontext)
283
    {
284
        Vector optionsVector = new Vector();
285
        if (optiontext.indexOf(",") == -1) {
286
            optionsVector.addElement(optiontext);
287
            return optionsVector;
288
        }
289

    
290
        while (optiontext.indexOf(",") != -1) {
291
            String s = optiontext.substring(0, optiontext.indexOf(","));
292
            optionsVector.addElement(s.trim());
293
            optiontext = optiontext.substring(optiontext.indexOf(",") + 1,
294
                    optiontext.length());
295
            if (optiontext.indexOf(",") == -1) { //catch the last list entry
296
                optionsVector.addElement(optiontext.trim());
297
            }
298
        }
299
        return optionsVector;
300
    }
301

    
302
    /** Normalizes the given string. Taken from configXML.java */
303
    public static String normalize(String s)
304
    {
305
        StringBuffer str = new StringBuffer();
306

    
307
             int len = (s != null) ? s.length() : 0;
308
             for (int i = 0; i < len; i++) {
309
                 char ch = s.charAt(i);
310
                 switch (ch) {
311
                     case '<': {
312
                         str.append("&lt;");
313
                         break;
314
                     }
315
                     case '>': {
316
                         str.append("&gt;");
317
                         break;
318
                     }
319
                     case '&': {
320
                         /*
321
                          * patch provided by Johnoel Ancheta from U of Hawaii
322
                          */
323
                         // check if & is for a character reference &#xnnnn;
324
                         if (i + 1 < len - 1 && s.charAt(i + 1) == '#') {
325
                             str.append("&#");
326
                             i += 2;
327

    
328
                             ch = s.charAt(i);
329
                             while (i < len && ch != ';') {
330
                                 str.append(ch);
331
                                 i++;
332
                                 ch = s.charAt(i);
333
                             }
334
                             str.append(';');
335
                         } else 
336
                         // check if & is in front of amp; 
337
                         // (we dont yet check for other HTML 4.0 Character entities) 
338
                         if (i + 4 < len -1 && s.charAt(i + 1) == 'a' 
339
                        	 && s.charAt(i + 2) == 'm' 
340
                        		 && s.charAt(i + 3) == 'p' 
341
                        			 && s.charAt(i + 4) == ';'){
342
                             str.append("&amp;");
343
                             i += 5;                        	 
344
                         } else
345
                             str.append("&amp;");
346
                         /////////
347
                         break;
348
                     }
349
                    default: {
350
                         if ( (ch<128) && (ch>31) ) {
351
                             str.append(ch);
352
                         }
353
                         else if (ch<32) {
354
                             if (ch == 10) { // new line
355
                                 str.append(ch);
356
                             }
357
                             if (ch == 13) { // carriage return
358
                                 str.append(ch);
359
                             }
360
                             if (ch == 9) {  // tab
361
                                 str.append(ch);
362
                             }
363
                             // otherwise skip
364
                         }
365
                         else {
366
                             str.append("&#");
367
                             str.append(Integer.toString(ch));
368
                             str.append(';');
369
                         }
370
                     }
371
                 }
372
             }
373
             return str.toString();
374
    }
375

    
376
    /**
377
     * Get docid from online/url string
378
     */
379
    public static String getDocIdWithRevFromOnlineURL(String url)
380
    {
381
        String docid = null;
382
        String DOCID = "docid";
383
        boolean find = false;
384
        char limited = '&';
385
        int count = 0; //keep track how many & was found
386
        Vector list = new Vector();// keep index number for &
387
        if (url == null) {
388
            MetaCatUtil.debugMessage("url is null and null will be returned",
389
                    30);
390
            return docid;
391
        }
392
        // the first element in list is 0
393
        list.add(new Integer(0));
394
        for (int i = 0; i < url.length(); i++) {
395
            if (url.charAt(i) == limited) {
396
                // count plus 1
397
                count++;
398
                list.add(new Integer(i));
399
                // get substring beween two &
400
                String str = url.substring(
401
                        ((Integer) list.elementAt(count - 1)).intValue(), i);
402
                MetaCatUtil.debugMessage("substring between two & is: " + str,
403
                        30);
404
                //if the subString contains docid, we got it
405
                if (str.indexOf(DOCID) != -1) {
406
                    //get index of '="
407
                    int start = getIndexForGivenChar(str, '=') + 1;
408
                    int end = str.length();
409
                    docid = str.substring(start, end);
410
                    find = true;
411
                }//if
412
            }//if
413
        }//for
414
        //if not find, we need check the subtring between the index of last &
415
        // and
416
        // the end of string
417
        if (!find) {
418
            MetaCatUtil.debugMessage("Checking the last substring", 35);
419
            String str = url.substring(((Integer) list.elementAt(count))
420
                    .intValue() + 1, url.length());
421
            MetaCatUtil.debugMessage("Last substring is: " + str, 30);
422
            if (str.indexOf(DOCID) != -1) {
423
                //get index of '="
424
                int start = getIndexForGivenChar(str, '=') + 1;
425
                int end = str.length();
426
                docid = str.substring(start, end);
427
                find = true;
428
            }//if
429
        }//if
430
        MetaCatUtil.debugMessage("The docid from online url is:" + docid, 30);
431
        return docid.trim();
432
    }
433

    
434

    
435
    /**
436
     * Eocgorid identifier will look like: ecogrid://knb/tao.1.1
437
     * The AccessionNumber tao.1.1 will be returned. If the given doesn't
438
     * contains ecogrid, null will be returned.
439
     * @param identifier String
440
     * @return String
441
     */
442
    public static String getAccessionNumberFromEcogridIdentifier(String identifier)
443
    {
444
      String accessionNumber = null;
445
      if (identifier != null && identifier.startsWith(DBSAXHandler.ECOGRID))
446
      {
447
        // find the last "/" in identifier
448
        int indexOfLastSlash = identifier.lastIndexOf("/");
449
        int start = indexOfLastSlash+1;
450
        int end   = identifier.length();
451
        accessionNumber = identifier.substring(start, end);
452
      }
453
      MetaCatUtil.debugMessage("The accession number from url is " +
454
                                 accessionNumber, 10);
455
      return accessionNumber;
456
    }
457

    
458
    private static int getIndexForGivenChar(String str, char character)
459
    {
460
        int index = -1;
461
        // make sure str is not null
462
        if (str == null) {
463
            MetaCatUtil.debugMessage(
464
                    "The given str is null and -1 will be returned", 30);
465
            return index;
466
        }
467
        // got though the string
468
        for (int i = 0; i < str.length(); i++) {
469
            // find the first one then break the loop
470
            if (str.charAt(i) == character) {
471
                index = i;
472
                break;
473
            }//if
474
        }//for
475
        MetaCatUtil.debugMessage("the index for char " + character + " is: "
476
                + index, 30);
477
        return index;
478
    }
479

    
480
    /**
481
     * Utility method to get docid from a given string
482
     *
483
     * @param string, the given string should be these two format: 1) str1.str2
484
     *            in this case docid= str1.str2 2) str1.str2.str3, in this case
485
     *            docid =str1.str2
486
     * @param the sperator char
487
     */
488
    public static String getDocIdFromString(String str)
489
    {
490
        String docId = null;
491
        if (str == null) {
492
            MetaCatUtil.debugMessage(
493
                    "The given str is null and null will be returned"
494
                            + " in getDocIdfromString", 30);
495
            return docId;
496
        } //make sure docid is not null
497
        int dotNumber = 0;//count how many dots in given string
498
        int indexOfLastDot = 0;
499

    
500
        //assume that seperator is one charactor string
501
        char seperator = getOption("accNumSeparator").charAt(0);
502

    
503
        for (int i = 0; i < str.length(); i++) {
504
            if (str.charAt(i) == seperator) {
505
                dotNumber++;//count how many dots
506
                indexOfLastDot = i;//keep the last dot postion
507
            }
508
        }//for
509

    
510
        //The string formatt is wrong, because it has more than two or less
511
        // than
512
        //one seperator
513
        if (dotNumber > 2 || dotNumber < 1) {
514
            docId = null;
515
        } else if (dotNumber == 2) //the case for str1.str2.str3
516
        {
517
            docId = str.substring(0, indexOfLastDot);
518
        } else if (dotNumber == 1) //the case for str1.str2
519
        {
520
            docId = str;
521
        }
522

    
523
        return docId;
524
    }//getDocIdFromString
525

    
526
    /**
527
     * Utility method to get version number from a given string
528
     *
529
     * @param string, the given string should be these two format: 1)
530
     *            str1.str2(no version) version =-1; 2) str1.str2.str3, in this
531
     *            case version = str3; 3) other, vresion =-2
532
     */
533
    public static int getVersionFromString(String str)
534
            throws NumberFormatException
535
    {
536
        int version = -1;
537
        String versionString = null;
538
        int dotNumber = 0;//count how many dots in given string
539
        int indexOfLastDot = 0;
540

    
541
        //assume that seperator is one charactor string
542
        char seperator = getOption("accNumSeparator").charAt(0);
543

    
544
        for (int i = 0; i < str.length(); i++) {
545
            if (str.charAt(i) == seperator) {
546
                dotNumber++;//count how many dots
547
                indexOfLastDot = i;//keep the last dot postion
548
            }
549
        }//for
550

    
551
        //The string formatt is wrong, because it has more than two or less
552
        // than
553
        //one seperator
554
        if (dotNumber > 2 || dotNumber < 1) {
555
            version = -2;
556
        } else if (dotNumber == 2 && (indexOfLastDot != (str.length() - 1)))
557
        //the case for str1.str2.str3
558
        {
559
            versionString = str.substring((indexOfLastDot + 1), str.length());
560
            version = Integer.parseInt(versionString);
561
        } else if (dotNumber == 1) //the case for str1.str2
562
        {
563
            version = -1;
564
        }
565

    
566
        return version;
567
    }//getVersionFromString
568

    
569
    /**
570
     * Utility method to get version string from a given string
571
     *
572
     * @param string, the given string should be these two format: 1)
573
     *            str1.str2(no version) version=null; 2) str1.str2.str3, in
574
     *            this case version = str3; 3) other, vresion =null;
575
     */
576
    public static String getRevisionStringFromString(String str)
577
            throws NumberFormatException
578
    {
579
        // String to store the version
580
        String versionString = null;
581
        int dotNumber = 0;//count how many dots in given string
582
        int indexOfLastDot = 0;
583

    
584
        //assume that seperator is one charactor string
585
        char seperator = getOption("accNumSeparator").charAt(0);
586

    
587
        for (int i = 0; i < str.length(); i++) {
588
            if (str.charAt(i) == seperator) {
589
                dotNumber++;//count how many dots
590
                indexOfLastDot = i;//keep the last dot postion
591
            }
592
        }//for
593

    
594
        //The string formatt is wrong, because it has more than two or less
595
        // than
596
        //one seperator
597
        if (dotNumber > 2 || dotNumber < 1) {
598
            versionString = null;
599
        } else if (dotNumber == 2 && (indexOfLastDot != (str.length() - 1))) {
600
            //the case for str1.str2.str3
601
            // indexOfLastDot != (str.length() -1) means get rid of str1.str2.
602
            versionString = str.substring((indexOfLastDot + 1), str.length());
603
        } else if (dotNumber == 1) //the case for str1.str2 or str1.str2.
604
        {
605
            versionString = null;
606
        }
607

    
608
        return versionString;
609
    }//getVersionFromString
610

    
611
    /**
612
     * This method will get docid from an AccessionNumber. There is no
613
     * assumption the accessnumber will be str1.str2.str3. It can be more. So
614
     * we think the docid will be get rid of last part
615
     */
616
    public static String getDocIdFromAccessionNumber(String accessionNumber)
617
    {
618
        String docid = null;
619
        if (accessionNumber == null) { return docid; }
620
        String seperator = getOption("accNumSeparator");
621
        int indexOfLastSeperator = accessionNumber.lastIndexOf(seperator);
622
        docid = accessionNumber.substring(0, indexOfLastSeperator);
623
        MetaCatUtil.debugMessage("after parsing accessionnumber, docid is "
624
                + docid, 30);
625
        return docid;
626
    }
627

    
628
    /**
629
     * This method will get inline data id without the revision number.
630
     * So if inlineData.1.2 is passed as input, inlineData.2 is returned.
631
     */
632
    public static String getInlineDataIdWithoutRev(String accessionNumber)
633
    {
634
        String docid = null;
635
        if (accessionNumber == null) { return docid; }
636
        String seperator = getOption("accNumSeparator");
637
        int indexOfLastSeperator = accessionNumber.lastIndexOf(seperator);
638
        String version = accessionNumber.substring(indexOfLastSeperator,
639
                                                   accessionNumber.length());
640
        accessionNumber = accessionNumber.substring(0, indexOfLastSeperator);
641
        indexOfLastSeperator = accessionNumber.lastIndexOf(seperator);
642
        docid = accessionNumber.substring(0, indexOfLastSeperator) + version;
643
        MetaCatUtil.debugMessage("after parsing accessionnumber, docid is "
644
                                 + docid, 30);
645

    
646
        return docid;
647
    }
648

    
649
    /**
650
     * This method will call both getDocIdFromString and
651
     * getDocIdFromAccessionNumber. So first, if the string looks str1.str2,
652
     * the docid will be str1.str2. If the string is str1.str2.str3, the docid
653
     * will be str1.str2. If the string is str1.str2.str3.str4 or more, the
654
     * docid will be str1.str2.str3. If the string look like str1, null will be
655
     * returned
656
     *
657
     */
658
    public static String getSmartDocId(String str)
659
    {
660
        String docid = null;
661
        //call geDocIdFromString first.
662
        docid = getDocIdFromString(str);
663
        // If docid is null, try to call getDocIdFromAccessionNumber
664
        // it will handle the seperator more than2
665
        if (docid == null) {
666
            docid = getDocIdFromAccessionNumber(str);
667
        }
668
        MetaCatUtil.debugMessage("The docid get from smart docid getor is "
669
                + docid, 30);
670
        return docid;
671
    }
672

    
673
    /**
674
     * This method will get revision from an AccessionNumber. There is no
675
     * assumption the accessnumber will be str1.str2.str3. It can be more. So
676
     * we think the docid will be get rid of last part
677
     */
678
    public static int getRevisionFromAccessionNumber(String accessionNumber)
679
            throws NumberFormatException
680
    {
681
        String rev = null;
682
        int revNumber = -1;
683
        if (accessionNumber == null) { return revNumber; }
684
        String seperator = getOption("accNumSeparator");
685
        int indexOfLastSeperator = accessionNumber.lastIndexOf(seperator);
686
        rev = accessionNumber.substring(indexOfLastSeperator + 1,
687
                accessionNumber.length());
688
        revNumber = Integer.parseInt(rev);
689
        MetaCatUtil.debugMessage("after parsing accessionnumber, rev is "
690
                + revNumber, 30);
691
        return revNumber;
692
    }
693

    
694
    /**
695
     * Method to get the name of local replication server
696
     */
697
    public static String getLocalReplicationServerName()
698
    {
699
        String replicationServerName = null;
700
        String serverHost = null;
701
        serverHost = getOption("server");
702
        // append "context/servelet/replication" to the host name
703
        replicationServerName = serverHost + getOption("replicationpath");
704
        return replicationServerName;
705

    
706
    }
707

    
708
    /**
709
     * Method to get docidwithrev from eml2 inline data id The eml inline data
710
     * id would look like eml.200.2.3
711
     */
712
    public static String getDocIdWithoutRevFromInlineDataID(String inlineDataID)
713
    {
714
        String docidWithoutRev = null;
715
        if (inlineDataID == null) { return docidWithoutRev; }
716
        String seperator = MetaCatUtil.getOption("accNumSeparator");
717
        char charSeperator = seperator.charAt(0);
718
        int targetNumberOfSeperator = 2;// we want to know his index
719
        int numberOfSeperator = 0;
720
        for (int i = 0; i < inlineDataID.length(); i++) {
721
            // meet seperator, increase number of seperator
722
            if (inlineDataID.charAt(i) == charSeperator) {
723
                numberOfSeperator++;
724
            }
725
            // if number of seperator reach the target one, record the index(i)
726
            // and get substring and terminate the loop
727
            if (numberOfSeperator == targetNumberOfSeperator) {
728
                docidWithoutRev = inlineDataID.substring(0, i);
729
                break;
730
            }
731
        }
732

    
733
        MetaCatUtil.debugMessage("Docid without rev from inlinedata id: "
734
                + docidWithoutRev, 35);
735
        return docidWithoutRev;
736

    
737
    }
738

    
739
    /**
740
     * Revise stack change a stack to opposite order
741
     */
742
    public static Stack reviseStack(Stack stack)
743
    {
744
        Stack result = new Stack();
745
        // make sure the parameter is correct
746
        if (stack == null || stack.isEmpty()) {
747
            result = stack;
748
            return result;
749
        }
750

    
751
        while (!stack.isEmpty()) {
752
            Object obj = stack.pop();
753
            result.push(obj);
754
        }
755
        return result;
756
    }
757

    
758
    /** A method to replace whitespace in url */
759
    public static String replaceWhiteSpaceForURL(String urlHasWhiteSpace)
760
    {
761
        StringBuffer newUrl = new StringBuffer();
762
        String whiteSpaceReplace = "%20";
763
        if (urlHasWhiteSpace == null || urlHasWhiteSpace.trim().equals("")) { return null; }
764

    
765
        for (int i = 0; i < urlHasWhiteSpace.length(); i++) {
766
            char ch = urlHasWhiteSpace.charAt(i);
767
            if (!Character.isWhitespace(ch)) {
768
                newUrl.append(ch);
769
            } else {
770
                //it is white sapce, replace it by %20
771
                newUrl = newUrl.append(whiteSpaceReplace);
772
            }
773

    
774
        }//for
775
        MetaCatUtil.debugMessage("The new string without space is:"
776
                + newUrl.toString(), 35);
777
        return newUrl.toString();
778

    
779
    }// replaceWhiteSpaceForUR
780

    
781
}
(43-43/63)