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-10-10 11:22:50 -0700 (Mon, 10 Oct 2005) $'
11
 * '$Revision: 2665 $'
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
import java.util.regex.PatternSyntaxException;
37

    
38
import org.apache.log4j.Logger;
39

    
40
import edu.ucsb.nceas.dbadapter.AbstractDatabase;
41
import edu.ucsb.nceas.utilities.Options;
42

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

    
49
    public static AbstractDatabase dbAdapter;
50

    
51
    public static Vector pathsForIndexing;
52

    
53
    private static Options options = null;
54

    
55
    private static boolean debug = true;
56
    
57
    private static String[] administrators;
58
    
59
    private static String[] moderators;
60

    
61
    private static String[] allowedSubmitters;
62

    
63
    private static String[] deniedSubmitters;
64
    
65
    private static Logger logMetacat = Logger.getLogger(MetaCatUtil.class);
66

    
67
    static {
68
    	// Determine our db adapter class and create an instance of that class
69
        try {
70
            dbAdapter = (AbstractDatabase) createObject(getOption("dbAdapter"));
71
        } catch (Exception e) {
72
            System.err.println("Error in MetaCatUtil static block:"
73
                    + e.getMessage());
74
        }
75

    
76
        // read administrator and moderator lists from metacat.properties
77
        getUserAccessControlLists();
78
    }
79
    
80
    /**
81
     * Instantiate a class using the name of the class at runtime
82
     *
83
     * @param className the fully qualified name of the class to instantiate
84
     */
85
    public static Object createObject(String className) throws Exception
86
    {
87

    
88
        Object object = null;
89
        try {
90
            Class classDefinition = Class.forName(className);
91
            object = classDefinition.newInstance();
92
        } catch (InstantiationException e) {
93
            throw e;
94
        } catch (IllegalAccessException e) {
95
            throw e;
96
        } catch (ClassNotFoundException e) {
97
            throw e;
98
        }
99
        return object;
100
    }
101

    
102
    /**
103
     * Utility method to get an option value from the properties file
104
     *
105
     * @param optionName the name of the option requested
106
     * @return the String value for the option, or null if not set
107
     */
108
    public static String getOption(String optionName)
109
    {
110
        if (options == null) {
111
            options = Options.getInstance();
112
        }
113
        String value = options.getOption(optionName);
114
        return value;
115
    }
116
    
117
    /**
118
     * Utility method to set an option value from the properties file
119
     *
120
     * @param optionName the name of the option requested
121
     */
122
    public static void setOption(String optionName, String newValue)
123
    {
124
        if (options == null) {
125
            options = Options.getInstance();
126
        }
127
        options.setOption(optionName, newValue);
128
        
129
    }
130

    
131
    /** Utility method to convert a file handle into a URL */
132
    public static URL fileToURL(File file)
133
    {
134
        String path = file.getAbsolutePath();
135
        String fSep = System.getProperty("file.separator");
136
        if (fSep != null && fSep.length() == 1)
137
                path = path.replace(fSep.charAt(0), '/');
138
        if (path.length() > 0 && path.charAt(0) != '/') path = '/' + path;
139
        try {
140
            return new URL("file", null, path);
141
        } catch (java.net.MalformedURLException e) {
142
            /*
143
             * According to the spec this could only happen if the file
144
             */
145
            throw new Error("unexpected MalformedURLException");
146
        }
147
    }
148

    
149
    /**
150
     * Utility method to parse the query part of a URL into parameters. This
151
     * method assumes the format of the query par tof the url is an ampersand
152
     * separated list of name/value pairs, with equal signs separating the name
153
     * from the value (e.g., name=tom&zip=99801 ). Returns a has of the name
154
     * value pairs, hashed on name.
155
     */
156
    public static Hashtable parseQuery(String query)
157
            throws MalformedURLException
