Project

General

Profile

1 51 jones
/**
2 203 jones
 *  '$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 309 bojilova
 *    Authors: Matt Jones, Jivka Bojilova
7 1538 berkley
 *
8 203 jones
 *   '$Author$'
9
 *     '$Date$'
10
 * '$Revision$'
11 669 jones
 *
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 51 jones
 */
26
27
package edu.ucsb.nceas.metacat;
28
29 185 jones
import java.io.File;
30 3420 walbridge
import java.io.FileInputStream;
31 3269 tao
import java.io.FileOutputStream;
32
import java.io.FileWriter;
33 3420 walbridge
import java.io.IOException;
34 3269 tao
import java.io.PrintWriter;
35
import java.io.StringReader;
36 2068 jones
import java.net.MalformedURLException;
37 185 jones
import java.net.URL;
38 3269 tao
import java.text.SimpleDateFormat;
39 2893 sgarg
import java.util.HashMap;
40 309 bojilova
import java.util.Hashtable;
41 3673 barteau
import java.util.Properties;
42 1545 tao
import java.util.Stack;
43 887 berkley
import java.util.Vector;
44 2558 sgarg
import java.util.regex.PatternSyntaxException;
45 50 jones
46 2591 sgarg
import org.apache.log4j.Logger;
47
48 3420 walbridge
import com.oreilly.servlet.multipart.FilePart;
49
50 777 bojilova
import edu.ucsb.nceas.dbadapter.AbstractDatabase;
51 1951 jones
import edu.ucsb.nceas.utilities.Options;
52 747 bojilova
53 50 jones
/**
54
 * A suite of utility classes for the metadata catalog server
55
 */
