Index: src/edu/ucsb/nceas/metacat/util/MetaCatUtil.java
===================================================================
--- src/edu/ucsb/nceas/metacat/util/MetaCatUtil.java	(revision 4698)
+++ src/edu/ucsb/nceas/metacat/util/MetaCatUtil.java	(nonexistent)
@@ -1,967 +0,0 @@
-/**
- *  '$RCSfile$'
- *    Purpose: A Class that implements utility methods for a metadata catalog
- *  Copyright: 2000 Regents of the University of California and the
- *             National Center for Ecological Analysis and Synthesis
- *    Authors: Matt Jones, Jivka Bojilova
- *
- *   '$Author$'
- *     '$Date$'
- * '$Revision$'
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-package edu.ucsb.nceas.metacat.util;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.net.MalformedURLException;
-import java.util.Hashtable;
-import java.util.Stack;
-import java.util.Vector;
-
-import org.apache.log4j.Logger;
-
-import com.oreilly.servlet.multipart.FilePart;
-
-import edu.ucsb.nceas.dbadapter.AbstractDatabase;
-import edu.ucsb.nceas.metacat.DBSAXHandler;
-import edu.ucsb.nceas.metacat.MetaCatServlet;
-import edu.ucsb.nceas.metacat.NodeRecord;
-import edu.ucsb.nceas.metacat.service.PropertyService;
-import edu.ucsb.nceas.metacat.service.SkinPropertyService;
-import edu.ucsb.nceas.utilities.PropertyNotFoundException;
-import edu.ucsb.nceas.utilities.FileUtil;
-
-/**
- * A suite of utility classes for the metadata catalog server
- */
-public class MetaCatUtil
-{
-
-    public static AbstractDatabase dbAdapter;
-
-    public static Vector pathsForIndexing;
-    
-    private static boolean debug = true;
-    
-    private static boolean debugErrorDisplayed = false;
-    
-    private static Logger logMetacat = Logger.getLogger(MetaCatUtil.class);
-    private static char separator = '.';
-
-    static {
-        try {
-        	separator = PropertyService.getProperty("document.accNumSeparator").charAt(0);
-        } catch (PropertyNotFoundException pnfe) {
-        	logMetacat.error("Could not retrieve account number separator. " 
-        			+ "Separator set to '.' : " + pnfe.getMessage());
-        }
-    }
-
-    /**
-     * Utility method to parse the query part of a URL into parameters. This
-     * method assumes the format of the query par tof the url is an ampersand
-     * separated list of name/value pairs, with equal signs separating the name
-     * from the value (e.g., name=tom&zip=99801 ). Returns a has of the name
-     * value pairs, hashed on name.
-     */
-    public static Hashtable<String,String> parseQuery(String query)
-            throws MalformedURLException
-    {
-        String[][] params = new String[200][2];
-        Hashtable<String,String> parameters = new Hashtable<String,String>();
-
-        String temp = "";
-        boolean ampflag = true;
-        boolean poundflag = false;
-        int arrcount = 0;
-
-        if (query != null) {
-            for (int i = 0; i < query.length(); i++) {
-
-                // go throught the remainder of the query one character at a
-                // time.
-                if (query.charAt(i) == '=') {
-                    // if the current char is a # then the preceding should be
-                    // a name
-                    if (!poundflag && ampflag) {
-                        params[arrcount][0] = temp.trim();
-                        temp = "";
-                    } else {
-                        //if there are two #s or &s in a row throw an
-                        // exception.
-                        throw new MalformedURLException(
-                                "metacatURL: Two parameter names "
-                                        + "not allowed in sequence");
-                    }
-                    poundflag = true;
-                    ampflag = false;
-                } else if (query.charAt(i) == '&' || i == query.length() - 1) {
-                    //the text preceding the & should be the param value.
-                    if (i == query.length() - 1) {
-                        //if at the end of the string grab the last value and
-                        // append it.
-                        if (query.charAt(i) != '=') {
-                            //ignore an extra & on the end of the string
-                            temp += query.charAt(i);
-                        }
-                    }
-
-                    if (!ampflag && poundflag) {
-                        params[arrcount][1] = temp.trim();
-                        parameters
-                                .put(params[arrcount][0], params[arrcount][1]);
-                        temp = "";
-                        arrcount++; //increment the array to the next row.
-                    } else {
-                        //if there are two =s or &s in a row through an
-                        // exception
-                        throw new MalformedURLException(
-                                "metacatURL: Two parameter values "
-                                        + "not allowed in sequence");
-                    }
-                    poundflag = false;
-                    ampflag = true;
-                } else {
-                    //get the next character in the string
-                    temp += query.charAt(i);
-                }
-            }
-        }
-        return parameters;
-    }
-  
-    public static Vector<String> getOptionList(String optiontext)
-    {
-        Vector<String> optionsVector = new Vector<String>();
-        if (optiontext.indexOf(",") == -1) {
-            optionsVector.addElement(optiontext);
-            return optionsVector;
-        }
-
-        while (optiontext.indexOf(",") != -1) {
-            String s = optiontext.substring(0, optiontext.indexOf(","));
-            optionsVector.addElement(s.trim());
-            optiontext = optiontext.substring(optiontext.indexOf(",") + 1,
-                    optiontext.length());
-            if (optiontext.indexOf(",") == -1) { //catch the last list entry
-                optionsVector.addElement(optiontext.trim());
-            }
-        }
-        return optionsVector;
-    }
-
-    /** Normalizes a string read from DB. So it will be compatible to HTML */
-    public static String normalize(String s)
-    {
-        StringBuffer str = new StringBuffer();
-
-             int len = (s != null) ? s.length() : 0;
-             for (int i = 0; i < len; i++) {
-                 char ch = s.charAt(i);
-                 switch (ch) {
-                     case '<': {
-                         str.append("&lt;");
-                         break;
-                     }
-                     case '>': {
-                         str.append("&gt;");
-                         break;
-                     }
-                     case '&': {
-                         /*
-                          * patch provided by Johnoel Ancheta from U of Hawaii
-                          */
-                         // check if & is for a character reference &#xnnnn;
-                         if (i + 1 < len - 1 && s.charAt(i + 1) == '#') {
-                             str.append("&#");
-                             i += 2;
-
-                             ch = s.charAt(i);
-                             while (i < len && ch != ';') {
-                                 str.append(ch);
-                                 i++;
-                                 ch = s.charAt(i);
-                             }
-                             str.append(';');
-                         } else 
-                         // check if & is in front of amp; 
-                         // (we dont yet check for other HTML 4.0 Character entities) 
-                         if (i + 4 < len  && s.charAt(i + 1) == 'a' 
-                        	 && s.charAt(i + 2) == 'm' 
-                        		 && s.charAt(i + 3) == 'p' 
-                        			 && s.charAt(i + 4) == ';'){
-                             str.append("&amp;");
-                             i += 4;                        	 
-                         }
-                         else  if (i + 3 < len && s.charAt(i + 1) == 'l' 
-                        	 && s.charAt(i + 2) == 't' 
-                        		 && s.charAt(i + 3) == ';' ){
-                    	  // check if & is in front of it; 
-                             str.append("&lt;");
-                             i += 3;                        	 
-                         } 
-                         else  if (i + 3 < len && s.charAt(i + 1) == 'g' 
-                        	 && s.charAt(i + 2) == 't' 
-                        		 && s.charAt(i + 3) == ';' ){
-                    	  // check if & is in front of gt; 
-                           // (we dont yet check for other HTML 4.0 Character entities) 
-                             str.append("&gt;");
-                             i += 3;                        	 
-                         } 
-                         else  if (i + 5 < len && s.charAt(i + 1) == 'q' 
-                        	 && s.charAt(i + 2) == 'u' 
-                        		 && s.charAt(i + 3) == 'o' 
-                        	 && s.charAt(i + 4) == 't'
-                        	 && s.charAt(i + 5) == ';')
-                             {
-                    	   // check if & is in front of quot; 
-                           // (we dont yet check for other HTML 4.0 Character entities) 
-                             str.append("&quot;");
-                             i += 5;                        	 
-                         } 
-                         else  if (i + 5 < len && s.charAt(i + 1) == 'a' 
-                        	 && s.charAt(i + 2) == 'p' 
-                        		 && s.charAt(i + 3) == 'o' 
-                        	 && s.charAt(i + 4) == 's'
-                        	 && s.charAt(i + 5) == ';')
-                             {
-                    	   // check if & is in front of apostrophe; 
-                           // (we dont yet check for other HTML 4.0 Character entities) 
-                             str.append("&apos;");
-                             i += 5;                        	 
-                         } 
-                         else{
-                             str.append("&amp;");
-                         }
-                         /////////
-                         break;
-                     }
-                     case '"':
-                    	 str.append("&quot;");
-                         break;
-                     case '\'':
-                    	 str.append("&apos;");
-                         break;
-                    default: {
-                         if ( (ch<128) && (ch>31) ) {
-                             str.append(ch);
-                         }
-                         else if (ch<32) {
-                             if (ch == 10) { // new line
-                                 str.append(ch);
-                             }
-                             if (ch == 13) { // carriage return
-                                 str.append(ch);
-                             }
-                             if (ch == 9) {  // tab
-                                 str.append(ch);
-                             }
-                             // otherwise skip
-                         }
-                         else {
-                        	 //Don't transfer special character to numeric entity
-                             /*str.append("&#");
-                             str.append(Integer.toString(ch));
-                             str.append(';');*/
-                             str.append(ch);
-                         }
-                     }
-                 }
-             }
-             return str.toString();
-    }
-
-    /**
-     * Get docid from online/url string
-     */
-    public static String getDocIdWithRevFromOnlineURL(String url)
-    {
-        String docid = null;
-        String DOCID = "docid";
-        boolean find = false;
-        char limited = '&';
-        int count = 0; //keep track how many & was found
-        Vector list = new Vector();// keep index number for &
-        if (url == null) {
-            logMetacat.info("url is null and null will be returned");
-            return docid;
-        }
-        // the first element in list is 0
-        list.add(new Integer(0));
-        for (int i = 0; i < url.length(); i++) {
-            if (url.charAt(i) == limited) {
-                // count plus 1
-                count++;
-                list.add(new Integer(i));
-                // get substring beween two &
-                String str = url.substring(
-                        ((Integer) list.elementAt(count - 1)).intValue(), i);
-                logMetacat.info("substring between two & is: " + str);
-                //if the subString contains docid, we got it
-                if (str.indexOf(DOCID) != -1) {
-                    //get index of '="
-                    int start = getIndexForGivenChar(str, '=') + 1;
-                    int end = str.length();
-                    docid = str.substring(start, end);
-                    find = true;
-                }//if
-            }//if
-        }//for
-        //if not find, we need check the subtring between the index of last &
-        // and
-        // the end of string
-        if (!find) {
-            logMetacat.info("Checking the last substring");
-            String str = url.substring(((Integer) list.elementAt(count))
-                    .intValue() + 1, url.length());
-            logMetacat.info("Last substring is: " + str);
-            if (str.indexOf(DOCID) != -1) {
-                //get index of '="
-                int start = getIndexForGivenChar(str, '=') + 1;
-                int end = str.length();
-                docid = str.substring(start, end);
-                find = true;
-            }//if
-        }//if
-        logMetacat.info("The docid from online url is:" + docid);
-        return docid.trim();
-    }
-
-
-    /**
-     * Eocgorid identifier will look like: ecogrid://knb/tao.1.1
-     * The AccessionNumber tao.1.1 will be returned. If the given doesn't
-     * contains ecogrid, null will be returned.
-     * @param identifier String
-     * @return String
-     */
-    public static String getAccessionNumberFromEcogridIdentifier(String identifier)
-    {
-      String accessionNumber = null;
-      if (identifier != null && identifier.startsWith(DBSAXHandler.ECOGRID))
-      {
-        // find the last "/" in identifier
-        int indexOfLastSlash = identifier.lastIndexOf("/");
-        int start = indexOfLastSlash+1;
-        int end   = identifier.length();
-        accessionNumber = identifier.substring(start, end);
-      }
-      logMetacat.warn("The accession number from url is " +
-                                 accessionNumber);
-      return accessionNumber;
-    }
-
-    private static int getIndexForGivenChar(String str, char character)
-    {
-        int index = -1;
-        // make sure str is not null
-        if (str == null) {
-            logMetacat.info(
-                    "The given str is null and -1 will be returned");
-            return index;
-        }
-        // got though the string
-        for (int i = 0; i < str.length(); i++) {
-            // find the first one then break the loop
-            if (str.charAt(i) == character) {
-                index = i;
-                break;
-            }//if
-        }//for
-        logMetacat.info("the index for char " + character + " is: "
-                + index);
-        return index;
-    }
-
-    /**
-     * Utility method to get docid from a given string
-     *
-     * @param string, the given string should be these two format: 1) str1.str2
-     *            in this case docid= str1.str2 2) str1.str2.str3, in this case
-     *            docid =str1.str2
-     * @param the sperator char
-     */
-    public static String getDocIdFromString(String str)
-    {
-        String docId = null;
-        if (str == null) {
-            logMetacat.info(
-                    "The given str is null and null will be returned"
-                            + " in getDocIdfromString");
-            return docId;
-        } //make sure docid is not null
-        int dotNumber = 0;//count how many dots in given string
-        int indexOfLastDot = 0;
-
-        for (int i = 0; i < str.length(); i++) {
-            if (str.charAt(i) == separator) {
-                dotNumber++;//count how many dots
-                indexOfLastDot = i;//keep the last dot postion
-            }
-        }//for
-
-        //The string formatt is wrong, because it has more than two or less
-        // than
-        //one seperator
-        if (dotNumber > 2 || dotNumber < 1) {
-            docId = null;
-        } else if (dotNumber == 2) //the case for str1.str2.str3
-        {
-            docId = str.substring(0, indexOfLastDot);
-        } else if (dotNumber == 1) //the case for str1.str2
-        {
-            docId = str;
-        }
-
-        return docId;
-    }//getDocIdFromString
-
-    /**
-     * Utility method to get version number from a given string
-     *
-     * @param string, the given string should be these two format: 1)
-     *            str1.str2(no version) version =-1; 2) str1.str2.str3, in this
-     *            case version = str3; 3) other, vresion =-2
-     */
-    public static int getVersionFromString(String str)
-            throws NumberFormatException
-    {
-        int version = -1;
-        String versionString = null;
-        int dotNumber = 0;//count how many dots in given string
-        int indexOfLastDot = 0;
-
-        for (int i = 0; i < str.length(); i++) {
-            if (str.charAt(i) == separator) {
-                dotNumber++;//count how many dots
-                indexOfLastDot = i;//keep the last dot postion
-            }
-        }//for
-
-        //The string formatt is wrong, because it has more than two or less
-        // than
-        //one seperator
-        if (dotNumber > 2 || dotNumber < 1) {
-            version = -2;
-        } else if (dotNumber == 2 && (indexOfLastDot != (str.length() - 1)))
-        //the case for str1.str2.str3
-        {
-            versionString = str.substring((indexOfLastDot + 1), str.length());
-            version = Integer.parseInt(versionString);
-        } else if (dotNumber == 1) //the case for str1.str2
-        {
-            version = -1;
-        }
-
-        return version;
-    }//getVersionFromString
-
-    /**
-     * Utility method to get version string from a given string
-     *
-     * @param string, the given string should be these two format: 1)
-     *            str1.str2(no version) version=null; 2) str1.str2.str3, in
-     *            this case version = str3; 3) other, vresion =null;
-     */
-    public static String getRevisionStringFromString(String str)
-            throws NumberFormatException
-    {
-        // String to store the version
-        String versionString = null;
-        int dotNumber = 0;//count how many dots in given string
-        int indexOfLastDot = 0;
-
-        for (int i = 0; i < str.length(); i++) {
-            if (str.charAt(i) == separator) {
-                dotNumber++;//count how many dots
-                indexOfLastDot = i;//keep the last dot postion
-            }
-        }//for
-
-        //The string formatt is wrong, because it has more than two or less
-        // than
-        //one seperator
-        if (dotNumber > 2 || dotNumber < 1) {
-            versionString = null;
-        } else if (dotNumber == 2 && (indexOfLastDot != (str.length() - 1))) {
-            //the case for str1.str2.str3
-            // indexOfLastDot != (str.length() -1) means get rid of str1.str2.
-            versionString = str.substring((indexOfLastDot + 1), str.length());
-        } else if (dotNumber == 1) //the case for str1.str2 or str1.str2.
-        {
-            versionString = null;
-        }
-
-        return versionString;
-    }//getVersionFromString
-
-    /**
-     * This method will get docid from an AccessionNumber. There is no
-     * assumption the accessnumber will be str1.str2.str3. It can be more. So
-     * we think the docid will be get rid of last part
-     */
-    public static String getDocIdFromAccessionNumber(String accessionNumber)
-    {
-        String docid = null;
-        if (accessionNumber == null) { return docid; }
-        int indexOfLastSeperator = accessionNumber.lastIndexOf(separator);
-        docid = accessionNumber.substring(0, indexOfLastSeperator);
-        logMetacat.info("after parsing accessionnumber, docid is "
-                + docid);
-        return docid;
-    }
-
-    /**
-     * This method will get inline data id without the revision number.
-     * So if inlineData.1.2 is passed as input, inlineData.2 is returned.
-     */
-    public static String getInlineDataIdWithoutRev(String accessionNumber)
-    {
-        String docid = null;
-        if (accessionNumber == null) { return docid; }
-        int indexOfLastSeperator = accessionNumber.lastIndexOf(separator);
-        String version = accessionNumber.substring(indexOfLastSeperator,
-                                                   accessionNumber.length());
-        accessionNumber = accessionNumber.substring(0, indexOfLastSeperator);
-        indexOfLastSeperator = accessionNumber.lastIndexOf(separator);
-        docid = accessionNumber.substring(0, indexOfLastSeperator) + version;
-        logMetacat.info("after parsing accessionnumber, docid is "
-                                 + docid);
-
-        return docid;
-    }
-
-    /**
-     * This method will call both getDocIdFromString and
-     * getDocIdFromAccessionNumber. So first, if the string looks str1.str2,
-     * the docid will be str1.str2. If the string is str1.str2.str3, the docid
-     * will be str1.str2. If the string is str1.str2.str3.str4 or more, the
-     * docid will be str1.str2.str3. If the string look like str1, null will be
-     * returned
-     *
-     */
-    public static String getSmartDocId(String str)
-    {
-        String docid = null;
-        //call geDocIdFromString first.
-        docid = getDocIdFromString(str);
-        // If docid is null, try to call getDocIdFromAccessionNumber
-        // it will handle the seperator more than2
-        if (docid == null) {
-            docid = getDocIdFromAccessionNumber(str);
-        }
-        logMetacat.info("The docid get from smart docid getor is "
-                + docid);
-        return docid;
-    }
-
-    /**
-     * This method will get revision from an AccessionNumber. There is no
-     * assumption the accessnumber will be str1.str2.str3. It can be more. So
-     * we think the docid will be get rid of last part
-     */
-    public static int getRevisionFromAccessionNumber(String accessionNumber)
-            throws NumberFormatException
-    {
-        String rev = null;
-        int revNumber = -1;
-        if (accessionNumber == null) { return revNumber; }
-        int indexOfLastSeperator = accessionNumber.lastIndexOf(separator);
-        rev = accessionNumber.substring(indexOfLastSeperator + 1,
-                accessionNumber.length());
-        revNumber = Integer.parseInt(rev);
-        logMetacat.info("after parsing accessionnumber, rev is "
-                + revNumber);
-        return revNumber;
-    }
-
-    /**
-     * Method to get the name of local replication server
-     */
-    public static String getLocalReplicationServerName()
-    {
-        String replicationServerName = null;
-        // String serverHost = null;
-        // serverHost = getProperty("server");
-        // append "context/servlet/replication" to the host name
-        try {
-        replicationServerName = 
-        	SystemUtil.getSecureServer() 
-        	+ FileUtil.getFS()
-			+ PropertyService.getProperty("application.context")
-			+ "/servlet/replication";
-        } catch (PropertyNotFoundException pnfe) {
-        	logMetacat.error("Could not get local replication server name " 
-        			+ "because property could not be found: " + pnfe.getMessage());
-        }
-        return replicationServerName;
-
-    }
-
-    /**
-     * Method to get docidwithrev from eml2 inline data id The eml inline data
-     * id would look like eml.200.2.3
-     */
-    public static String getDocIdWithoutRevFromInlineDataID(String inlineDataID)
-    {
-        String docidWithoutRev = null;
-        if (inlineDataID == null) { return docidWithoutRev; }
-        char charSeperator = separator;
-        int targetNumberOfSeperator = 2;// we want to know his index
-        int numberOfSeperator = 0;
-        for (int i = 0; i < inlineDataID.length(); i++) {
-            // meet seperator, increase number of seperator
-            if (inlineDataID.charAt(i) == charSeperator) {
-                numberOfSeperator++;
-            }
-            // if number of seperator reach the target one, record the index(i)
-            // and get substring and terminate the loop
-            if (numberOfSeperator == targetNumberOfSeperator) {
-                docidWithoutRev = inlineDataID.substring(0, i);
-                break;
-            }
-        }
-
-        logMetacat.info("Docid without rev from inlinedata id: "
-                + docidWithoutRev);
-        return docidWithoutRev;
-
-    }
-
-    /**
-     * Revise stack change a stack to opposite order
-     */
-    public static Stack<NodeRecord> reviseStack(Stack<NodeRecord> stack)
-    {
-        Stack result = new Stack();
-        // make sure the parameter is correct
-        if (stack == null || stack.isEmpty()) {
-            result = stack;
-            return result;
-        }
-
-        while (!stack.isEmpty()) {
-            Object obj = stack.pop();
-            result.push(obj);
-        }
-        return result;
-    }
-
-    /** A method to replace whitespace in url */
-    public static String replaceWhiteSpaceForURL(String urlHasWhiteSpace)
-    {
-        StringBuffer newUrl = new StringBuffer();
-        String whiteSpaceReplace = "%20";
-        if (urlHasWhiteSpace == null || urlHasWhiteSpace.trim().equals("")) { return null; }
-
-        for (int i = 0; i < urlHasWhiteSpace.length(); i++) {
-            char ch = urlHasWhiteSpace.charAt(i);
-            if (!Character.isWhitespace(ch)) {
-                newUrl.append(ch);
-            } else {
-                //it is white sapce, replace it by %20
-                newUrl = newUrl.append(whiteSpaceReplace);
-            }
-
-        }//for
-        logMetacat.info("The new string without space is:"
-                + newUrl.toString());
-        return newUrl.toString();
-
-    }// replaceWhiteSpaceForUR
-
-    /**
-	 * Writes debug information into a file. In metacat.properties, if property
-	 * application.writeDebugToFile is set to true, the debug information will be written to
-	 * debug file, which value is the property application.debugOutputFile in
-	 * metacat.properties.
-	 * 
-	 */
-	public static void writeDebugToFile(String debugInfo) {
-		String debug = "false";
-		try {
-			debug = PropertyService.getProperty("application.writeDebugToFile");
-			if (debug != null && debug.equalsIgnoreCase("true")) {
-				File outputFile = 
-					new File(PropertyService.getProperty("application.debugOutputFile"));
-				FileOutputStream fos = new FileOutputStream(outputFile, true);
-				PrintWriter pw = new PrintWriter(fos);
-				pw.println(debugInfo);
-				pw.flush();
-				pw.close();
-				fos.close();
-			}
-		} catch (PropertyNotFoundException pnfe) {
-			// only log debug to file warning once
-			if (!debugErrorDisplayed) {
-				logMetacat.warn("Could not get debug property.  Write debug to " 
-						+ "file is set to false: " + pnfe.getMessage());
-				debugErrorDisplayed = true;
-			}
-		} catch (Exception io) {
-			logMetacat.warn("Error in MetacatUtil.writeDebugToFile "
-					+ io.getMessage());
-		}
-	}
-    
-   /**
-	 * Writes debug information into a file in delimitered format
-	 * 
-	 * @param debugInfo
-	 *            the debug information
-	 * @param newLine
-	 *            append the debug info to a line or not
-	 */
-	public static void writeDebugToDelimiteredFile(String debugInfo, boolean newLine) {
-		String debug = "false";
-		try {
-			debug = PropertyService.getProperty("application.writeDebugToFile");
-			if (debug != null && debug.equalsIgnoreCase("true")) {
-				File outputFile = new File(PropertyService
-						.getProperty("application.delimiteredOutputFile"));
-				FileOutputStream fos = new FileOutputStream(outputFile, true);
-				PrintWriter pw = new PrintWriter(fos);
-				if (newLine) {
-					pw.println(debugInfo);
-				} else {
-					pw.print(debugInfo);
-				}
-				pw.flush();
-				pw.close();
-				fos.close();
-			}
-		} catch (PropertyNotFoundException pnfe) {
-			// only log debug to file warning once
-			if (!debugErrorDisplayed) {
-				logMetacat.warn("Could not get delimited debug property. Write debug to " 
-						+ "file is set to false: " + pnfe.getMessage());
-				debugErrorDisplayed = true;
-			}
-		} catch (Exception io) {
-			logMetacat.warn("Eorr in writeDebugToDelimiteredFile "
-					+ io.getMessage());
-		}
-	}
-
-		/**
-		 * Write the uploaded file to disk for temporary storage before moving
-		 * it to its final Metacat location.
-		 * 
-		 * @param filePart
-		 *            the FilePart object containing the file form element
-		 * @param fileName
-		 *            the name of the file to be written to disk
-		 * @return tempFilePath a String containing location of temporary file
-		 */
-    public static String writeTempFile (FilePart filePart, String fileName) {
-        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
-        String tempFilePath = null;
-        String tempDirPath = null;
-        try {
-        	tempDirPath = PropertyService.getProperty("application.tempDir");
-        } catch (PropertyNotFoundException pnfe) {
-        	logMetacat.warn("Temp property not found.  An attempt will be made " 
-        			+ "to use system temp directory: " + pnfe.getMessage());
-        }
-        long fileSize;
-        File tempFile;
-        File tempDir;
-
-        if ((fileName == null) || fileName.equals("")) {
-            return tempFilePath;
-        }
-				
-        // the tempfilepath token isn't set, use Java default
-		if (tempDirPath == null) {
-			String javaTempDir = System.getProperty("java.io.tempdir");
-			if (javaTempDir == null) {
-				// no paths set, use unix default
-				tempDirPath = "/tmp";
-			} else {
-				tempDirPath = javaTempDir;
-			}
-		}
-
-        tempDir = new File(tempDirPath);
-
-        // Create the temporary directory if it doesn't exist
-        try {
-            if (!tempDir.exists()) {
-                tempDir.mkdirs();
-            }
-        } catch (SecurityException e) {
-            logMetacat.error("Can't create directory: " + tempDir.getPath() +
-                             ". Error: " + e.getMessage());
-        }
-        try {
-            tempFile = new File(tempDirPath, fileName);
-            fileSize = filePart.writeTo(tempFile);
-            tempFilePath = tempDirPath + File.separator + fileName;
-
-            if (fileSize == 0) {
-                logMetacat.error("Uploaded file '" + fileName + "'is empty!");
-            }
-        } catch (IOException e) {
-            logMetacat.error("IO exception which writing temporary file: " +
-                             tempFilePath + " " + e.getMessage());
-        }
-
-        logMetacat.info("Temporary file is: " + tempFilePath);
-
-        return tempFilePath;
-    }
-
-    /**
-	 * 
-	 * Copy a file between two locations specified as strings. Fails if either
-	 * path cannot be created. Based on the public domain FileCopy class in
-	 * _Java in a Nutshell_.
-	 * 
-	 * @param sourceName
-	 *            the source file to read from disk
-	 * @param destName
-	 *            the destination file on disk
-	 */
-    public static void copyFile(String sourceName, String destName) throws IOException {
-        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
-
-        File sourceFile = new File(sourceName);
-        File destFile = new File(destName);
-        FileInputStream source = null;
-        FileOutputStream dest = null;
-        byte[] buffer;
-        int bytesRead;
-
-        try {
-            if (!sourceFile.exists() || !sourceFile.isFile()) {
-                logMetacat.error("File copy: no such source" +
-                                 " file: " + sourceName);
-            }
-            if (!sourceFile.canRead()) {
-                logMetacat.error("File copy: source file " +
-                                 "is unreadable: " + sourceName);
-            }
-
-            if (destFile.exists()) {
-                if (destFile.isFile()) {
-                    if (!destFile.canWrite()) {
-                        logMetacat.error("File copy: destination " +
-                                         "file is unwriteable: " + destFile);
-                    }
-                } else {
-                    logMetacat.error("File copy: destination file " +
-                                     "is not a file: " + destFile);
-                }
-            } else {
-                File parentDir = parent(destFile);
-
-                if (!parentDir.exists())
-                {
-                    logMetacat.error("File copy: destination diretory " +
-                                     " doesn't exist: " + destName);
-                }
-                if (!parentDir.canWrite()) {
-                    logMetacat.error("File copy: destination directory " +
-                                     " is unwritable: " + destName);
-                }
-            }
-
-            // Verbose error checking done, copy the file object
-            source = new FileInputStream(sourceFile);
-            dest = new FileOutputStream(destFile);
-            buffer = new byte[1024];
-
-            while (true) {
-                bytesRead = source.read(buffer);
-                if (bytesRead == -1) {
-                    break;
-                }
-                dest.write(buffer, 0, bytesRead);
-            }
-        }
-        finally {
-            if (source != null) {
-                try { source.close(); } catch (IOException e) { ; }
-            }
-            if (dest != null) {
-                try { dest.close(); } catch (IOException e) { ; }
-            }
-        }
-    }
-
-    private static File parent(File f) {
-        String dirname = f.getParent();
-        if (dirname == null) {
-            if (f.isAbsolute()) return new File(File.separator);
-            else return new File(System.getProperty("user.dir"));
-        }
-        return new File(dirname);
-    }
-
-	/**
-	 * Reports whether metacat is fully configured.
-	 * 
-	 * @return a boolean that is true if all sections are configured and 
-	 * false otherwise
-	 */
-	public static boolean isMetacatConfigured() {
-		boolean metacatConfigured = false;
-		try {
-			metacatConfigured = PropertyService.arePropertiesConfigured()
-//					&& OrganizationUtil.areOrganizationsConfigured() 
-					&& AuthUtil.isAuthConfigured()
-					&& SkinUtil.areSkinsConfigured()
-					&& DatabaseUtil.isDatabaseConfigured()
-					&& GeoserverUtil.isGeoserverConfigured();
-		} catch (UtilException ue) {
-			logMetacat.error("Could not determine if metacat is configured: "
-					+ ue.getMessage());
-		}
-
-		return metacatConfigured;
-	}
-		
-	/**
-	 * Reports whether the metacat configuration utility should be run.  
-	 * Returns false if  
-	 *   -- dev.runConfiguration=false and
-	 *   -- backup properties file exists
-	 * Note that dev.runConfiguration should only be set to false when
-	 * reinstalling the same version of the application in developement.
-	 * 
-	 * @return a boolean that is false if dev.runConfiguration is false and 
-	 * the backup properties file exists.  
-	 */
-	public static boolean bypassConfiguration() {
-		
-		// we use the bypassConfiguration() method in Property service
-		// to determine if bypass is necessary.  if it is, we call the 
-		// similar method in SkinPropertyService.  Both of these calls
-		// make sure backup properties get persisted to active properties.
-		boolean bypass = PropertyService.bypassConfiguration();
-		if (bypass) {
-			SkinPropertyService.bypassConfiguration();
-		}
-		
-		return bypass;
-	}
-		
-}

