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
 *
8
 *   '$Author: tao $'
9
 *     '$Date: 2008-03-05 17:08:30 -0800 (Wed, 05 Mar 2008) $'
10
 * '$Revision: 3759 $'
11
 *
12
 * This program is free software; you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License as published by
14
 * the Free Software Foundation; either version 2 of the License, or
15
 * (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU General Public License
23
 * along with this program; if not, write to the Free Software
24
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25
 */
26

    
27
package edu.ucsb.nceas.metacat;
28

    
29
import java.io.File;
30
import java.io.FileInputStream;
31
import java.io.FileOutputStream;
32
import java.io.FileWriter;
33
import java.io.IOException;
34
import java.io.PrintWriter;
35
import java.io.StringReader;
36
import java.net.MalformedURLException;
37
import java.net.URL;
38
import java.text.SimpleDateFormat;
39
import java.util.HashMap;
40
import java.util.Hashtable;
41
import java.util.Properties;
42
import java.util.Stack;
43
import java.util.Vector;
44
import java.util.regex.PatternSyntaxException;
45

    
46
import org.apache.log4j.Logger;
47

    
48
import com.oreilly.servlet.multipart.FilePart;
49

    
50
import edu.ucsb.nceas.dbadapter.AbstractDatabase;
51
import edu.ucsb.nceas.utilities.Options;
52

    
53
/**
54
 * A suite of utility classes for the metadata catalog server
55
 */
56
public class MetaCatUtil
57
{
58

    
59
    public static AbstractDatabase dbAdapter;
60

    
61
    public static Vector pathsForIndexing;
62
    
63
    private static HashMap skinconfigs = new HashMap();
64

    
65
    private static edu.ucsb.nceas.utilities.Options options = null;
66

    
67
    private static boolean debug = true;
68
    
69
    private static String[] administrators;
70
    
71
    private static String[] moderators;
72

    
73
    private static String[] allowedSubmitters;
74

    
75
    private static String[] deniedSubmitters;
76
    
77
    private static Logger logMetacat = Logger.getLogger(MetaCatUtil.class);
78

    
79
    static {
80
    	// Determine our db adapter class and create an instance of that class
81
        try {
82
            dbAdapter = (AbstractDatabase) createObject(getOption("dbAdapter"));
83
        } catch (Exception e) {
84
            System.err.println("Error in MetaCatUtil static block:"
85
                    + e.getMessage());
86
            e.printStackTrace();
87
        }
88

    
89
        // read administrator and moderator lists from metacat.properties
90
        getUserAccessControlLists();
91
    }
92
    
93
    /**
94
     * Instantiate a class using the name of the class at runtime
95
     *
96
     * @param className the fully qualified name of the class to instantiate
97
     */
98
    public static Object createObject(String className) throws Exception
99
    {
100

    
101
        Object object = null;
102
        try {
103
            Class classDefinition = Class.forName(className);
104
            object = classDefinition.newInstance();
105
        } catch (InstantiationException e) {
106
            throw e;
107
        } catch (IllegalAccessException e) {
108
            throw e;
109
        } catch (ClassNotFoundException e) {
110
            throw e;
111
        }
112
        return object;
113
    }
114

    
115
    /**
116
     * Utility method to get an option value from the properties file
117
     *
118
     * @param optionName the name of the option requested
119
     * @return the String value for the option, or null if not set
120
     */
121
    public static String getOption(String optionName)
122
    {
123
        if (options == null) {
124
            options = edu.ucsb.nceas.utilities.Options.getInstance();
125
        }
126
        if (options == null) {
127
            Logger logMetacat = Logger.getLogger(MetaCatUtil.class);
128
        	logMetacat.info("options is null");
129
        }
130
        String value = options.getOption(optionName);
131
        return value;
132
    }
133
    
134
    /**
135
     * Utility method to set an option value from the properties file
136
     *
137
     * @param optionName the name of the option requested
138
     */
139
    public static void setOption(String optionName, String newValue)
140
    {
141
        if (options == null) {
142
            options = edu.ucsb.nceas.utilities.Options.getInstance();
143
        }
144
        options.setOption(optionName, newValue);
145
        
146
    }
147

    
148
    /** Utility method to convert a file handle into a URL */
149
    public static URL fileToURL(File file)
150
    {
151
        String path = file.getAbsolutePath();
152
        String fSep = System.getProperty("file.separator");
153
        if (fSep != null && fSep.length() == 1)
154
                path = path.replace(fSep.charAt(0), '/');
155
        if (path.length() > 0 && path.charAt(0) != '/') path = '/' + path;
156
        try {
157
            return new URL("file", null, path);
158
        } catch (java.net.MalformedURLException e) {
159
            /*
160
             * According to the spec this could only happen if the file
161
             */
162
            throw new Error("unexpected MalformedURLException");
163
        }
164
    }
165

    
166
    /**
167
     * Utility method to parse the query part of a URL into parameters. This
168
     * method assumes the format of the query par tof the url is an ampersand
169
     * separated list of name/value pairs, with equal signs separating the name
170
     * from the value (e.g., name=tom&zip=99801 ). Returns a has of the name
171
     * value pairs, hashed on name.
172
     */
173
    public static Hashtable parseQuery(String query)
174
            throws MalformedURLException
175
    {
176
        String[][] params = new String[200][2];
177
        Hashtable parameters = new Hashtable();
178

    
179
        String temp = "";
180
        boolean ampflag = true;
181
        boolean poundflag = false;
182
        int arrcount = 0;
183

    
184
        if (query != null) {
185
            for (int i = 0; i < query.length(); i++) {
186

    
187
                // go throught the remainder of the query one character at a
188
                // time.
189
                if (query.charAt(i) == '=') {
190
                    // if the current char is a # then the preceding should be
191
                    // a name
192
                    if (!poundflag && ampflag) {
193
                        params[arrcount][0] = temp.trim();
194
                        temp = "";
195
                    } else {
196
                        //if there are two #s or &s in a row throw an
197
                        // exception.
198
                        throw new MalformedURLException(
199
                                "metacatURL: Two parameter names "
200
                                        + "not allowed in sequence");
201
                    }
202
                    poundflag = true;
203
                    ampflag = false;
204
                } else if (query.charAt(i) == '&' || i == query.length() - 1) {
205
                    //the text preceding the & should be the param value.
206
                    if (i == query.length() - 1) {
207
                        //if at the end of the string grab the last value and
208
                        // append it.
209
                        if (query.charAt(i) != '=') {
210
                            //ignore an extra & on the end of the string
211
                            temp += query.charAt(i);
212
                        }
213
                    }
214

    
215
                    if (!ampflag && poundflag) {
216
                        params[arrcount][1] = temp.trim();
217
                        parameters
218
                                .put(params[arrcount][0], params[arrcount][1]);
219
                        temp = "";
220
                        arrcount++; //increment the array to the next row.
221
                    } else {
222
                        //if there are two =s or &s in a row through an
223
                        // exception
224
                        throw new MalformedURLException(
225
                                "metacatURL: Two parameter values "
226
                                        + "not allowed in sequence");
227
                    }
228
                    poundflag = false;
229
                    ampflag = true;
230
                } else {
231
                    //get the next character in the string
232
                    temp += query.charAt(i);
233
                }
234
            }
235
        }
236
        return parameters;
237
    }
238
  
239
    public static Vector getOptionList(String optiontext)
240
    {
241
        Vector optionsVector = new Vector();
242
        if (optiontext.indexOf(",") == -1) {
243
            optionsVector.addElement(optiontext);
244
            return optionsVector;
245
        }
246

    
247
        while (optiontext.indexOf(",") != -1) {
248
            String s = optiontext.substring(0, optiontext.indexOf(","));
249
            optionsVector.addElement(s.trim());
250
            optiontext = optiontext.substring(optiontext.indexOf(",") + 1,
251
                    optiontext.length());
252
            if (optiontext.indexOf(",") == -1) { //catch the last list entry
253
                optionsVector.addElement(optiontext.trim());
254
            }
255
        }
256
        return optionsVector;
257
    }
258

    
259
    /** Normalizes a string read from DB. So it will be compatible to HTML */
260
    public static String normalize(String s)
261
    {
262
        StringBuffer str = new StringBuffer();
263

    
264
             int len = (s != null) ? s.length() : 0;
265
             for (int i = 0; i < len; i++) {
266
                 char ch = s.charAt(i);
267
                 switch (ch) {
268
                     case '<': {
269
                         str.append("&lt;");
270
                         break;
271
                     }
272
                     case '>': {
273
                         str.append("&gt;");
274
                         break;
275
                     }
276
                     case '&': {
277
                         /*
278
                          * patch provided by Johnoel Ancheta from U of Hawaii
279
                          */
280
                         // check if & is for a character reference &#xnnnn;
281
                         if (i + 1 < len - 1 && s.charAt(i + 1) == '#') {
282
                             str.append("&#");
283
                             i += 2;
284

    
285
                             ch = s.charAt(i);
286
                             while (i < len && ch != ';') {
287
                                 str.append(ch);
288
                                 i++;
289
                                 ch = s.charAt(i);
290
                             }
291
                             str.append(';');
292
                         } else 
293
                         // check if & is in front of amp; 
294
                         // (we dont yet check for other HTML 4.0 Character entities) 
295
                         if (i + 4 < len  && s.charAt(i + 1) == 'a' 
296
                        	 && s.charAt(i + 2) == 'm' 
297
                        		 && s.charAt(i + 3) == 'p' 
298
                        			 && s.charAt(i + 4) == ';'){
299
                             str.append("&amp;");
300
                             i += 4;                        	 
301
                         }
302
                         else  if (i + 3 < len && s.charAt(i + 1) == 'l' 
303
                        	 && s.charAt(i + 2) == 't' 
304
                        		 && s.charAt(i + 3) == ';' ){
305
                    	  // check if & is in front of it; 
306
                             str.append("&lt;");
307
                             i += 3;                        	 
308
                         } 
309
                         else  if (i + 3 < len && s.charAt(i + 1) == 'g' 
310
                        	 && s.charAt(i + 2) == 't' 
311
                        		 && s.charAt(i + 3) == ';' ){
312
                    	  // check if & is in front of gt; 
313
                           // (we dont yet check for other HTML 4.0 Character entities) 
314
                             str.append("&gt;");
315
                             i += 3;                        	 
316
                         } 
317
                         else  if (i + 5 < len && s.charAt(i + 1) == 'q' 
318
                        	 && s.charAt(i + 2) == 'u' 
319
                        		 && s.charAt(i + 3) == 'o' 
320
                        	 && s.charAt(i + 4) == 't'
321
                        	 && s.charAt(i + 5) == ';')
322
                             {
323
                    	   // check if & is in front of quot; 
324
                           // (we dont yet check for other HTML 4.0 Character entities) 
325
                             str.append("&quot;");
326
                             i += 5;                        	 
327
                         } 
328
                         else  if (i + 5 < len && s.charAt(i + 1) == 'a' 
329
                        	 && s.charAt(i + 2) == 'p' 
330
                        		 && s.charAt(i + 3) == 'o' 
331
                        	 && s.charAt(i + 4) == 's'
332
                        	 && s.charAt(i + 5) == ';')
333
                             {
334
                    	   // check if & is in front of apostrophe; 
335
                           // (we dont yet check for other HTML 4.0 Character entities) 
336
                             str.append("&apos;");
337
                             i += 5;                        	 
338
                         } 
339
                         else{
340
                             str.append("&amp;");
341
                         }
342
                         /////////
343
                         break;
344
                     }
345
                     case '"':
346
                    	 str.append("&quot;");
347
                         break;
348
                     case '\'':
349
                    	 str.append("&apos;");
350
                         break;
351
                    default: {
352
                         if ( (ch<128) && (ch>31) ) {
353
                             str.append(ch);
354
                         }
355
                         else if (ch<32) {
356
                             if (ch == 10) { // new line
357
                                 str.append(ch);
358
                             }
359
                             if (ch == 13) { // carriage return
360
                                 str.append(ch);
361
                             }
362
                             if (ch == 9) {  // tab
363
                                 str.append(ch);
364
                             }
365
                             // otherwise skip
366
                         }
367
                         else {
368
                        	 //Don't transfer special character to numeric entity
369
                             /*str.append("&#");
370
                             str.append(Integer.toString(ch));
371
                             str.append(';');*/
372
                             str.append(ch);
373
                         }
374
                     }
375
                 }
376
             }
377
             return str.toString();
378
    }
379

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

    
436

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

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

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

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

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

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

    
525
        return docId;
526
    }//getDocIdFromString
527

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

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

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

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

    
568
        return version;
569
    }//getVersionFromString
