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 3755 tao
    /** Normalizes a string read from DB. So it will be compatible to HTML */
260 2068 jones
    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 3755 tao
                         if (i + 4 < len  && s.charAt(i + 1) == 'a'
296 2557 sgarg
                        	 && 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 3755 tao
                         }
302
                         else  if (i + 3 < len && s.charAt(i + 1) == 'l'
303
                        	 && s.charAt(i + 2) == 't'
304
                        		 && s.charAt(i + 3) == ';' ){
305
                    	  // check if & is in front of it;
306
                             str.append("&lt;");
307
                             i += 3;
308
                         }
309
                         else  if (i + 3 < len && s.charAt(i + 1) == 'g'
310
                        	 && s.charAt(i + 2) == 't'
311
                        		 && s.charAt(i + 3) == ';' ){
312
                    	  // check if & is in front of gt;
313
                           // (we dont yet check for other HTML 4.0 Character entities)
314
                             str.append("&gt;");
315
                             i += 3;
316
                         }
317
                         else  if (i + 5 < len && s.charAt(i + 1) == 'q'
318
                        	 && s.charAt(i + 2) == 'u'
319
                        		 && s.charAt(i + 3) == 'o'
320
                        	 && s.charAt(i + 4) == 't'
321
                        	 && s.charAt(i + 5) == ';')
322
                             {
323
                    	   // check if & is in front of quot;
324
                           // (we dont yet check for other HTML 4.0 Character entities)
325
                             str.append("&quot;");
326
                             i += 5;
327
                         }
328
                         else  if (i + 5 < len && s.charAt(i + 1) == 'a'
329
                        	 && s.charAt(i + 2) == 'p'
330
                        		 && s.charAt(i + 3) == 'o'
331
                        	 && s.charAt(i + 4) == 's'
332
                        	 && s.charAt(i + 5) == ';')
333
                             {
334
                    	   // check if & is in front of apostrophe;
335
                           // (we dont yet check for other HTML 4.0 Character entities)
336
                             str.append("&apos;");
337
                             i += 5;
338
                         }
339
                         else{
340 2557 sgarg
                             str.append("&amp;");
341 3755 tao
                         }
342 2449 sgarg
                         /////////
343 2339 sgarg
                         break;
344
                     }
345 3150 tao
                     case '"':
346
                    	 str.append("&quot;");
347
                         break;
348 3755 tao
                     case '\'':
349
                    	 str.append("&apos;");
350
                         break;
351 2449 sgarg
                    default: {
352
                         if ( (ch<128) && (ch>31) ) {
353 2339 sgarg
                             str.append(ch);
354
                         }
355
                         else if (ch<32) {
356 2449 sgarg
                             if (ch == 10) { // new line
357 2339 sgarg
                                 str.append(ch);
358
                             }
359 2449 sgarg
                             if (ch == 13) { // carriage return
360 2339 sgarg
                                 str.append(ch);
361
                             }
362 2449 sgarg
                             if (ch == 9) {  // tab
363 2339 sgarg
                                 str.append(ch);
364
                             }
365
                             // otherwise skip
366
                         }
367
                         else {
368
                             str.append("&#");
369
                             str.append(Integer.toString(ch));
370
                             str.append(';');
371
                         }
372
                     }
373
                 }
374
             }
375 2437 sgarg
             return str.toString();
376 887 berkley
    }
377 1538 berkley
378 2068 jones
    /**
379
     * Get docid from online/url string
380
     */
381
    public static String getDocIdWithRevFromOnlineURL(String url)
