| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache license, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the license for the specific language governing permissions and |
| * limitations under the license. |
| */ |
| package org.apache.logging.log4j.core.appender.rolling; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.nio.file.DirectoryStream; |
| import java.nio.file.Files; |
| import java.nio.file.Path; |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.SortedMap; |
| import java.util.TreeMap; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| import org.apache.logging.log4j.Logger; |
| import org.apache.logging.log4j.LoggingException; |
| import org.apache.logging.log4j.core.appender.rolling.action.Action; |
| import org.apache.logging.log4j.core.appender.rolling.action.CompositeAction; |
| import org.apache.logging.log4j.core.lookup.StrSubstitutor; |
| import org.apache.logging.log4j.core.pattern.NotANumber; |
| import org.apache.logging.log4j.status.StatusLogger; |
| |
| /** |
| * |
| */ |
| public abstract class AbstractRolloverStrategy implements RolloverStrategy { |
| |
| /** |
| * Allow subclasses access to the status logger without creating another instance. |
| */ |
| protected static final Logger LOGGER = StatusLogger.getLogger(); |
| |
| protected final StrSubstitutor strSubstitutor; |
| |
| protected AbstractRolloverStrategy(final StrSubstitutor strSubstitutor) { |
| this.strSubstitutor = strSubstitutor; |
| } |
| |
| |
| public StrSubstitutor getStrSubstitutor() { |
| return strSubstitutor; |
| } |
| |
| protected Action merge(final Action compressAction, final List<Action> custom, final boolean stopOnError) { |
| if (custom.isEmpty()) { |
| return compressAction; |
| } |
| if (compressAction == null) { |
| return new CompositeAction(custom, stopOnError); |
| } |
| final List<Action> all = new ArrayList<>(); |
| all.add(compressAction); |
| all.addAll(custom); |
| return new CompositeAction(all, stopOnError); |
| } |
| |
| protected int suffixLength(final String lowFilename) { |
| for (final FileExtension extension : FileExtension.values()) { |
| if (extension.isExtensionFor(lowFilename)) { |
| return extension.length(); |
| } |
| } |
| return 0; |
| } |
| |
| |
| protected SortedMap<Integer, Path> getEligibleFiles(final RollingFileManager manager) { |
| return getEligibleFiles(manager, true); |
| } |
| |
| protected SortedMap<Integer, Path> getEligibleFiles(final RollingFileManager manager, |
| final boolean isAscending) { |
| final StringBuilder buf = new StringBuilder(); |
| final String pattern = manager.getPatternProcessor().getPattern(); |
| manager.getPatternProcessor().formatFileName(strSubstitutor, buf, NotANumber.NAN); |
| return getEligibleFiles(buf.toString(), pattern, isAscending); |
| } |
| |
| protected SortedMap<Integer, Path> getEligibleFiles(final String path, final String pattern) { |
| return getEligibleFiles(path, pattern, true); |
| } |
| |
| protected SortedMap<Integer, Path> getEligibleFiles(final String path, final String logfilePattern, final boolean isAscending) { |
| final TreeMap<Integer, Path> eligibleFiles = new TreeMap<>(); |
| final File file = new File(path); |
| File parent = file.getParentFile(); |
| if (parent == null) { |
| parent = new File("."); |
| } else { |
| parent.mkdirs(); |
| } |
| if (!logfilePattern.contains("%i")) { |
| return eligibleFiles; |
| } |
| final Path dir = parent.toPath(); |
| String fileName = file.getName(); |
| final int suffixLength = suffixLength(fileName); |
| if (suffixLength > 0) { |
| fileName = fileName.substring(0, fileName.length() - suffixLength) + ".*"; |
| } |
| final String filePattern = fileName.replace(NotANumber.VALUE, "(\\d+)"); |
| final Pattern pattern = Pattern.compile(filePattern); |
| |
| try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) { |
| for (final Path entry: stream) { |
| final Matcher matcher = pattern.matcher(entry.toFile().getName()); |
| if (matcher.matches()) { |
| final Integer index = Integer.parseInt(matcher.group(1)); |
| eligibleFiles.put(index, entry); |
| } |
| } |
| } catch (final IOException ioe) { |
| throw new LoggingException("Error reading folder " + dir + " " + ioe.getMessage(), ioe); |
| } |
| return isAscending? eligibleFiles : eligibleFiles.descendingMap(); |
| } |
| } |