158
    {
159
        String[][] params = new String[200][2];
160
        Hashtable parameters = new Hashtable();
161

    
162
        String temp = "";
163
        boolean ampflag = true;
164
        boolean poundflag = false;
165
        int arrcount = 0;
166

    
167
        if (query != null) {
168
            for (int i = 0; i < query.length(); i++) {
169

    
170
                // go throught the remainder of the query one character at a
171
                // time.
172
                if (query.charAt(i) == '=') {
173
                    // if the current char is a # then the preceding should be
174
                    // a name
175
                    if (!poundflag && ampflag) {
176
                        params[arrcount][0] = temp.trim();
177
                        temp = "";
178
                    } else {
179
                        //if there are two #s or &s in a row throw an
180
                        // exception.
181
                        throw new MalformedURLException(
182
                                "metacatURL: Two parameter names "
183
                                        + "not allowed in sequence");
184
                    }
185
                    poundflag = true;
186
                    ampflag = false;
187
                } else if (query.charAt(i) == '&' || i == query.length() - 1) {
188
                    //the text preceding the & should be the param value.
189
                    if (i == query.length() - 1) {
190
                        //if at the end of the string grab the last value and
191
                        // append it.
192
                        if (query.charAt(i) != '=') {
193
                            //ignore an extra & on the end of the string
194
                            temp += query.charAt(i);
195
                        }
196
                    }
197

    
198
                    if (!ampflag && poundflag) {
199
                        params[arrcount][1] = temp.trim();
200
                        parameters
201
                                .put(params[arrcount][0], params[arrcount][1]);
202
                        temp = "";
203
                        arrcount++; //increment the array to the next row.
204
                    } else {
205
                        //if there are two =s or &s in a row through an
206
                        // exception
207
                        throw new MalformedURLException(
208
                                "metacatURL: Two parameter values "
209
                                        + "not allowed in sequence");
210
                    }
211
                    poundflag = false;
212
                    ampflag = true;
213
                } else {
214
                    //get the next character in the string
215
                    temp += query.charAt(i);
216
                }
217
            }
218
        }
219
        return parameters;
220
    }
221

    
222
    /**
223
     * Utility method to print debugging messages. User can set debug level for
224
     * this message. The number is fewer, the message is more important
225
     *
226
     * @param msg, the content of the message
227
     * @param debugLevel, an integer indicating the message debug leve
228
     */
229
    /** 
230
     * Commenting out the function for now...
231
     * public static void debugMessage(String msg, int debugLevel)
232
     * {
233
     *   if (debug) {
234
     *       int limit = 1;
235
     *       try {
236
     *           limit = Integer.parseInt(getOption("debuglevel"));
237
     *
238
     *       } catch (Exception e) {
239
     *           System.out.println(e.getMessage());
240
     *       }
241
     *       //don't allow the user set debugLevel less than or equals 0
242
     *       if (debugLevel <= 0) {
243
     *           debugLevel = 1;
244
     *       }
245
     *
246
     *       if (debugLevel < limit) {
247
     *           System.err.println("@debugprefix@ " + msg);
248
     *       }
249
     *   }
250
     *}
251
     */
252

    
253

    
254
    /**
255
     * Utility method to print debugging messages. User can set debug level for
256
     * this message. The number is fewer, the message is more important
257
     *
258
     * @param msg, the content of the message
259
     * @param debugLevel, an integer indicating the message debug leve
260
     */
261
    public static void printMessage(String msg)
262
    {
263
    	System.err.println("@debugprefix@ " + msg);
264
    }
265
    
266
  
267
    public static Vector getOptionList(String optiontext)
268
    {
269
        Vector optionsVector = new Vector();
270
        if (optiontext.indexOf(",") == -1) {
271
            optionsVector.addElement(optiontext);
272
            return optionsVector;
273
        }
274

    
275
        while (optiontext.indexOf(",") != -1) {
276
            String s = optiontext.substring(0, optiontext.indexOf(","));
277
            optionsVector.addElement(s.trim());
278
            optiontext = optiontext.substring(optiontext.indexOf(",") + 1,
279
                    optiontext.length());
280
            if (optiontext.indexOf(",") == -1) { //catch the last list entry
281
                optionsVector.addElement(optiontext.trim());
282
            }
283
        }
284
        return optionsVector;
285
    }