Property changes on: src/edu/ucsb/nceas/metacat/util/MetaCatUtil.java
___________________________________________________________________
Deleted: svn:eol-style
## -1 +0,0 ##
-native
\ No newline at end of property
Deleted: svn:executable
## -1 +0,0 ##
-*
\ No newline at end of property
Deleted: svn:keywords
## -1 +0,0 ##
-Author Date Id Revision
\ No newline at end of property
Index: src/edu/ucsb/nceas/metacat/spatial/SpatialHarvester.java
===================================================================
--- src/edu/ucsb/nceas/metacat/spatial/SpatialHarvester.java	(revision 4698)
+++ src/edu/ucsb/nceas/metacat/spatial/SpatialHarvester.java	(revision 4699)
@@ -32,7 +32,7 @@
 import org.apache.log4j.Logger;
 
 import edu.ucsb.nceas.metacat.DBConnection;
-import edu.ucsb.nceas.metacat.util.MetaCatUtil;
+import edu.ucsb.nceas.metacat.util.MetacatUtil;
 
 import org.geotools.feature.Feature;
 
Index: src/edu/ucsb/nceas/metacat/spatial/SpatialQuery.java
===================================================================
--- src/edu/ucsb/nceas/metacat/spatial/SpatialQuery.java	(revision 4698)
+++ src/edu/ucsb/nceas/metacat/spatial/SpatialQuery.java	(revision 4699)
@@ -59,7 +59,7 @@
 
 import org.apache.log4j.Logger;
 
