Friday, August 7, 2015

Getting Started with the Google Drive API

Step 1. Create a Client ID 

See also Retrieve and Use OAuth 2.0 Credentials.
  • Go to https://console.developers.google.com/
  • Switch to appropriate Google account
  • Click on ENABLE APIS in the "Enable Google APIs for use in your apps
  • Named the project "Upload Project" and agreed to the terms
  • Click Drive API and hit Enable API
  • Click Credentials in left nav
  • Click Create new Client ID
  • Select Web Application
  • In the form for Consent Screen, name the product "Upload Project"
  • Click Save
  • Click Create Client ID
  • You will get "Client ID", "Client secret", "Redirect URIs" and "JavaScript origins"
Note: We will used ${clientID} to represent the client ID in this post.

Step 2. Generate a new Auth Token

For protocol information about OAuth protocol and workflow, see https://developers.google.com/identity/protocols/OAuth2?csw=1

For REST endpoint information on the oauth2 REST API used here, see https://developers.google.com/identity/protocols/OAuth2WebServer

For parameter information on Auth Token scopes for Google Drive API access, see https://developers.google.com/drive/v2/reference/files/insert

For parameter information on Auth Token scopes for You Tube API access, see https://developers.google.com/youtube/v3/guides/auth/client-side-web-apps
  • In developer console, edit settings and change Redirect URIs to http://localhost
  • The URL needed to generate the Auth Token looks something like this:
    • https://accounts.google.com/o/oauth2/auth?client_id=****nko08rm1s2qebr300ll3a0kakm3aue.apps.googleusercontent.com&redirect_uri=http://localhost&scope=https://www.googleapis.com/auth/drive&response_type=token
    • Open Google Chrome and enter this is the browser, after replacing ${clientID}
      • https://accounts.google.com/o/oauth2/auth?client_id=${clientID}&redirect_uri=http://localhost&scope=https://www.googleapis.com/auth/drive&response_type=token
    • Go through the flows to sign in (Username, Password, User Consent)
    • The URL in the Browser will contain the Google API access token which will be something like this:
      • http://localhost/#access_token=ya29.xwHjsm--zQ6Wi5qD6mAoMfnDcNdCl0FvaUN8TuAwCvMJ4-YYq2ozj1vKCE1aAGECW4s8&token_type=Bearer&expires_in=3600
    • The access token would then be something like this:
      • ya29.xwHjsm--zQ6Wi5qD6mAoMfnDcNdCl0FvaUN8TuAwCvMJ4-YYq2ozj1vKCE1aAGECW4s8
    Note: In this post, we will refer to this Auth Token using ${AuthToken}

    Step 3. List all files (curl)

    Open Git Bash command line and execute the following.  This will create a file filesResponse.txt with all the files in google drive.

    curl -k -H "Authorization: Bearer ${AuthToken}" https://www.googleapis.com/drive/v2/files > filesResponse.txt

    curl -k -H "Authorization: Bearer ya29.xwE3y4ErpmdEXVS3v02hC-DEm2gz05ZwpjOvrmdOXOcCSz0YALOH9A1Qc4YHQGnFPqjN" https://www.googleapis.com/drive/v2/files > filesResponse.txt

    You will get a json response with a ton of information.

    Alternate Step 3: List all files (Java)

    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.util.EntityUtils;
    // Step 1 - LIST ALL FILES TO TEST GOOGLE DRIVE API
    // curl -k -H "Authorization: Bearer ya29.xwE3y4ErpmdEXVS3v02hC-DEm2gz05ZwpjOvrmdOXOcCSz0YALOH9A1Qc4YHQGnFPqjN" https://www.googleapis.com/drive/v2/files > files.txt
    //<!-- Shipping with selenium-htmlunit-driver 2.41.0 -->
    //<!-- Includes httpclient 4.3.1 org.apache.http.client.methods.CloseableHttpResponse -->
    //<!-- Includes httpmime 4.3.1 org.apache.http.entity.mime -->
    //<!-- Includes commons-lang3 3.1 org.apache.commons.lang3.exception.ExceptionUtils -->
    //<dependency>
    //    <groupId>net.sourceforge.htmlunit</groupId>
    //    <artifactId>htmlunit</artifactId>
    //    <version>2.13</version>
    //</dependency>
    public class ListAllFiles {
        public static void main(String[] args) {
            try {
                String token = "ya29.yAFLSqN1xaR9EKuMrcJu6iLMt9PyaRqotTK01PbaPjd7gZZMtqE9XgFgHz3A5IEwKV7-";
                HttpGet httpGet = new HttpGet("https://www.googleapis.com/drive/v2/files");
                httpGet.addHeader("Authorization""Bearer "+token);
                CloseableHttpResponse response = new DefaultHttpClient().execute(httpGet);
                String jsonResponse = EntityUtils.toString(response.getEntity());
                response.close();
                System.out.println("jsonResponse:"+jsonResponse);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }

    Thursday, July 30, 2015

    A Simple Image Overlay Example

    From jquerytools.org
    This example uses jquery 1.2.7. Create a file “test.html” and edit with a text editor. Add the following code.
    <html>
        <head>
            <meta charset="UTF-8" />
            <title>Image Overlay Example</title>
    <script src="http://cdn.jquerytools.org/1.2.7/full/jquery.tools.min.js"></script>

    </head>
        <body>
    <p>
    <button class="modalInput" rel="#myID">Show Image</button>
    <!-- yes/no dialog -->
    <div class="modal" id="myID" style="display:none;padding:15px;border:2px solid #333;-webkit-border-radius:6px;">
    <image src="https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif" />
    <br>
    <button class="close">Close</button>
    </div>
    </p>

    <script>
    $(document).ready(function() {
    $(".modalInput").overlay({
    // some mask tweaks suitable for modal dialogs
    mask: {
    color: '#ebecff',
    loadSpeed: 200,
    opacity: 0.9
    },
    closeOnClick: false,
    fixed: false
    });
      });
    </script>
        </body>
    </html>

    Thursday, June 25, 2015

    Working with HttpPost and SSL Certificates

    This is code to perform an HttpPost to hit a REST endpoint.  It assumes the REST endpoint is expecting the Request to contain data in JSON format.  It also assumes the Response can come back in JSON format.  This will perform the HttpPost and pull the 'status' and 'token' values from the JSON response.

    JAVA


    The HttpPostSSLHandler code will install an SSL certificate prior to the HttpPost.  This will install in the same location as the Java Development Kit (jdk) being used.

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.security.KeyStore;
    import java.security.MessageDigest;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    import java.util.ArrayList;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Set;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLException;
    import javax.net.ssl.SSLSocket;
    import javax.net.ssl.SSLSocketFactory;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.TrustManagerFactory;
    import javax.net.ssl.X509TrustManager;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.protocol.HTTP;
    import org.apache.http.util.EntityUtils;
    import org.codehaus.jettison.json.JSONObject;


    public class HttpPostRequestAndResponse {
        static String USERNAME = "sizu";
        static String PASSWORD = "myPassword";
        static String APPID = "myApp";
        static String HOST = "rest.host.com";
        static String REST_END_POINT = "http://rest.host.com:443/rest/api/services/authentication";
        
        /**
         * @param args
         * @throws Exception
         */

        public static void main(String[] args) throws Exception {
            System.out.println("Step 1: Install SSL Certificate");
            HttpPostSSLHandler.setupSSLContextByInstallingCertification(HOST);

            System.out.println("Step 2a: Create HttpPost");    
            HttpPost httpPost = new HttpPost(REST_END_POINT);

            System.out.println("Step 2b: Set Headers");
            httpPost.setHeader("Content-Type""application/json");
            httpPost.setHeader("Accept""application/json");

            System.out.println("Step 2c: Set Request for POST");    
            JSONObject jsonRequest = new JSONObject();
            jsonRequest.put("account", USERNAME);
            jsonRequest.put("appName", APPID);
            jsonRequest.put("password", PASSWORD);
            httpPost.setEntity(new StringEntity(jsonRequest.toString(), HTTP.UTF_8));

            System.out.println("Step 3a Start: Send Request/Receive Response");
            String jsonResponseString = EntityUtils.toString(new DefaultHttpClient().execute(httpPost).getEntity());
            System.out.println("Step 3a Finish: jsonResponseString:"+jsonResponseString);

            System.out.println("Step 3b Start: Obtain token from response");
            JSONObject jsonResponse = new JSONObject(jsonResponseString);
            String status = jsonResponse.getString("status");
            String token = jsonResponse.getString("token");
            System.out.println("Step 3b Finish: status:"+status+" token:"+token);
        }
        
        /**
         * Should be called right before connection
         * 
         * Installs C:\Program Files\Java\jdk1.7.0_51\jre\lib\security\jssecacerts file
         * @param host
         * @throws Exception
         */

        public static class HttpPostSSLHandler {
            static Set<String> hostsInstalled = new HashSet<String>();
            public static void setupSSLContextByInstallingCertification(String host) {
                if(hostsInstalled.contains(host)) {
                    return;
                } else {
                    hostsInstalled.add(host);
                }
                System.out.println("Installing SSLContext Certification into Java Home...");
                try {
                    int port = 443;
                    char[] passphrase = "changeit".toCharArray();
                    
                    char SEP = File.separatorChar;
                    File file = new File("jssecacerts");
                    if (file.isFile() == false) {
                        File dir = new File(System.getProperty("java.home") + SEP
                                + "lib" + SEP + "security");
                        file = new File(dir, "jssecacerts");
                        if (file.isFile() == false) {
                            file = new File(dir, "cacerts");
                        }
                    }
                    
                    System.out.println("Loading KeyStore " + file + "...");
                    InputStream in = new FileInputStream(file);
                    KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
                    ks.load(in, passphrase);
                    in.close();
             
                    TrustManagerFactory tmf =
                            TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
                    tmf.init(ks);
                    final X509TrustManager defaultTrustManager = (X509TrustManager) tmf.getTrustManagers()[0];
                    final List<X509Certificate> chainList = new ArrayList<X509Certificate>();
                    
                    TrustManager tm = new X509TrustManager() {
                        public void checkClientTrusted(X509Certificate[] arg0, String arg1)
                                        throws CertificateException { }
                        public void checkServerTrusted(X509Certificate[] arg0, String arg1)
                                throws CertificateException {
                                chainList.clear();
                                if(arg0 != null) {
                                    for (int i = 0; i < arg0.length; i++) {
                                        chainList.add(arg0[i]);
                                    }
                                }
                                defaultTrustManager.checkServerTrusted(arg0, arg1); }
                        public X509Certificate[] getAcceptedIssuers() { return null; }
                    };
                    
                    SSLContext context = SSLContext.getInstance("TLS");
                    context.init(nullnew TrustManager[]{tm}, null);
                    SSLSocketFactory factory = context.getSocketFactory();
             
                    System.out.println("Opening connection to " + host + ":" + port + "...");
                    SSLSocket socket = (SSLSocket) factory.createSocket(host, port);
                    socket.setSoTimeout(10000);
                    try {
                        socket.startHandshake();
                        System.out.println("No errors, certificate is already trusted");
                    } catch (SSLException e) { }
                    socket.close();
             
                    if (chainList.isEmpty()) {
                        System.out.println("Could not obtain server certificate chain");
                        return;
                    }
             
                    System.out.println("Server sent " + chainList.size() + " certificate(s):");
        
                    MessageDigest sha1 = MessageDigest.getInstance("SHA1");
                    MessageDigest md5 = MessageDigest.getInstance("MD5");
                    for (int i = 0; i < chainList.size(); i++) {
                        X509Certificate cert = chainList.get(i);
                        System.out.println
                                (" " + (i + 1) + " Subject " + cert.getSubjectDN());
                        System.out.println("   Issuer  " + cert.getIssuerDN());
                        sha1.update(cert.getEncoded());
                        System.out.println("   sha1    " + toHexString(sha1.digest()));
                        md5.update(cert.getEncoded());
                        System.out.println("   md5     " + toHexString(md5.digest()));
                    }
                    
                    int k = 0;
                    X509Certificate cert = chainList.get(k);
                    String alias = host + "-" + (k + 1);
                    ks.setCertificateEntry(alias, cert);
             
                    File dir = new File(System.getProperty("java.home") + SEP
                            + "lib" + SEP + "security");
                    file = new File(dir, "jssecacerts");
                    OutputStream out = new FileOutputStream(file);
                    ks.store(out, passphrase);
                    out.close();
                    
                    System.out.println("Installed SSLContext Certification into Java Home: "+file.getAbsolutePath());
                } catch (Exception ex) { }
            }
        
            /**
             * Used to print ssl certificate message
             */

            private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray();
            private static String toHexString(byte[] bytes) {
                StringBuilder sb = new StringBuilder(bytes.length * 3);
                for (int b : bytes) {
                    b &= 0xff;
                    sb.append(HEXDIGITS[b >> 4]);
                    sb.append(HEXDIGITS[b & 15]);
                    sb.append(' ');
                }
                return sb.toString();
            }
        }
    }

    CURL

    The corresponding curl command would be

    curl -X POST --data '{"account":"sizu","appName":"myApp","password":"myPassord"}' http://rest.host.com:443/rest/api/services/authentication --header "Content-Type:application/json" --header "Accept:application/json"

    Common Error: error setting certificate verify locations

    curl: (77) error setting certificate verify locations:
    CAfile: C:\Users\sizu\Downloads\curl-ca-bundle.crt
    CApath: none

    The problem is that the system default CA bundle is missing or does not have read access.

    Option 1: Use the -k option to use an insecure version of curl without SSL verification

    curl -k -X POST --data '{"account":"sizu","appName":"myApp","password":"myPassord"}' http://rest.host.com:443/rest/api/services/authentication --header "Content-Type:application/json" --header "Accept:application/json"

    Option 2: Download a default CA bundle file to the missing location

    curl http://curl.haxx.se/ca/cacert.pem -o /c/Users/sizu/Downloads/curl-ca-bundle.crt

    curl -X POST --data '{"account":"sizu","appName":"myApp","password":"myPassord"}' http://rest.host.com:443/rest/api/services/authentication --header "Content-Type:application/json" --header "Accept:application/json"

    Option 3: Download a default CA bundle file and use the --cacert option

    curl http://curl.haxx.se/ca/cacert.pem -o cacert.crt

    curl -X POST --data '{"account":"sizu","appName":"myApp","password":"myPassord"}' http://rest.host.com:443/rest/api/services/authentication --header "Content-Type:application/json" --header "Accept:application/json" --cacert cacert.crt

    Common Error: SSL certificate problem

    If you get the following error, this will be hard to solve (root certificates, creating your own certificates, exporting from internet explorer):

    SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

    Wednesday, May 20, 2015

    Checking if Elements are Hidden Using Javascript

    According to stackoverflow.com, Selenium WebDriver has 9 checks to verify whether an element is hidden or not.

    1.  OPTION, OPTGROUP (iff enclosing select is hidden)
    2.  IMAGEMAP (iff image is hidden)
    3.  INPUT (iff type is hidden)

        if((element.tagName.toLowerCase() == "input") && (element.type.toLowerCase() == "hidden")) {
            return true;
        }

    4. NOSCRIPT (always hidden)

        if(element.tagName.toLowerCase() == "noscript") {
            return true;
        }

    5. Visibility (iff value is hidden)

        if(element.style.visibility == 'hidden') {
            return true;
        }

    6.  Display (iff value is none or has ancestor)

        if(findFirstAncestorByDisplayNone(element) != null) {
            return true;
        }

    function findFirstAncestorByDisplayNone(element) {
        while(element != null){
            if(element.style.display == 'none') {
                return element;
            }
            element = element.parentElement;
        }
        return element;
    }

    7.  Transparency/Opacity (iff value is 0)

        if(element.style.opacity == 0) {
            return true;
        }

    8.  Hidden (iff value is true or has ancestor)
    Note: variation for IE, see stackoverflow.com.

        if(findFirstAncestorByHidden(element) != null) {
            return true;
        }

    function findFirstAncestorByHidden(element) {
        while(element != null){
            if(element.hidden == true) {
                return element;
            }
            element = element.parentElement;
        }
        return element;
    }

    9.  Size (iff enclosing box is 0 by 0)
    Note: variation positive size, see stackoverflow.com.

        if(element.offsetWidth == 0 && element.offsetHeight == 0) {
            return true;
        }

    10.  Overflow

        if(element.style.overflow == 'hidden') {
            return true;
        }

    For step 9, there are many variations for checking height and width.  Let me do a quick and dirty overview.  See stackoverflow.com for more on this.

    https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetHeight - Includes border
        element.offsetWidth
        element.offsetHeight;

    //https://developer.mozilla.org/en-US/docs/Web/API/Element/clientHeight
        element.clientWidth;
        element.clientHeight;

    // More precise, non integer value
        element.getBoundingClientRect().right - element.getBoundingClientRect().left;
        element.getBoundingClientRect().top - element.getBoundingClientRect().bottom;

    // Additional style, depending on certain circumstances, will roll into offset
        element.width;
        element.height;

    // Additional style, depending on certain circumstances, will roll into offset
        element.style.width;
        element.style.height;

    // For scroll bar
        element.scrollWidth;
        element.scrollHeight;"


    Monday, January 5, 2015

    An Implementation in Javascript of the Interest Rate Algorithm

    This is a follow on from Binary Search Algorithm for Calculating Interest Rate.
    <html>
    <body>
    <pre>
    <script>
    function log(arg) {
        document.body.innerHTML = document.body.innerHTML + arg + '\n<br>';
    }
    function clear() {
        document.body.innerHTML = '';
    }

    function parseDate(dateString) {
        var mdy = dateString.split('/')
        return new Date(mdy[2], mdy[0]-1, mdy[1]);
    }

    function yearsInBetweenDates(date1, date2) {
        return (date2-date1)/(1000*60*60*24*365);
    }

    function assignYearsInBetween(paymentArray, currentNetWorth) {
        for (var i = 0; i<paymentArray.length; i++) {
            paymentArray[i].years = yearsInBetweenDates(paymentArray[i].date, currentNetWorth.date);
        }
    }

    function findRateOfReturn(paymentArray, currentNetWorth, lowRate, highRate){
        assignYearsInBetween(paymentArray, currentNetWorth);
        
        while(highRate-lowRate > .0001) {
            var testRate = (lowRate + highRate)/2;
            var calculatedNetWorth = calculateNetWorth(paymentArray, testRate);
            if(calculatedNetWorth < currentNetWorth.amount) {
                lowRate = testRate;
            } else {
                highRate = testRate;
            }
        }
        return lowRate;
    }

    function calculateNetWorth(paymentArray, interestRate) {
        var total = 0;
        for (var i=0; i<paymentArray.length; i++) {
            var P = paymentArray[i].amount;
            var r = interestRate;
            var y = paymentArray[i].years;
            total = total + P*Math.pow((1+r), y);
        }
        return total;
    }

    function createTransaction(date, amount) {
        var object = new Object();
        object.date = parseDate(date);
        object.amount = amount;
        return object;
    }

    var currentNetWorth = createTransaction("05/30/2014", 3170.14);
    var paymentArray = [];
    paymentArray[0] = createTransaction("04/02/2013", 300.00);
    paymentArray[1] = createTransaction("05/03/2013", 300.00);
    paymentArray[2] = createTransaction("09/03/2013", 300.00);
    paymentArray[3] = createTransaction("10/01/2013", 300.00);
    paymentArray[4] = createTransaction("11/01/2013", 300.00);
    paymentArray[5] = createTransaction("12/01/2013", 300.00);
    paymentArray[6] = createTransaction("01/02/2014", 250.00);
    paymentArray[7] = createTransaction("02/04/2014", 250.00);
    paymentArray[8] = createTransaction("03/04/2014", 250.00);
    paymentArray[9] = createTransaction("04/02/2014", 300.00);
    paymentArray[10] = createTransaction("05/02/2014", 300.00);
    log('Rate:'+findRateOfReturn(paymentArray, currentNetWorth, -1, 1));

    </script>
    </pre>
    </body>
    </html>
    The nice thing about Javascript is that these types of functions can be calculated anywhere without the need for the whole support.

    This program outputs 1.17 as the interest rate.

    This post was reposted from http://scottizu.wordpress.com/2014/06/12/an-implementation-in-javascript-of-the-interest-rate-algorithm/, originally written on June 12th, 2014.

    Saturday, January 3, 2015

    A Javascript Example to Calculate Net Worth Based on Monthly Contributions

    Suppose you want to calculate how much your money would grow if you started out with a large lump sum and contributed monthly.

    The formula here would be:

    P*(1+r)^y + sum_{n=0}^{y*12-1} M*(1+r)^(y-n/12)

    where P is the original amount, r is the rate, y is the number of years and M is the monthly contribution.

    <html>
    <head>
    <script type="text/javascript">
    function calculate(original, monthly, rate, years) {
       var multiplier1 = Math.pow((1+rate),years);
       var value1 = original*multiplier1;
       var multiplier2 = 0;
       for(var i=0; i<(years*12); i++) {
          multiplier2 = multiplier2 + Math.pow((1+rate), years-i/12);
       }
       var value2 = monthly*multiplier2;
       var total = value1 + value2;
       var o = '<b>Total:</b> '+total;
       o = o + '<br>';
       o = o + '<br><b>Original:</b> '+original;
       o = o + '<br><b>Multiplier1:</b> '+multiplier1;
       o = o + '<br><b>Value1:</b> '+value1;
       o = o + '<br>';
       o = o + '<br><b>Monthly:</b> '+monthly;
       o = o + '<br><b>Multiplier2:</b> '+multiplier2;
       o = o + '<br><b>Value2:</b> '+value2;
       output(o);
       return total;
    }
    function output(outputVal) { // Output Function
       document.getElementById('myoutput').innerHTML = outputVal;
    }
    function documentReady() { // Document Ready Function
       calculate(100000, 120, .05, 5);
    }
    </script>
    </head>
    <body onload="documentReady();">
       <div id="myoutput"></div>
    </body>
    </html>


    Output:
    Total: 135798.95858737087

    Original: 100000
    Multiplier1: 1.2762815625000001
    Value1: 127628.15625000001

    Monthly: 120
    Multiplier2: 68.09001947809055
    Value2: 8170.802337370867

    This post was reposted from http://scottizu.wordpress.com/2014/07/30/a-javascript-example-to-calculate-net-worth-based-on-monthly-contributions/, originally written on July 30th, 2014.

    Binary Search Algorithm for Calculating Interest Rate

    This java code gives a snippet of how to calculate the interest rate based on 11 deposits in about a year's time frame.

    The rate calculated was 1.17%.
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.LinkedHashMap;
    import java.util.Map;

    public class SolverExample {
        static SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
        public static void main(String[] args) {
            try {
                Double currentNetWorth = 3170.14;
                Date currentDate = sdf.parse("05/30/2014");
                Map<Double, Double> yearsToPaymentsMap = new LinkedHashMap<Double, Double>();
                yearsToPaymentsMap.put(yearsBetween(sdf.parse("04/02/2013"), currentDate), 300.00);
                yearsToPaymentsMap.put(yearsBetween(sdf.parse("05/03/2013"), currentDate), 300.00);
                yearsToPaymentsMap.put(yearsBetween(sdf.parse("09/03/2013"), currentDate), 300.00);
                yearsToPaymentsMap.put(yearsBetween(sdf.parse("10/01/2013"), currentDate), 300.00);
                yearsToPaymentsMap.put(yearsBetween(sdf.parse("11/01/2013"), currentDate), 300.00);
                yearsToPaymentsMap.put(yearsBetween(sdf.parse("12/01/2013"), currentDate), 300.00);
                yearsToPaymentsMap.put(yearsBetween(sdf.parse("01/02/2014"), currentDate), 250.00);
                yearsToPaymentsMap.put(yearsBetween(sdf.parse("02/04/2014"), currentDate), 250.00);
                yearsToPaymentsMap.put(yearsBetween(sdf.parse("03/04/2014"), currentDate), 250.00);
                yearsToPaymentsMap.put(yearsBetween(sdf.parse("04/02/2014"), currentDate), 300.00);
                yearsToPaymentsMap.put(yearsBetween(sdf.parse("05/02/2014"), currentDate), 300.00);
                
                Double rate = findRateOfReturn(-1.00, 1.00, yearsToPaymentsMap, currentDate, currentNetWorth);
                
                System.out.println("Rate:"+rate);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }

        /**
         * Uses a binary search to converge on an interest rate between two guesses: lowRate and highRate
         * @param lowRate
         * @param highRate
         * @param yearsToPaymentsMap
         * @param currentDate
         * @param currentNetWorth
         * @return
         */

        private static Double findRateOfReturn(double lowRate, double highRate, Map<Double, Double> yearsToPaymentsMap, Date currentDate, Double currentNetWorth) {
            
            while(highRate-lowRate > .0001) {
                double testRate = (lowRate + highRate)/2;
                Double calculatedNetWorth = calculateNetWorth(testRate, yearsToPaymentsMap);

                if(calculatedNetWorth < currentNetWorth) {
                    lowRate = testRate;
                } else {
                    highRate = testRate;
                }
            }
            
            return lowRate;
        }
        
        /**
         * Returns P1(1+r)^Y1 + P2(1+r)^Y2 + ...
         * @param interestRate - r
         * @param yearsToPaymentsMap - give Y1->P1, Y2->P2, etc
         * @return
         */

        private static double calculateNetWorth(double interestRate, Map<Double, Double> yearsToPaymentsMap) {
            double sum = 0.0;
            for(double years: yearsToPaymentsMap.keySet()) {
                double payment = yearsToPaymentsMap.get(years);
                sum = sum + payment*Math.pow((1 + interestRate), years); // P(1+r)^y
            }
            return sum;
        }

        /**
         * 1000 millisec/sec * 60 sec/min * 60 min/hr * 24 hr/day * 365 day/year = 31536000000 millisec/year 
         * @param d1
         * @param d2
         * @return
         */

        public static double yearsBetween(Date d1, Date d2){
            return (double) (d2.getTime() - d1.getTime()) / 31536000000.0;
        }
    }


    This post was reposted from http://scottizu.wordpress.com/2014/05/30/binary-search-algorithm-for-calculating-interest-rate/, originally written on May 30th, 2014.