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: barteau $'
9
 *     '$Date: 2008-01-10 11:08:29 -0800 (Thu, 10 Jan 2008) $'
10
 * '$Revision: 3673 $'
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 the given string. Taken from configXML.java */
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 -1 && 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
                         } else
302
                             str.append("&amp;");
303
                         /////////
304
                         break;
305
                     }
306
                     case '"':
307
                    	 str.append("&quot;");
308
                         break;
309
                    default: {
310
                         if ( (ch<128) && (ch>31) ) {
311
                             str.append(ch);
312
                         }
313
                         else if (ch<32) {
314
                             if (ch == 10) { // new line
315
                                 str.append(ch);
316
                             }
317
                             if (ch == 13) { // carriage return
318
                                 str.append(ch);
319
                             }
320
                             if (ch == 9) {  // tab
321
                                 str.append(ch);
322
                             }
323
                             // otherwise skip
324
                         }
325
                         else {
326
                             str.append("&#");
327
                             str.append(Integer.toString(ch));
328
                             str.append(';');
329
                         }
330
                     }
331
                 }
332
             }
333
             return str.toString();
334
    }
335

    
336
    /**
337
     * Get docid from online/url string
338
     */
339
    public static String getDocIdWithRevFromOnlineURL(String url)
340
    {
341
        String docid = null;
342
        String DOCID = "docid";
343
        boolean find = false;
344
        char limited = '&';
345
        int count = 0; //keep track how many & was found
346
        Vector list = new Vector();// keep index number for &
347
        if (url == null) {
348
            logMetacat.info("url is null and null will be returned");
349
            return docid;
350
        }
351
        // the first element in list is 0
352
        list.add(new Integer(0));
353
        for (int i = 0; i < url.length(); i++) {
354
            if (url.charAt(i) == limited) {
355
                // count plus 1
356
                count++;
357
                list.add(new Integer(i));
358
                // get substring beween two &
359
                String str = url.substring(
360
                        ((Integer) list.elementAt(count - 1)).intValue(), i);
361
                logMetacat.info("substring between two & is: " + str);
362
                //if the subString contains docid, we got it
363
                if (str.indexOf(DOCID) != -1) {
364
                    //get index of '="
365
                    int start = getIndexForGivenChar(str, '=') + 1;
366
                    int end = str.length();
367
                    docid = str.substring(start, end);
368
                    find = true;
369
                }//if
370
            }//if
371
        }//for
372
        //if not find, we need check the subtring between the index of last &
373
        // and
374
        // the end of string
375
        if (!find) {
376
            logMetacat.info("Checking the last substring");
377
            String str = url.substring(((Integer) list.elementAt(count))
378
                    .intValue() + 1, url.length());
379
            logMetacat.info("Last substring is: " + str);
380
            if (str.indexOf(DOCID) != -1) {
381
                //get index of '="
382
                int start = getIndexForGivenChar(str, '=') + 1;
383
                int end = str.length();
384
                docid = str.substring(start, end);
385
                find = true;
386
            }//if
387
        }//if
388
        logMetacat.info("The docid from online url is:" + docid);
389
        return docid.trim();
390
    }
391

    
392

    
393
    /**
394
     * Eocgorid identifier will look like: ecogrid://knb/tao.1.1
395
     * The AccessionNumber tao.1.1 will be returned. If the given doesn't
396
     * contains ecogrid, null will be returned.
397
     * @param identifier String
398
     * @return String
399
     */
400
    public static String getAccessionNumberFromEcogridIdentifier(String identifier)
401
    {
402
      String accessionNumber = null;
403
      if (identifier != null && identifier.startsWith(DBSAXHandler.ECOGRID))
404
      {
405
        // find the last "/" in identifier
406
        int indexOfLastSlash = identifier.lastIndexOf("/");
407
        int start = indexOfLastSlash+1;
408
        int end   = identifier.length();
409
        accessionNumber = identifier.substring(start, end);
410
      }
411
      logMetacat.warn("The accession number from url is " +
412
                                 accessionNumber);
413
      return accessionNumber;
414
    }
415

    
416
    private static int getIndexForGivenChar(String str, char character)