382 894 berkley
    {
383 2068 jones
        String docid = null;
384
        String DOCID = "docid";
385
        boolean find = false;
386
        char limited = '&';
387
        int count = 0; //keep track how many & was found
388
        Vector list = new Vector();// keep index number for &
389
        if (url == null) {
390 2665 sgarg
            logMetacat.info("url is null and null will be returned");
391 2068 jones
            return docid;
392
        }
393
        // the first element in list is 0
394
        list.add(new Integer(0));
395
        for (int i = 0; i < url.length(); i++) {
396
            if (url.charAt(i) == limited) {
397
                // count plus 1
398
                count++;
399
                list.add(new Integer(i));
400
                // get substring beween two &
401
                String str = url.substring(
402
                        ((Integer) list.elementAt(count - 1)).intValue(), i);
403 2665 sgarg
                logMetacat.info("substring between two & is: " + str);
404 2068 jones
                //if the subString contains docid, we got it
405
                if (str.indexOf(DOCID) != -1) {
406
                    //get index of '="
407
                    int start = getIndexForGivenChar(str, '=') + 1;
408
                    int end = str.length();
409
                    docid = str.substring(start, end);
410
                    find = true;
411
                }//if
412
            }//if
413
        }//for
414
        //if not find, we need check the subtring between the index of last &
415
        // and
416
        // the end of string
417
        if (!find) {
418 2665 sgarg
            logMetacat.info("Checking the last substring");
419 2068 jones
            String str = url.substring(((Integer) list.elementAt(count))
420
                    .intValue() + 1, url.length());
421 2665 sgarg
            logMetacat.info("Last substring is: " + str);
422 2068 jones
            if (str.indexOf(DOCID) != -1) {
423
                //get index of '="
424
                int start = getIndexForGivenChar(str, '=') + 1;
425
                int end = str.length();
426
                docid = str.substring(start, end);
427
                find = true;
428
            }//if
429
        }//if
430 2665 sgarg
        logMetacat.info("The docid from online url is:" + docid);
431 2068 jones
        return docid.trim();
432 894 berkley
    }
433 2068 jones
434 2165 tao
435
    /**
436
     * Eocgorid identifier will look like: ecogrid://knb/tao.1.1
437
     * The AccessionNumber tao.1.1 will be returned. If the given doesn't
438
     * contains ecogrid, null will be returned.
439
     * @param identifier String
440
     * @return String
441
     */
442
    public static String getAccessionNumberFromEcogridIdentifier(String identifier)
443
    {
444
      String accessionNumber = null;
445
      if (identifier != null && identifier.startsWith(DBSAXHandler.ECOGRID))
446
      {
447
        // find the last "/" in identifier
448
        int indexOfLastSlash = identifier.lastIndexOf("/");
449
        int start = indexOfLastSlash+1;
450
        int end   = identifier.length();
451
        accessionNumber = identifier.substring(start, end);
452
      }
453 2665 sgarg
      logMetacat.warn("The accession number from url is " +
454
                                 accessionNumber);
455 2165 tao
      return accessionNumber;
456
    }
457
458 2068 jones
    private static int getIndexForGivenChar(String str, char character)
459 1557 tao
    {
460 2068 jones
        int index = -1;
461
        // make sure str is not null
462
        if (str == null) {
463 2665 sgarg
            logMetacat.info(
464
                    "The given str is null and -1 will be returned");
465 2068 jones
            return index;
466
        }
467
        // got though the string
468
        for (int i = 0; i < str.length(); i++) {
469
            // find the first one then break the loop
470
            if (str.charAt(i) == character) {
471
                index = i;
472
                break;
473
            }//if
474
        }//for
475 2665 sgarg
        logMetacat.info("the index for char " + character + " is: "
476
                + index);
477 2068 jones
        return index;
478 1557 tao
    }
479 2068 jones
480
    /**
481
     * Utility method to get docid from a given string
482 2165 tao
     *
483 2068 jones
     * @param string, the given string should be these two format: 1) str1.str2
484
     *            in this case docid= str1.str2 2) str1.str2.str3, in this case
485
     *            docid =str1.str2
486
     * @param the sperator char
487
     */
488
    public static String getDocIdFromString(String str)
