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; 015 016import ch.qos.logback.core.FileAppender; 017import ch.qos.logback.core.rolling.helper.CompressionMode; 018import ch.qos.logback.core.rolling.helper.FileNamePattern; 019import ch.qos.logback.core.spi.ContextAwareBase; 020 021import static ch.qos.logback.core.util.Loader.isClassLoadable; 022 023/** 024 * Implements methods common to most, it not all, rolling policies. Currently 025 * such methods are limited to a compression mode getter/setter. 026 * 027 * @author Ceki Gülcü 028 */ 029public abstract class RollingPolicyBase extends ContextAwareBase implements RollingPolicy { 030 protected CompressionMode compressionMode = CompressionMode.NONE; 031 032 FileNamePattern fileNamePattern; 033 // fileNamePatternStr is always slashified, see setter 034 protected String fileNamePatternStr; 035 036 private FileAppender<?> parent; 037 038 // use to name files within zip file, i.e. the zipEntry 039 FileNamePattern zipEntryFileNamePattern; 040 private boolean started; 041 042 043 /** 044 * @deprecated replaced by #fileNamePatternStrToCompressionMode(String) followed by #outputCompressionModeMessage(CompressionMode) 045 */ 046 @Deprecated 047 protected void determineCompressionMode() { 048 compressionMode = fileNamePatternStrToCompressionMode(fileNamePatternStr); 049 outputCompressionModeMessage(compressionMode); 050 } 051 052 protected void outputCompressionModeMessage(CompressionMode compressionMode) { 053 054 switch (compressionMode) { 055 case GZ: 056 addInfo("Will use gz compression"); 057 break; 058 case ZIP: 059 addInfo("Will use zip compression"); 060 break; 061 case XZ: 062 addInfo("Will use xz compression"); 063 break; 064 case NONE: 065 addInfo("No compression will be used"); 066 break; 067 } 068 } 069 070 /** 071 * Given the FileNamePattern string, this method determines the compression mode 072 * depending on last letters of the fileNamePatternStr. Patterns ending with .gz 073 * imply GZIP compression, endings with '.zip' imply ZIP compression, endings with 074 * .xz imply XZ compression. Otherwise and by default, there is no compression. 075 * 076 * @since 1.6.1 077 */ 078 protected CompressionMode fileNamePatternStrToCompressionMode(String aFileNamePatternStr) { 079 if (aFileNamePatternStr.endsWith(CompressionMode.GZ_SUFFIX)) { 080 return CompressionMode.GZ; 081 } else if (aFileNamePatternStr.endsWith(CompressionMode.ZIP_SUFFIX)) { 082 return CompressionMode.ZIP; 083 } else if (aFileNamePatternStr.endsWith(CompressionMode.XZ_SUFFIX)) { 084 return CompressionMode.XZ; 085 } else { 086 return CompressionMode.NONE; 087 } 088 } 089 090 091 /** 092 * If compression mode is XZ but the XZ library is missing, then fallback to GZ compression. 093 */ 094 protected void adjustCompressionModeAndFileNamePatternStrIfNecessary() { 095 if (compressionMode == compressionMode.XZ) { 096 boolean xzLibraryLoadable = isClassLoadable("org.tukaani.xz.XZOutputStream", getContext()); 097 if (!xzLibraryLoadable) { 098 addWarn("XZ library missing, falling back to GZ compression"); 099 compressionMode = CompressionMode.GZ; 100 fileNamePatternStr = replaceSuffix(fileNamePatternStr, CompressionMode.XZ_SUFFIX, CompressionMode.GZ_SUFFIX); 101 } 102 } 103 } 104 105 private String replaceSuffix(String input, String existingSuffix, String newSuffix) { 106 int existingSuffixLen = existingSuffix.length(); 107 if (input.endsWith(existingSuffix)) { 108 return input.substring(0, input.length() - existingSuffixLen) + newSuffix; 109 } else { 110 // unreachable code 111 throw new IllegalArgumentException("[" + input + "] should end with "+existingSuffix); 112 } 113 } 114 115 public void setFileNamePattern(String fnp) { 116 fileNamePatternStr = fnp; 117 } 118 119 public String getFileNamePattern() { 120 return fileNamePatternStr; 121 } 122 123 public CompressionMode getCompressionMode() { 124 return compressionMode; 125 } 126 127 public boolean isStarted() { 128 return started; 129 } 130 131 public void start() { 132 started = true; 133 } 134 135 public void stop() { 136 started = false; 137 } 138 139 public void setParent(FileAppender<?> appender) { 140 this.parent = appender; 141 } 142 143 public boolean isParentPrudent() { 144 return parent.isPrudent(); 145 } 146 147 public String getParentsRawFileProperty() { 148 return parent.rawFileProperty(); 149 } 150}