417
    {
418
        int index = -1;
419
        // make sure str is not null
420
        if (str == null) {
421
            logMetacat.info(
422
                    "The given str is null and -1 will be returned");
423
            return index;
424
        }
425
        // got though the string
426
        for (int i = 0; i < str.length(); i++) {
427
            // find the first one then break the loop
428
            if (str.charAt(i) == character) {
429
                index = i;
430
                break;
431
            }//if
432
        }//for
433
        logMetacat.info("the index for char " + character + " is: "
434
                + index);
435
        return index;
436
    }
437

    
438
    /**
439
     * Utility method to get docid from a given string
440
     *
441
     * @param string, the given string should be these two format: 1) str1.str2
442
     *            in this case docid= str1.str2 2) str1.str2.str3, in this case
443
     *            docid =str1.str2
444
     * @param the sperator char
445
     */
446
    public static String getDocIdFromString(String str)
447
    {
448
        String docId = null;
449
        if (str == null) {
450
            logMetacat.info(
451
                    "The given str is null and null will be returned"
452
                            + " in getDocIdfromString");
453
            return docId;
454
        } //make sure docid is not null
455
        int dotNumber = 0;//count how many dots in given string
456
        int indexOfLastDot = 0;
457

    
458
        //assume that seperator is one charactor string
459
        char seperator = getOption("accNumSeparator").charAt(0);
460

    
461
        for (int i = 0; i < str.length(); i++) {
462
            if (str.charAt(i) == seperator) {
463
                dotNumber++;//count how many dots
464
                indexOfLastDot = i;//keep the last dot postion
465
            }
466
        }//for
467

    
468
        //The string formatt is wrong, because it has more than two or less
469
        // than
470
        //one seperator
471
        if (dotNumber > 2 || dotNumber < 1) {
472
            docId = null;
473
        } else if (dotNumber == 2) //the case for str1.str2.str3
474
        {
475
            docId = str.substring(0, indexOfLastDot);
476
        } else if (dotNumber == 1) //the case for str1.str2
477
        {
478
            docId = str;
479
        }
480

    
481
        return docId;
482
    }//getDocIdFromString
483

    
484
    /**
485
     * Utility method to get version number from a given string
486
     *
487
     * @param string, the given string should be these two format: 1)
488
     *            str1.str2(no version) version =-1; 2) str1.str2.str3, in this
489
     *            case version = str3; 3) other, vresion =-2
490
     */
491
    public static int getVersionFromString(String str)
492
            throws NumberFormatException
493
    {
494
        int version = -1;
495
        String versionString = null;
496
        int dotNumber = 0;//count how many dots in given string
497
        int indexOfLastDot = 0;
498

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

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

    
509
        //The string formatt is wrong, because it has more than two or less
510
        // than
511
        //one seperator
512
        if (dotNumber > 2 || dotNumber < 1) {
513
            version = -2;
514
        } else if (dotNumber == 2 && (indexOfLastDot != (str.length() - 1)))
515
        //the case for str1.str2.str3
516
        {
517
            versionString = str.substring((indexOfLastDot + 1), str.length());
518
            version = Integer.parseInt(versionString);
519
        } else if (dotNumber == 1) //the case for str1.str2
520
        {
521
            version = -1;
522
        }
523

    
524
        return version;
525
    }//getVersionFromString
526

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

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

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

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

    
566
        return versionString;
567
    }//getVersionFromString
568

    
569
    /**
570
     * This method will get docid from an AccessionNumber. There is no
571
     * assumption the accessnumber will be str1.str2.str3. It can be more. So
572
     * we think the docid will be get rid of last part
573
     */
574
    public static String getDocIdFromAccessionNumber(String accessionNumber)
575
    {
576
        String docid = null;
577
        if (accessionNumber == null) { return docid; }
578
        String seperator = getOption("accNumSeparator");
579
        int indexOfLastSeperator = accessionNumber.lastIndexOf(seperator);
580
        docid = accessionNumber.substring(0, indexOfLastSeperator);
581
        logMetacat.info("after parsing accessionnumber, docid is "
582
                + docid);
583
        return docid;
584
    }
585

    
586
    /**
587
     * This method will get inline data id without the revision number.
588
     * So if inlineData.1.2 is passed as input, inlineData.2 is returned.
589
     */
590
    public static String getInlineDataIdWithoutRev(String accessionNumber)