286

    
287
    /** Normalizes the given string. Taken from configXML.java */
288
    public static String normalize(String s)
289
    {
290
        StringBuffer str = new StringBuffer();
291

    
292
             int len = (s != null) ? s.length() : 0;
293
             for (int i = 0; i < len; i++) {
294
                 char ch = s.charAt(i);
295
                 switch (ch) {
296
                     case '<': {
297
                         str.append("&lt;");
298
                         break;
299
                     }
300
                     case '>': {
301
                         str.append("&gt;");
302
                         break;
303
                     }
304
                     case '&': {
305
                         /*
306
                          * patch provided by Johnoel Ancheta from U of Hawaii
307
                          */
308
                         // check if & is for a character reference &#xnnnn;
309
                         if (i + 1 < len - 1 && s.charAt(i + 1) == '#') {
310
                             str.append("&#");
311
                             i += 2;
312

    
313
                             ch = s.charAt(i);
314
                             while (i < len && ch != ';') {
315
                                 str.append(ch);
316
                                 i++;
317
                                 ch = s.charAt(i);
318
                             }
319
                             str.append(';');
320
                         } else 
321
                         // check if & is in front of amp; 
322
                         // (we dont yet check for other HTML 4.0 Character entities) 
323
                         if (i + 4 < len -1 && s.charAt(i + 1) == 'a' 
324
                        	 && s.charAt(i + 2) == 'm' 
325
                        		 && s.charAt(i + 3) == 'p' 
326
                        			 && s.charAt(i + 4) == ';'){
327
                             str.append("&amp;");
328
                             i += 5;                        	 
329
                         } else
330
                             str.append("&amp;");
331
                         /////////
332
                         break;
333
                     }
334
                    default: {
335
                         if ( (ch<128) && (ch>31) ) {
336
                             str.append(ch);
337
                         }
338
                         else if (ch<32) {
339
                             if (ch == 10) { // new line
340
                                 str.append(ch);
341
                             }
342
                             if (ch == 13) { // carriage return
343
                                 str.append(ch);
344
                             }
345
                             if (ch == 9) {  // tab
346
                                 str.append(ch);
347
                             }
348
                             // otherwise skip
349
                         }
350
                         else {
351
                             str.append("&#");
352
                             str.append(Integer.toString(ch));
353
                             str.append(';');
354
                         }
355
                     }
356
                 }
357
             }
358
             return str.toString();
359
    }
360

    
361
    /**
362
     * Get docid from online/url string
363
     */
364
    public static String getDocIdWithRevFromOnlineURL(String url)