570

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

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

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

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

    
610
        return versionString;
611
    }//getVersionFromString
612

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

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

    
648
        return docid;
649
    }
650

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

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

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

    
708
    }
709

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

    
735
        logMetacat.info("Docid without rev from inlinedata id: "
736
                + docidWithoutRev);
737
        return docidWithoutRev;
738

    
739
    }
740

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

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

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

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

    
776
        }//for
777
        logMetacat.info("The new string without space is:"
778
                + newUrl.toString());
779
        return newUrl.toString();
780

    
781
    }// replaceWhiteSpaceForUR
782

    
783
    /** 
784
     * A method to read administrators and moderators list from the metacat.properties 
785
     **/
786
    public static void getUserAccessControlLists(){
787
    	administrators = getListFromOption("administrators");
788
    	moderators = getListFromOption("moderators");
789
    	allowedSubmitters = getListFromOption("allowedSubmitters");
790
    	deniedSubmitters = getListFromOption("deniedSubmitters");
791
    }
792

    
793
    /** 
794
     * A method to read value of a given option from the metacat.properties 
795
     * into specified String array
796
     **/
797
    private static String[] getListFromOption(String optionName){
798
    	String[] list = null;
799
    	String listString = MetaCatUtil.getOption(optionName);
800
      
801
        try {
802
            if ( listString != null && !listString.trim().equals("")) {
803
            	list = listString.split(":");
804
            } else {
805
            	list = null;
806
            }
807
            
808
        } catch (PatternSyntaxException pse) {
809
        	list = null;
810
            logMetacat.error("Error in MetacatServlet.init: "
811
                + pse.getMessage());
812
        }
813
        return list;
814
    }