591
    {
592
        String docid = null;
593
        if (accessionNumber == null) { return docid; }
594
        String seperator = getOption("accNumSeparator");
595
        int indexOfLastSeperator = accessionNumber.lastIndexOf(seperator);
596
        String version = accessionNumber.substring(indexOfLastSeperator,
597
                                                   accessionNumber.length());
598
        accessionNumber = accessionNumber.substring(0, indexOfLastSeperator);
599
        indexOfLastSeperator = accessionNumber.lastIndexOf(seperator);
600
        docid = accessionNumber.substring(0, indexOfLastSeperator) + version;
601
        logMetacat.info("after parsing accessionnumber, docid is "
602
                                 + docid);
603

    
604
        return docid;
605
    }
606

    
607
    /**
608
     * This method will call both getDocIdFromString and
609
     * getDocIdFromAccessionNumber. So first, if the string looks str1.str2,
610
     * the docid will be str1.str2. If the string is str1.str2.str3, the docid
611
     * will be str1.str2. If the string is str1.str2.str3.str4 or more, the
612
     * docid will be str1.str2.str3. If the string look like str1, null will be
613
     * returned
614
     *
615
     */
616
    public static String getSmartDocId(String str)
617
    {
618
        String docid = null;
619
        //call geDocIdFromString first.
620
        docid = getDocIdFromString(str);
621
        // If docid is null, try to call getDocIdFromAccessionNumber
622
        // it will handle the seperator more than2
623
        if (docid == null) {
624
            docid = getDocIdFromAccessionNumber(str);
625
        }
626
        logMetacat.info("The docid get from smart docid getor is "
627
                + docid);
628
        return docid;
629
    }
630

    
631
    /**
632
     * This method will get revision from an AccessionNumber. There is no
633
     * assumption the accessnumber will be str1.str2.str3. It can be more. So
634
     * we think the docid will be get rid of last part
635
     */
636
    public static int getRevisionFromAccessionNumber(String accessionNumber)
637
            throws NumberFormatException
638
    {
639
        String rev = null;
640
        int revNumber = -1;
641
        if (accessionNumber == null) { return revNumber; }
642
        String seperator = getOption("accNumSeparator");
643
        int indexOfLastSeperator = accessionNumber.lastIndexOf(seperator);
644
        rev = accessionNumber.substring(indexOfLastSeperator + 1,
645
                accessionNumber.length());
646
        revNumber = Integer.parseInt(rev);
647
        logMetacat.info("after parsing accessionnumber, rev is "
648
                + revNumber);
649
        return revNumber;
650
    }
651

    
652
    /**
653
     * Method to get the name of local replication server
654
     */
655
    public static String getLocalReplicationServerName()
656
    {
657
        String replicationServerName = null;
658
        String serverHost = null;
659
        serverHost = getOption("server");
660
        // append "context/servelet/replication" to the host name
661
        replicationServerName = serverHost.trim() + getOption("replicationpath").trim();
662
        return replicationServerName;
663

    
664
    }
665

    
666
    /**
667
     * Method to get docidwithrev from eml2 inline data id The eml inline data
668
     * id would look like eml.200.2.3
669
     */
670
    public static String getDocIdWithoutRevFromInlineDataID(String inlineDataID)
671
    {
672
        String docidWithoutRev = null;
673
        if (inlineDataID == null) { return docidWithoutRev; }
674
        String seperator = MetaCatUtil.getOption("accNumSeparator");
675
        char charSeperator = seperator.charAt(0);
676
        int targetNumberOfSeperator = 2;// we want to know his index
677
        int numberOfSeperator = 0;
678
        for (int i = 0; i < inlineDataID.length(); i++) {
679
            // meet seperator, increase number of seperator
680
            if (inlineDataID.charAt(i) == charSeperator) {
681
                numberOfSeperator++;
682
            }
683
            // if number of seperator reach the target one, record the index(i)
684
            // and get substring and terminate the loop
685
            if (numberOfSeperator == targetNumberOfSeperator) {
686
                docidWithoutRev = inlineDataID.substring(0, i);
687
                break;
688
            }
689
        }
690

    
691
        logMetacat.info("Docid without rev from inlinedata id: "
692
                + docidWithoutRev);
693
        return docidWithoutRev;
694

    
695
    }
696

    
697
    /**
698
     * Revise stack change a stack to opposite order
699
     */
700
    public static Stack reviseStack(Stack stack)
701
    {
702
        Stack result = new Stack();
703
        // make sure the parameter is correct
704
        if (stack == null || stack.isEmpty()) {
705
            result = stack;
706
            return result;
707
        }
708

    
709
        while (!stack.isEmpty()) {
710
            Object obj = stack.pop();
711
            result.push(obj);
712
        }
713
        return result;
714
    }
