001/**
002 * Logback: the reliable, generic, fast and flexible logging framework.
003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
004 *
005 * This program and the accompanying materials are dual-licensed under
006 * either the terms of the Eclipse Public License v1.0 as published by
007 * the Eclipse Foundation
008 *
009 *   or (per the licensee's choosing)
010 *
011 * under the terms of the GNU Lesser General Public License version 2.1
012 * as published by the Free Software Foundation.
013 */
014package ch.qos.logback.core.rolling.helper;
015
016import java.io.File;
017import java.io.FilenameFilter;
018import java.util.Arrays;
019import java.util.Comparator;
020import java.util.regex.Matcher;
021import java.util.regex.Pattern;
022
023import static ch.qos.logback.core.CoreConstants.EMPTY_FILE_ARRAY;
024
025public class FileFilterUtil {
026
027
028
029    public static void sortFileArrayByName(File[] fileArray) {
030        Arrays.sort(fileArray, new Comparator<File>() {
031            public int compare(File o1, File o2) {
032                String o1Name = o1.getName();
033                String o2Name = o2.getName();
034                return (o1Name.compareTo(o2Name));
035            }
036        });
037    }
038
039    public static void reverseSortFileArrayByName(File[] fileArray) {
040        Arrays.sort(fileArray, new Comparator<File>() {
041            public int compare(File o1, File o2) {
042                String o1Name = o1.getName();
043                String o2Name = o2.getName();
044                return (o2Name.compareTo(o1Name));
045            }
046        });
047    }
048
049    public static String afterLastSlash(String sregex) {
050        int i = sregex.lastIndexOf('/');
051        if (i == -1) {
052            return sregex;
053        } else {
054            return sregex.substring(i + 1);
055        }
056    }
057
058    static public boolean isEmptyDirectory(File dir) {
059        if (!dir.isDirectory()) {
060            throw new IllegalArgumentException("[" + dir + "] must be a directory");
061        }
062        String[] filesInDir = dir.list();
063        if (filesInDir == null || filesInDir.length == 0) {
064            return true;
065        } else {
066            return false;
067        }
068    }
069
070    /**
071     * Return the set of files matching the stemRegex as found in 'directory'. A
072     * stemRegex does not contain any slash characters or any folder separators.
073     * 
074     * @param file
075     * @param stemRegex
076     * @return
077     */
078    public static File[] filesInFolderMatchingStemRegex(File file, final String stemRegex) {
079
080        if (file == null) {
081            return EMPTY_FILE_ARRAY;
082        }
083        if (!file.isDirectory()) {
084            return EMPTY_FILE_ARRAY;
085        }
086
087        // better compile the regex. See also LOGBACK-1409
088        Pattern pattern = Pattern.compile(stemRegex);
089        return file.listFiles((dir, name) -> pattern.matcher(name).matches());
090    }
091
092    static public int findHighestCounter(File[] matchingFileArray, final String stemRegex) {
093        int max = Integer.MIN_VALUE;
094        for (File aFile : matchingFileArray) {
095            int aCounter = FileFilterUtil.extractCounter(aFile, stemRegex);
096            if (max < aCounter)
097                max = aCounter;
098        }
099        return max;
100    }
101
102    static public int extractCounter(File file, final String stemRegex) {
103        Pattern p = Pattern.compile(stemRegex);
104        String lastFileName = file.getName();
105
106        Matcher m = p.matcher(lastFileName);
107        if (!m.matches()) {
108            throw new IllegalStateException("The regex [" + stemRegex + "] should match [" + lastFileName + "]");
109        }
110        String counterAsStr = m.group(1);
111        return Integer.parseInt(counterAsStr);
112    }
113
114    public static String slashify(String in) {
115        return in.replace('\\', '/');
116    }
117
118    public static void removeEmptyParentDirectories(File file, int recursivityCount) {
119        // we should never go more than 3 levels higher
120        if (recursivityCount >= 3) {
121            return;
122        }
123        File parent = file.getParentFile();
124        if (parent.isDirectory() && FileFilterUtil.isEmptyDirectory(parent)) {
125            parent.delete();
126            removeEmptyParentDirectories(parent, recursivityCount + 1);
127        }
128    }
129}