815
    
816
    /** 
817
     * A method to check if the specified user is part of the moderators list 
818
     **/
819
    private static boolean onList(String list[], String username, String[] groups){
820

    
821
    	if(list == null){
822
    		return false;
823
    	}
824

    
825
    	// Check that the user is authenticated as an administrator account
826
        for (int i = 0; i < list.length; i++) {
827
            // check the given admin dn is a group dn...
828
        	if(groups != null && list[i].startsWith("cn=")){
829
            	// is a group dn
830
        		for (int j = 0; j < groups.length; j++) {
831
        			if (groups[j].equals(list[i])) {
832
                		return true;
833
                	}	
834
        		}   		
835
            } else { 
836
            	// is a user dn
837
            	if (username != null && username.equals(list[i])) {
838
    	    		return true;
839
            	}	
840
            }
841
        }
842
        return false;
843
    }
844

    
845
    /** 
846
     * A method to check if the specified user is part of the administrators list 
847
     **/
848
    public static boolean isAdministrator(String username, String[] groups){
849
    	return (onList(administrators, username, groups));
850
    }
851
    
852
    /** 
853
     * A method to check if the specified user is part of the moderators list 
854
     **/
855
    public static boolean isModerator(String username, String[] groups){
856
    	return (onList(moderators, username, groups));
857
    }