489 1557 tao
    {
490 2068 jones
        String docId = null;
491
        if (str == null) {
492 2665 sgarg
            logMetacat.info(
493 2068 jones
                    "The given str is null and null will be returned"
494 2665 sgarg
                            + " in getDocIdfromString");
495 2068 jones
            return docId;
496
        } //make sure docid is not null
497
        int dotNumber = 0;//count how many dots in given string
498
        int indexOfLastDot = 0;
499 1538 berkley
500 2068 jones
        //assume that seperator is one charactor string
501
        char seperator = getOption("accNumSeparator").charAt(0);
502 1538 berkley
503 2068 jones
        for (int i = 0; i < str.length(); i++) {
504
            if (str.charAt(i) == seperator) {
505
                dotNumber++;//count how many dots
506
                indexOfLastDot = i;//keep the last dot postion
507
            }
508
        }//for
509 1538 berkley
510 2068 jones
        //The string formatt is wrong, because it has more than two or less
511
        // than
512
        //one seperator
513
        if (dotNumber > 2 || dotNumber < 1) {
514
            docId = null;
515
        } else if (dotNumber == 2) //the case for str1.str2.str3
516
        {
517
            docId = str.substring(0, indexOfLastDot);
518
        } else if (dotNumber == 1) //the case for str1.str2
519
        {
520
            docId = str;
521
        }
522
523
        return docId;
524
    }//getDocIdFromString
525
526
    /**
527
     * Utility method to get version number from a given string
528 2165 tao
     *
529 2068 jones
     * @param string, the given string should be these two format: 1)
530
     *            str1.str2(no version) version =-1; 2) str1.str2.str3, in this
531
     *            case version = str3; 3) other, vresion =-2
532
     */
533
    public static int getVersionFromString(String str)
534
            throws NumberFormatException
535 942 tao
    {
536 2068 jones
        int version = -1;
537
        String versionString = null;
538
        int dotNumber = 0;//count how many dots in given string
539
        int indexOfLastDot = 0;
540 1538 berkley
541 2068 jones
        //assume that seperator is one charactor string
542
        char seperator = getOption("accNumSeparator").charAt(0);
543 942 tao
544 2068 jones
        for (int i = 0; i < str.length(); i++) {
545
            if (str.charAt(i) == seperator) {
546
                dotNumber++;//count how many dots
547
                indexOfLastDot = i;//keep the last dot postion
548
            }
549
        }//for
550 2045 tao
551 2068 jones
        //The string formatt is wrong, because it has more than two or less
552
        // than
553
        //one seperator
554
        if (dotNumber > 2 || dotNumber < 1) {
555
            version = -2;
556
        } else if (dotNumber == 2 && (indexOfLastDot != (str.length() - 1)))
557
        //the case for str1.str2.str3
558
        {
559
            versionString = str.substring((indexOfLastDot + 1), str.length());
560
            version = Integer.parseInt(versionString);
561
        } else if (dotNumber == 1) //the case for str1.str2
562
        {
563
            version = -1;
564
        }
565 1538 berkley
566 2068 jones
        return version;
567
    }//getVersionFromString
568 1538 berkley
569 2068 jones
    /**
570
     * Utility method to get version string from a given string
571 2165 tao
     *
572 2068 jones
     * @param string, the given string should be these two format: 1)
573
     *            str1.str2(no version) version=null; 2) str1.str2.str3, in
574
     *            this case version = str3; 3) other, vresion =null;
575
     */
576
    public static String getRevisionStringFromString(String str)
577
            throws NumberFormatException
578 942 tao
    {
579 2068 jones
        // String to store the version
580
        String versionString = null;
581
        int dotNumber = 0;//count how many dots in given string
582
        int indexOfLastDot = 0;
583 1538 berkley
584 2068 jones
        //assume that seperator is one charactor string
585
        char seperator = getOption("accNumSeparator").charAt(0);
586 1538 berkley
587 2068 jones
        for (int i = 0; i < str.length(); i++) {
588
            if (str.charAt(i) == seperator) {
589
                dotNumber++;//count how many dots
590
                indexOfLastDot = i;//keep the last dot postion
591
            }
592
        }//for
593 1538 berkley
594 2068 jones
        //The string formatt is wrong, because it has more than two or less
595
        // than
596
        //one seperator
597
        if (dotNumber > 2 || dotNumber < 1) {
598
            versionString = null;
599
        } else if (dotNumber == 2 && (indexOfLastDot != (str.length() - 1))) {
600
            //the case for str1.str2.str3
601
            // indexOfLastDot != (str.length() -1) means get rid of str1.str2.
602
            versionString = str.substring((indexOfLastDot + 1), str.length());
603
        } else if (dotNumber == 1) //the case for str1.str2 or str1.str2.
604
        {
605
            versionString = null;
606
        }
607 1538 berkley
608 2068 jones
        return versionString;
609
    }//getVersionFromString
