[Webfunds-commits] java/webfunds/utils VersionNumbers.java

Ian Grigg iang@cypherpunks.ai
Sat, 14 Apr 2001 13:48:01 -0400 (AST)


iang        01/04/14 13:48:00

  Added:       webfunds/util VersionNumbers.java
  Removed:     webfunds/utils VersionNumbers.java
  Log:
  moved into utils

Revision  Changes    Path
1.1                  java/webfunds/util/VersionNumbers.java

Index: VersionNumbers.java
===================================================================
/*
 * $Id: VersionNumbers.java,v 1.1 2001/04/14 17:48:00 iang Exp $
 *
 * Copyright (c) 2001 Systemics Inc on behalf of
 * the WebFunds Development Team.  All Rights Reserved.
 */
package webfunds.util;


import java.io.File;
import java.io.PrintWriter;
import java.util.Vector;
import java.util.Enumeration;

// import webfunds.util.Log;

/**
 * Work out version numbers embedded in file names.
 * A version number is a series of {dash number}
 * where there is a leading dash and all numbers
 * are separated by dash.
 *
 *      -1
 *      -1-2-3
 *
 * The version number must be the last component in the string.
 *
 * Note that plugins and wallets use this code.
 *
 * @return a list of latest-version plugin directories.
 */
public class VersionNumbers
{
    static Log bug;
    static void logmsg(String s) { if (bug != null) bug.println(s); }

    /**
     * Note that plugins and wallets use this code.
     *
     * @return a list of latest-version plugin directories.
     */
    static public String[] getListOfAddOns(File dir)
    {
        bug = null;
        return getList(dir);
    }

    /**
     * Note that plugins and wallets use this code.
     *
     * @return a list of latest-version plugin directories.
     */
    static public String[] getListOfAddOns(File dir, Log callerBug)
    {
        bug = callerBug;
        return getList(dir);
    }

    /**
     * XXX: Deprecated
     */
    static public String[] getListOfAddOns(File dir, PrintWriter callerBug)
    {
        bug = new Log(callerBug);
        return getList(dir);
    }

    static protected void checkOutDirectory(File dir)
    {
        logmsg("directory: " + dir + " list is null");
        logmsg("absolute path: " + dir.getAbsolutePath());
        if (!dir.exists())
           logmsg("version directory: " + dir + " is non existant");
        else
        {
          if (!dir.isDirectory())
            logmsg("version directory: " + dir + " is not a directory");
          if (!dir.canRead())
            logmsg("version directory: " + dir + " is not readable");
        }

        String pp = dir.getParent();
        logmsg("pp is " + pp);
        if (pp == null)
            pp = ".";
        File parent = new File(pp);
        if (!parent.exists())
        {
           logmsg("parent directory: " + parent + " is non existant");
           return ;
        }

        if (!parent.isDirectory())
            logmsg("parent directory: " + parent + " is not a directory");
        else
        {
            String[] list = parent.list();
            if (list == null || (list.length == 0))
                logmsg("parent directory: " + parent + " has no list "+list);
            else
            {
                for (int i = 0; i < list.length; i++)
                    logmsg("     ++++ " + i + " " + list[i]);
            }
        }

        if (!parent.canRead())
            logmsg("parent directory: " + parent + " is not readable");

    }


    static protected String[] getList(File dir)
    {
        String[] list = dir.list();
        if (list == null)          // means "not a directory" or "IO error"
        {
            checkOutDirectory(dir);

            return new String[0] ;
        }
        Vector victor = new Vector();

        //
        //  There is a directory per plugin here.
        //
        for (int i = 0; i < list.length; i++)
        {
            String product = list[i];
            File pugDir = new File(dir, product);

            if (!pugDir.isDirectory())
                continue ;
//logmsg(" dir " + product);

            //
            //  There is a directory per version within each plugin.
            //
            String[] versions = pugDir.list();
            String thisOne = null;
            String thisName = null;
            for (int j = 0; j < versions.length; j++)
            {
                //
                //  Each name is of the form name-i-j-k.
                //  The first dash signifies the start of the 3 component
                //  version code.
                //
                String name = versions[j];
                int dash = name.indexOf("-");
                if (dash < 0 || dash > (name.length() - 1))
                {
                    logmsg("no dash, skipping " + name);
                    continue ;
                }
                String vers = name.substring(dash + 1);
                if (vers == null || vers.equals(""))
                {
                    logmsg("no version, skipping " + name);
                    continue ;
                }
logmsg("   "  + name + " gives " + vers);
                boolean isBetter;
                try {
                    isBetter = isGreater(vers, thisOne);
                } catch (NumberFormatException ex) {
                    ex = null; // jikes
                    logmsg("not valid version: " + name);
                    continue ;
                }
                if (isBetter)
                {
logmsg("      raising " + name);
                    thisOne = vers;
                    thisName = name;
                }
            }

            if (thisName != null)
                victor.addElement(product + File.separator + thisName);
            else
                logmsg("    " + dir + " has no version directory?");
        }

        int siz = victor.size();
//logmsg(" found " + siz + "!");
        String[] found = new String[siz];
        Enumeration e = victor.elements();
        for (int k = 0;  k < siz;  k++)
//{
            found[k] = (String)e.nextElement();
//logmsg("adding ... " + found[k]);}
        if (e.hasMoreElements())
            throw new RuntimeException("more elements in vector");

        return found ;
    }