715

    
716
    /** A method to replace whitespace in url */
717
    public static String replaceWhiteSpaceForURL(String urlHasWhiteSpace)
718
    {
719
        StringBuffer newUrl = new StringBuffer();
720
        String whiteSpaceReplace = "%20";
721
        if (urlHasWhiteSpace == null || urlHasWhiteSpace.trim().equals("")) { return null; }
722

    
723
        for (int i = 0; i < urlHasWhiteSpace.length(); i++) {
724
            char ch = urlHasWhiteSpace.charAt(i);
725
            if (!Character.isWhitespace(ch)) {
726
                newUrl.append(ch);
727
            } else {
728
                //it is white sapce, replace it by %20
729
                newUrl = newUrl.append(whiteSpaceReplace);
730
            }
731

    
732
        }//for
733
        logMetacat.info("The new string without space is:"
734
                + newUrl.toString());
735
        return newUrl.toString();
736

    
737
    }// replaceWhiteSpaceForUR
738

    
739
    /** 
740
     * A method to read administrators and moderators list from the metacat.properties 
741
     **/
742
    public static void getUserAccessControlLists(){
743
    	administrators = getListFromOption("administrators");
744
    	moderators = getListFromOption("moderators");
745
    	allowedSubmitters = getListFromOption("allowedSubmitters");
746
    	deniedSubmitters = getListFromOption("deniedSubmitters");
747
    }
748

    
749
    /** 
750
     * A method to read value of a given option from the metacat.properties 
751
     * into specified String array
752
     **/
753
    private static String[] getListFromOption(String optionName){
754
    	String[] list = null;
755
    	String listString = MetaCatUtil.getOption(optionName);
756
      
757
        try {
758
            if ( listString != null && !listString.trim().equals("")) {
759
            	list = listString.split(":");
760
            } else {
761
            	list = null;
762
            }
763
            
764
        } catch (PatternSyntaxException pse) {
765
        	list = null;
766
            logMetacat.error("Error in MetacatServlet.init: "
767
                + pse.getMessage());
768
        }
769
        return list;
770
    }
771
    
772
    /** 
773
     * A method to check if the specified user is part of the moderators list 
774
     **/
775
    private static boolean onList(String list[], String username, String[] groups){
776

    
777
    	if(list == null){
778
    		return false;
779
    	}
780

    
781
    	// Check that the user is authenticated as an administrator account
782
        for (int i = 0; i < list.length; i++) {
783
            // check the given admin dn is a group dn...
784
        	if(groups != null && list[i].startsWith("cn=")){
785
            	// is a group dn
786
        		for (int j = 0; j < groups.length; j++) {
787
        			if (groups[j].equals(list[i])) {
788
                		return true;
789
                	}	
790
        		}   		
791
            } else { 
792
            	// is a user dn
793
            	if (username != null && username.equals(list[i])) {
794
    	    		return true;
795
            	}	
796
            }
797
        }
798
        return false;
799
    }
800

    
801
    /** 
802
     * A method to check if the specified user is part of the administrators list 
803
     **/
804
    public static boolean isAdministrator(String username, String[] groups){
805
    	return (onList(administrators, username, groups));
806
    }
807
    
808
    /** 
809
     * A method to check if the specified user is part of the moderators list 
810
     **/
811
    public static boolean isModerator(String username, String[] groups){
812
    	return (onList(moderators, username, groups));
813
    }
814

    
815
    /** 
816
     * A method to check if the specified user is part of the moderators list 
817
     **/
818
    public static boolean isAllowedSubmitter(String username, String[] groups){
819
    	if(allowedSubmitters != null){
820
    		return (onList(allowedSubmitters, username, groups));
821
    	} else {
822
    		// no allowedSubmitters list specified - 
823
    		// hence everyone should be allowed
824
    		return true;
825
    	}
826
   }
827

    
828
    /** 
829
     * A method to check if the specified user is part of the moderators list 
830
     **/
831
    public static boolean isDeniedSubmitter(String username, String[] groups){
832
		return (onList(deniedSubmitters, username, groups));
833
    }
834
    
835
    /** 
836
     * A method to check if the specified user can insert the document 
837
     **/