858

    
859
    /** 
860
     * A method to check if the specified user is part of the moderators list 
861
     **/
862
    public static boolean isAllowedSubmitter(String username, String[] groups){
863
    	if(allowedSubmitters != null){
864
    		return (onList(allowedSubmitters, username, groups));
865
    	} else {
866
    		// no allowedSubmitters list specified - 
867
    		// hence everyone should be allowed
868
    		return true;
869
    	}
870
   }
871

    
872
    /** 
873
     * A method to check if the specified user is part of the moderators list 
874
     **/
875
    public static boolean isDeniedSubmitter(String username, String[] groups){
876
		return (onList(deniedSubmitters, username, groups));
877
    }
878
    
879
    /** 
880
     * A method to check if the specified user can insert the document 
881
     **/
882
    public static boolean canInsertOrUpdate(String username, String[] groups){
883
    	return (isAllowedSubmitter(username, groups) 
884
    			&& !isDeniedSubmitter(username, groups));
885
    }
886
    
887
    /**
888
     * Writes debug information into a file. In metacat.properties, if property writeDebugToFile is
889
     * set to true, the debug information will be written to debug file, which value is the property
890
     * debugOutputFile in metacat.properties.
891
     *
892
     */
893
    public static void writeDebugToFile(String debugInfo)