610 1538 berkley
611 2068 jones
    /**
612
     * This method will get docid from an AccessionNumber. There is no
613
     * assumption the accessnumber will be str1.str2.str3. It can be more. So
614
     * we think the docid will be get rid of last part
615
     */
616
    public static String getDocIdFromAccessionNumber(String accessionNumber)
617 1292 tao
    {
618 2068 jones
        String docid = null;
619
        if (accessionNumber == null) { return docid; }
620
        String seperator = getOption("accNumSeparator");
621
        int indexOfLastSeperator = accessionNumber.lastIndexOf(seperator);
622
        docid = accessionNumber.substring(0, indexOfLastSeperator);
623 2665 sgarg
        logMetacat.info("after parsing accessionnumber, docid is "
624
                + docid);
625 2068 jones
        return docid;
626
    }
627 1538 berkley
628 2068 jones
    /**
629 2290 sgarg
     * This method will get inline data id without the revision number.
630
     * So if inlineData.1.2 is passed as input, inlineData.2 is returned.
631
     */
632
    public static String getInlineDataIdWithoutRev(String accessionNumber)
633
    {
634
        String docid = null;
635
        if (accessionNumber == null) { return docid; }
636
        String seperator = getOption("accNumSeparator");
637
        int indexOfLastSeperator = accessionNumber.lastIndexOf(seperator);
638
        String version = accessionNumber.substring(indexOfLastSeperator,
639
                                                   accessionNumber.length());
640
        accessionNumber = accessionNumber.substring(0, indexOfLastSeperator);
641
        indexOfLastSeperator = accessionNumber.lastIndexOf(seperator);
642
        docid = accessionNumber.substring(0, indexOfLastSeperator) + version;
643 2665 sgarg
        logMetacat.info("after parsing accessionnumber, docid is "
644
                                 + docid);
645 2290 sgarg
646
        return docid;
647
    }
648
649
    /**
650 2068 jones
     * This method will call both getDocIdFromString and
651
     * getDocIdFromAccessionNumber. So first, if the string looks str1.str2,
652
     * the docid will be str1.str2. If the string is str1.str2.str3, the docid
653
     * will be str1.str2. If the string is str1.str2.str3.str4 or more, the
654
     * docid will be str1.str2.str3. If the string look like str1, null will be
655
     * returned
656 2165 tao
     *
657 2068 jones
     */
658
    public static String getSmartDocId(String str)
659 1292 tao
    {
660 2068 jones
        String docid = null;
661
        //call geDocIdFromString first.
662
        docid = getDocIdFromString(str);
663
        // If docid is null, try to call getDocIdFromAccessionNumber
664
        // it will handle the seperator more than2
665
        if (docid == null) {
666
            docid = getDocIdFromAccessionNumber(str);
667
        }
668 2665 sgarg
        logMetacat.info("The docid get from smart docid getor is "
669
                + docid);
670 2068 jones
        return docid;
671 1292 tao
    }
672 2068 jones
673
    /**
674
     * This method will get revision from an AccessionNumber. There is no
675
     * assumption the accessnumber will be str1.str2.str3. It can be more. So
676
     * we think the docid will be get rid of last part
677
     */
678
    public static int getRevisionFromAccessionNumber(String accessionNumber)
679
            throws NumberFormatException
680 1292 tao
    {
681 2068 jones
        String rev = null;
682
        int revNumber = -1;
683
        if (accessionNumber == null) { return revNumber; }
684
        String seperator = getOption("accNumSeparator");
685
        int indexOfLastSeperator = accessionNumber.lastIndexOf(seperator);
686
        rev = accessionNumber.substring(indexOfLastSeperator + 1,
687
                accessionNumber.length());
688
        revNumber = Integer.parseInt(rev);
689 2665 sgarg
        logMetacat.info("after parsing accessionnumber, rev is "
690
                + revNumber);
691 2068 jones
        return revNumber;
692 1292 tao
    }