    /**
     * is one greater than two?
     * Empty string or null counts as version -1.
     * @return true if one is a more recent version than two, else false
     */
    public static boolean isGreater(String one, String two)
        throws NumberFormatException
    {
        if (two == null)
            return true ;
        if (one == null)
            return false ;

        int[] oneV = getVersionsFromString(one);
//System.err.println("test " + one + ": " + oneV.length);
//if (oneV.length > 0) System.err.println("      " + "<<" + oneV[0] + ">>");
        int[] twoV = getVersionsFromString(two);
//System.err.println("     " + two + ": " + twoV.length);
//if (twoV.length > 0) System.err.println("      " + "<<" + twoV[0] + ">>");

        int min = (oneV.length < twoV.length) ? oneV.length : twoV.length;
        for (int i = 0; i < min; i++)
        {
            if (oneV[i] > twoV[i])
               return true ;
            if (oneV[i] < twoV[i])
               return false ;
        }

        if (oneV.length >= twoV.length)
            return true ;

        return false;
    }

    /**
     *  Looks for the first dash '-' and then looks for a triplet
     *  of numbers after that, something like 1.2.3 or 3-2-1.
     *
     *  @return list of ints that correspond to this version
     */
    public static int[] getVersionsFromString(String versionString)
        throws NumberFormatException
    {
        Vector vv = new Vector();
        int i = 0;
        int dashes = 0;
        int len = versionString.length();
//logmsg("    len == " + len);
        while (i < len)
        {
            if (versionString.regionMatches(i, "-", 0, 1) ||
                versionString.regionMatches(i, ".", 0, 1))
            {
//logmsg("    skipping dash");
                i++;
                dashes++;
                continue ;
            }

            int end = versionString.indexOf("-", i);  // dash separated or dot
            if (end < 0)
                end = versionString.indexOf(".", i);  // might not work on M$
            if (end < 0)
                end = len;
            String num = versionString.substring(i, end);
//logmsg("    found " + num);
            vv.addElement(num);
            i = end;
        }

        int[] found = new int[vv.size()];
//logmsg("    count == " + vv.size());

        Enumeration e = vv.elements();
        for (int k = 0;  k < found.length;  k++)
        {
            String s = (String)e.nextElement();
//logmsg("    got == " + s);
            int v = new Integer(s).intValue();
            found[k] = v;
        }
        if (e.hasMoreElements())
            throw new RuntimeException("more elements in vector");

        return found ;
    }

    /**
     * Test the comparisons.
     */
    public static void main(String[] arg)
    {

        bug = new Log();

        if (arg.length > 0)
        {
            File d = new File(arg[0]);
            String[] found = getList(d);
            for (int i = 0; i < found.length; i++)
                logmsg(i + ": " + found[i]);
            System.exit (0) ;
        }

        check(false, "", "0");
        check(false, null, "0");
        check(true, "4", "");
        check(true, "4", null);

        check(false, "1", "2");
        check(false, "1", "2");
        check(false, "2-5", "3");

        check(true, "5", "4");
        check(true, "7", "6-8");
        check(true, "1-2-0", "1-2");

        checkEx("a", "1");
        checkEx("1a", "1");
        checkEx("a1", "1");
        checkEx("-a1", "1");
        checkEx("-1-a", "1");
        checkEx("-1-a-", "1");
        checkEx("-1-a-1", "1");
    }

    /**
     * throws an Ex if false.
     */
    public static void check(boolean result, String one, String two)
    {
        boolean b = isGreater(one, two);
        if (b != result)
            throw new RuntimeException(one + " > " + two + " is " + b);
    }

    /**
     * Must throw an exception.
     */
    public static void checkEx(String one, String two)
    {
        boolean b;
        try {
            b = isGreater(one, two);
        } catch (Throwable ex) {
            ex = null;
            return ;
        }
        throw new RuntimeException(one + " > " + two + " is " + b);
    }
}