    001     /*******************************************************************************
    002     * Filename : ToolBox.java
    003     * Created  : 13-Sep-2003
    004     *
    005     * History
    006     */
    007
    008    package ifs.util;
    009
    010    import java.io.*;
    011    import java.util.*;
    012    import org.apache.log4j.*;
    013
    014    /** Several auxiliary static methods.
    015     *
    016     * @author <a href="mailto:muller@ktiml.mff.cuni.cz">Tomáš Müller</a>
    017     * @version 1.0
    018     */
    019    public class ToolBox {
    020        private static org.apache.log4j.Logger sLogger = org.apache.log4j.Logger.getLogger(ToolBox.class);
    021        private static long sSeed = System.currentTimeMillis();
    022        private static Random sRandom = new Random(sSeed);
    023
    024        /** Returns random number (int) from the set 0 .. limit - 1 */
    025        public static int random(int limit) {
    026            return (int)(random()*limit);
    027        }
    028
    029        /** Returns random element from the given set of elements */
    030        public static Object random(Collection set) {
    031            if (set==null || set.size()==0) return null;
    032            Vector v = (set instanceof Vector?(Vector)set:new Vector(set));
    033            return v.elementAt(random(v.size()));
    034        }
    035
    036        /** Returns a randomly generated subset of the given set
    037         * @param set set
    038         * @param part probability of selection of an element into the resultant subset
    039         */
    040        public static Collection subSet(Collection set, double part) {
    041            return subSet(set,part,1);
    042        }
    043
    044        /** Swaps two elements in the list */
    045        private static void swap(ArrayList list, int first, int second) {
    046            Object o = list.get(first);
    047            list.set(first,list.get(second));
    048            list.set(second,o);
    049        }
    050
    051        /** Returns a randomly generated subset of the given set
    052         * @param set set
    053         * @param part probability of selection of an element into the resultant subset
    054         * @param minSize minimal size of the returned subset
    055         */
    056        public static Collection subSet(Collection set, double part, int minSize) {
    057            if (set.size()<=minSize || part>=1.0) return set;
    058            ArrayList subSet = new ArrayList(set);
    059            int size = set.size();
    060            int numberToSelect = Math.max(minSize,(int)(part*set.size()));
    061            for (int idx=0;idx<numberToSelect;idx++) {
    062                swap(subSet, idx, idx+(int)(random()*(size-idx)));
    063            }
    064            return subSet.subList(0, numberToSelect);
    065        }
    066
    067        /** Trim a string to have given length */
    068        public static String trim(String s, int length) {
    069            if (s.length()>length) return s.substring(0,length);
    070            StringBuffer sb = new StringBuffer(s);
    071            while (sb.length()<length) sb.append(" ");
    072            return sb.toString();
    073        }
    074
    075        /** Multiline representation of a colection */
    076        public static String col2string(Collection col, int tab) {
    077            StringBuffer tabsb = new StringBuffer();
    078            while (tabsb.length()<2*tab)
    079                tabsb.append("  ");
    080            StringBuffer sb = new StringBuffer("[\n");
    081            for (Iterator i=col.iterator();i.hasNext();) {
    082                sb.append(tabsb+"  "+i.next()+(i.hasNext()?",":"")+"\n");
    083            }
    084            sb.append(tabsb+"]");
    085            return sb.toString();
    086        }
    087
    088        /** Multiline representation of a dictionary */
    089        public static String dict2string(Dictionary dict, int tab) {
    090            StringBuffer tabsb = new StringBuffer();
    091            while (tabsb.length()<2*tab)
    092                tabsb.append("  ");
    093            StringBuffer sb = new StringBuffer("[\n");
    094            for (Enumeration e=sortEnumeration(dict.keys());e.hasMoreElements();) {
    095                Object key = e.nextElement();
    096                Object value = dict.get(key);
    097                sb.append(tabsb+"  "+key+": "+value+"\n");
    098            }
    099            sb.append(tabsb+"]");
    100            return sb.toString();
    101        }
    102
    103        /** Root mean square
    104         * @param n number of tests
    105         * @param x total value of all tests
    106         * @param x2 total value^2 of all tests
    107         */
    108        public static double rms(int n, double x, double x2) {
    109            double var = x2/n   ;
    110            double mean = x/n;
    111            return Math.sqrt(Math.abs(var-mean*mean));
    112        }
    113
    114        /** Sort enumeration
    115         * @param e an enumeration
    116         * @return sorted enumeration
    117         */
    118        public static Enumeration sortEnumeration(java.util.Enumeration e) {
    119            return sortEnumeration(e,null);
    120        }
    121
    122        /** Sort enumeration
    123         * @param e an enumeration
    124         * @param c comparator of two objects in enumeration e
    125         * @return sorted enumeration
    126         */
    127        public static Enumeration sortEnumeration(java.util.Enumeration e, java.util.Comparator c) {
    128            Vector v = new Vector();
    129            for (;e.hasMoreElements();) v.addElement(e.nextElement());
    130            Collections.sort(v,c);
    131            return v.elements();
    132        }
    133
    134        /** Merge source with target */
    135        public static void merge(Vector target, Collection source) {
    136            for (Iterator i=source.iterator(); i.hasNext();) {
    137                Object o = i.next();
    138                if (!target.contains(o)) target.addElement(o);
    139            }
    140        }
    141
    142        /** Returns intersection of two collections */
    143        public static Vector intersect(Collection source1, Collection source2) {
    144            Vector target = new FastVector();
    145            for (Iterator i=source1.iterator(); i.hasNext();) {
    146                Object o = i.next();
    147                if (!source2.contains(o)) target.addElement(o);
    148            }
    149            return target;
    150        }
    151
    152        /** Sets seeds for {@link ToolBox#getRandom()} and {@link ToolBox#random()} methods. */
    153        public static void setSeed(long seed) {
    154            sSeed = seed;
    155            sRandom = new Random(sSeed);
    156        }
    157
    158        /** Gets current seed */
    159        public static long getSeed() {
    160            return sSeed;
    161        }
    162        /** Gets random number generator */
    163        public static Random getRandom() {
    164            return sRandom;
    165        }
    166        /** Generates random double number */
    167        public static double random() {
    168            return sRandom.nextDouble();
    169        }
    170
    171        /** Configurates log4j loging */
    172        public static void configureLogging() {
    173            Properties props = new Properties();
    174            props.setProperty("log4j.rootLogger", "DEBUG, A1");
    175            props.setProperty("log4j.appender.A1", "org.apache.log4j.ConsoleAppender");
    176            props.setProperty("log4j.appender.A1.layout", "org.apache.log4j.PatternLayout");
    177            props.setProperty("log4j.appender.A1.layout.ConversionPattern","%-5p %c{2}: %m%n");
    178            PropertyConfigurator.configure(props);
    179        }
    180
    181        /** Configurates log4j loging
    182         * @param logDir output folder
    183         * @param properties some other log4j properties
    184         */
    185        public static void configureLogging(String logDir, Properties properties) {
    186            configureLogging(logDir, properties, false);
    187        }
    188
    189        /** Configurates log4j loging
    190         * @param logDir output folder
    191         * @param properties some other log4j properties
    192         * @param timeInFileName if true log file is named debug_yyyy-MM-dd_(HH.mm.ss).log, it is named debug.log otherwise
    193         */
    194        public static void configureLogging(String logDir, Properties properties, boolean timeInFileName) {
    195            String time = new java.text.SimpleDateFormat( "yyyy-MM-dd_(HH.mm.ss)",java.util.Locale.US).format(new Date());
    196            (new File(logDir)).mkdirs();
    197            String fileName = logDir+File.separator+(timeInFileName?"debug_"+time:"debug")+".log";
    198            Properties props = (properties!=null?properties:new Properties());
    199            if (!props.containsKey("log4j.rootLogger")) {
    200                props.setProperty("log4j.rootLogger", "debug, LogFile");
    201                props.setProperty("log4j.appender.LogFile","org.apache.log4j.RollingFileAppender");
    202                props.setProperty("log4j.appender.LogFile.MaxFileSize", "5MB");
    203                props.setProperty("log4j.appender.LogFile.File",fileName);
    204                props.setProperty("log4j.appender.LogFile.MaxBackupIndex","5");
    205                props.setProperty("log4j.appender.LogFile.layout","org.apache.log4j.PatternLayout");
    206                props.setProperty("log4j.appender.LogFile.layout.ConversionPattern","%d{dd-MMM-yy HH:mm:ss.SSS} [%t] %-5p %c{2}> %m%n");
    207            }
    208            PropertyConfigurator.configure(props);
    209            Logger log = Logger.getRootLogger();
    210            log.info("IFS debug file");
    211            log.info("");
    212            log.info("Created: "+new Date());
    213            log.info("");
    214            log.info("System info:");
    215            log.info("System:      "+System.getProperty("os.name")+" "+System.getProperty("os.version")+" "+System.getProperty("os.arch"));
    216            log.info("CPU:         "+System.getProperty("sun.cpu.isalist")+" endian:"+System.getProperty("sun.cpu.endian")+" encoding:"+System.getProperty("sun.io.unicode.encoding"));
    217            log.info("Java:        "+System.getProperty("java.vendor")+", "+System.getProperty("java.runtime.name")+" "+System.getProperty("java.runtime.version",System.getProperty("java.version")));
    218            log.info("User:        "+System.getProperty("user.name"));
    219            log.info("Timezone:    "+System.getProperty("user.timezone"));
    220            log.info("Working dir: "+System.getProperty("user.dir"));
    221            log.info("Classpath:   "+System.getProperty("java.class.path"));
    222            log.info("");
    223        }
    224
    225        /** Loads data properties. If there is INCLUDE property available, it is interpreted as semi-colon separated list of
    226         * porperty files which should be also loaded (works recursively).
    227         *
    228         */
    229        public static DataProperties loadProperties(File propertyFile) {
    230            try {
    231                DataProperties ret = new DataProperties();
    232                FileInputStream is = new FileInputStream(propertyFile);
    233                ret.load(is);
    234                is.close();
    235                if (ret.getProperty("INCLUDE")!=null) {
    236                    is=null;
    237                    StringTokenizer stk = new StringTokenizer(ret.getProperty("INCLUDE"),";");
    238                    while (stk.hasMoreTokens()) {
    239                        String aFile = stk.nextToken();
    240                        System.out.println("  Loading included file '"+aFile+"' ... ");
    241                        if ((new File(aFile)).exists())
    242                            is = new FileInputStream(aFile);
    243                        if ((new File(propertyFile.getParent()+File.separator+aFile)).exists())
    244                            is = new FileInputStream(propertyFile.getParent()+File.separator+aFile);
    245                        if (is==null) System.err.println("Unable to find include file '"+aFile+"'.");
    246                        ret.load(is);
    247                        is.close();
    248                    }
    249                    ret.remove("INCLUDE");
    250                }
    251                return ret;
    252            } catch (Exception e) {
    253                System.err.println("Unable to load property file "+propertyFile);
    254                e.printStackTrace();
    255                return new DataProperties();
    256            }
    257        }
    258    }