693 2068 jones
694
    /**
695
     * Method to get the name of local replication server
696
     */
697
    public static String getLocalReplicationServerName()
698 1292 tao
    {
699 2068 jones
        String replicationServerName = null;
700
        String serverHost = null;
701
        serverHost = getOption("server");
702
        // append "context/servelet/replication" to the host name
703 2574 tao
        replicationServerName = serverHost.trim() + getOption("replicationpath").trim();
704 2068 jones
        return replicationServerName;
705
706 1292 tao
    }
707 1538 berkley
708 2068 jones
    /**
709
     * Method to get docidwithrev from eml2 inline data id The eml inline data
710
     * id would look like eml.200.2.3
711
     */
712
    public static String getDocIdWithoutRevFromInlineDataID(String inlineDataID)
713 2045 tao
    {
714 2068 jones
        String docidWithoutRev = null;
715
        if (inlineDataID == null) { return docidWithoutRev; }
716
        String seperator = MetaCatUtil.getOption("accNumSeparator");
717
        char charSeperator = seperator.charAt(0);
718
        int targetNumberOfSeperator = 2;// we want to know his index
719
        int numberOfSeperator = 0;
720
        for (int i = 0; i < inlineDataID.length(); i++) {
721
            // meet seperator, increase number of seperator
722
            if (inlineDataID.charAt(i) == charSeperator) {
723
                numberOfSeperator++;
724
            }
725
            // if number of seperator reach the target one, record the index(i)
726
            // and get substring and terminate the loop
727
            if (numberOfSeperator == targetNumberOfSeperator) {
728
                docidWithoutRev = inlineDataID.substring(0, i);
729
                break;
730
            }
731
        }
732 1538 berkley
733 2665 sgarg
        logMetacat.info("Docid without rev from inlinedata id: "
734
                + docidWithoutRev);
735 2068 jones
        return docidWithoutRev;
736 1538 berkley
737 2068 jones
    }
738 1538 berkley
739 2068 jones
    /**
740
     * Revise stack change a stack to opposite order
741
     */
742
    public static Stack reviseStack(Stack stack)
743
    {
744
        Stack result = new Stack();
745
        // make sure the parameter is correct
746
        if (stack == null || stack.isEmpty()) {
747
            result = stack;
748
            return result;
749
        }
750 1538 berkley
751 2068 jones
        while (!stack.isEmpty()) {
752
            Object obj = stack.pop();
753
            result.push(obj);
754
        }
755
        return result;
756 1598 tao
    }
757 1538 berkley
758 2068 jones
    /** A method to replace whitespace in url */
759
    public static String replaceWhiteSpaceForURL(String urlHasWhiteSpace)
760 1598 tao
    {
761 2068 jones
        StringBuffer newUrl = new StringBuffer();
762
        String whiteSpaceReplace = "%20";
763
        if (urlHasWhiteSpace == null || urlHasWhiteSpace.trim().equals("")) { return null; }
764 1598 tao
765 2068 jones
        for (int i = 0; i < urlHasWhiteSpace.length(); i++) {
766
            char ch = urlHasWhiteSpace.charAt(i);
767
            if (!Character.isWhitespace(ch)) {
768
                newUrl.append(ch);
769
            } else {
770
                //it is white sapce, replace it by %20
771
                newUrl = newUrl.append(whiteSpaceReplace);
772
            }
773 1598 tao
774 2068 jones
        }//for
775 2665 sgarg
        logMetacat.info("The new string without space is:"
776
                + newUrl.toString());
777 2068 jones
        return newUrl.toString();
778 1598 tao
779 2068 jones
    }// replaceWhiteSpaceForUR
780
781 2558 sgarg
    /**
782
     * A method to read administrators and moderators list from the metacat.properties
783
     **/
