Mega Code Archive

 
Categories / Java / Data Type
 

Parse Fraction

/*  * Copyright (c) 2003 - 2007 OpenSubsystems s.r.o. Slovak Republic. All rights reserved.  *   * Project: OpenSubsystems  *   * $Id: StringUtils.java,v 1.14 2007/02/20 04:08:10 bastafidli Exp $  *   * 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; version 2 of the License.   *   * 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   */ import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.StringTokenizer; /**  * Utility methods for String manipulation.  *   * @version $Id: StringUtils.java,v 1.14 2007/02/20 04:08:10 bastafidli Exp $  * @author Peter Satury  * @code.reviewer Miro Halas  * @code.reviewed 1.11 2006/04/29 00:24:18 jlegeny  */ public final class StringUtils {   // Constants ////////////////////////////////////////////////////////////////   /**    * Constant for assigning    */   public static final String EMPTY_STRING = "";   /**    * Constant for assigning    */   public static final String COMMA_STRING = ",";   /**    * Keep the original case of the string;    */   public static final int CASE_ORIGINAL = 0;   /**    * Convert the string to upper case.    */   public static final int CASE_TOUPPER = 1;   /**    * Convert the string to lower case.    */   public static final int CASE_TOLOWER = 2;   // Constructors /////////////////////////////////////////////////////////////   /**    * Private constructor since this class cannot be instantiated    */   private StringUtils() {     // Do nothing   }   // Public methods ///////////////////////////////////////////////////////////   /**    * Count number of occurences of lookup in text.    *     * @param text -    *          text to search in for occurences of lookup    * @param lookup -    *          character to count    * @return int - number of occurences of lookup in text.    */   public static int count(String text, char lookup) {     int iCount = 0;     if (text != null) {       int iIndex = text.indexOf(lookup);       while (iIndex != -1) {         iCount++;         iIndex = text.indexOf(lookup, iIndex + 1);       }     }     return iCount;   }   /**    * Parse textual representation of fraction to a floating point number    *     * @param textToParse -    *          in the form "any_text whole_part quotient/divisor any_text"    * @param defaultValue -    *          if the test is unparsable, what default value to return    * @param bIgnoreRest -    *          if true, this will ignore the rest of the string (any_other_text)    *          after the fraction, if false then the whole string is considered    * @return double - number coresponding to the fraction    */   public static double parseFraction(String textToParse, double defaultValue, boolean bIgnoreRest) {     double parsed = defaultValue;     int iLength;     int iIndex;     int iIndexStart;     int iIndexEnd;     int iNumber;     // lets use "xxxxxxx 123 456 / 789 yyyyy" as example or     // lets use "xxxxxxx 123 / 789 yyyyy" as example     iIndexStart = 0;     iLength = textToParse.length();     if (bIgnoreRest) {       // Skip while not number       while ((iIndexStart < iLength) && (!Character.isDigit(textToParse.charAt(iIndexStart)))) {         iIndexStart++;       }       // We skiped "xxxxxxx", iIndexStart is at "123 456 / 789 yyyyy"     }     // We should be at first digit     if (iIndexStart < iLength) {       // Find end of the number       iIndex = iIndexStart;       while ((iIndex < iLength) && (Character.isDigit(textToParse.charAt(iIndex)))) {         iIndex++;       }       iIndexEnd = iIndex;       // We skiped "123", iIndexStart is at "123 456 / 789 yyyyy"       // iIndexEnd is at " 456 / 789 yyyyy"       if (iIndexStart != iIndexEnd) {         // There was at least some digits         iNumber = Integer.parseInt(textToParse.substring(iIndexStart, iIndexEnd));         // iNumber is 123         // There was at least one digit, now is it whole part or quotient?         // Skip spaces         while ((iIndex < iLength)             && ((textToParse.charAt(iIndex) == ' ') || (textToParse.charAt(iIndex) == '-'))) {           iIndex++;         }         // We skiped "123", iIndex is at "456 / 789 yyyyy"         // Now we have stopped because of 2 things, we either reached end of         // string or we have found something other than space, if it is /         // then it was qoutient, if it is digit, then it was whole part         if (iIndex == iLength) {           // it was a whole part and we are done           parsed = iNumber;         } else {           int iQuotient = 0;           int iDivisor = Integer.MAX_VALUE;           if (Character.isDigit(textToParse.charAt(iIndex))) {             int iWholePart = 0;             // it was a whole part and we continue to look for the quotient             iWholePart = iNumber;             // Find end of the number             iIndexStart = iIndex; // Remember start             while ((iIndex < iLength) && (Character.isDigit(textToParse.charAt(iIndex)))) {               iIndex++;             }             iIndexEnd = iIndex;             // We skiped "456", iStartIndex is at "456 / 789 yyyyy"             // And iIndexEnd is at " / 789 yyyyy"             iQuotient = Integer.parseInt(textToParse.substring(iIndexStart, iIndexEnd));             // iQuotient is 456             // Skip spaces             while ((iIndex < iLength) && (textToParse.charAt(iIndex) == ' ')) {               iIndex++;             }             // And iIndex is at "/ 789 yyyyy"             if (textToParse.charAt(iIndex) == '/') {               // It was a quotient and we continue to look for divisor               iIndexStart = iIndex + 1;               while ((iIndexStart < iLength) && (textToParse.charAt(iIndexStart) == ' ')) {                 iIndexStart++;               }               // And iIndexStart is at "789 yyyyy"               // We should be at next digit               if (iIndexStart < iLength) {                 // Find end of the number                 iIndex = iIndexStart;                 while ((iIndex < iLength) && (Character.isDigit(textToParse.charAt(iIndex)))) {                   iIndex++;                 }                 iIndexEnd = iIndex;                 // We skiped "789", iStartIndex is at "789 yyyyy"                 // And iIndexEnd is at " yyyyy"                 if (iIndexStart != iIndexEnd) {                   iDivisor = Integer.parseInt(textToParse.substring(iIndexStart, iIndexEnd));                   // iDivisor is 789                   if (iDivisor != 0) {                     if (iIndexEnd == iLength) {                       // And we are at the end of the string                       parsed = ((double) (iWholePart))                           + (((double) iQuotient) / ((double) iDivisor));                     } else {                       if (bIgnoreRest) {                         // And we can ignore what is after                         parsed = ((double) (iWholePart))                             + (((double) iQuotient) / ((double) iDivisor));                       } else {                         // there was something else we don't know what so                         // return the default value                       }                     }                   }                 } else {                   // The divisor is missing, return default value                 }               } else {                 // The divisor is missing, return default value               }             } else {               // The divisor is missing, return default value             }           } else {             if (textToParse.charAt(iIndex) == '/') {               // And iIndex is at "/ 456 yyyyy"               // It was a quotient and we continue to look for divisor               iQuotient = iNumber;               // iQuotient is 123               iIndexStart = iIndex + 1;               while ((iIndexStart < iLength) && (textToParse.charAt(iIndexStart) == ' ')) {                 iIndexStart++;               }               // And iIndexStart is at "456 yyyyy"               // We should be at next digit               if (iIndexStart < iLength) {                 // Find end of the number                 iIndex = iIndexStart;                 while ((iIndex < iLength) && (Character.isDigit(textToParse.charAt(iIndex)))) {                   iIndex++;                 }                 iIndexEnd = iIndex;                 // We skipped "456", iIndexStart is at "456 yyyyy"                 // iIndexEnd is at " yyyyy"                 if (iIndexStart != iIndexEnd) {                   iDivisor = Integer.parseInt(textToParse.substring(iIndexStart, iIndexEnd));                   // iDivisor is 456                   if (iDivisor != 0) {                     if (iIndexEnd == iLength) {                       // And we are at the end of the string                       parsed = ((double) iQuotient) / ((double) iDivisor);                     } else {                       if (bIgnoreRest) {                         // And we can ignore what is after                         parsed = ((double) iQuotient) / ((double) iDivisor);                       } else {                         // there was something else we don't know what so                         // return the default value                       }                     }                   }                 } else {                   // The divisor is missing, return default value                 }               } else {                 // The divisor is missing, return default value               }             } else {               // It was a whole part and there is something else               if (bIgnoreRest) {                 // and we are done                 parsed = iNumber;               } else {                 // there was something else we don't know what so                 // return the default value               }             }           }         }       }     }     return parsed;   }   /**    * Parse String to array of Strings while treating quoted values as single    * element.    *     * @param strParse -    *          String to parse    * @param strDel -    *          String deliminer    * @param bAllowSingleQuote -    *          single qoutes such as ' can be used to group value    * @param bAllowDoubleQuote -    *          double quote such as " can be used to group value    * @return String[] - parsed list    * @throws OSSInvalidDataException -    *           error during parsing    */   public static String[] parseQuotedStringToStringArray(String strParse, String strDel,       boolean bAllowSingleQuote, boolean bAllowDoubleQuote) throws Exception {     String[] arrayStrings;     if (strParse == null) {       arrayStrings = null;     } else {       List lstElements = new ArrayList();       int iCurrentIndex = 0;       int iNextIndex;       int iDelLength = strDel.length();       int iParseLength = strParse.length();       while (iCurrentIndex < iParseLength) {         if ((bAllowSingleQuote) && (strParse.charAt(iCurrentIndex) == '\'')) {           // Find next single quote and treat the things in the middle as           // single element           iNextIndex = strParse.indexOf('\'', iCurrentIndex + 1);           if (iNextIndex == -1) {             throw new Exception("Incorrect input. " + strParse                 + " No single quote following the one" + " at location " + iCurrentIndex);           }           lstElements.add(strParse.substring(iCurrentIndex + 1, iNextIndex));           iCurrentIndex = iNextIndex + 1;           if (strParse.substring(iCurrentIndex).startsWith(strDel)) {             iCurrentIndex += iDelLength;           }         } else if ((bAllowDoubleQuote) && (strParse.charAt(iCurrentIndex) == '"')) {           // Find next double quote and treat the things in the middle as           // single element           iNextIndex = strParse.indexOf('"', iCurrentIndex + 1);           if (iNextIndex == -1) {             throw new Exception("Incorrect input. " + strParse                 + " No double quote following the one" + " at location " + iCurrentIndex);           }           lstElements.add(strParse.substring(iCurrentIndex + 1, iNextIndex));           iCurrentIndex = iNextIndex + 1;           if (strParse.substring(iCurrentIndex).startsWith(strDel)) {             iCurrentIndex += iDelLength;           }         } else {           // Find next separator and treat the things in the middle as           // single element           iNextIndex = strParse.indexOf(strDel, iCurrentIndex);           if (iNextIndex == -1) {             // No other delimiter found so take the rest of the string             lstElements.add(strParse.substring(iCurrentIndex));             iCurrentIndex = iParseLength;           } else {             lstElements.add(strParse.substring(iCurrentIndex, iNextIndex));             iCurrentIndex = iNextIndex + iDelLength;           }         }       }       arrayStrings = (String[]) lstElements.toArray(new String[lstElements.size()]);     }     return arrayStrings;   }   /**    * Parse String to array of integers.    *     * @param strParse -    *          String to parse    * @param strDel -    *          String deliminer    * @return int[] - parsed list    * @throws OSSException -    *           error during parsing    */   public static int[] parseStringToIntArray(String strParse, String strDel) throws Exception {     int[] arrayInts;     try {       if (strParse == null) {         arrayInts = null;       } else {         // TODO: Performance: Memory vs speed, here we allocate list and then         // another array, how about just counting the number of elements         // and then allocating array and parsing directly to array without         // the extra list and copying from list to array?         List lstInts = parseStringToList(strParse, strDel);         if (lstInts == null || lstInts.size() < 1) {           arrayInts = null;         } else {           Iterator items;           int iCount;           arrayInts = new int[lstInts.size()];           for (iCount = 0, items = lstInts.iterator(); items.hasNext();) {             arrayInts[iCount++] = Integer.parseInt(((String) items.next()).trim());           }         }       }     } catch (NumberFormatException eExc) {       throw new RuntimeException("Problems with parsing String to array of int.", eExc);     }     return arrayInts;   }   /**    * Parse String to array of Integers.    *     * @param strParse -    *          String to parse    * @param strDel -    *          String deliminer    * @return Integer[] - parsed list    * @throws OSSException -    *           error during parsing    */   public static Integer[] parseStringToIntegerArray(String strParse, String strDel)       throws Exception {     Integer[] arrayInts;     try {       if (strParse == null) {         arrayInts = null;       } else {         // TODO: Performance: Memory vs speed, here we allocate list and then         // another array, how about just counting the number of elements         // and then allocating array and parsing directly to array without         // the extra list and copying from list to array?         List strInts = parseStringToList(strParse, strDel);         if (strInts == null || strInts.size() < 1) {           arrayInts = null;         } else {           arrayInts = new Integer[strInts.size()];           for (int iCount = 0; iCount < strInts.size(); iCount++) {             arrayInts[iCount] = Integer.valueOf((String) strInts.get(iCount));           }         }       }     } catch (NumberFormatException eExc) {       throw new RuntimeException("Problems with parsing String to array of int.", eExc);     }     return arrayInts;   }   /**    * Parse String to array of Strings.    *     * @param strParse -    *          String to parse    * @param strDel -    *          String deliminer    * @return String[] - parsed list    */   public static String[] parseStringToStringArray(String strParse, String strDel) {     String[] arrayStrings;     if (strParse == null) {       arrayStrings = null;     } else {       // TODO: Performance: Memory vs speed, here we allocate list and then       // another array, how about just counting the number of elements       // and then allocating array and parsing directly to array without       // the extra list and copying from list to array?       List lstStrings = parseStringToList(strParse, strDel);       if ((lstStrings == null) || (lstStrings.isEmpty())) {         arrayStrings = null;       } else {         arrayStrings = (String[]) lstStrings.toArray(new String[lstStrings.size()]);       }     }     return arrayStrings;   }   /**    * Parse array of integers to String.    *     * @param arrParse -    *          int array to parse    * @param strDel -    *          String deliminer    * @return String - parsed array    */   public static String parseIntArrayToString(int[] arrParse, String strDel) {     StringBuffer strbInts = new StringBuffer();     if ((arrParse != null) && (arrParse.length > 0)) {       for (int iCount = 0; iCount < arrParse.length; iCount++) {         if (iCount > 0) {           strbInts.append(strDel);         }         strbInts.append(arrParse[iCount]);       }     }     return strbInts.toString();   }   /**    * Parse collection of objects to String by calling toString on each element.    *     * @param colObjects -    *          collection of data objects to parse    * @param strDel -    *          String deliminer    * @return String - parsed array    */   public static String parseCollectionToString(Collection colObjects, String strDel) {     StringBuffer strbInts = new StringBuffer();     if ((colObjects != null) && (!colObjects.isEmpty())) {       for (Iterator items = colObjects.iterator(); items.hasNext();) {         if (strbInts.length() > 0) {           strbInts.append(strDel);         }         strbInts.append(items.next().toString());       }     }     return strbInts.toString();   }   /**    * Parse String to List.    *     * @param strParse -    *          String to parse    * @param strDel -    *          String deliminer    * @return List - parsed list of items in the string delimtied by delimiter    */   public static List parseStringToList(String strParse, String strDel) {     return (List) parseStringToCollection(strParse, strDel, false, CASE_ORIGINAL, null);   }   /**    * Parse String to ANY collection you specify and trim each item.    *     * @param strParse -    *          String to parse    * @param strDel -    *          String deliminer    * @param container -    *          if specified then it will be filled with items (it WILL NOT be    *          emptied first). If this is null, the default collection will be    *          allocated. This allows you here to pass list or set so this method    *          is more flexible.    * @param bTrim -    *          should it be trimmed or not    * @param iConvertCase -    *          how to convert the case of the string - one of the CASE_XXX    *          costants    * @return Collection - parsed collection, if container was specified, the    *         same object will be returned. If it was not specified default    *         object will be returned. If strParse was not null, then this will    *         be not null.    */   public static Collection parseStringToCollection(String strParse, String strDel, boolean bTrim,       int iConvertCase, Collection container) {     Collection colReturn;     if (strParse == null || strParse.length() < 1) {       if (container != null) {         colReturn = container;       } else {         colReturn = null;       }     } else {       // TODO: Performance: StringTokenizer is considered to be slow       // because it creates lots of objects internally, consider replacing       // this with String.indexOf(delimiter)       StringTokenizer strTokParse = new StringTokenizer(strParse, strDel);       String strTemp;       if (container == null) {         // This has to be List since parseStringToList requires it         colReturn = new ArrayList();       } else {         container.clear();         colReturn = container;       }       if (strParse.startsWith(strDel)) {         // If the string starts with the delimiter, tokenizer would skip it         // but we have to have empty element in front         colReturn.add("");       }       while (strTokParse.hasMoreTokens()) {         strTemp = (String) strTokParse.nextToken();         if (bTrim) {           strTemp = strTemp.trim();         }         switch (iConvertCase) {         case (CASE_ORIGINAL): {           // do nothing           break;         }         case (CASE_TOUPPER): {           strTemp = strTemp.toUpperCase();           break;         }         case (CASE_TOLOWER): {           strTemp = strTemp.toLowerCase();           break;         }         default: {           assert false : "Incorrect case specification.";         }         }         colReturn.add(strTemp);       }     }     return colReturn;   }   /**    * Method to limit String length for display and add '...' to the end    *     * @param limitLength -    *          limit of length    * @param strValue -    *          String to limit    * @return String - limited String    */   public static String limitStringLength(int limitLength, String strValue) {     StringBuffer sbReturn = new StringBuffer();     if ((limitLength > 0) && (strValue.length() > limitLength)) {       // If limit length is lower then 5 we will do just exact substring       if (limitLength < 5) {         sbReturn.append(strValue.substring(0, limitLength));       }       // If limit length is lower then 15 and higher then 4 we will       // return substring of (limit - 3) and '...'       else if (limitLength < 15) {         sbReturn.append(strValue.substring(0, limitLength - 3));         sbReturn.append("...");       }       // If limit length is higher then 15 we will try to find       // some space ' ' near before limit and cut string there       else {         // if we will not find ' ' near before limit         // we will return substring of (limit - 3) and '...'         if ((strValue.indexOf(" ", limitLength - 12) > (limitLength - 4))             || (strValue.indexOf(" ", limitLength - 12) < 0)) {           sbReturn.append(strValue.substring(0, limitLength - 3));           sbReturn.append("...");         }         // if we will find ' ' near before limit         // we will return substring until ' ' and ' ...'         else {           sbReturn.append(strValue.substring(0, strValue.indexOf(" ", limitLength - 12)));           sbReturn.append(" ...");         }       }     } else {       sbReturn.append(strValue);     }     return sbReturn.toString();   }   /**    * Method to remove comma from start and from end of the string for examples    * to use it as parameter to SQL IN operator    *     * @param strToRemoveFrom -    *          String to remove comma from    * @return String - string with removed commas from the start and end of the    *         string    */   public static String removeComma(String strToRemoveFrom) {     // we have to remove comma from start and from end of the string     // because then it can be used for SQL IN operator     if (strToRemoveFrom.length() > 2) {       strToRemoveFrom = strToRemoveFrom.substring(1, strToRemoveFrom.length() - 1);     } else {       strToRemoveFrom = "";     }     return strToRemoveFrom;   }   /**    * Concat all the specified strings to a single one    *     * @param strings -    *          strings to concat, all null and empty ones will be ignored    * @param separator -    *          separator to put in between the string elements    * @param quote -    *          quote string to put around string elements, if null nothing will    *          be put around them    * @return String with concatenated inputs    */   public static String concat(String[] strings, String separator, String quote) {     StringBuffer output = new StringBuffer();     if (strings != null) {       int iIndex;       boolean bSeparator;       boolean bQuote;       bSeparator = (separator != null) && (separator.length() > 0);       bQuote = (quote != null) && (quote.length() > 0);       for (iIndex = 0; iIndex < strings.length; iIndex++) {         if ((strings[iIndex] != null) && (strings[iIndex].length() > 0)) {           if ((output.length() > 0) && (bSeparator)) {             output.append(separator);           }           if (bQuote) {             output.append(quote);           }           output.append(strings[iIndex]);           if (bQuote) {             output.append(quote);           }         }       }     }     return output.toString();   }   /**    * Test if any element in the container contains given string.    *     * @param container -    *          container of which elements will be searched to see if they    *          contains given text    * @param strSearch -    *          text to search in the elements of specified container    * @return boolean - true if any of the elements in container contains given    *         text    */   public static boolean isContained(Collection container, String strSearch) {     boolean bReturn = false;     if ((container != null) && (!container.isEmpty())) {       for (Iterator itrElements = container.iterator(); (itrElements.hasNext() && (!bReturn));) {         if (((String) itrElements.next()).indexOf(strSearch) != -1) {           bReturn = true;         }       }     }     return bReturn;   }   /**    * Test if given string contains any element in the container.    *     * @param container -    *          container of which elements will be searched to see if they are    *          contained within given text    * @param strSearch -    *          text to search in for the elements of specified container    * @return boolean - true if the search text contains any of the elements in    *         container    */   public static boolean contains(Collection container, String strSearch) {     boolean bReturn = false;     if ((container != null) && (!container.isEmpty())) {       for (Iterator itrElements = container.iterator(); (itrElements.hasNext() && (!bReturn));) {         if (strSearch.indexOf((String) itrElements.next()) != -1) {           bReturn = true;         }       }     }     return bReturn;   }   /**    * Method return boolean result if particular substring is contained within    * the list of substrings separated by a separator.    *     * @param strSearchIn -    *          string of all substrings separated by separator to search in    * @param strSearchFor -    *          string that will be search for    * @param strSeparator -    *          item separator    * @return boolean - true if it contains the ID, false otherwise    */   public static boolean containsInSeparatedString(String strSearchIn, String strSearchFor,       String strSeparator) {     boolean bReturn = false;     StringBuffer sbInputString = new StringBuffer();     StringBuffer sbSearchString = new StringBuffer();     if (strSearchIn.length() > 0) {       // add separator at the beginning and end of the input string       sbInputString.append(strSeparator);       sbInputString.append(strSearchIn);       sbInputString.append(strSeparator);       // add separator at the beginning and end of the search string       sbSearchString.append(strSeparator);       sbSearchString.append(strSearchFor);       sbSearchString.append(strSeparator);       // search for particular ID       if (sbInputString.indexOf(sbSearchString.toString()) != -1) {         bReturn = true;       }     }     return bReturn;   } }