365
    {
366
        String docid = null;
367
        String DOCID = "docid";
368
        boolean find = false;
369
        char limited = '&';
370
        int count = 0; //keep track how many & was found
371
        Vector list = new Vector();// keep index number for &
372
        if (url == null) {
373
            logMetacat.info("url is null and null will be returned");
374
            return docid;
375
        }
376
        // the first element in list is 0
377
        list.add(new Integer(0));
378
        for (int i = 0; i < url.length(); i++) {
379
            if (url.charAt(i) == limited) {
380
                // count plus 1
381
                count++;
382
                list.add(new Integer(i));
383
                // get substring beween two &
384
                String str = url.substring(
385
                        ((Integer) list.elementAt(count - 1)).intValue(), i);
386
                logMetacat.info("substring between two & is: " + str);
387
                //if the subString contains docid, we got it
388
                if (str.indexOf(DOCID) != -1) {
389
                    //get index of '="
390
                    int start = getIndexForGivenChar(str, '=') + 1;
391
                    int end = str.length();
392
                    docid = str.substring(start, end);
393
                    find = true;
394
                }//if
395
            }//if
396
        }//for
397
        //if not find, we need check the subtring between the index of last &
398
        // and
399
        // the end of string
400
        if (!find) {
401
            logMetacat.info("Checking the last substring");
402
            String str = url.substring(((Integer) list.elementAt(count))
403
                    .intValue() + 1, url.length());
404
            logMetacat.info("Last substring is: " + str);
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
        logMetacat.info("The docid from online url is:" + docid);
414
        return docid.trim();
415
    }
416

    
417

    
418
    /**
419
     * Eocgorid identifier will look like: ecogrid://knb/tao.1.1
420
     * The AccessionNumber tao.1.1 will be returned. If the given doesn't
421
     * contains ecogrid, null will be returned.
422
     * @param identifier String
423
     * @return String
424
     */
425
    public static String getAccessionNumberFromEcogridIdentifier(String identifier)
426
    {
427
      String accessionNumber = null;
428
      if (identifier != null && identifier.startsWith(DBSAXHandler.ECOGRID))
429
      {
430
        // find the last "/" in identifier
431
        int indexOfLastSlash = identifier.lastIndexOf("/");
432
        int start = indexOfLastSlash+1;
433
        int end   = identifier.length();
434
        accessionNumber = identifier.substring(start, end);
435
      }
436
      logMetacat.warn("The accession number from url is " +
437
                                 accessionNumber);
438
      return accessionNumber;
439
    }
440

    
441
    private static int getIndexForGivenChar(String str, char character)
442
    {
443
        int index = -1;
444
        // make sure str is not null
445
        if (str == null) {
446
            logMetacat.info(
447
                    "The given str is null and -1 will be returned");
448
            return index;
449
        }
450
        // got though the string
451
        for (int i = 0; i < str.length(); i++) {
452
            // find the first one then break the loop
453
            if (str.charAt(i) == character) {
454
                index = i;
455
                break;
456
            }//if
457
        }//for
458
        logMetacat.info("the index for char " + character + " is: "
459
                + index);
460
        return index;
461
    }
462

    
463
    /**
464
     * Utility method to get docid from a given string
465
     *
466
     * @param string, the given string should be these two format: 1) str1.str2
467
     *            in this case docid= str1.str2 2) str1.str2.str3, in this case
468
     *            docid =str1.str2
469
     * @param the sperator char
470
     */
471
    public static String getDocIdFromString(String str)
472
    {
473
        String docId = null;
474
        if (str == null) {
475
            logMetacat.info(
476
                    "The given str is null and null will be returned"
477
                            + " in getDocIdfromString");
478
            return docId;
479
        } //make sure docid is not null
480
        int dotNumber = 0;//count how many dots in given string
481
        int indexOfLastDot = 0;
482

    
483
        //assume that seperator is one charactor string
484
        char seperator = getOption("accNumSeparator").charAt(0);
485

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

    
493
        //The string formatt is wrong, because it has more than two or less
494
        // than
495
        //one seperator
496
        if (dotNumber > 2 || dotNumber < 1) {
497
            docId = null;
498
        } else if (dotNumber == 2) //the case for str1.str2.str3
499
        {
500
            docId = str.substring(0, indexOfLastDot);
501
        } else if (dotNumber == 1) //the case for str1.str2
502
        {
503
            docId = str;
504
        }
505

    
506
        return docId;
507
    }//getDocIdFromString
508

    
509
    /**
510
     * Utility method to get version number from a given string
511
     *
512
     * @param string, the given string should be these two format: 1)
513
     *            str1.str2(no version) version =-1; 2) str1.str2.str3, in this
514
     *            case version = str3; 3) other, vresion =-2
515
     */
516
    public static int getVersionFromString(String str)
517
            throws NumberFormatException
518
    {
519
        int version = -1;
520
        String versionString = null;
521
        int dotNumber = 0;//count how many dots in given string
522
        int indexOfLastDot = 0;
523

    
524
        //assume that seperator is one charactor string
525
        char seperator = getOption("accNumSeparator").charAt(0);
526

    
527
        for (int i = 0; i < str.length(); i++) {
528
            if (str.charAt(i) == seperator) {
529
                dotNumber++;//count how many dots
530
                indexOfLastDot = i;//keep the last dot postion
531
            }
532
        }//for
533

    
534
        //The string formatt is wrong, because it has more than two or less
535
        // than
536
        //one seperator
537
        if (dotNumber > 2 || dotNumber < 1) {
538
            version = -2;
539
        } else if (dotNumber == 2 && (indexOfLastDot != (str.length() - 1)))
540
        //the case for str1.str2.str3
541
        {
542
            versionString = str.substring((indexOfLastDot + 1), str.length());
543
            version = Integer.parseInt(versionString);
544
        } else if (dotNumber == 1) //the case for str1.str2
545
        {
546
            version = -1;
547
        }
548

    
549
        return version;
550
    }//getVersionFromString
551

    
552
    /**
553
     * Utility method to get version string from a given string
554
     *
555
     * @param string, the given string should be these two format: 1)
556
     *            str1.str2(no version) version=null; 2) str1.str2.str3, in
557
     *            this case version = str3; 3) other, vresion =null;
558
     */
559
    public static String getRevisionStringFromString(String str)
560
            throws NumberFormatException
561
    {
562
        // String to store the version
563
        String versionString = null;
564
        int dotNumber = 0;//count how many dots in given string
565
        int indexOfLastDot = 0;
566

    
567
        //assume that seperator is one charactor string
568
        char seperator = getOption("accNumSeparator").charAt(0);
569

    
570
        for (int i = 0; i < str.length(); i++) {
571
            if (str.charAt(i) == seperator) {
572
                dotNumber++;//count how many dots
573
                indexOfLastDot = i;//keep the last dot postion
574
            }
575
        }//for
576

    
577
        //The string formatt is wrong, because it has more than two or less
578
        // than
579
        //one seperator
580
        if (dotNumber > 2 || dotNumber < 1) {
581
            versionString = null;
582
        } else if (dotNumber == 2 && (indexOfLastDot != (str.length() - 1))) {
583
            //the case for str1.str2.str3
584
            // indexOfLastDot != (str.length() -1) means get rid of str1.str2.
585
            versionString = str.substring((indexOfLastDot + 1), str.length());
586
        } else if (dotNumber == 1) //the case for str1.str2 or str1.str2.
587
        {
588
            versionString = null;
589
        }
590

    
591
        return versionString;
592
    }//getVersionFromString
593

    
594
    /**
595
     * This method will get docid from an AccessionNumber. There is no
596
     * assumption the accessnumber will be str1.str2.str3. It can be more. So
597
     * we think the docid will be get rid of last part
598
     */
599
    public static String getDocIdFromAccessionNumber(String accessionNumber)
600
    {
601
        String docid = null;
602
        if (accessionNumber == null) { return docid; }
603
        String seperator = getOption("accNumSeparator");
604
        int indexOfLastSeperator = accessionNumber.lastIndexOf(seperator);
605
        docid = accessionNumber.substring(0, indexOfLastSeperator);
606
        logMetacat.info("after parsing accessionnumber, docid is "
607
                + docid);
608
        return docid;
609
    }
610

    
611
    /**
612
     * This method will get inline data id without the revision number.
613
     * So if inlineData.1.2 is passed as input, inlineData.2 is returned.
614
     */
615
    public static String getInlineDataIdWithoutRev(String accessionNumber)
616
    {
617
        String docid = null;
618
        if (accessionNumber == null) { return docid; }
619
        String seperator = getOption("accNumSeparator");
620
        int indexOfLastSeperator = accessionNumber.lastIndexOf(seperator);
621
        String version = accessionNumber.substring(indexOfLastSeperator,
622
                                                   accessionNumber.length());
623
        accessionNumber = accessionNumber.substring(0, indexOfLastSeperator);
624
        indexOfLastSeperator = accessionNumber.lastIndexOf(seperator);
625
        docid = accessionNumber.substring(0, indexOfLastSeperator) + version;
626
        logMetacat.info("after parsing accessionnumber, docid is "
627
                                 + docid);
628

    
629
        return docid;
630
    }
631

    
632
    /**
633
     * This method will call both getDocIdFromString and
634
     * getDocIdFromAccessionNumber. So first, if the string looks str1.str2,
635
     * the docid will be str1.str2. If the string is str1.str2.str3, the docid
636
     * will be str1.str2. If the string is str1.str2.str3.str4 or more, the
637
     * docid will be str1.str2.str3. If the string look like str1, null will be
638
     * returned
639
     *
640
     */
641
    public static String getSmartDocId(String str)
642
    {
643
        String docid = null;
644
        //call geDocIdFromString first.
645
        docid = getDocIdFromString(str);
646
        // If docid is null, try to call getDocIdFromAccessionNumber
647
        // it will handle the seperator more than2
648
        if (docid == null) {
649
            docid = getDocIdFromAccessionNumber(str);
650
        }
651
        logMetacat.info("The docid get from smart docid getor is "
652
                + docid);
653
        return docid;
654
    }
655

    
656
    /**
657
     * This method will get revision from an AccessionNumber. There is no
658
     * assumption the accessnumber will be str1.str2.str3. It can be more. So
659
     * we think the docid will be get rid of last part
660
     */
661
    public static int getRevisionFromAccessionNumber(String accessionNumber)
662
            throws NumberFormatException
663
    {
664
        String rev = null;
665
        int revNumber = -1;
666
        if (accessionNumber == null) { return revNumber; }
667
        String seperator = getOption("accNumSeparator");
668
        int indexOfLastSeperator = accessionNumber.lastIndexOf(seperator);
669
        rev = accessionNumber.substring(indexOfLastSeperator + 1,
670
                accessionNumber.length());
671
        revNumber = Integer.parseInt(rev);
672
        logMetacat.info("after parsing accessionnumber, rev is "
673
                + revNumber);
674
        return revNumber;
675
    }
676

    
677
    /**
678
     * Method to get the name of local replication server
679
     */
680
    public static String getLocalReplicationServerName()
681
    {
682
        String replicationServerName = null;
683
        String serverHost = null;
684
        serverHost = getOption("server");
685
        // append "context/servelet/replication" to the host name
686
        replicationServerName = serverHost.trim() + getOption("replicationpath").trim();
687
        return replicationServerName;
688

    
689
    }
690

    
691
    /**
692
     * Method to get docidwithrev from eml2 inline data id The eml inline data
693
     * id would look like eml.200.2.3
694
     */
695
    public static String getDocIdWithoutRevFromInlineDataID(String inlineDataID)
696
    {
697
        String docidWithoutRev = null;
698
        if (inlineDataID == null) { return docidWithoutRev; }
699
        String seperator = MetaCatUtil.getOption("accNumSeparator");
700
        char charSeperator = seperator.charAt(0);
701
        int targetNumberOfSeperator = 2;// we want to know his index
702
        int numberOfSeperator = 0;
703
        for (int i = 0; i < inlineDataID.length(); i++) {
704
            // meet seperator, increase number of seperator
705
            if (inlineDataID.charAt(i) == charSeperator) {
706
                numberOfSeperator++;
707
            }
708
            // if number of seperator reach the target one, record the index(i)
709
            // and get substring and terminate the loop
710
            if (numberOfSeperator == targetNumberOfSeperator) {
711
                docidWithoutRev = inlineDataID.substring(0, i);
712
                break;
713
            }
714
        }
715

    
716
        logMetacat.info("Docid without rev from inlinedata id: "
717
                + docidWithoutRev);
718
        return docidWithoutRev;
719

    
720
    }
721

    
722
    /**
723
     * Revise stack change a stack to opposite order
724
     */
725
    public static Stack reviseStack(Stack stack)
726
    {
727
        Stack result = new Stack();
728
        // make sure the parameter is correct
729
        if (stack == null || stack.isEmpty()) {
730
            result = stack;
731
            return result;
732
        }
733

    
734
        while (!stack.isEmpty()) {
735
            Object obj = stack.pop();
736
            result.push(obj);
737
        }
738
        return result;
739
    }
740

    
741
    /** A method to replace whitespace in url */
742
    public static String replaceWhiteSpaceForURL(String urlHasWhiteSpace)
743
    {
744
        StringBuffer newUrl = new StringBuffer();
745
        String whiteSpaceReplace = "%20";
746
        if (urlHasWhiteSpace == null || urlHasWhiteSpace.trim().equals("")) { return null; }
747

    
748
        for (int i = 0; i < urlHasWhiteSpace.length(); i++) {
749
            char ch = urlHasWhiteSpace.charAt(i);
750
            if (!Character.isWhitespace(ch)) {
751
                newUrl.append(ch);
752
            } else {
753
                //it is white sapce, replace it by %20
754
                newUrl = newUrl.append(whiteSpaceReplace);
755
            }
756

    
757
        }//for
758
        logMetacat.info("The new string without space is:"
759
                + newUrl.toString());
760
        return newUrl.toString();
761

    
762
    }// replaceWhiteSpaceForUR
763

    
764
    /** 
765
     * A method to read administrators and moderators list from the metacat.properties 
766
     **/
767
    public static void getUserAccessControlLists(){
768
    	administrators = getListFromOption("administrators");
769
    	moderators = getListFromOption("moderators");
770
    	allowedSubmitters = getListFromOption("allowedSubmitters");
771
    	deniedSubmitters = getListFromOption("deniedSubmitters");
772
    }
773

    
774
    /** 
775
     * A method to read value of a given option from the metacat.properties 
776
     * into specified String array
777
     **/
778
    private static String[] getListFromOption(String optionName){
779
    	String[] list = null;
780
    	String listString = MetaCatUtil.getOption(optionName);
781
      
782
        try {
783
            if ( listString != null && !listString.trim().equals("")) {
784
            	list = listString.split(":");
785
            } else {
786
            	list = null;
787
            }
788
            
789
        } catch (PatternSyntaxException pse) {
790
        	list = null;
791
            logMetacat.error("Error in MetacatServlet.init: "
792
                + pse.getMessage());
793
        }
794
        return list;
795
    }
796
    
797
    /** 
798
     * A method to check if the specified user is part of the moderators list 
799
     **/
800
    private static boolean onList(String list[], String username, String[] groups){
801

    
802
    	if(list == null){
803
    		return false;
804
    	}
805

    
806
    	// Check that the user is authenticated as an administrator account
807
        for (int i = 0; i < list.length; i++) {
808
            // check the given admin dn is a group dn...
809
        	if(groups != null && list[i].startsWith("cn=")){
810
            	// is a group dn
811
        		for (int j = 0; j < groups.length; j++) {
812
        			if (groups[j].equals(list[i])) {
813
                		return true;
814
                	}	
815
        		}   		
816
            } else { 
817
            	// is a user dn
818
            	if (username != null && username.equals(list[i])) {
819
    	    		return true;
820
            	}	
821
            }
822
        }
823
        return false;
824
    }
825

    
826
    /** 
827
     * A method to check if the specified user is part of the administrators list 
828
     **/
829
    public static boolean isAdministrator(String username, String[] groups){
830
    	return (onList(administrators, username, groups));
831
    }
832
    
833
    /** 
834
     * A method to check if the specified user is part of the moderators list 
835
     **/
836
    public static boolean isModerator(String username, String[] groups){
837
    	return (onList(moderators, username, groups));
838
    }
839

    
840
    /** 
841
     * A method to check if the specified user is part of the moderators list 
842
     **/
843
    public static boolean isAllowedSubmitter(String username, String[] groups){
844
    	if(allowedSubmitters != null){
845
    		return (onList(allowedSubmitters, username, groups));
846
    	} else {
847
    		// no allowedSubmitters list specified - 
848
    		// hence everyone should be allowed
849
    		return true;
850
    	}
851
   }
852

    
853
    /** 
854
     * A method to check if the specified user is part of the moderators list 
855
     **/
856
    public static boolean isDeniedSubmitter(String username, String[] groups){
857
		return (onList(deniedSubmitters, username, groups));
858
    }
859
    
860
    /** 
861
     * A method to check if the specified user can insert the document 
862
     **/
863
    public static boolean canInsertOrUpdate(String username, String[] groups){
864
    	return (isAllowedSubmitter(username, groups) 
865
    			&& !isDeniedSubmitter(username, groups));
866
    }
867
}
(43-43/63)