838
    public static boolean canInsertOrUpdate(String username, String[] groups){
839
    	return (isAllowedSubmitter(username, groups) 
840
    			&& !isDeniedSubmitter(username, groups));
841
    }
842
    
843
    /**
844
     * Writes debug information into a file. In metacat.properties, if property writeDebugToFile is
845
     * set to true, the debug information will be written to debug file, which value is the property
846
     * debugOutputFile in metacat.properties.
847
     *
848
     */
849
    public static void writeDebugToFile(String debugInfo)
850
    {
851
    	String debug = MetaCatUtil.getOption("writeDebugToFile");
852
    	if (debug != null && debug.equalsIgnoreCase("true"))
853
    	{
854
    		 try
855
    		 {
856
    			 File outputFile = new File(MetaCatUtil.getOption("debugOutputFile"));   			 
857
    			 FileOutputStream fos = new FileOutputStream(outputFile, true);
858
                 PrintWriter pw = new PrintWriter(fos);
859
                 pw.println(debugInfo);
860
                 pw.flush();
861
                 pw.close();
862
    			 fos.close();
863
    			 
864
    		 }
865
    		 catch(Exception io)
866
    		 {
867
    			logMetacat.warn("Eorr in MetacatUtil.writeDebugToFile "+io.getMessage()) ;
868
    		 }
869
    	}
870
    	
871
    }
872
    
873
   /**
874
    *  Writes debug information into a file in delimitered format
875
    * @param debugInfo   the debug information
876
    * @param newLine    append the debug info to a line or not
877
    */
878
    public static void writeDebugToDelimiteredFile(String debugInfo, boolean newLine)
879
    {
880
    	String debug = MetaCatUtil.getOption("writeDebugToFile");
881
    	if (debug != null && debug.equalsIgnoreCase("true"))
882
    	{
883
    		 try
884
    		 {
885
    			 File outputFile = new File(MetaCatUtil.getOption("delimiteredOutputFile"));   			 
886
    			 FileOutputStream fos = new FileOutputStream(outputFile, true);
887
                 PrintWriter pw = new PrintWriter(fos);
888
                 if (newLine)
889
                 {
890
                     pw.println(debugInfo);
891
                 }
892
                 else
893
                 {
894
                	 pw.print(debugInfo);
895
                 }
896
                 pw.flush();
897
                 pw.close();
898
    			 fos.close();
899
    			 
900
    		 }
901
    		 catch(Exception io)
902
    		 {
903
    			logMetacat.warn("Eorr in writeDebugToDelimiteredFile "+io.getMessage()) ;
904
    		 }
905
    	}
906
    	
907
    }
908

    
909
		/**
910
     * Write the uploaded file to disk for temporary storage before moving it 
911
     * to its final Metacat location.
912
     *
913
     * @param  filePart          the FilePart object containing the file form element
914
     * @param  fileName          the name of the file to be written to disk
915
     * @return tempFilePath      a String containing location of temporary file
916
     */
917
    public static String writeTempFile (FilePart filePart, String fileName) {
918
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
919
        String tempFilePath = null;
920
        String tempDirPath = getOption("temp-dir");
921
        long fileSize;
922
        File tempFile;
923
        File tempDir;
924

    
925
        if ((fileName == null) || fileName.equals("")) {
926
            return tempFilePath;
927
        }
928
				
929
        // the tempfilepath token isn't set, use Java default
930
        if (tempDirPath == null) {
931
						String javaTempDir = System.getProperty("java.io.tempdir");
932
						if (javaTempDir == null) {
933
							  // no paths set, use unix default
934
								tempDirPath = "/tmp";
935
						} else {
936
								tempDirPath = javaTempDir;
937
						}
938
        }
939

    
940
        tempDir = new File(tempDirPath);
941

    
942
        // Create the temporary directory if it doesn't exist
943
        try {
944
            if (!tempDir.exists()) {
945
                tempDir.mkdirs();
946
            }
947
        } catch (SecurityException e) {
948
            logMetacat.error("Can't create directory: " + tempDir.getPath() +
949
                             ". Error: " + e.getMessage());
950
        }
951
        try {
952
            tempFile = new File(tempDirPath, fileName);
953
            fileSize = filePart.writeTo(tempFile);
954
            tempFilePath = tempDirPath + File.separator + fileName;
955

    
956
            if (fileSize == 0) {
957
                logMetacat.error("Uploaded file '" + fileName + "'is empty!");
958
            }
959
        } catch (IOException e) {
960
            logMetacat.error("IO exception which writing temporary file: " +
961
                             tempFilePath + " " + e.getMessage());
962
        }
963

    
964
        logMetacat.info("Temporary file is: " + tempFilePath);
965

    
966
        return tempFilePath;
967
    }