784 2576 sgarg
    public static void getUserAccessControlLists(){
785
    	administrators = getListFromOption("administrators");
786
    	moderators = getListFromOption("moderators");
787
    	allowedSubmitters = getListFromOption("allowedSubmitters");
788
    	deniedSubmitters = getListFromOption("deniedSubmitters");
789
    }
790
791
    /**
792
     * A method to read value of a given option from the metacat.properties
793
     * into specified String array
794
     **/
795
    private static String[] getListFromOption(String optionName){
796
    	String[] list = null;
797
    	String listString = MetaCatUtil.getOption(optionName);
798
799 2558 sgarg
        try {
800 2576 sgarg
            if ( listString != null && !listString.trim().equals("")) {
801
            	list = listString.split(":");
802
            } else {
803
            	list = null;
804 2566 tao
            }
805
806 2558 sgarg
        } catch (PatternSyntaxException pse) {
807 2576 sgarg
        	list = null;
808 2665 sgarg
            logMetacat.error("Error in MetacatServlet.init: "
809
                + pse.getMessage());
810 2558 sgarg
        }
811 2576 sgarg
        return list;
812 2558 sgarg
    }
813 2576 sgarg
814 2558 sgarg
    /**
815 2576 sgarg
     * A method to check if the specified user is part of the moderators list
816 2558 sgarg
     **/
817 2576 sgarg
    private static boolean onList(String list[], String username, String[] groups){
818
819
    	if(list == null){
820
    		return false;
821
    	}
822
823
    	// Check that the user is authenticated as an administrator account
824
        for (int i = 0; i < list.length; i++) {
825 2558 sgarg
            // check the given admin dn is a group dn...
826 2585 tao
        	if(groups != null && list[i].startsWith("cn=")){
827 2576 sgarg
            	// is a group dn
828 2558 sgarg
        		for (int j = 0; j < groups.length; j++) {
829 2576 sgarg
        			if (groups[j].equals(list[i])) {
830 2558 sgarg
                		return true;
831
                	}
832
        		}
833
            } else {
834
            	// is a user dn
835 2585 tao
            	if (username != null && username.equals(list[i])) {
836 2576 sgarg
    	    		return true;
837 2558 sgarg
            	}
838
            }
839
        }
840
        return false;
841
    }
842 2576 sgarg
843
    /**
844
     * A method to check if the specified user is part of the administrators list
845
     **/
846
    public static boolean isAdministrator(String username, String[] groups){
847
    	return (onList(administrators, username, groups));
848
    }
849 2558 sgarg
850
    /**
851
     * A method to check if the specified user is part of the moderators list
852
     **/
853
    public static boolean isModerator(String username, String[] groups){
854 2576 sgarg
    	return (onList(moderators, username, groups));
855 2558 sgarg
    }
856 2576 sgarg
857
    /**
858
     * A method to check if the specified user is part of the moderators list
859
     **/
860
    public static boolean isAllowedSubmitter(String username, String[] groups){
861
    	if(allowedSubmitters != null){
862
    		return (onList(allowedSubmitters, username, groups));
863
    	} else {
864
    		// no allowedSubmitters list specified -
865
    		// hence everyone should be allowed
866
    		return true;
867
    	}
868
   }
869
870
    /**
871
     * A method to check if the specified user is part of the moderators list
872
     **/
873
    public static boolean isDeniedSubmitter(String username, String[] groups){
874
		return (onList(deniedSubmitters, username, groups));
875
    }
876
877
    /**
878
     * A method to check if the specified user can insert the document
879
     **/
880
    public static boolean canInsertOrUpdate(String username, String[] groups){
881
    	return (isAllowedSubmitter(username, groups)
882
    			&& !isDeniedSubmitter(username, groups));
883
    }
884 3269 tao
885
    /**
886
     * Writes debug information into a file. In metacat.properties, if property writeDebugToFile is
887
     * set to true, the debug information will be written to debug file, which value is the property
888
     * debugOutputFile in metacat.properties.
889
     *
890
     */
891
    public static void writeDebugToFile(String debugInfo)