894
    {
895
    	String debug = MetaCatUtil.getOption("writeDebugToFile");
896
    	if (debug != null && debug.equalsIgnoreCase("true"))
897
    	{
898
    		 try
899
    		 {
900
    			 File outputFile = new File(MetaCatUtil.getOption("debugOutputFile"));   			 
901
    			 FileOutputStream fos = new FileOutputStream(outputFile, true);
902
                 PrintWriter pw = new PrintWriter(fos);
903
                 pw.println(debugInfo);
904
                 pw.flush();
905
                 pw.close();
906
    			 fos.close();
907
    			 
908
    		 }
909
    		 catch(Exception io)
910
    		 {
911
    			logMetacat.warn("Eorr in MetacatUtil.writeDebugToFile "+io.getMessage()) ;
912
    		 }
913
    	}
914
    	
915
    }
916
    
917
   /**
918
    *  Writes debug information into a file in delimitered format
919
    * @param debugInfo   the debug information
920
    * @param newLine    append the debug info to a line or not
921
    */
922
    public static void writeDebugToDelimiteredFile(String debugInfo, boolean newLine)
923
    {
924
    	String debug = MetaCatUtil.getOption("writeDebugToFile");
925
    	if (debug != null && debug.equalsIgnoreCase("true"))
926
    	{
927
    		 try
928
    		 {
929
    			 File outputFile = new File(MetaCatUtil.getOption("delimiteredOutputFile"));   			 
930
    			 FileOutputStream fos = new FileOutputStream(outputFile, true);
931
                 PrintWriter pw = new PrintWriter(fos);
932
                 if (newLine)
933
                 {
934
                     pw.println(debugInfo);
935
                 }
936
                 else
937
                 {
938
                	 pw.print(debugInfo);
939
                 }
940
                 pw.flush();
941
                 pw.close();
942
    			 fos.close();
943
    			 
944
    		 }
945
    		 catch(Exception io)
946
    		 {
947
    			logMetacat.warn("Eorr in writeDebugToDelimiteredFile "+io.getMessage()) ;
948
    		 }
949
    	}
950
    	
951
    }
952

    
953
		/**
954
     * Write the uploaded file to disk for temporary storage before moving it 
955
     * to its final Metacat location.
956
     *
957
     * @param  filePart          the FilePart object containing the file form element
958
     * @param  fileName          the name of the file to be written to disk
959
     * @return tempFilePath      a String containing location of temporary file
960
     */
961
    public static String writeTempFile (FilePart filePart, String fileName) {
962
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
963
        String tempFilePath = null;
964
        String tempDirPath = getOption("temp-dir");
965
        long fileSize;
966
        File tempFile;
967
        File tempDir;
968

    
969
        if ((fileName == null) || fileName.equals("")) {
970
            return tempFilePath;
971
        }
972
				
973
        // the tempfilepath token isn't set, use Java default
974
        if (tempDirPath == null) {
975
						String javaTempDir = System.getProperty("java.io.tempdir");
976
						if (javaTempDir == null) {
977
							  // no paths set, use unix default
978
								tempDirPath = "/tmp";
979
						} else {
980
								tempDirPath = javaTempDir;
981
						}
982
        }
983

    
984
        tempDir = new File(tempDirPath);
985

    
986
        // Create the temporary directory if it doesn't exist
987
        try {
988
            if (!tempDir.exists()) {
989
                tempDir.mkdirs();
990
            }
991
        } catch (SecurityException e) {
992
            logMetacat.error("Can't create directory: " + tempDir.getPath() +
993
                             ". Error: " + e.getMessage());
994
        }
995
        try {
996
            tempFile = new File(tempDirPath, fileName);
997
            fileSize = filePart.writeTo(tempFile);
998
            tempFilePath = tempDirPath + File.separator + fileName;
999

    
1000
            if (fileSize == 0) {
1001
                logMetacat.error("Uploaded file '" + fileName + "'is empty!");
1002
            }
1003
        } catch (IOException e) {
1004
            logMetacat.error("IO exception which writing temporary file: " +
1005
                             tempFilePath + " " + e.getMessage());
1006
        }
1007

    
1008
        logMetacat.info("Temporary file is: " + tempFilePath);
1009

    
1010
        return tempFilePath;
1011
    }