56 2068 jones
public class MetaCatUtil
57
{
58 50 jones
59 2068 jones
    public static AbstractDatabase dbAdapter;
60 109 bojilova
61 2521 sgarg
    public static Vector pathsForIndexing;
62 2893 sgarg
63 3673 barteau
    private static HashMap skinconfigs = new HashMap();
64 2521 sgarg
65 3034 perry
    private static edu.ucsb.nceas.utilities.Options options = null;
66 747 bojilova
67 2068 jones
    private static boolean debug = true;
68 2558 sgarg
69
    private static String[] administrators;
70
71
    private static String[] moderators;
72 2068 jones
73 2576 sgarg
    private static String[] allowedSubmitters;
74
75
    private static String[] deniedSubmitters;
76 2665 sgarg
77
    private static Logger logMetacat = Logger.getLogger(MetaCatUtil.class);
78 2576 sgarg
79 2068 jones
    static {
80 2591 sgarg
    	// Determine our db adapter class and create an instance of that class
81 2068 jones
        try {
82
            dbAdapter = (AbstractDatabase) createObject(getOption("dbAdapter"));
83
        } catch (Exception e) {
84
            System.err.println("Error in MetaCatUtil static block:"
85
                    + e.getMessage());
86 3034 perry
            e.printStackTrace();
87 2068 jones
        }
88 2558 sgarg
89
        // read administrator and moderator lists from metacat.properties
90 2576 sgarg
        getUserAccessControlLists();
91 747 bojilova
    }
92 2665 sgarg
93 2068 jones
    /**
94
     * Instantiate a class using the name of the class at runtime
95 2165 tao
     *
96 2068 jones
     * @param className the fully qualified name of the class to instantiate
97
     */
98
    public static Object createObject(String className) throws Exception
99
    {
100 747 bojilova
101 2068 jones
        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 1217 tao
115 2068 jones
    /**
116
     * Utility method to get an option value from the properties file
117 2165 tao
     *
118 2068 jones
     * @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 3034 perry
            options = edu.ucsb.nceas.utilities.Options.getInstance();
125 2068 jones
        }
126 3034 perry
        if (options == null) {
127 3078 jones
            Logger logMetacat = Logger.getLogger(MetaCatUtil.class);
128
        	logMetacat.info("options is null");
129 3034 perry
        }
130 2068 jones
        String value = options.getOption(optionName);
131
        return value;
132
    }
133 2554 tao
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 3034 perry
            options = edu.ucsb.nceas.utilities.Options.getInstance();
143 2554 tao
        }
144
        options.setOption(optionName, newValue);
145
146
    }
147 1538 berkley
148 2068 jones
    /** 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 747 bojilova
    }
165
166 2068 jones
    /**
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 747 bojilova
179 2068 jones
        String temp = "";
180
        boolean ampflag = true;
181
        boolean poundflag = false;
182
        int arrcount = 0;
183 185 jones
184 2068 jones
        if (query != null) {
185
            for (int i = 0; i < query.length(); i++) {
186 566 jones
187 2068 jones
                // 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 566 jones
215 2068 jones
                    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 731 bojilova
            }
235 566 jones
        }
236 2068 jones
        return parameters;
237 566 jones
    }
238 2665 sgarg
239 2068 jones
    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 1538 berkley
247 2068 jones
        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 887 berkley
    }
258 1538 berkley
259 2068 jones
    /** Normalizes the given string. Taken from configXML.java */
260
    public static String normalize(String s)
261 887 berkley
    {
262 2068 jones
        StringBuffer str = new StringBuffer();
263
264 2339 sgarg
             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 2449 sgarg
                         /*
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 2557 sgarg
                         } 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 2449 sgarg
                             str.append("&amp;");
300 2997 sgarg
                             i += 4;
301 2557 sgarg
                         } else
302
                             str.append("&amp;");
303 2449 sgarg
                         /////////
304 2339 sgarg
                         break;
305
                     }
306 3150 tao
                     case '"':
307
                    	 str.append("&quot;");
308
                         break;
309 2449 sgarg
                    default: {
310
                         if ( (ch<128) && (ch>31) ) {
311 2339 sgarg
                             str.append(ch);
312
                         }
313
                         else if (ch<32) {
314 2449 sgarg
                             if (ch == 10) { // new line
315 2339 sgarg
                                 str.append(ch);
316
                             }
317 2449 sgarg
                             if (ch == 13) { // carriage return
318 2339 sgarg
                                 str.append(ch);
319
                             }
320 2449 sgarg
                             if (ch == 9) {  // tab
321 2339 sgarg
                                 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 2437 sgarg
             return str.toString();
334 887 berkley
    }
335 1538 berkley
336 2068 jones
    /**
337
     * Get docid from online/url string
338
     */
339
    public static String getDocIdWithRevFromOnlineURL(String url)
340 894 berkley
    {
341 2068 jones
        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 2665 sgarg
            logMetacat.info("url is null and null will be returned");
349 2068 jones
            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 2665 sgarg
                logMetacat.info("substring between two & is: " + str);
362 2068 jones
                //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 2665 sgarg
            logMetacat.info("Checking the last substring");
377 2068 jones
            String str = url.substring(((Integer) list.elementAt(count))
378
                    .intValue() + 1, url.length());
379 2665 sgarg
            logMetacat.info("Last substring is: " + str);
380 2068 jones
            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 2665 sgarg
        logMetacat.info("The docid from online url is:" + docid);
389 2068 jones
        return docid.trim();
390 894 berkley
    }
391 2068 jones
392 2165 tao
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 2665 sgarg
      logMetacat.warn("The accession number from url is " +
412
                                 accessionNumber);
413 2165 tao
      return accessionNumber;
414
    }
415
416 2068 jones
    private static int getIndexForGivenChar(String str, char character)
417 1557 tao
    {
418 2068 jones
        int index = -1;
419
        // make sure str is not null
420
        if (str == null) {
421 2665 sgarg
            logMetacat.info(
422
                    "The given str is null and -1 will be returned");
423 2068 jones
            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 2665 sgarg
        logMetacat.info("the index for char " + character + " is: "
434
                + index);
435 2068 jones
        return index;
436 1557 tao
    }
437 2068 jones
438
    /**
439
     * Utility method to get docid from a given string
440 2165 tao
     *
441 2068 jones
     * @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 1557 tao
    {
448 2068 jones
        String docId = null;
449
        if (str == null) {
450 2665 sgarg
            logMetacat.info(
451 2068 jones
                    "The given str is null and null will be returned"
452 2665 sgarg
                            + " in getDocIdfromString");
453 2068 jones
            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 1538 berkley
458 2068 jones
        //assume that seperator is one charactor string
459
        char seperator = getOption("accNumSeparator").charAt(0);
460 1538 berkley
461 2068 jones
        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 1538 berkley
468 2068 jones
        //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 2165 tao
     *
487 2068 jones
     * @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 942 tao
    {
494 2068 jones
        int version = -1;
495
        String versionString = null;
496
        int dotNumber = 0;//count how many dots in given string
497
        int indexOfLastDot = 0;
498 1538 berkley
499 2068 jones
        //assume that seperator is one charactor string
500
        char seperator = getOption("accNumSeparator").charAt(0);
501 942 tao
502 2068 jones
        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 2045 tao
509 2068 jones
        //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 1538 berkley
524 2068 jones
        return version;
525
    }//getVersionFromString
526 1538 berkley
527 2068 jones
    /**
528
     * Utility method to get version string from a given string
529 2165 tao
     *
530 2068 jones
     * @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 942 tao
    {
537 2068 jones
        // 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 1538 berkley
542 2068 jones
        //assume that seperator is one charactor string
543
        char seperator = getOption("accNumSeparator").charAt(0);
544 1538 berkley
545 2068 jones
        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 1538 berkley
552 2068 jones
        //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 1538 berkley
566 2068 jones
        return versionString;
567
    }//getVersionFromString
568 1538 berkley
569 2068 jones
    /**
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 1292 tao
    {
576 2068 jones
        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 2665 sgarg
        logMetacat.info("after parsing accessionnumber, docid is "
582
                + docid);
583 2068 jones
        return docid;
584
    }
585 1538 berkley
586 2068 jones
    /**
587 2290 sgarg
     * 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 2665 sgarg
        logMetacat.info("after parsing accessionnumber, docid is "
602
                                 + docid);
603 2290 sgarg
604
        return docid;
605
    }
606
607
    /**
608 2068 jones
     * 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 2165 tao
     *
615 2068 jones
     */
616
    public static String getSmartDocId(String str)
617 1292 tao
    {
618 2068 jones
        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 2665 sgarg
        logMetacat.info("The docid get from smart docid getor is "
627
                + docid);
628 2068 jones
        return docid;
629 1292 tao
    }
630 2068 jones
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 1292 tao
    {
639 2068 jones
        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 2665 sgarg
        logMetacat.info("after parsing accessionnumber, rev is "
648
                + revNumber);
649 2068 jones
        return revNumber;
650 1292 tao
    }
651 2068 jones
652
    /**
653
     * Method to get the name of local replication server
654
     */
655
    public static String getLocalReplicationServerName()
656 1292 tao
    {
657 2068 jones
        String replicationServerName = null;
658
        String serverHost = null;
659
        serverHost = getOption("server");
660
        // append "context/servelet/replication" to the host name
661 2574 tao
        replicationServerName = serverHost.trim() + getOption("replicationpath").trim();
662 2068 jones
        return replicationServerName;
663
664 1292 tao
    }
665 1538 berkley
666 2068 jones
    /**
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 2045 tao
    {
672 2068 jones
        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 1538 berkley
691 2665 sgarg
        logMetacat.info("Docid without rev from inlinedata id: "
692
                + docidWithoutRev);
693 2068 jones
        return docidWithoutRev;
694 1538 berkley
695 2068 jones
    }
696 1538 berkley
697 2068 jones
    /**
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 1538 berkley
709 2068 jones
        while (!stack.isEmpty()) {
710
            Object obj = stack.pop();
711
            result.push(obj);
712
        }
713
        return result;
714 1598 tao
    }
715 1538 berkley
716 2068 jones
    /** A method to replace whitespace in url */
717
    public static String replaceWhiteSpaceForURL(String urlHasWhiteSpace)
718 1598 tao
    {
719 2068 jones
        StringBuffer newUrl = new StringBuffer();
720
        String whiteSpaceReplace = "%20";
721
        if (urlHasWhiteSpace == null || urlHasWhiteSpace.trim().equals("")) { return null; }
722 1598 tao
723 2068 jones
        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 1598 tao
732 2068 jones
        }//for
733 2665 sgarg
        logMetacat.info("The new string without space is:"
734
                + newUrl.toString());
735 2068 jones
        return newUrl.toString();
736 1598 tao
737 2068 jones
    }// replaceWhiteSpaceForUR
738
739 2558 sgarg
    /**
740
     * A method to read administrators and moderators list from the metacat.properties
741
     **/
742 2576 sgarg
    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 2558 sgarg
        try {
758 2576 sgarg
            if ( listString != null && !listString.trim().equals("")) {
759
            	list = listString.split(":");
760
            } else {
761
            	list = null;
762 2566 tao
            }
763
764 2558 sgarg
        } catch (PatternSyntaxException pse) {
765 2576 sgarg
        	list = null;
766 2665 sgarg
            logMetacat.error("Error in MetacatServlet.init: "
767
                + pse.getMessage());
768 2558 sgarg
        }
769 2576 sgarg
        return list;
770 2558 sgarg
    }
771 2576 sgarg
772 2558 sgarg
    /**
773 2576 sgarg
     * A method to check if the specified user is part of the moderators list
774 2558 sgarg
     **/
775 2576 sgarg
    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 2558 sgarg
            // check the given admin dn is a group dn...
784 2585 tao
        	if(groups != null && list[i].startsWith("cn=")){
785 2576 sgarg
            	// is a group dn
786 2558 sgarg
        		for (int j = 0; j < groups.length; j++) {
787 2576 sgarg
        			if (groups[j].equals(list[i])) {
788 2558 sgarg
                		return true;
789
                	}
790
        		}
791
            } else {
792
            	// is a user dn
793 2585 tao
            	if (username != null && username.equals(list[i])) {
794 2576 sgarg
    	    		return true;
795 2558 sgarg
            	}
796
            }
797
        }
798
        return false;
799
    }
800 2576 sgarg
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 2558 sgarg
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 2576 sgarg
    	return (onList(moderators, username, groups));
813 2558 sgarg
    }
814 2576 sgarg
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 3269 tao
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 3275 tao
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 3420 walbridge
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 3673 barteau
    /**
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 50 jones
}