-import edu.ucsb.nceas.metacat.util.MetaCatUtil;
+import edu.ucsb.nceas.metacat.util.MetacatUtil;
 
 /** 
  * Class to query the persistent spatial cache
Index: src/edu/ucsb/nceas/metacat/spatial/SpatialDocument.java
===================================================================
--- src/edu/ucsb/nceas/metacat/spatial/SpatialDocument.java	(revision 4698)
+++ src/edu/ucsb/nceas/metacat/spatial/SpatialDocument.java	(revision 4699)
@@ -26,7 +26,7 @@
 
 import edu.ucsb.nceas.metacat.DBConnection;
 import edu.ucsb.nceas.metacat.service.PropertyService;
-import edu.ucsb.nceas.metacat.util.MetaCatUtil;
+import edu.ucsb.nceas.metacat.util.MetacatUtil;
 import edu.ucsb.nceas.metacat.util.SystemUtil;
 import edu.ucsb.nceas.utilities.PropertyNotFoundException;
 
@@ -120,7 +120,7 @@
 		// document matches
 		// If so, get the appropriate corner xpaths
 		try {
-			Vector spatialDocnames = MetaCatUtil.getOptionList(PropertyService
+			Vector spatialDocnames = MetacatUtil.getOptionList(PropertyService
 					.getProperty("spatial.spatialDocnameList"));
 			for (int i = 0; i < spatialDocnames.size(); i++) {
 				thisDocname = ((String) spatialDocnames.elementAt(i)).trim();
Index: src/edu/ucsb/nceas/metacat/util/MetacatUtil.java
===================================================================
--- src/edu/ucsb/nceas/metacat/util/MetacatUtil.java	(nonexistent)
+++ src/edu/ucsb/nceas/metacat/util/MetacatUtil.java	(revision 4699)
@@ -0,0 +1,1013 @@
+/**
+ *  '$RCSfile$'
+ *    Purpose: A Class that implements utility methods for a metadata catalog
+ *  Copyright: 2000 Regents of the University of California and the
+ *             National Center for Ecological Analysis and Synthesis
+ *    Authors: Matt Jones, Jivka Bojilova
+ *
+ *   '$Author$'
+ *     '$Date$'
+ * '$Revision$'
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+package edu.ucsb.nceas.metacat.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.MalformedURLException;
+import java.util.Hashtable;
+import java.util.Stack;
+import java.util.Vector;
+
+import org.apache.log4j.Logger;
+
+import com.oreilly.servlet.multipart.FilePart;
+
+import edu.ucsb.nceas.dbadapter.AbstractDatabase;
+import edu.ucsb.nceas.metacat.DBSAXHandler;
+import edu.ucsb.nceas.metacat.MetaCatServlet;
+import edu.ucsb.nceas.metacat.NodeRecord;
+import edu.ucsb.nceas.metacat.service.PropertyService;
+import edu.ucsb.nceas.metacat.service.ServiceException;
+import edu.ucsb.nceas.metacat.service.ServiceService;
+import edu.ucsb.nceas.metacat.service.SkinPropertyService;
+import edu.ucsb.nceas.utilities.GeneralPropertyException;
+import edu.ucsb.nceas.utilities.PropertyNotFoundException;
+import edu.ucsb.nceas.utilities.FileUtil;
+
+/**
+ * A suite of utility classes for the metadata catalog server
+ */
+public class MetacatUtil
+{
+
+    public static AbstractDatabase dbAdapter;
+
+    public static Vector pathsForIndexing;
+    
+    private static boolean debug = true;
+    
+    private static boolean debugErrorDisplayed = false;
+    
+    private static Logger logMetacat = Logger.getLogger(MetacatUtil.class);
+    private static char separator = '.';
+
+    static {
+        try {
+        	separator = PropertyService.getProperty("document.accNumSeparator").charAt(0);
+        } catch (PropertyNotFoundException pnfe) {
+        	logMetacat.error("Could not retrieve account number separator. " 
+        			+ "Separator set to '.' : " + pnfe.getMessage());
+        }
+    }
+
+    /**
+     * Utility method to parse the query part of a URL into parameters. This
+     * method assumes the format of the query par tof the url is an ampersand
+     * separated list of name/value pairs, with equal signs separating the name
+     * from the value (e.g., name=tom&zip=99801 ). Returns a has of the name
+     * value pairs, hashed on name.
+     */
+    public static Hashtable<String,String> parseQuery(String query)
+            throws MalformedURLException
+    {
+        String[][] params = new String[200][2];
+        Hashtable<String,String> parameters = new Hashtable<String,String>();
+
+        String temp = "";
+        boolean ampflag = true;
+        boolean poundflag = false;
+        int arrcount = 0;
+
+        if (query != null) {
+            for (int i = 0; i < query.length(); i++) {
+
+                // go throught the remainder of the query one character at a
+                // time.
+                if (query.charAt(i) == '=') {
+                    // if the current char is a # then the preceding should be
+                    // a name
+                    if (!poundflag && ampflag) {
+                        params[arrcount][0] = temp.trim();
+                        temp = "";
+                    } else {
+                        //if there are two #s or &s in a row throw an
+                        // exception.
+                        throw new MalformedURLException(
+                                "metacatURL: Two parameter names "
+                                        + "not allowed in sequence");
+                    }
+                    poundflag = true;
+                    ampflag = false;
+                } else if (query.charAt(i) == '&' || i == query.length() - 1) {
+                    //the text preceding the & should be the param value.
+                    if (i == query.length() - 1) {
+                        //if at the end of the string grab the last value and
+                        // append it.
+                        if (query.charAt(i) != '=') {
+                            //ignore an extra & on the end of the string
+                            temp += query.charAt(i);
+                        }
+                    }
+
+                    if (!ampflag && poundflag) {
+                        params[arrcount][1] = temp.trim();
+                        parameters
+                                .put(params[arrcount][0], params[arrcount][1]);
+                        temp = "";
+                        arrcount++; //increment the array to the next row.
+                    } else {
+                        //if there are two =s or &s in a row through an
+                        // exception
+                        throw new MalformedURLException(
+                                "metacatURL: Two parameter values "
+                                        + "not allowed in sequence");
+                    }
+                    poundflag = false;
+                    ampflag = true;
+                } else {
+                    //get the next character in the string
+                    temp += query.charAt(i);
+                }
+            }
+        }
+        return parameters;
+    }
+  
+    public static Vector<String> getOptionList(String optiontext)
+    {
+        Vector<String> optionsVector = new Vector<String>();
+        if (optiontext.indexOf(",") == -1) {
+            optionsVector.addElement(optiontext);
+            return optionsVector;
+        }
+
+        while (optiontext.indexOf(",") != -1) {
+            String s = optiontext.substring(0, optiontext.indexOf(","));
+            optionsVector.addElement(s.trim());
+            optiontext = optiontext.substring(optiontext.indexOf(",") + 1,
+                    optiontext.length());
+            if (optiontext.indexOf(",") == -1) { //catch the last list entry
+                optionsVector.addElement(optiontext.trim());
+            }
+        }
+        return optionsVector;
+    }
+
+    /** Normalizes a string read from DB. So it will be compatible to HTML */
+    public static String normalize(String s)
+    {
+        StringBuffer str = new StringBuffer();
+
+             int len = (s != null) ? s.length() : 0;
+             for (int i = 0; i < len; i++) {
+                 char ch = s.charAt(i);
+                 switch (ch) {
+                     case '<': {
+                         str.append("&lt;");
+                         break;
+                     }
+                     case '>': {
+                         str.append("&gt;");
+                         break;
+                     }
+                     case '&': {
+                         /*
+                          * patch provided by Johnoel Ancheta from U of Hawaii
+                          */
+                         // check if & is for a character reference &#xnnnn;
+                         if (i + 1 < len - 1 && s.charAt(i + 1) == '#') {
+                             str.append("&#");
+                             i += 2;
+
+                             ch = s.charAt(i);
+                             while (i < len && ch != ';') {
+                                 str.append(ch);
+                                 i++;
+                                 ch = s.charAt(i);
+                             }
+                             str.append(';');
+                         } else 
+                         // check if & is in front of amp; 
+                         // (we dont yet check for other HTML 4.0 Character entities) 
+                         if (i + 4 < len  && s.charAt(i + 1) == 'a' 
+                        	 && s.charAt(i + 2) == 'm' 
+                        		 && s.charAt(i + 3) == 'p' 
+                        			 && s.charAt(i + 4) == ';'){
+                             str.append("&amp;");
+                             i += 4;                        	 
+                         }
+                         else  if (i + 3 < len && s.charAt(i + 1) == 'l' 
+                        	 && s.charAt(i + 2) == 't' 
+                        		 && s.charAt(i + 3) == ';' ){
+                    	  // check if & is in front of it; 
+                             str.append("&lt;");
+                             i += 3;                        	 
+                         } 
+                         else  if (i + 3 < len && s.charAt(i + 1) == 'g' 
+                        	 && s.charAt(i + 2) == 't' 
+                        		 && s.charAt(i + 3) == ';' ){
+                    	  // check if & is in front of gt; 
+                           // (we dont yet check for other HTML 4.0 Character entities) 
+                             str.append("&gt;");
+                             i += 3;                        	 
+                         } 
+                         else  if (i + 5 < len && s.charAt(i + 1) == 'q' 
+                        	 && s.charAt(i + 2) == 'u' 
+                        		 && s.charAt(i + 3) == 'o' 
+                        	 && s.charAt(i + 4) == 't'
+                        	 && s.charAt(i + 5) == ';')
+                             {
+                    	   // check if & is in front of quot; 
+                           // (we dont yet check for other HTML 4.0 Character entities) 
+                             str.append("&quot;");
+                             i += 5;                        	 
+                         } 
+                         else  if (i + 5 < len && s.charAt(i + 1) == 'a' 
+                        	 && s.charAt(i + 2) == 'p' 
+                        		 && s.charAt(i + 3) == 'o' 
+                        	 && s.charAt(i + 4) == 's'
+                        	 && s.charAt(i + 5) == ';')
+                             {
+                    	   // check if & is in front of apostrophe; 
+                           // (we dont yet check for other HTML 4.0 Character entities) 
+                             str.append("&apos;");
+                             i += 5;                        	 
+                         } 
+                         else{
+                             str.append("&amp;");
+                         }
+                         /////////
+                         break;
+                     }
+                     case '"':
+                    	 str.append("&quot;");
+                         break;
+                     case '\'':
+                    	 str.append("&apos;");
+                         break;
+                    default: {
+                         if ( (ch<128) && (ch>31) ) {
+                             str.append(ch);
+                         }
+                         else if (ch<32) {
+                             if (ch == 10) { // new line
+                                 str.append(ch);
+                             }
+                             if (ch == 13) { // carriage return
+                                 str.append(ch);
+                             }
+                             if (ch == 9) {  // tab
+                                 str.append(ch);
+                             }
+                             // otherwise skip
+                         }
+                         else {
+                        	 //Don't transfer special character to numeric entity
+                             /*str.append("&#");
+                             str.append(Integer.toString(ch));
+                             str.append(';');*/
+                             str.append(ch);
+                         }
+                     }
+                 }
+             }
+             return str.toString();
+    }
+
+    /**
+     * Get docid from online/url string
+     */
+    public static String getDocIdWithRevFromOnlineURL(String url)
+    {
+        String docid = null;
+        String DOCID = "docid";
+        boolean find = false;
+        char limited = '&';
+        int count = 0; //keep track how many & was found
+        Vector list = new Vector();// keep index number for &
+        if (url == null) {
+            logMetacat.info("url is null and null will be returned");
+            return docid;
+        }
+        // the first element in list is 0
+        list.add(new Integer(0));
+        for (int i = 0; i < url.length(); i++) {
+            if (url.charAt(i) == limited) {
+                // count plus 1
+                count++;
+                list.add(new Integer(i));
+                // get substring beween two &
+                String str = url.substring(
+                        ((Integer) list.elementAt(count - 1)).intValue(), i);
+                logMetacat.info("substring between two & is: " + str);
+                //if the subString contains docid, we got it
+                if (str.indexOf(DOCID) != -1) {
+                    //get index of '="
+                    int start = getIndexForGivenChar(str, '=') + 1;
+                    int end = str.length();
+                    docid = str.substring(start, end);
+                    find = true;
+                }//if
+            }//if
+        }//for
+        //if not find, we need check the subtring between the index of last &
+        // and
+        // the end of string
+        if (!find) {
+            logMetacat.info("Checking the last substring");
+            String str = url.substring(((Integer) list.elementAt(count))
+                    .intValue() + 1, url.length());
+            logMetacat.info("Last substring is: " + str);
+            if (str.indexOf(DOCID) != -1) {
+                //get index of '="
+                int start = getIndexForGivenChar(str, '=') + 1;
+                int end = str.length();
+                docid = str.substring(start, end);
+                find = true;
+            }//if
+        }//if
+        logMetacat.info("The docid from online url is:" + docid);
+        return docid.trim();
+    }
+
+
+    /**
+     * Eocgorid identifier will look like: ecogrid://knb/tao.1.1
+     * The AccessionNumber tao.1.1 will be returned. If the given doesn't
+     * contains ecogrid, null will be returned.
+     * @param identifier String
+     * @return String
+     */
+    public static String getAccessionNumberFromEcogridIdentifier(String identifier)
+    {
+      String accessionNumber = null;
+      if (identifier != null && identifier.startsWith(DBSAXHandler.ECOGRID))
+      {
+        // find the last "/" in identifier
+        int indexOfLastSlash = identifier.lastIndexOf("/");
+        int start = indexOfLastSlash+1;
+        int end   = identifier.length();
+        accessionNumber = identifier.substring(start, end);
+      }
+      logMetacat.warn("The accession number from url is " +
+                                 accessionNumber);
+      return accessionNumber;
+    }
+
+    private static int getIndexForGivenChar(String str, char character)
+    {
+        int index = -1;
+        // make sure str is not null
+        if (str == null) {
+            logMetacat.info(
+                    "The given str is null and -1 will be returned");
+            return index;
+        }
+        // got though the string
+        for (int i = 0; i < str.length(); i++) {
+            // find the first one then break the loop
+            if (str.charAt(i) == character) {
+                index = i;
+                break;
+            }//if
+        }//for
+        logMetacat.info("the index for char " + character + " is: "
+                + index);
+        return index;
+    }
+
+    /**
+     * Utility method to get docid from a given string
+     *
+     * @param string, the given string should be these two format: 1) str1.str2
+     *            in this case docid= str1.str2 2) str1.str2.str3, in this case
+     *            docid =str1.str2
+     * @param the sperator char
+     */
+    public static String getDocIdFromString(String str)
+    {
+        String docId = null;
+        if (str == null) {
+            logMetacat.info(
+                    "The given str is null and null will be returned"
+                            + " in getDocIdfromString");
+            return docId;
+        } //make sure docid is not null
+        int dotNumber = 0;//count how many dots in given string
+        int indexOfLastDot = 0;
+
+        for (int i = 0; i < str.length(); i++) {
+            if (str.charAt(i) == separator) {
+                dotNumber++;//count how many dots
+                indexOfLastDot = i;//keep the last dot postion
+            }
+        }//for
+
+        //The string formatt is wrong, because it has more than two or less
+        // than
+        //one seperator
+        if (dotNumber > 2 || dotNumber < 1) {
+            docId = null;
+        } else if (dotNumber == 2) //the case for str1.str2.str3
+        {
+            docId = str.substring(0, indexOfLastDot);
+        } else if (dotNumber == 1) //the case for str1.str2
+        {
+            docId = str;
+        }
+
+        return docId;
+    }//getDocIdFromString
+
+    /**
+     * Utility method to get version number from a given string
+     *
+     * @param string, the given string should be these two format: 1)
+     *            str1.str2(no version) version =-1; 2) str1.str2.str3, in this
+     *            case version = str3; 3) other, vresion =-2
+     */
+    public static int getVersionFromString(String str)
+            throws NumberFormatException
+    {
+        int version = -1;
+        String versionString = null;
+        int dotNumber = 0;//count how many dots in given string
+        int indexOfLastDot = 0;
+
+        for (int i = 0; i < str.length(); i++) {
+            if (str.charAt(i) == separator) {
+                dotNumber++;//count how many dots
+                indexOfLastDot = i;//keep the last dot postion
+            }
+        }//for
+
+        //The string formatt is wrong, because it has more than two or less
+        // than
+        //one seperator
+        if (dotNumber > 2 || dotNumber < 1) {
+            version = -2;
+        } else if (dotNumber == 2 && (indexOfLastDot != (str.length() - 1)))
+        //the case for str1.str2.str3
+        {
+            versionString = str.substring((indexOfLastDot + 1), str.length());
+            version = Integer.parseInt(versionString);
+        } else if (dotNumber == 1) //the case for str1.str2
+        {
+            version = -1;
+        }
+
+        return version;
+    }//getVersionFromString
+
+    /**
+     * Utility method to get version string from a given string
+     *
+     * @param string, the given string should be these two format: 1)
+     *            str1.str2(no version) version=null; 2) str1.str2.str3, in
+     *            this case version = str3; 3) other, vresion =null;
+     */
+    public static String getRevisionStringFromString(String str)
+            throws NumberFormatException
+    {
+        // String to store the version
+        String versionString = null;
+        int dotNumber = 0;//count how many dots in given string
+        int indexOfLastDot = 0;
+
+        for (int i = 0; i < str.length(); i++) {
+            if (str.charAt(i) == separator) {
+                dotNumber++;//count how many dots
+                indexOfLastDot = i;//keep the last dot postion
+            }
+        }//for
+
+        //The string formatt is wrong, because it has more than two or less
+        // than
+        //one seperator
+        if (dotNumber > 2 || dotNumber < 1) {
+            versionString = null;
+        } else if (dotNumber == 2 && (indexOfLastDot != (str.length() - 1))) {
+            //the case for str1.str2.str3
+            // indexOfLastDot != (str.length() -1) means get rid of str1.str2.
+            versionString = str.substring((indexOfLastDot + 1), str.length());
+        } else if (dotNumber == 1) //the case for str1.str2 or str1.str2.
+        {
+            versionString = null;
+        }
+
+        return versionString;
+    }//getVersionFromString
+
+    /**
+     * This method will get docid from an AccessionNumber. There is no
+     * assumption the accessnumber will be str1.str2.str3. It can be more. So
+     * we think the docid will be get rid of last part
+     */
+    public static String getDocIdFromAccessionNumber(String accessionNumber)
+    {
+        String docid = null;
+        if (accessionNumber == null) { return docid; }
+        int indexOfLastSeperator = accessionNumber.lastIndexOf(separator);
+        docid = accessionNumber.substring(0, indexOfLastSeperator);
+        logMetacat.info("after parsing accessionnumber, docid is "
+                + docid);
+        return docid;
+    }
+
+    /**
+     * This method will get inline data id without the revision number.
+     * So if inlineData.1.2 is passed as input, inlineData.2 is returned.
+     */
+    public static String getInlineDataIdWithoutRev(String accessionNumber)
+    {
+        String docid = null;
+        if (accessionNumber == null) { return docid; }
+        int indexOfLastSeperator = accessionNumber.lastIndexOf(separator);
+        String version = accessionNumber.substring(indexOfLastSeperator,
+                                                   accessionNumber.length());
+        accessionNumber = accessionNumber.substring(0, indexOfLastSeperator);
+        indexOfLastSeperator = accessionNumber.lastIndexOf(separator);
+        docid = accessionNumber.substring(0, indexOfLastSeperator) + version;
+        logMetacat.info("after parsing accessionnumber, docid is "
+                                 + docid);
+
+        return docid;
+    }
+
+    /**
+     * This method will call both getDocIdFromString and
+     * getDocIdFromAccessionNumber. So first, if the string looks str1.str2,
+     * the docid will be str1.str2. If the string is str1.str2.str3, the docid
+     * will be str1.str2. If the string is str1.str2.str3.str4 or more, the
+     * docid will be str1.str2.str3. If the string look like str1, null will be
+     * returned
+     *
+     */
+    public static String getSmartDocId(String str)
+    {
+        String docid = null;
+        //call geDocIdFromString first.
+        docid = getDocIdFromString(str);
+        // If docid is null, try to call getDocIdFromAccessionNumber
+        // it will handle the seperator more than2
+        if (docid == null) {
+            docid = getDocIdFromAccessionNumber(str);
+        }
+        logMetacat.info("The docid get from smart docid getor is "
+                + docid);
+        return docid;
+    }
+
+    /**
+     * This method will get revision from an AccessionNumber. There is no
+     * assumption the accessnumber will be str1.str2.str3. It can be more. So
+     * we think the docid will be get rid of last part
+     */
+    public static int getRevisionFromAccessionNumber(String accessionNumber)
+            throws NumberFormatException
+    {
+        String rev = null;
+        int revNumber = -1;
+        if (accessionNumber == null) { return revNumber; }
+        int indexOfLastSeperator = accessionNumber.lastIndexOf(separator);
+        rev = accessionNumber.substring(indexOfLastSeperator + 1,
+                accessionNumber.length());
+        revNumber = Integer.parseInt(rev);
+        logMetacat.info("after parsing accessionnumber, rev is "
+                + revNumber);
+        return revNumber;
+    }
+
+    /**
+     * Method to get the name of local replication server
+     */
+    public static String getLocalReplicationServerName()
+    {
+        String replicationServerName = null;
+        // String serverHost = null;
+        // serverHost = getProperty("server");
+        // append "context/servlet/replication" to the host name
+        try {
+        replicationServerName = 
+        	SystemUtil.getSecureServer() 
+        	+ FileUtil.getFS()
+			+ PropertyService.getProperty("application.context")
+			+ "/servlet/replication";
+        } catch (PropertyNotFoundException pnfe) {
+        	logMetacat.error("Could not get local replication server name " 
+        			+ "because property could not be found: " + pnfe.getMessage());
+        }
+        return replicationServerName;
+
+    }
+
+    /**
+     * Method to get docidwithrev from eml2 inline data id The eml inline data
+     * id would look like eml.200.2.3
+     */
+    public static String getDocIdWithoutRevFromInlineDataID(String inlineDataID)
+    {
+        String docidWithoutRev = null;
+        if (inlineDataID == null) { return docidWithoutRev; }
+        char charSeperator = separator;
+        int targetNumberOfSeperator = 2;// we want to know his index
+        int numberOfSeperator = 0;
+        for (int i = 0; i < inlineDataID.length(); i++) {
+            // meet seperator, increase number of seperator
+            if (inlineDataID.charAt(i) == charSeperator) {
+                numberOfSeperator++;
+            }
+            // if number of seperator reach the target one, record the index(i)
+            // and get substring and terminate the loop
+            if (numberOfSeperator == targetNumberOfSeperator) {
+                docidWithoutRev = inlineDataID.substring(0, i);
+                break;
+            }
+        }
+
+        logMetacat.info("Docid without rev from inlinedata id: "
+                + docidWithoutRev);
+        return docidWithoutRev;
+
+    }
+
+    /**
+     * Revise stack change a stack to opposite order
+     */
+    public static Stack<NodeRecord> reviseStack(Stack<NodeRecord> stack)
+    {
+        Stack result = new Stack();
+        // make sure the parameter is correct
+        if (stack == null || stack.isEmpty()) {
+            result = stack;
+            return result;
+        }
+
+        while (!stack.isEmpty()) {
+            Object obj = stack.pop();
+            result.push(obj);
+        }
+        return result;
+    }
+
+    /** A method to replace whitespace in url */
+    public static String replaceWhiteSpaceForURL(String urlHasWhiteSpace)
+    {
+        StringBuffer newUrl = new StringBuffer();
+        String whiteSpaceReplace = "%20";
+        if (urlHasWhiteSpace == null || urlHasWhiteSpace.trim().equals("")) { return null; }
+
+        for (int i = 0; i < urlHasWhiteSpace.length(); i++) {
+            char ch = urlHasWhiteSpace.charAt(i);
+            if (!Character.isWhitespace(ch)) {
+                newUrl.append(ch);
+            } else {
+                //it is white sapce, replace it by %20
+                newUrl = newUrl.append(whiteSpaceReplace);
+            }
+
+        }//for
+        logMetacat.info("The new string without space is:"
+                + newUrl.toString());
+        return newUrl.toString();
+
+    }// replaceWhiteSpaceForUR
+
+    /**
+	 * Writes debug information into a file. In metacat.properties, if property
+	 * application.writeDebugToFile is set to true, the debug information will be written to
+	 * debug file, which value is the property application.debugOutputFile in
+	 * metacat.properties.
+	 * 
+	 */
+	public static void writeDebugToFile(String debugInfo) {
+		String debug = "false";
+		try {
+			debug = PropertyService.getProperty("application.writeDebugToFile");
+			if (debug != null && debug.equalsIgnoreCase("true")) {
+				File outputFile = 
+					new File(PropertyService.getProperty("application.debugOutputFile"));
+				FileOutputStream fos = new FileOutputStream(outputFile, true);
+				PrintWriter pw = new PrintWriter(fos);
+				pw.println(debugInfo);
+				pw.flush();
+				pw.close();
+				fos.close();
+			}
+		} catch (PropertyNotFoundException pnfe) {
+			// only log debug to file warning once
+			if (!debugErrorDisplayed) {
+				logMetacat.warn("Could not get debug property.  Write debug to " 
+						+ "file is set to false: " + pnfe.getMessage());
+				debugErrorDisplayed = true;
+			}
+		} catch (Exception io) {
+			logMetacat.warn("Error in MetacatUtil.writeDebugToFile "
+					+ io.getMessage());
+		}
+	}
+    
+   /**
+	 * Writes debug information into a file in delimitered format
+	 * 
+	 * @param debugInfo
+	 *            the debug information
+	 * @param newLine
+	 *            append the debug info to a line or not
+	 */
+	public static void writeDebugToDelimiteredFile(String debugInfo, boolean newLine) {
+		String debug = "false";
+		try {
+			debug = PropertyService.getProperty("application.writeDebugToFile");
+			if (debug != null && debug.equalsIgnoreCase("true")) {
+				File outputFile = new File(PropertyService
+						.getProperty("application.delimiteredOutputFile"));
+				FileOutputStream fos = new FileOutputStream(outputFile, true);
+				PrintWriter pw = new PrintWriter(fos);
+				if (newLine) {
+					pw.println(debugInfo);
+				} else {
+					pw.print(debugInfo);
+				}
+				pw.flush();
+				pw.close();
+				fos.close();
+			}
+		} catch (PropertyNotFoundException pnfe) {
+			// only log debug to file warning once
+			if (!debugErrorDisplayed) {
+				logMetacat.warn("Could not get delimited debug property. Write debug to " 
+						+ "file is set to false: " + pnfe.getMessage());
+				debugErrorDisplayed = true;
+			}
+		} catch (Exception io) {
+			logMetacat.warn("Eorr in writeDebugToDelimiteredFile "
+					+ io.getMessage());
+		}
+	}
+
+		/**
+		 * Write the uploaded file to disk for temporary storage before moving
+		 * it to its final Metacat location.
+		 * 
+		 * @param filePart
+		 *            the FilePart object containing the file form element
+		 * @param fileName
+		 *            the name of the file to be written to disk
+		 * @return tempFilePath a String containing location of temporary file
+		 */
+    public static String writeTempFile (FilePart filePart, String fileName) {
+        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
+        String tempFilePath = null;
+        String tempDirPath = null;
+        try {
+        	tempDirPath = PropertyService.getProperty("application.tempDir");
+        } catch (PropertyNotFoundException pnfe) {
+        	logMetacat.warn("Temp property not found.  An attempt will be made " 
+        			+ "to use system temp directory: " + pnfe.getMessage());
+        }
+        long fileSize;
+        File tempFile;
+        File tempDir;
+
+        if ((fileName == null) || fileName.equals("")) {
+            return tempFilePath;
+        }
+				
+        // the tempfilepath token isn't set, use Java default
+		if (tempDirPath == null) {
+			String javaTempDir = System.getProperty("java.io.tempdir");
+			if (javaTempDir == null) {
+				// no paths set, use unix default
+				tempDirPath = "/tmp";
+			} else {
+				tempDirPath = javaTempDir;
+			}
+		}
+
+        tempDir = new File(tempDirPath);
+
+        // Create the temporary directory if it doesn't exist
+        try {
+            if (!tempDir.exists()) {
+                tempDir.mkdirs();
+            }
+        } catch (SecurityException e) {
+            logMetacat.error("Can't create directory: " + tempDir.getPath() +
+                             ". Error: " + e.getMessage());
+        }
+        try {
+            tempFile = new File(tempDirPath, fileName);
+            fileSize = filePart.writeTo(tempFile);
+            tempFilePath = tempDirPath + File.separator + fileName;
+
+            if (fileSize == 0) {
+                logMetacat.error("Uploaded file '" + fileName + "'is empty!");
+            }
+        } catch (IOException e) {
+            logMetacat.error("IO exception which writing temporary file: " +
+                             tempFilePath + " " + e.getMessage());
+        }
+
+        logMetacat.info("Temporary file is: " + tempFilePath);
+
+        return tempFilePath;
+    }
+
+    /**
+	 * 
+	 * Copy a file between two locations specified as strings. Fails if either
+	 * path cannot be created. Based on the public domain FileCopy class in
+	 * _Java in a Nutshell_.
+	 * 
+	 * @param sourceName
+	 *            the source file to read from disk
+	 * @param destName
+	 *            the destination file on disk
+	 */
+    public static void copyFile(String sourceName, String destName) throws IOException {
+        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
+
+        File sourceFile = new File(sourceName);
+        File destFile = new File(destName);
+        FileInputStream source = null;
+        FileOutputStream dest = null;
+        byte[] buffer;
+        int bytesRead;
+
+        try {
+            if (!sourceFile.exists() || !sourceFile.isFile()) {
+                logMetacat.error("File copy: no such source" +
+                                 " file: " + sourceName);
+            }
+            if (!sourceFile.canRead()) {
+                logMetacat.error("File copy: source file " +
+                                 "is unreadable: " + sourceName);
+            }
+
+            if (destFile.exists()) {
+                if (destFile.isFile()) {
+                    if (!destFile.canWrite()) {
+                        logMetacat.error("File copy: destination " +
+                                         "file is unwriteable: " + destFile);
+                    }
+                } else {
+                    logMetacat.error("File copy: destination file " +
+                                     "is not a file: " + destFile);
+                }
+            } else {
+                File parentDir = parent(destFile);
+
+                if (!parentDir.exists())
+                {
+                    logMetacat.error("File copy: destination diretory " +
+                                     " doesn't exist: " + destName);
+                }
+                if (!parentDir.canWrite()) {
+                    logMetacat.error("File copy: destination directory " +
+                                     " is unwritable: " + destName);
+                }
+            }
+
+            // Verbose error checking done, copy the file object
+            source = new FileInputStream(sourceFile);
+            dest = new FileOutputStream(destFile);
+            buffer = new byte[1024];
+
+            while (true) {
+                bytesRead = source.read(buffer);
+                if (bytesRead == -1) {
+                    break;
+                }
+                dest.write(buffer, 0, bytesRead);
+            }
+        }
+        finally {
+            if (source != null) {
+                try { source.close(); } catch (IOException e) { ; }
+            }
+            if (dest != null) {
+                try { dest.close(); } catch (IOException e) { ; }
+            }
+        }
+    }
+
+    private static File parent(File f) {
+        String dirname = f.getParent();
+        if (dirname == null) {
+            if (f.isAbsolute()) return new File(File.separator);
+            else return new File(System.getProperty("user.dir"));
+        }
+        return new File(dirname);
+    }
+
+	/**
+	 * Reports whether metacat is fully configured.
+	 * 
+	 * @return a boolean that is true if all sections are configured and 
+	 * false otherwise
+	 */
+	public static boolean isMetacatConfigured() {
+		boolean metacatConfigured = false;
+		try {			
+			metacatConfigured = PropertyService.arePropertiesConfigured()
+					&& AuthUtil.isAuthConfigured()
+					&& SkinUtil.areSkinsConfigured()
+					&& DatabaseUtil.isDatabaseConfigured()
+					&& GeoserverUtil.isGeoserverConfigured()
+					&& isBackupDirConfigured();
+		} catch (UtilException ue) {
+			logMetacat.error("Could not determine if metacat is configured due to utility exception: "
+					+ ue.getMessage());
+		} catch (PropertyNotFoundException pnfe) {
+			logMetacat.error("Could not determine if metacat is configured due to property exception: "
+					+ pnfe.getMessage());
+		}
+
+		return metacatConfigured;
+	}
+
+	/**
+	 * Check if the application.backupDir property is populated in
+	 * metacat.properties and that it points to a writable directory.
+	 * 
+	 * @return false if the application.backupDir property does not point to a
+	 *         writable directory.
+	 */
+	public static boolean isBackupDirConfigured() throws PropertyNotFoundException {
+		String backupDir = PropertyService.getProperty("application.backupDir");
+		if (backupDir == null) {
+			return false;
+		}		
+		if (FileUtil.getFileStatus(backupDir) < FileUtil.EXISTS_READ_WRITABLE) {
+			return false;
+		}
+		
+		return true;
+	}
+		
+	/**
+	 * Reports whether the metacat configuration utility should be run. Returns
+	 * false if 
+	 *   -- dev.runConfiguration=false and 
+	 *   -- backup properties file exists 
+	 * Note that dev.runConfiguration should only be set to false when reinstalling the 
+	 * same version of the application in development.
+	 * 
+	 * @return a boolean that is false if dev.runConfiguration is false and the
+	 *         backup properties file exists.
+	 */
+	public static boolean bypassConfiguration() throws UtilException, ServiceException {
+		try {
+			// If the system is not configured to do bypass, return false.
+			if (!PropertyService.doBypass()) {
+				return false;
+			}
+
+			// Get the most likely backup files.  If these cannot be found, we 
+			// cannot do the configuration bypass.
+			String backupDir = SystemUtil.discoverExternalBaseDir();
+			if (backupDir == null) {
+				logMetacat.error("bypassConfiguration: Could not find backup directory.");
+				// could not find backup files ... force the configuration
+				return false;
+			}
+			PropertyService.setProperty("application.backupDir", backupDir);
+
+			// Refresh the property service and skin property service.  This will pick up 
+			// the backup directory and populate backup properties in caches.
+			ServiceService.refreshService("PropertyService");
+			ServiceService.refreshService("SkinPropertyService");
+
+			// Call bypassConfiguration to make sure backup properties get persisted 
+			// to active properties for both main and skin properties.
+			PropertyService.bypassConfiguration();
+			SkinPropertyService.bypassConfiguration();
+
+			return true;
+		} catch (GeneralPropertyException gpe) {
+			throw new UtilException("Property error while discovering backup directory: "
+					+ gpe.getMessage());
+		}
+
+	}
+		
+}

Property changes on: src/edu/ucsb/nceas/metacat/util/MetacatUtil.java
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Author Date Id Revision
\ No newline at end of property
Added: svn:mergeinfo
## -0,0 +0,0 ##