892
    {
893
    	String debug = MetaCatUtil.getOption("writeDebugToFile");
894
    	if (debug != null && debug.equalsIgnoreCase("true"))
895
    	{
896
    		 try
897
    		 {
898
    			 File outputFile = new File(MetaCatUtil.getOption("debugOutputFile"));
899
    			 FileOutputStream fos = new FileOutputStream(outputFile, true);
900
                 PrintWriter pw = new PrintWriter(fos);
901
                 pw.println(debugInfo);
902
                 pw.flush();
903
                 pw.close();
904
    			 fos.close();
905
906
    		 }
907
    		 catch(Exception io)
908
    		 {
909
    			logMetacat.warn("Eorr in MetacatUtil.writeDebugToFile "+io.getMessage()) ;
910
    		 }
911
    	}
912
913
    }
914 3275 tao
915
   /**
916
    *  Writes debug information into a file in delimitered format
917
    * @param debugInfo   the debug information
918
    * @param newLine    append the debug info to a line or not
919
    */
920
    public static void writeDebugToDelimiteredFile(String debugInfo, boolean newLine)
921
    {
922
    	String debug = MetaCatUtil.getOption("writeDebugToFile");
923
    	if (debug != null && debug.equalsIgnoreCase("true"))
924
    	{
925
    		 try
926
    		 {
927
    			 File outputFile = new File(MetaCatUtil.getOption("delimiteredOutputFile"));
928
    			 FileOutputStream fos = new FileOutputStream(outputFile, true);
929
                 PrintWriter pw = new PrintWriter(fos);
930
                 if (newLine)
931
                 {
932
                     pw.println(debugInfo);
933
                 }
934
                 else
935
                 {
936
                	 pw.print(debugInfo);
937
                 }
938
                 pw.flush();
939
                 pw.close();
940
    			 fos.close();
941
942
    		 }
943
    		 catch(Exception io)
944
    		 {
945
    			logMetacat.warn("Eorr in writeDebugToDelimiteredFile "+io.getMessage()) ;
946
    		 }
947
    	}
948
949
    }
950 3420 walbridge
951
		/**
952
     * Write the uploaded file to disk for temporary storage before moving it
953
     * to its final Metacat location.
954
     *
955
     * @param  filePart          the FilePart object containing the file form element
956
     * @param  fileName          the name of the file to be written to disk
957
     * @return tempFilePath      a String containing location of temporary file
958
     */
959
    public static String writeTempFile (FilePart filePart, String fileName) {
960
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
961
        String tempFilePath = null;
962
        String tempDirPath = getOption("temp-dir");
963
        long fileSize;
964
        File tempFile;
965
        File tempDir;
966
967
        if ((fileName == null) || fileName.equals("")) {
968
            return tempFilePath;
969
        }
970
971
        // the tempfilepath token isn't set, use Java default
972
        if (tempDirPath == null) {
973
						String javaTempDir = System.getProperty("java.io.tempdir");
974
						if (javaTempDir == null) {
975
							  // no paths set, use unix default
976
								tempDirPath = "/tmp";
977
						} else {
978
								tempDirPath = javaTempDir;
979
						}
980
        }
981
982
        tempDir = new File(tempDirPath);
983
984
        // Create the temporary directory if it doesn't exist
985
        try {
986
            if (!tempDir.exists()) {
987
                tempDir.mkdirs();
988
            }
989
        } catch (SecurityException e) {
990
            logMetacat.error("Can't create directory: " + tempDir.getPath() +
991
                             ". Error: " + e.getMessage());
992
        }
993
        try {
994
            tempFile = new File(tempDirPath, fileName);
995
            fileSize = filePart.writeTo(tempFile);
996
            tempFilePath = tempDirPath + File.separator + fileName;
997
998
            if (fileSize == 0) {
999
                logMetacat.error("Uploaded file '" + fileName + "'is empty!");
1000
            }
1001
        } catch (IOException e) {
1002
            logMetacat.error("IO exception which writing temporary file: " +
1003
                             tempFilePath + " " + e.getMessage());
1004
        }
1005
1006
        logMetacat.info("Temporary file is: " + tempFilePath);
1007
1008
        return tempFilePath;
1009
    }
