Data Type Java

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/*
 * Copyright 2007-2011 Nicolas Zozol
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
//package com.robustaweb.library.commons.util;
/**
 * This class is designed to simplify Numbers representation in HTML views. 

Be aware that it's not time efficiency, not designed for complex Math

.
 * @author Nicolas Zozol for Robusta Web ToolKit & http://www.edupassion.com - nzozol@robustaweb.com
 */
public class MathUtils {
    /**
     *  Numbers will be equals if enough decimals are equals, without thinking about approximations. This is absolutely not a pure mathematic Equality.
     * 


     * approximativelyEquals(1.2352, 1.2357, 3) returns true because there is no rounding at the 3th decimal
     * 


     *
     * @param n1 first numbre
     * @param n2 second number
     * @param decimalPrecision
     * @return true if n1 is approximatively equal to n2
     */
    public static boolean approximativelyEquals(Number n1, Number n2, int decimalPrecision) {
        if (n1.toString().equals(n2.toString())) {
            return true;
        }
        String s1 = n1.toString();
        String s2 = n2.toString();
        s1 = StringUtils.removeTrailingCharacters(s1, '0');
        s2 = StringUtils.removeTrailingCharacters(s2, '0');
        if (!s1.contains(".") && !s2.contains(".")) {
            return s1.equals(s2);
        }
        int seriousNumber;
        if (s1.contains(".")) {
            seriousNumber = s1.indexOf('.');
        } else {//s2.contains(".")
            seriousNumber = s2.indexOf('.');
        }
        /* checking before */
        if (s1.substring(0, seriousNumber).equals(s2.substring(0, seriousNumber))) {
            s1 = s1.substring(seriousNumber);
            s1 = StringUtils.removeCharacter(s1, '.');
            s2 = s2.substring(seriousNumber);
            s2 = StringUtils.removeCharacter(s2, '.');
            /* truncation */
            String t1 = StringUtils.truncate(s1, decimalPrecision);
            String t2 = StringUtils.truncate(s2, decimalPrecision);
            t1 = StringUtils.removeTrailingCharacters(t1, '0');
            t2 = StringUtils.removeTrailingCharacters(t2, '0');
            return t1.equals(t2);
        } else {
            return false;
        }
    }
    /**
     * 


     * Returns a visual approximation of a number, keeping only a specified decimals. 
     * For exemple : 
     *      approximate(12.2578887 , 2) will return 12.25 
     *      approximate(12.25 , 0) will return 12 
     *      approximate(12.00 , 3) will return 12 
     *      approximate(19.5 , 0) will return 20 
     *


     * 

The last exemple emphasis the fact that it's made for showing convenient numbers for no mathematical public. If the number was


     * 

Note that Math.round(19.5) returns 20, not 19. This function will act the same way.


     * @param n
     * @param precision
     * @return
     */
    public static String approximate(Number n, int precision) {
        if (n instanceof Integer) {
            return n.toString();
        }
        String s = n.toString();
        if (!s.contains(".")) {
            return s;
        }
        String serious = s.substring(0, s.indexOf('.'));
        s = s.substring(s.indexOf('.') + 1);
        s = StringUtils.removeTrailingCharacters(s, '0');
        if (s.length() == 0) {
            return serious;
        }
        // We'll comments results based on approximate(12.63645, 3) and approximate(12.63545, 0)
        String decimals = "";
        if (s.length() > precision) {
            decimals = StringUtils.truncate(s, precision + 1);
            //decimal is now "636" or "6"
            Float after = new Float(decimals);
            //after is 636 or 6, as Float objects
            after = after / 10;
            //after is 63.6 or .6, as Float objects
            Integer round = Math.round(after);
            //round is 64 or 1
            decimals = round.toString();
            decimals = StringUtils.removeTrailingCharacters(decimals, '0');
        } else {
            decimals = StringUtils.truncate(s, precision);
            decimals = StringUtils.removeTrailingCharacters(decimals, '0');
        }
        if (decimals.length() > 0 && precision > 0) {
            return serious + "." + decimals;
        } else {
            //if we must round the serious string
            if (decimals.length() > 0 && precision == 0) {
                assert decimals.length() == 1 : "problem here !";
                if (decimals.length() != 1) {
                    throw new IllegalStateException("Error in the algorithm for MathUtilisties.approximate(" + n + ", " + precision + ")");
                }
                Integer finalValue = new Integer(decimals);
                if (finalValue > 0) {
                    Integer si = new Integer(serious);
                    si += 1;
                    return si.toString();
                } else {
                    return serious;
                }
            } else {
                return serious;
            }
        }
    }
    /**
     * Convert a String in Double, Float, Integer, Long, Short or Byte, depending on the T exemple
     * For exemple convert("2", 0f) will return 2.0 as a float
     * @param  type returned
     * @param str String to convert
     * @param exemple exemple of the type
     * @return a number representation of the String
     * @throws IllegalArgumentException if the T type is not Double, Float, Integer, Long, Short or Byte
     * @throws NumberFormatException if the conversion fails
     */
    public static  T convert(String str, T exemple) throws NumberFormatException, IllegalArgumentException{
        T result = null;
        if (exemple instanceof Double) {
            result = (T) new Double(str);
        } else if (exemple instanceof Float) {
            result = (T) new Float(str);
        } else if (exemple instanceof Integer) {
            result = (T) new Integer(str);
        } else if (exemple instanceof Long) {
            result = (T) new Long(str);
        } else if (exemple instanceof Short) {
            result = (T) new Short(str);
        } else if (exemple instanceof Byte) {
            result = (T) new Byte(str);
        }else{
            throw new IllegalArgumentException("Conversion is not possible with class "+exemple.getClass()
                    +"; only allowing Double, Float, integer, Long, Short & Byte");
        }
        return result;
    }
  
}
/**
 * This class gives a few function to waork on Strings.
 * 

Most importants are probably 


     * 
  • {@link StringUtils#validateEmail(String) validateEmail()}
     * 
  • {@link StringUtils#replaceAll(String, String, String) replaceAll()}
     * 
  •  {@link StringUtils#removeCharacters(String, String) removeCharacters()}
     * 

 * 


 * @author Nicolas Zozol for Robusta Web ToolKit & http://www.edupassion.com - nzozol@robustaweb.com
 * TODO : verify this class is GWT compatible
 */
 class StringUtils {
    /**
     * This function test if an email is valid. It's not the best validation of the world : all good emails will pass,
     * but some wrong emails (even if it's very unlikely) may also pass.
     * 

 This function is based on the Javascript pattern /^([a-zA-Z0-9_.-])+@([a-zA-Z0-9_.-])+\.([a-zA-Z])+([a-zA-Z])+/
     * 


     * 

Check IETF for more informations.


     * @param email email to be tested
     * @return true if email is an email pattern, false if not
     * @throws  IllegalArgumentException if the email is null
     */
    public static boolean validateEmail(String email) {
        if (email == null) {
            throw new IllegalArgumentException("The email is null");
        }
        if (email.equals("")) {
            return false;
        }
        String worker = new String(email);
        worker = worker.trim();
        return worker.matches("^([a-zA-Z0-9_.-])+@([a-zA-Z0-9_.-])+\\.([a-zA-Z])+([a-zA-Z])+");
        /*
        //Set the email pattern string
        //Pattern p = Pattern.compile(".+@.+\\.[a-z]+");
        Pattern p = Pattern.compile("^([a-zA-Z0-9_.-])+@([a-zA-Z0-9_.-])+\\.([a-zA-Z])+([a-zA-Z])+");
        //Match the given string with the pattern
        Matcher m = p.matcher(worker);
        return m.matches();*/
    }
    /**
     * Returns true if the String could be a md5
     * @param md5String String to test : could it be a MD5, or there is no way ?
     * @return true if the String could be a md5
     * @throws IllegalArgumentException if the md5String is null
     */
    public static boolean validateMD5(String md5String) {
        if (md5String == null) {
            throw new IllegalArgumentException("md5String is null");
        }
        return md5String.length() == 32 && md5String.matches("([a-z0-9])+");
    }
    /**
     * 

removes a character in the String 


     *
     * 


     * String boss="Bruce Springsteen";
     * String result = StringUtils.removeCharacter(boss, 'e') returns "Bruc Springstn".
     * But the original String boss is not modified.
     * 


     * @param originalString
     * @param c
     * @return
     */
    public static String removeCharacter(String string, char c) {
        String work = new String(string);
        String s = "" + c;
        work = work.replace(s, "");
        return work;
    }
    /**
     * 

Removes in the string every characters inside charactersToRemove.
     * For exemple removeCharacters("Napoleon","nou") returns Naple because it will remove one 'n', two 'o' and zero 'u' 
     * Like for removeCharacter(String string, char c), the original String is not modified.


     * 

It's a recursive function, not the fastest you may have.


     * 
     * @param originalString Original string
     * @param charactersToRemove characters that will be removed form the Original String
     * @return a new string without the specified characters
     * @throws IllegalArgumentException if original or charactersToRemove is null
     */
    public static String removeCharacters(String original, String charactersToRemove) {
        if (original == null) {
            throw new IllegalArgumentException("Your original parameter is null");
        }
        if (charactersToRemove == null) {
            throw new IllegalArgumentException("charactersToRemove parameter si null");
        }
        String work = new String(original);
        char c;
        for (int i = 0; i < charactersToRemove.length(); i++) {
            c = charactersToRemove.charAt(i);
            work = removeCharacter(work, c);
        }
        return work;
    }
    /**
     * Will remove all characters from the end. 
     * 


     * removeStartingCharacters(iiiiMalagi, 'i') returns Malagi
     * 


     * If the string is empty, it returns also an empty string.
     * If the string is null, it will throw a IllegalArgumentException
     * @param originalString Original parameter
     * @param character
     * @throws IllegalArgumentException : if the string is null
     * @return Removes all the specified character found at the beginning of the string
     */
    public static String removeStartingCharacters(String originalString, char character) {
        if (originalString == null) {
            throw new IllegalArgumentException("original String is null");
        }
        if (originalString.length() == 0) {
            return originalString;
        }
        String result = new String(originalString);
        while (result.indexOf(character) == 0) {
            result = removeFirstCharacter(result);
            if (result.length() == 0) {
                return "";
            }
        }
        return result;
    }
    /**
     * Will remove all characters from the end. 
     * 


     * removeTrailingCharacters(Malagaaaa, 'a') returns Malag
     * 


     * If the string is empty, it returns also an empty string.
     * If the string is null, it will throw a IllegalArgumentException
     * @param originalString Original parameter
     * @param character
     * @throws IllegalArgumentException : if the string is null
     * @return Removes all the specified character found at the end of the string
     */
    public static String removeTrailingCharacters(String originalString, char character) {
        if (originalString == null) {
            throw new IllegalArgumentException("original String is null");
        }
        if (originalString.length() == 0) {
            return originalString;
        }
        String result = new String(originalString);
        while (result.lastIndexOf(character) == result.length() - 1) {
            result = removeLastCharacter(result);
            if (result.length() == 0) {
                return "";
            }
        }
        return result;
    }
    /**
     * 

Simply removes the last character


     * @param originalString
     * @return a new String without the
     * @throws IllegalArgumentException if the string is null
     */
    public static String removeFirstCharacter(String originalString) {
        if (originalString == null) {
            throw new IllegalArgumentException("string is null");
        }
        if (originalString.length() <= 1) {
            return "";
        }
        return originalString.substring(1);
    }
    /**
     * 

Simply removes the last character


     * @param originalString
     * @return a new String without the
     * @throws IllegalArgumentException if the string is null
     */
    public static String removeLastCharacter(String originalString) {
        if (originalString == null) {
            throw new IllegalArgumentException("string is null");
        }
        if (originalString.length() <= 1) {
            return "";
        }
        return originalString.substring(0, originalString.length() - 1);
    }
    /**
     * 

This is a simpler alternative to original String.replaceAll function that uses complex Regexp.
     * Here, you modify a String by changing the characters sequence sequenceToReplace by the replacement string.


     *
     * 


     * Exemple :
     *   String original = "//cooluri//living.js///";
     * Then 
     *   StringUtils.replaceAll(original,"//", "-");
     * will return :
     * -cooluri-living.js-/
     * 


     * 

Note that the '///' is always seen as ('//'+'/') and never as ('/'+'//'). This function is sequential, and will not always work like regular expressions.

     
     * @param originalString The original string
     * @param sequenceToReplace The characters sequence to replace
     * @param replacement
     * @return
     * @throws IllegalArgumentExceptionif a param is null
     */
    public static String replaceSequence(String originalString, String sequenceToReplace, String replacement) {
        if (originalString == null) {
            throw new IllegalArgumentException("originalString is null");
        }
        if (sequenceToReplace == null) {
            throw new IllegalArgumentException("charsToReplace is null");
        }
        if (replacement == null) {
            throw new IllegalArgumentException("replacement is null");
        }
        if (sequenceToReplace.equals(replacement)){
            return originalString;
        }
        
        String newString = new String(originalString);
        if (originalString == null || originalString.length() == 0) {
            return originalString;
        }
        if (sequenceToReplace == null || sequenceToReplace.length() == 0) {
            return originalString;
        }
        int indexPiece = originalString.indexOf(sequenceToReplace);
        while (indexPiece != -1) {
            newString = newString.substring(0, indexPiece) + replacement + newString.substring(indexPiece + sequenceToReplace.length());
            indexPiece = newString.indexOf(sequenceToReplace);
        }
        return newString;
    }
    /**
     * Replace any character defined in anyCharacter by a replacement sequence
     * Ex :
     * 

     * replaceAny("john jack jim", "ji", "t") => "tohn tack ttm"
     * 

     * @param originalString
     * @param anyCharacter
     * @param replacement
     * @return
     */
    public static String replaceAny(String originalString, String anyCharacter, String replacement){
        String worker = originalString;
        for (Character c : anyCharacter.toCharArray()){
            String pattern = ""+c;
            worker = worker.replaceAll(pattern, replacement);
        }
        return worker;
    }
    /**
     * 

Keeps the 'number' first characters, and might be useful to keep your user's privacy :
     *  truncate("Hernandez", 3)
     * will produce: "Her"
     *


     * 


     * If number is bigger than the size of the String, the whole string is kept : 
     *  truncate("Hernandez", 24)
     * will produce: "Hernandez"
     *


     * 

If number==0, the function returns an empty string.


     * @param originalString
     * @param number
     * @return a new smaller String.
     * @throws IllegalArgumentException if number<0 or original is null
     */
    public static String truncate(String original, int number) {
        if (number < 0) {
            throw new IllegalArgumentException("number :" + number + " is <0");
        }
        if (original == null) {
            throw new IllegalArgumentException("original string is null");
        }
        String newLastName = original.length() >= number ? original.substring(0, number) : original;
        return newLastName;
    }
    /**
     * If stringToTes contains any character in 'characatersToTest', the function returns true, false if not
     * @param stringToTest
     * @param charatersToTest
     * @return true if stringToTes contains any character in 'characatersToTest'
     * @throws IllegalArgumentException if charactersToTest is null or empty
     */
    public static boolean containsCharacter(String stringToTest, String charatersToTest) {
        if (charatersToTest == null) {
            throw new IllegalArgumentException("characters is null");
        }
        if (charatersToTest.length() == 0) {
            throw new IllegalArgumentException("No character to Test");
        }
        for (int i = 0; i < charatersToTest.length(); i++) {
            char c = charatersToTest.charAt(i);
            if (stringToTest.contains(String.valueOf(c))) {
                return true;
            }
        }
        return false;
    }
  
    /**
     * Returns the concatenation of the absolute and relative paths, adding a "/" character between them if needed
     * Calling addPath(uri, "/") ensures that the path will finish with only one "/" (as long as uri doesn't finishes with more than one "/")
     * @param absolute
     * @param relative
     * @return
     */
    public static String addPath(String absolute, String relative){
        return removeTrailingCharacters(absolute, '/')+"/"+removeStartingCharacters(relative, '/');
    }
    /**
     * Add the protocol to the String
     * @param protocol
     * @param uri
     * @return a new Stirng with the protocol
     */
    public static String addProtocol(String protocol, String uri){
        String worker=removeTrailingCharacters(protocol, '/');
        worker=removeTrailingCharacters(worker, ':');
        return worker+"://"+removeStartingCharacters(uri, '/');
    }
    /**
     * Needed for Gwt Compatibility : GWT does not yet provide a getSimpleClassName
     * @param o
     * @return
     */
    public static String getSimpleClassName(Object o) {
        String className = o.getClass().getName();
        return className.substring(
                className.lastIndexOf(".") + 1, className.length());
    }
    /**
     * Return a String that starts with an Uppercase character, and ends with LowerCase characters
     * strictCapitalize("johnDoe") returns Johndoe
     * @param string string to capitalize
     * @return a String that starts with an Uppercase character, and ends with LowerCase characters
     * @see #simpleCapitalize(java.lang.String) 
     */
    public static String strictCapitalize(String str) {
        if (str == null){
            throw new IllegalArgumentException("String is null");
        }
        if (str.length() == 0) {
            return str;
        }
        String worker = str.toLowerCase();
        return worker.substring(0, 1).toUpperCase() + worker.substring(1);
    }
    /**
     * Capitalize the first letter, and doesn't touch any other
     * simpleCapitalize("johnDoe") returns JohnDoe
     * @param string string to capitalize
     * @return the same string with capitalized first letter
     * @see #strictCapitalize(java.lang.String) 
     */
    public static String simpleCapitalize(String str){
        if (str == null){
            throw new IllegalArgumentException("String is null");
        }
        if (str.length() == 0) {
            return str;
        }
        String work = new String(str);
        return work.substring(0, 1).toUpperCase() + work.substring(1);
    }
    /**
     * TODO 1 : work on this ; Use StringTokenizer
     * 

Splits the provided text into an array ,* separators specified.


     *
     * 

The separator is not included in the returned String array.
     * Adjacent separators are treated as one separator.


     *
     * 
     
     * StringUtils.split("ab de fg", " ")   = ["ab", "de", "fg"]
     * StringUtils.split("ab   de fg", " ") = ["ab", "cd", "ef"]
     * StringUtils.split("ab:cd:ef", ":")    = ["ab", "cd", "ef"]
     * 

     *
     * @param string  the String to parse, may be null
     * @param separatorChars  the characters used as the delimiters
     * @return an array of parsed Strings
     * @throws IllegalArgumentException if string or separatorChars is null, or if separatorChars is empty
     */
    public static String[] split(String string, String separatorChars){
        if (string == null){
            throw new IllegalArgumentException("string argument is null");
        }
        if (separatorChars == null || separatorChars.length() == 0){
            throw new IllegalArgumentException("separators is null or empty");
        }
        List resultList = new ArrayList();
        String worker =new String(string);
        String firstSeparator = separatorChars.substring(0, 1);
        assert firstSeparator.length() == 1;
        char[] charArray = separatorChars.toCharArray();
        //We replace multiple instance of other separator by only one firstSeparator
        for (int i = 1 ; i < charArray.length ; i++){
            String pattern = "("+charArray[i]+")+";
            worker = worker.replaceAll(pattern, firstSeparator);
        }
        
        //One more pass for the first separator
        String pattern = "("+firstSeparator+")+";
        worker = worker.replaceAll(pattern, firstSeparator);
        System.out.println("separator : "+firstSeparator+" ; worker : "+worker);
        Collections.addAll(resultList, worker.split(firstSeparator) );
        return (String[]) resultList.toArray(new String[resultList.size()]);       
    }
    /**
     * @todo3 : to be tested
     * Join elements
     * @param strings
     * @param join
     * @return
     */
    public static String join (Object [] strings, String joint){
        if (strings == null){
            throw new IllegalArgumentException("strings array is null");
        }
        if (joint == null){
            throw new IllegalArgumentException("No joint ; use empty String instead of null");
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0 ; i < strings.length ; i++){
            sb.append(strings[i].toString());
            //if not last
            if (i < strings.length - 1 && joint.length()>0){
                sb.append(joint);
            }
        }
        return sb.toString();
    }
    public static String defaultJoints = " _-";
    
    /**
     * Transfom joints in capital characters
     * Chateau De Versailles => ChateauDeVersaille
     * white_house => whiteHouse  (House is now capitalized)
     * groovyStyle_grails => groovyStyleGrails (inside capitals are untouched)
     * One difference with Java style is that the first letter might stay a capital
     *
     * If specifiedJoints == null, the method uses default ones : " _-", thought this
     * can be changed with the {@link StringUtils#defaultJoints}
     *
     * @param string
     * @return
     */
    public static String normalize(String string, String specifiedJoints){
        if (specifiedJoints == null){
            specifiedJoints = defaultJoints;
        }
        String worker = replaceAny(string, specifiedJoints, " ");
        String [] array = split(worker, " ");
        for (int i = 0 ; i < array.length ; i++){
            String s = array[i];
            if (i>0){
                array[i] = simpleCapitalize(s);
            }
            
        }
        return join(array, "");
    }
}