KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > grlea > log > rollover > FileSizeRolloverStrategy


1 package org.grlea.log.rollover;
2
3 // $Id: FileSizeRolloverStrategy.java,v 1.4 2006/07/13 12:39:15 grlea Exp $
4
// Copyright (c) 2004-2006 Graham Lea. All rights reserved.
5

6 // Licensed under the Apache License, Version 2.0 (the "License");
7
// you may not use this file except in compliance with the License.
8
// You may obtain a copy of the License at
9
//
10
// http://www.apache.org/licenses/LICENSE-2.0
11
//
12
// Unless required by applicable law or agreed to in writing, software
13
// distributed under the License is distributed on an "AS IS" BASIS,
14
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
// See the License for the specific language governing permissions and
16
// limitations under the License.
17

18 import java.io.IOException JavaDoc;
19 import java.util.Date JavaDoc;
20 import java.util.Map JavaDoc;
21
22 /**
23  * <p>A {@link RolloverStrategy} that requests rollover when the log file reaches a specified size.
24  * Note that, because the strategy is only consulted at intervals, log files will always grow to
25  * slightly more than the specified size before being rolled.</p>
26  *
27  * @author Graham Lea
28  * @version $Revision: 1.4 $
29  */

30 class
31 FileSizeRolloverStrategy
32 implements RolloverStrategy
33 {
34    /** The key of the property specifying the file size at which to roll over. */
35    private static final String JavaDoc KEY_FILE_SIZE = "simplelog.rollover.fileSize.size";
36
37    /** The default vaue for the file size. */
38    private static final String JavaDoc FILE_SIZE_DEFAULT = "100M";
39
40    private static final char[] factorUnits = {'B', 'K', 'M', 'G', 'T'};
41
42    /** The file size at which to rollover. */
43    private long rolloverSize;
44
45    /** Whether the current file size was set programatically, rather than by a call to configure. */
46    private boolean rolloverSizeSetProgramatically = false;
47
48    /**
49     * <p>Creates a new <code>FileSizeRolloverStrategy</code>.</p>
50     *
51     * <p>This constructor is only intended to be used by {@link RolloverManager}.</p>
52     */

53    FileSizeRolloverStrategy()
54    {
55       this.rolloverSize = -1;
56    }
57
58    /**
59     * Creates a new <code>FileSizeRolloverStrategy</code> that will request log files be rolled
60     * when they reach the specified size. The rollover file size set by using this method will not
61     * be changed by calls to {@link #configure}.
62     *
63     * @param rolloverSize the size (in bytes) at which files shoud be rolled over.
64     *
65     * @throws IllegalArgumentException if rolloverSize is less than <code>1</code>.
66     */

67    public
68    FileSizeRolloverStrategy(long rolloverSize)
69    {
70       setRolloverSize(rolloverSize);
71    }
72
73    public void
74    configure(Map JavaDoc properties)
75    throws IOException JavaDoc
76    {
77       if (rolloverSizeSetProgramatically)
78          return;
79
80       String JavaDoc fileSizeString = (String JavaDoc) properties.get(KEY_FILE_SIZE);
81       if (fileSizeString == null)
82          fileSizeString = FILE_SIZE_DEFAULT;
83       else
84          fileSizeString = fileSizeString.trim();
85
86       if (fileSizeString.length() == 0)
87          fileSizeString = FILE_SIZE_DEFAULT;
88
89       long fileSize = decodeFileSize(fileSizeString);
90       setRolloverSizeInernal(fileSize);
91    }
92
93    /**
94     * Converts the given string from a value and magnitude expression (e.g. 120K) to a raw file size
95     * in bytes.
96     *
97     * @param fileSizeString a string containing a number followed by a single letter, being one of
98     * the valid single-letter abbreviations for base-2 magnitude, i.e. B, K, M, G or T. Case is
99     * disregarded.
100     *
101     * @return The value contained in the given string as a raw number of bytes
102     *
103     * @throws IOException if the given string does not match the specified constraints
104     */

105    private long
106    decodeFileSize(String JavaDoc fileSizeString)
107    throws IOException JavaDoc
108    {
109 // assert fileSizeString != null;
110
// assert fileSizeString.length() != 0;
111

112       try
113       {
114          int lastCharacterIndex = fileSizeString.length() - 1;
115
116          String JavaDoc sizeOnlyString = fileSizeString.substring(0, lastCharacterIndex);
117          long fileSize = Long.parseLong(sizeOnlyString);
118
119          char lastCharacter = fileSizeString.charAt(lastCharacterIndex);
120          lastCharacter = Character.toUpperCase(lastCharacter);
121
122          boolean factorIdentified = false;
123          for (int factor = 0; !factorIdentified && (factor < factorUnits.length); factor++)
124          {
125             char factorAbbreviation = factorUnits[factor];
126             if (lastCharacter == factorAbbreviation)
127             {
128                factorIdentified = true;
129                fileSize = fileSize * (1L << (factor * 10));
130             }
131          }
132
133          if (!factorIdentified)
134          {
135             throw new IOException JavaDoc(
136                "The specified file size does not conform to the required pattern: " + fileSizeString);
137          }
138
139          return fileSize;
140       }
141       catch (NumberFormatException JavaDoc e)
142       {
143          // When you're writing a logging component, you can't debug stuff like this!
144
throw new IOException JavaDoc("Specified file size does not conform to the required pattern: " +
145                                fileSizeString);
146       }
147    }
148
149    public boolean
150    rolloverNow(Date JavaDoc fileCreated, long fileLength)
151    {
152       if (rolloverSize == -1)
153          throw new IllegalStateException JavaDoc("FileSizeRolloverStrategy has not been configured.");
154
155       return fileLength >= rolloverSize;
156    }
157
158    /**
159     * Returns the size at which files are currenty being rolled over.
160     */

161    public long
162    getRolloverSize()
163    {
164       return rolloverSize;
165    }
166
167    /**
168     * Sets the size at which files should be rolled over. One the rollover file size has been set
169     * using this method, it will not be changed by calls to {@link #configure}.
170     *
171     * @param rolloverSize the new size (in bytes) at which files should be rolled over.
172     *
173     * @throws IllegalArgumentException if rolloverSize is less than <code>1</code>.
174     */

175    public void
176    setRolloverSize(long rolloverSize)
177    {
178       setRolloverSizeInernal(rolloverSize);
179       this.rolloverSizeSetProgramatically = true;
180    }
181
182    /**
183     * Sets the size at which files should be rolled over. This method does not set
184     * {@link #rolloverSizeSetProgramatically}.
185     *
186     * @param rolloverSize the new size (in bytes) at which files should be rolled over.
187     */

188    private void
189    setRolloverSizeInernal(long rolloverSize)
190    {
191       if (rolloverSize < 1)
192       {
193          throw new IllegalArgumentException JavaDoc("rolloverSize must be > 0");
194       }
195       this.rolloverSize = rolloverSize;
196    }
197 }
Popular Tags