1010
1011
		/**
1012
		 *
1013
		 * Copy a file between two locations specified as strings.  Fails
1014
     * if either path cannot be created. Based on the public domain
1015
     * FileCopy class in _Java in a Nutshell_.
1016
     *
1017
		 * @param sourceName		the source file to read from disk
1018
     * @param destName  		the destination file on disk
1019
     */
1020
    public static void copyFile(String sourceName, String destName) throws IOException {
1021
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
1022
1023
        File sourceFile = new File(sourceName);
1024
        File destFile = new File(destName);
1025
        FileInputStream source = null;
1026
        FileOutputStream dest = null;
1027
        byte[] buffer;
1028
        int bytesRead;
1029
1030
        try {
1031
            if (!sourceFile.exists() || !sourceFile.isFile()) {
1032
                logMetacat.error("File copy: no such source" +
1033
                                 " file: " + sourceName);
1034
            }
1035
            if (!sourceFile.canRead()) {
1036
                logMetacat.error("File copy: source file " +
1037
                                 "is unreadable: " + sourceName);
1038
            }
1039
1040
            if (destFile.exists()) {
1041
                if (destFile.isFile()) {
1042
                    if (!destFile.canWrite()) {
1043
                        logMetacat.error("File copy: destination " +
1044
                                         "file is unwriteable: " + destFile);
1045
                    }
1046
                } else {
1047
                    logMetacat.error("File copy: destination file " +
1048
                                     "is not a file: " + destFile);
1049
                }
1050
            } else {
1051
                File parentDir = parent(destFile);
1052
1053
                if (!parentDir.exists())
1054
                {
1055
                    logMetacat.error("File copy: destination diretory " +
1056
                                     " doesn't exist: " + destName);
1057
                }
1058
                if (!parentDir.canWrite()) {
1059
                    logMetacat.error("File copy: destination directory " +
1060
                                     " is unwritable: " + destName);
1061
                }
1062
            }
1063
1064
            // Verbose error checking done, copy the file object
1065
            source = new FileInputStream(sourceFile);
1066
            dest = new FileOutputStream(destFile);
1067
            buffer = new byte[1024];
1068
1069
            while (true) {
1070
                bytesRead = source.read(buffer);
1071
                if (bytesRead == -1) {
1072
                    break;
1073
                }
1074
                dest.write(buffer, 0, bytesRead);
1075
            }
1076
        }
1077
        finally {
1078
            if (source != null) {
1079
                try { source.close(); } catch (IOException e) { ; }
1080
            }
1081
            if (dest != null) {
1082
                try { dest.close(); } catch (IOException e) { ; }
1083
            }
1084
        }
1085
    }
1086
1087
    private static File parent(File f) {
1088
        String dirname = f.getParent();
1089
        if (dirname == null) {
1090
            if (f.isAbsolute()) return new File(File.separator);
1091
            else return new File(System.getProperty("user.dir"));
1092
        }
1093
        return new File(dirname);
1094
    }
1095
1096 3673 barteau
    /**
1097
     * Adds the Properties and skin to the list of skin configurations.
1098
     * @param skinName String qformat
1099
     * @param skinProperties Properties instance
1100
     */
1101
    public static void addSkinConfig(String skinName, Properties skinProperties) {
1102
        skinconfigs.put(skinName, skinProperties);
1103
    }
1104
1105
    /**
1106
     * Return the Properties for a given skin name.
1107
     * @param skinName String qformat
1108
     * @return Properties, or null if none exist for the skin.
1109
     */
1110
    public static Properties getSkinConfig(String skinName) {
1111
        Properties                      result;
1112
1113
        result = (Properties) skinconfigs.get(skinName);
1114
        return(result);
1115
    }
1116
1117
    /**
1118
     * Returns true if Properties exist for a given skin name, false otherwise.
1119
     * @param skinName String qformat
1120
     * @return boolean
1121
     */
1122
    public static boolean hasSkinConfig(String skinName) {
1123
        boolean                     result;
1124
1125
        result = skinconfigs.containsKey(skinName);
1126
        return(result);
1127
    }
1128 50 jones
}