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: daigle $'
9
 *     '$Date: 2008-04-02 16:28:31 -0700 (Wed, 02 Apr 2008) $'
10
 * '$Revision: 3780 $'
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
        if (value == null) {
132
        	logMetacat.warn("Value for key: " + optionName + 
133
        			  " could not be retrieved from metacat properties.");
134
        }
135
        return value;
136
    }
137
    
138
    /**
139
     * Utility method to set an option value from the properties file
140
     *
141
     * @param optionName the name of the option requested
142
     */
143
    public static void setOption(String optionName, String newValue)
144
    {
145
        if (options == null) {
146
            options = edu.ucsb.nceas.utilities.Options.getInstance();
147
        }
148
        options.setOption(optionName, newValue);
149
        
150
    }
151

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

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

    
183
        String temp = "";
184
        boolean ampflag = true;
185
        boolean poundflag = false;
186
        int arrcount = 0;
187

    
188
        if (query != null) {
189
            for (int i = 0; i < query.length(); i++) {
190

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

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

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

    
263
    /** Normalizes a string read from DB. So it will be compatible to HTML */
264
    public static String normalize(String s)
265
    {
266
        StringBuffer str = new StringBuffer();
267

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

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

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

    
440

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

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

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

    
506
        //assume that seperator is one charactor string
507
        char seperator = getOption("accNumSeparator").charAt(0);
508

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

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

    
529
        return docId;
530
    }//getDocIdFromString
531

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

    
547
        //assume that seperator is one charactor string
548
        char seperator = getOption("accNumSeparator").charAt(0);
549

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

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

    
572
        return version;
573
    }//getVersionFromString
574

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

    
590
        //assume that seperator is one charactor string
591
        char seperator = getOption("accNumSeparator").charAt(0);
592

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

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

    
614
        return versionString;
615
    }//getVersionFromString
616

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

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

    
652
        return docid;
653
    }
654

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

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

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

    
712
    }
713

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

    
739
        logMetacat.info("Docid without rev from inlinedata id: "
740
                + docidWithoutRev);
741
        return docidWithoutRev;
742

    
743
    }
744

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

    
757
        while (!stack.isEmpty()) {
758
            Object obj = stack.pop();
759
            result.push(obj);
760
        }
761
        return result;
762
    }
763

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

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

    
780
        }//for
781
        logMetacat.info("The new string without space is:"
782
                + newUrl.toString());
783
        return newUrl.toString();
784

    
785
    }// replaceWhiteSpaceForUR
786

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

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

    
825
    	if(list == null){
826
    		return false;
827
    	}
828

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

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

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

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

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

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

    
988
        tempDir = new File(tempDirPath);
989

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

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

    
1012
        logMetacat.info("Temporary file is: " + tempFilePath);
1013

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

    
1029
        File sourceFile = new File(sourceName);
1030
        File destFile = new File(destName);
1031
        FileInputStream source = null;
1032
        FileOutputStream dest = null;
1033
        byte[] buffer;
1034
        int bytesRead;
1035

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

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

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

    
1070
            // Verbose error checking done, copy the file object
1071
            source = new FileInputStream(sourceFile);
1072
            dest = new FileOutputStream(destFile);
1073
            buffer = new byte[1024];
1074

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

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

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

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