1012
		
1013
		/**
1014
		 *
1015
		 * Copy a file between two locations specified as strings.  Fails
1016
     * if either path cannot be created. Based on the public domain
1017
     * FileCopy class in _Java in a Nutshell_.
1018
     *
1019
		 * @param sourceName		the source file to read from disk
1020
     * @param destName  		the destination file on disk
1021
     */
1022
    public static void copyFile(String sourceName, String destName) throws IOException {
1023
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
1024

    
1025
        File sourceFile = new File(sourceName);
1026
        File destFile = new File(destName);
1027
        FileInputStream source = null;
1028
        FileOutputStream dest = null;
1029
        byte[] buffer;
1030
        int bytesRead;
1031

    
1032
        try {
1033
            if (!sourceFile.exists() || !sourceFile.isFile()) {
1034
                logMetacat.error("File copy: no such source" +
1035
                                 " file: " + sourceName);
1036
            }
1037
            if (!sourceFile.canRead()) {
1038
                logMetacat.error("File copy: source file " +
1039
                                 "is unreadable: " + sourceName);
1040
            }
1041

    
1042
            if (destFile.exists()) {
1043
                if (destFile.isFile()) {
1044
                    if (!destFile.canWrite()) {
1045
                        logMetacat.error("File copy: destination " +
1046
                                         "file is unwriteable: " + destFile);
1047
                    }
1048
                } else {
1049
                    logMetacat.error("File copy: destination file " +
1050
                                     "is not a file: " + destFile);
1051
                }
1052
            } else {
1053
                File parentDir = parent(destFile);
1054

    
1055
                if (!parentDir.exists())
1056
                {
1057
                    logMetacat.error("File copy: destination diretory " +
1058
                                     " doesn't exist: " + destName);
1059
                }
1060
                if (!parentDir.canWrite()) {
1061
                    logMetacat.error("File copy: destination directory " +
1062
                                     " is unwritable: " + destName);
1063
                }
1064
            }
1065

    
1066
            // Verbose error checking done, copy the file object
1067
            source = new FileInputStream(sourceFile);
1068
            dest = new FileOutputStream(destFile);
1069
            buffer = new byte[1024];
1070

    
1071
            while (true) {
1072
                bytesRead = source.read(buffer);
1073
                if (bytesRead == -1) {
1074
                    break;
1075
                }
1076
                dest.write(buffer, 0, bytesRead);
1077
            }
1078
        }
1079
        finally {
1080
            if (source != null) {
1081
                try { source.close(); } catch (IOException e) { ; }
1082
            }
1083
            if (dest != null) {
1084
                try { dest.close(); } catch (IOException e) { ; }
1085
            }
1086
        }
1087
    }
1088

    
1089
    private static File parent(File f) {
1090
        String dirname = f.getParent();
1091
        if (dirname == null) {
1092
            if (f.isAbsolute()) return new File(File.separator);
1093
            else return new File(System.getProperty("user.dir"));
1094
        }
1095
        return new File(dirname);
1096
    }
1097

    
1098
    /**
1099
     * Adds the Properties and skin to the list of skin configurations.
1100
     * @param skinName String qformat
1101
     * @param skinProperties Properties instance
1102
     */
1103
    public static void addSkinConfig(String skinName, Properties skinProperties) {
1104
        skinconfigs.put(skinName, skinProperties);
1105
    }
1106

    
1107
    /**
1108
     * Return the Properties for a given skin name.
1109
     * @param skinName String qformat
1110
     * @return Properties, or null if none exist for the skin.
1111
     */
1112
    public static Properties getSkinConfig(String skinName) {
1113
        Properties                      result;
1114
        
1115
        result = (Properties) skinconfigs.get(skinName);
1116
        return(result);
1117
    }
1118
    
1119
    /**
1120
     * Returns true if Properties exist for a given skin name, false otherwise.
1121
     * @param skinName String qformat
1122
     * @return boolean
1123
     */
1124
    public static boolean hasSkinConfig(String skinName) {
1125
        boolean                     result;
1126
        
1127
        result = skinconfigs.containsKey(skinName);
1128
        return(result);
1129
    }
1130
}
(43-43/64)