968
		
969
		/**
970
		 *
971
		 * Copy a file between two locations specified as strings.  Fails
972
     * if either path cannot be created. Based on the public domain
973
     * FileCopy class in _Java in a Nutshell_.
974
     *
975
		 * @param sourceName		the source file to read from disk
976
     * @param destName  		the destination file on disk
977
     */
978
    public static void copyFile(String sourceName, String destName) throws IOException {
979
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
980

    
981
        File sourceFile = new File(sourceName);
982
        File destFile = new File(destName);
983
        FileInputStream source = null;
984
        FileOutputStream dest = null;
985
        byte[] buffer;
986
        int bytesRead;
987

    
988
        try {
989
            if (!sourceFile.exists() || !sourceFile.isFile()) {
990
                logMetacat.error("File copy: no such source" +
991
                                 " file: " + sourceName);
992
            }
993
            if (!sourceFile.canRead()) {
994
                logMetacat.error("File copy: source file " +
995
                                 "is unreadable: " + sourceName);
996
            }
997

    
998
            if (destFile.exists()) {
999
                if (destFile.isFile()) {
1000
                    if (!destFile.canWrite()) {
1001
                        logMetacat.error("File copy: destination " +
1002
                                         "file is unwriteable: " + destFile);
1003
                    }
1004
                } else {
1005
                    logMetacat.error("File copy: destination file " +
1006
                                     "is not a file: " + destFile);
1007
                }
1008
            } else {
1009
                File parentDir = parent(destFile);
1010

    
1011
                if (!parentDir.exists())
1012
                {
1013
                    logMetacat.error("File copy: destination diretory " +
1014
                                     " doesn't exist: " + destName);
1015
                }
1016
                if (!parentDir.canWrite()) {
1017
                    logMetacat.error("File copy: destination directory " +
1018
                                     " is unwritable: " + destName);
1019
                }
1020
            }
1021

    
1022
            // Verbose error checking done, copy the file object
1023
            source = new FileInputStream(sourceFile);
1024
            dest = new FileOutputStream(destFile);
1025
            buffer = new byte[1024];
1026

    
1027
            while (true) {
1028
                bytesRead = source.read(buffer);
1029
                if (bytesRead == -1) {
1030
                    break;
1031
                }
1032
                dest.write(buffer, 0, bytesRead);
1033
            }
1034
        }
1035
        finally {
1036
            if (source != null) {
1037
                try { source.close(); } catch (IOException e) { ; }
1038
            }
1039
            if (dest != null) {
1040
                try { dest.close(); } catch (IOException e) { ; }
1041
            }
1042
        }
1043
    }
1044

    
1045
    private static File parent(File f) {
1046
        String dirname = f.getParent();
1047
        if (dirname == null) {
1048
            if (f.isAbsolute()) return new File(File.separator);
1049
            else return new File(System.getProperty("user.dir"));
1050
        }
1051
        return new File(dirname);
1052
    }
1053

    
1054
    /**
1055
     * Adds the Properties and skin to the list of skin configurations.
1056
     * @param skinName String qformat
1057
     * @param skinProperties Properties instance
1058
     */
1059
    public static void addSkinConfig(String skinName, Properties skinProperties) {
1060
        skinconfigs.put(skinName, skinProperties);
1061
    }
1062

    
1063
    /**
1064
     * Return the Properties for a given skin name.
1065
     * @param skinName String qformat
1066
     * @return Properties, or null if none exist for the skin.
1067
     */
1068
    public static Properties getSkinConfig(String skinName) {
1069
        Properties                      result;
1070
        
1071
        result = (Properties) skinconfigs.get(skinName);
1072
        return(result);
1073
    }
1074
    
1075
    /**
1076
     * Returns true if Properties exist for a given skin name, false otherwise.
1077
     * @param skinName String qformat
1078
     * @return boolean
1079
     */
1080
    public static boolean hasSkinConfig(String skinName) {
1081
        boolean                     result;
1082
        
1083
        result = skinconfigs.containsKey(skinName);
1084
        return(result);
1085
    }
1086
}
(45-45/66)