001/* 002 * Logback: the reliable, generic, fast and flexible logging framework. 003 * Copyright (C) 1999-2026, 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 v2.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}