Source Code Cross Referenced for FileHandler.java in  » Apache-Harmony-Java-SE » java-package » java » util » logging » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Apache Harmony Java SE » java package » java.util.logging 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* 
002:         * Licensed to the Apache Software Foundation (ASF) under one or more
003:         * contributor license agreements.  See the NOTICE file distributed with
004:         * this work for additional information regarding copyright ownership.
005:         * The ASF licenses this file to You under the Apache License, Version 2.0
006:         * (the "License"); you may not use this file except in compliance with
007:         * the License.  You may obtain a copy of the License at
008:         * 
009:         *     http://www.apache.org/licenses/LICENSE-2.0
010:         * 
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS,
013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         * See the License for the specific language governing permissions and
015:         * limitations under the License.
016:         */
017:
018:        package java.util.logging;
019:
020:        import java.io.BufferedOutputStream;
021:        import java.io.File;
022:        import java.io.FileNotFoundException;
023:        import java.io.FileOutputStream;
024:        import java.io.IOException;
025:        import java.io.OutputStream;
026:        import java.nio.channels.FileChannel;
027:        import java.nio.channels.FileLock;
028:        import java.security.AccessController;
029:        import java.security.PrivilegedAction;
030:        import java.util.Hashtable;
031:
032:        import org.apache.harmony.logging.internal.nls.Messages;
033:
034:        /**
035:         * A <code>FileHandler</code> is a Handler that writes logging events to one
036:         * or more files.
037:         * 
038:         * <p>
039:         * If multiple files are used, when a given amount of data has been written to
040:         * one file, this file is closed, and the next file is opened. The names of
041:         * these files are generated by the given name pattern, see below for details.
042:         * When all the files have all been filled the Handler returns to the first one
043:         * and goes through the set again.
044:         * </p>
045:         * 
046:         * <p>
047:         * <code>FileHandler</code> defines the following configuration properties,
048:         * which are read by the <code>LogManager</code> on initialization. If the
049:         * properties have not been specified then defaults will be used. The properties
050:         * and defaults are as follows:
051:         * <ul>
052:         * <li>java.util.logging.FileHandler.append - If true then this
053:         * <code>FileHandler</code> appends to a file's existing content, if false it
054:         * overwrites it. Default is false.</li>
055:         * <li>java.util.logging.FileHandler.count - the number of output files to
056:         * rotate. Default is 1.</li>
057:         * <li>java.util.logging.FileHandler.filter - the name of the
058:         * <code>Filter</code> class. No <code>Filter</code> is used by default.</li>
059:         * <li>java.util.logging.FileHandler.formatter - the name of the
060:         * <code>Formatter</code> class. Default is
061:         * <code>java.util.logging.XMLFormatter</code>.</li>
062:         * <li>java.util.logging.FileHandler.encoding - the name of the character set
063:         * encoding. Default is the encoding used by the current platform.</li>
064:         * <li>java.util.logging.FileHandler.level - the log level for this
065:         * <code>Handler</code>. Default is <code>Level.ALL</code>.</li>
066:         * <li>java.util.logging.FileHandler.limit - the limit at which no more bytes
067:         * should be written to the current file. Default is no limit.</li>
068:         * <li>java.util.logging.FileHandler.pattern - the pattern for the name of log
069:         * files. Default is "%h/java%u.log".</li>
070:         * </ul>
071:         * </p>
072:         * 
073:         * <p>
074:         * The name pattern is a String that can contain some of the following
075:         * sub-strings, which will be replaced to generate the output file names:
076:         * <ul>
077:         * <li>"/" represents the local path separator</li>
078:         * <li>"%g" represents the generation number used to enumerate log files</li>
079:         * <li>"%h" represents the home directory of the current user, which is
080:         * specified by the "user.home" system property</li>
081:         * <li>"%t" represents the system's temporary directory</li>
082:         * <li>"%u" represents a unique number added to the file name if the original
083:         * file required is in use</li>
084:         * <li>"%%" represents the percent sign character '%'</li>
085:         * </ul>
086:         * </p>
087:         * 
088:         * <p>
089:         * The generation numbers, denoted by "%g" in the filename pattern will be
090:         * created in ascending numerical order from 0, i.e. 0,1,2,3... If "%g" was not
091:         * present in the pattern and more than one file is being used then a dot and a
092:         * generation number is appended to the filename at the end. This is equivalent
093:         * to appending ".%g" to the pattern.
094:         * </p>
095:         * 
096:         * <p>
097:         * The unique identifier, denoted by "%u" in the filename pattern will always be
098:         * 0 unless the <code>FileHandler</code> is unable to open the file. In that
099:         * case 1 is tried, then 2, and so on until a file is found that can be opened.
100:         * If "%u" was not present in the pattern but a unique number is required then a
101:         * dot and a unique number is added to the end of the filename, equivalent to
102:         * appending ".%u" to the pattern.
103:         * </p>
104:         */
105:        public class FileHandler extends StreamHandler {
106:
107:            private static final String LCK_EXT = ".lck"; //$NON-NLS-1$
108:
109:            private static final int DEFAULT_COUNT = 1;
110:
111:            private static final int DEFAULT_LIMIT = 0;
112:
113:            private static final boolean DEFAULT_APPEND = false;
114:
115:            private static final String DEFAULT_PATTERN = "%h/java%u.log"; //$NON-NLS-1$
116:
117:            // maintain all file locks hold by this process
118:            private static final Hashtable<String, FileLock> allLocks = new Hashtable<String, FileLock>();
119:
120:            // the count of files which the output cycle through
121:            private int count;
122:
123:            // the size limitation in byte of log file
124:            private int limit;
125:
126:            // whether the FileHandler should open a existing file for output in append
127:            // mode
128:            private boolean append;
129:
130:            // the pattern for output file name
131:            private String pattern;
132:
133:            // maintain a LogManager instance for convenience
134:            private LogManager manager;
135:
136:            // output stream, which can measure the output file length
137:            private MeasureOutputStream output;
138:
139:            // used output file
140:            private File[] files;
141:
142:            // output file lock
143:            FileLock lock = null;
144:
145:            // current output file name
146:            String fileName = null;
147:
148:            // current unique ID
149:            int uniqueID = -1;
150:
151:            /**
152:             * Construct a <code>FileHandler</code> using <code>LogManager</code>
153:             * properties or their default value
154:             * 
155:             * @throws IOException
156:             *             if any IO exception happened
157:             * @throws SecurityException
158:             *             if security manager exists and it determines that caller does
159:             *             not have the required permissions to control this handler,
160:             *             required permissions include
161:             *             <code>LogPermission("control")</code> and other permission
162:             *             like <code>FilePermission("write")</code>, etc.
163:             */
164:            public FileHandler() throws IOException {
165:                init(null, null, null, null);
166:            }
167:
168:            // init properties
169:            private void init(String p, Boolean a, Integer l, Integer c)
170:                    throws IOException {
171:                // check access
172:                manager = LogManager.getLogManager();
173:                manager.checkAccess();
174:                initProperties(p, a, l, c);
175:                initOutputFiles();
176:            }
177:
178:            private void initOutputFiles() throws FileNotFoundException,
179:                    IOException {
180:                while (true) {
181:                    // try to find a unique file which is not locked by other process
182:                    uniqueID++;
183:                    // FIXME: improve performance here
184:                    for (int generation = 0; generation < count; generation++) {
185:                        // cache all file names for rotation use
186:                        files[generation] = new File(parseFileName(generation));
187:                    }
188:                    fileName = files[0].getAbsolutePath();
189:                    synchronized (allLocks) {
190:                        /*
191:                         * if current process has held lock for this fileName continue
192:                         * to find next file
193:                         */
194:                        if (null != allLocks.get(fileName)) {
195:                            continue;
196:                        }
197:                        if (files[0].exists()
198:                                && (!append || files[0].length() >= limit)) {
199:                            for (int i = count - 1; i > 0; i--) {
200:                                if (files[i].exists()) {
201:                                    files[i].delete();
202:                                }
203:                                files[i - 1].renameTo(files[i]);
204:                            }
205:                        }
206:                        FileOutputStream fileStream = new FileOutputStream(
207:                                fileName + LCK_EXT);
208:                        FileChannel channel = fileStream.getChannel();
209:                        /*
210:                         * if lock is unsupported and IOException thrown, just let the
211:                         * IOException throws out and exit otherwise it will go into an
212:                         * undead cycle
213:                         */
214:                        lock = channel.tryLock();
215:                        if (null == lock) {
216:                            try {
217:                                fileStream.close();
218:                            } catch (Exception e) {
219:                                // ignore
220:                            }
221:                            continue;
222:                        }
223:                        allLocks.put(fileName, lock);
224:                        break;
225:                    }
226:                }
227:                output = new MeasureOutputStream(new BufferedOutputStream(
228:                        new FileOutputStream(fileName, append)), files[0]
229:                        .length());
230:                setOutputStream(output);
231:            }
232:
233:            @SuppressWarnings("nls")
234:            private void initProperties(String p, Boolean a, Integer l,
235:                    Integer c) {
236:                super .initProperties("ALL", null,
237:                        "java.util.logging.XMLFormatter", null);
238:                String className = this .getClass().getName();
239:                pattern = (null == p) ? getStringProperty(className
240:                        + ".pattern", DEFAULT_PATTERN) : p;
241:                if (null == pattern || "".equals(pattern)) {
242:                    // logging.19=Pattern cannot be empty
243:                    throw new NullPointerException(Messages
244:                            .getString("logging.19"));
245:                }
246:                append = (null == a) ? getBooleanProperty(
247:                        className + ".append", DEFAULT_APPEND) : a
248:                        .booleanValue();
249:                count = (null == c) ? getIntProperty(className + ".count",
250:                        DEFAULT_COUNT) : c.intValue();
251:                limit = (null == l) ? getIntProperty(className + ".limit",
252:                        DEFAULT_LIMIT) : l.intValue();
253:                count = count < 1 ? DEFAULT_COUNT : count;
254:                limit = limit < 0 ? DEFAULT_LIMIT : limit;
255:                files = new File[count];
256:            }
257:
258:            void findNextGeneration() {
259:                super .close();
260:                for (int i = count - 1; i > 0; i--) {
261:                    if (files[i].exists()) {
262:                        files[i].delete();
263:                    }
264:                    files[i - 1].renameTo(files[i]);
265:                }
266:                try {
267:                    output = new MeasureOutputStream(new BufferedOutputStream(
268:                            new FileOutputStream(files[0])));
269:                } catch (FileNotFoundException e1) {
270:                    // logging.1A=Error happened when open log file.
271:                    this .getErrorManager().error(
272:                            Messages.getString("logging.1A"), //$NON-NLS-1$
273:                            e1, ErrorManager.OPEN_FAILURE);
274:                }
275:                setOutputStream(output);
276:            }
277:
278:            /**
279:             * Transform the pattern to the valid file name, replacing any patterns, and
280:             * applying generation and uniqueID if present
281:             * 
282:             * @param gen
283:             *            generation of this file
284:             * @return transformed filename ready for use
285:             */
286:            private String parseFileName(int gen) {
287:                int cur = 0;
288:                int next = 0;
289:                boolean hasUniqueID = false;
290:                boolean hasGeneration = false;
291:
292:                // TODO privilege code?
293:
294:                String tempPath = System.getProperty("java.io.tmpdir"); //$NON-NLS-1$
295:                boolean tempPathHasSepEnd = (tempPath == null ? false
296:                        : tempPath.endsWith(File.separator));
297:
298:                String homePath = System.getProperty("user.home"); //$NON-NLS-1$
299:                boolean homePathHasSepEnd = (homePath == null ? false
300:                        : homePath.endsWith(File.separator));
301:
302:                StringBuilder sb = new StringBuilder();
303:                pattern = pattern.replace('/', File.separatorChar);
304:
305:                char[] value = pattern.toCharArray();
306:                while ((next = pattern.indexOf('%', cur)) >= 0) {
307:                    if (++next < pattern.length()) {
308:                        switch (value[next]) {
309:                        case 'g':
310:                            sb.append(value, cur, next - cur - 1).append(gen);
311:                            hasGeneration = true;
312:                            break;
313:                        case 'u':
314:                            sb.append(value, cur, next - cur - 1).append(
315:                                    uniqueID);
316:                            hasUniqueID = true;
317:                            break;
318:                        case 't':
319:                            /*
320:                             * we should probably try to do something cute here like
321:                             * lookahead for adjacent '/'
322:                             */
323:                            sb.append(value, cur, next - cur - 1).append(
324:                                    tempPath);
325:                            if (!tempPathHasSepEnd) {
326:                                sb.append(File.separator);
327:                            }
328:                            break;
329:                        case 'h':
330:                            sb.append(value, cur, next - cur - 1).append(
331:                                    homePath);
332:                            if (!homePathHasSepEnd) {
333:                                sb.append(File.separator);
334:                            }
335:                            break;
336:                        case '%':
337:                            sb.append(value, cur, next - cur - 1).append('%');
338:                            break;
339:                        default:
340:                            sb.append(value, cur, next - cur);
341:                        }
342:                        cur = ++next;
343:                    } else {
344:                        // fail silently
345:                    }
346:                }
347:
348:                sb.append(value, cur, value.length - cur);
349:
350:                if (!hasGeneration && count > 1) {
351:                    sb.append(".").append(gen); //$NON-NLS-1$
352:                }
353:
354:                if (!hasUniqueID && uniqueID > 0) {
355:                    sb.append(".").append(uniqueID); //$NON-NLS-1$
356:                }
357:
358:                return sb.toString();
359:            }
360:
361:            // get boolean LogManager property, if invalid value got, using default
362:            // value
363:            private boolean getBooleanProperty(String key, boolean defaultValue) {
364:                String property = manager.getProperty(key);
365:                if (null == property) {
366:                    return defaultValue;
367:                }
368:                boolean result = defaultValue;
369:                if ("true".equalsIgnoreCase(property)) { //$NON-NLS-1$
370:                    result = true;
371:                } else if ("false".equalsIgnoreCase(property)) { //$NON-NLS-1$
372:                    result = false;
373:                }
374:                return result;
375:            }
376:
377:            // get String LogManager property, if invalid value got, using default value
378:            private String getStringProperty(String key, String defaultValue) {
379:                String property = manager.getProperty(key);
380:                return property == null ? defaultValue : property;
381:            }
382:
383:            // get int LogManager property, if invalid value got, using default value
384:            private int getIntProperty(String key, int defaultValue) {
385:                String property = manager.getProperty(key);
386:                int result = defaultValue;
387:                if (null != property) {
388:                    try {
389:                        result = Integer.parseInt(property);
390:                    } catch (Exception e) {
391:                        // ignore
392:                    }
393:                }
394:                return result;
395:            }
396:
397:            /**
398:             * Construct a <code>FileHandler</code>, the given name pattern is used
399:             * as output filename, the file limit is set to zero(no limit), and the file
400:             * count is set to one, other configuration using <code>LogManager</code>
401:             * properties or their default value
402:             * 
403:             * This handler write to only one file and no amount limit.
404:             * 
405:             * @param pattern
406:             *            the name pattern of output file
407:             * @throws IOException
408:             *             if any IO exception happened
409:             * @throws SecurityException
410:             *             if security manager exists and it determines that caller does
411:             *             not have the required permissions to control this handler,
412:             *             required permissions include
413:             *             <code>LogPermission("control")</code> and other permission
414:             *             like <code>FilePermission("write")</code>, etc.
415:             * @throws NullPointerException
416:             *             if the pattern is <code>null</code>.
417:             * @throws IllegalArgumentException
418:             *             if the pattern is empty.
419:             */
420:            public FileHandler(String pattern) throws IOException {
421:                if (pattern.equals("")) { //$NON-NLS-1$
422:                    // logging.19=Pattern cannot be empty
423:                    throw new IllegalArgumentException(Messages
424:                            .getString("logging.19")); //$NON-NLS-1$
425:                }
426:                init(pattern, null, Integer.valueOf(DEFAULT_LIMIT), Integer
427:                        .valueOf(DEFAULT_COUNT));
428:            }
429:
430:            /**
431:             * Construct a <code>FileHandler</code>, the given name pattern is used
432:             * as output filename, the file limit is set to zero(i.e. no limit applies),
433:             * the file count is initialized to one, and the value of
434:             * <code>append</code> becomes the new instance's append mode. Other
435:             * configuration is done using <code>LogManager</code> properties.
436:             * 
437:             * This handler write to only one file and no amount limit.
438:             * 
439:             * @param pattern
440:             *            the name pattern of output file
441:             * @param append
442:             *            the append mode
443:             * @throws IOException
444:             *             if any IO exception happened
445:             * @throws SecurityException
446:             *             if security manager exists and it determines that caller does
447:             *             not have the required permissions to control this handler,
448:             *             required permissions include
449:             *             <code>LogPermission("control")</code> and other permission
450:             *             like <code>FilePermission("write")</code>, etc.
451:             * @throws NullPointerException
452:             *             if the pattern is <code>null</code>.
453:             * @throws IllegalArgumentException
454:             *             if the pattern is empty.
455:             */
456:            public FileHandler(String pattern, boolean append)
457:                    throws IOException {
458:                if (pattern.equals("")) { //$NON-NLS-1$
459:                    throw new IllegalArgumentException(Messages
460:                            .getString("logging.19")); //$NON-NLS-1$ 
461:                }
462:
463:                init(pattern, Boolean.valueOf(append), Integer
464:                        .valueOf(DEFAULT_LIMIT), Integer.valueOf(DEFAULT_COUNT));
465:            }
466:
467:            /**
468:             * Construct a <code>FileHandler</code>, the given name pattern is used
469:             * as output filename, the file limit is set to given limit argument, and
470:             * the file count is set to given count argument, other configuration using
471:             * <code>LogManager</code> properties or their default value
472:             * 
473:             * This handler is configured to write to a rotating set of count files,
474:             * when the limit of bytes has been written to one output file, another file
475:             * will be opened instead.
476:             * 
477:             * @param pattern
478:             *            the name pattern of output file
479:             * @param limit
480:             *            the data amount limit in bytes of one output file, cannot less
481:             *            than one
482:             * @param count
483:             *            the maximum number of files can be used, cannot less than one
484:             * @throws IOException
485:             *             if any IO exception happened
486:             * @throws SecurityException
487:             *             if security manager exists and it determines that caller does
488:             *             not have the required permissions to control this handler,
489:             *             required permissions include
490:             *             <code>LogPermission("control")</code> and other permission
491:             *             like <code>FilePermission("write")</code>, etc.
492:             * @throws NullPointerException
493:             *             if pattern is <code>null</code>.
494:             * @throws IllegalArgumentException
495:             *             if count<1, or limit<0
496:             */
497:            public FileHandler(String pattern, int limit, int count)
498:                    throws IOException {
499:                if (pattern.equals("")) { //$NON-NLS-1$
500:                    throw new IllegalArgumentException(Messages
501:                            .getString("logging.19")); //$NON-NLS-1$ 
502:                }
503:                if (limit < 0 || count < 1) {
504:                    // logging.1B=The limit and count property must be larger than 0 and
505:                    // 1, respectively
506:                    throw new IllegalArgumentException(Messages
507:                            .getString("logging.1B")); //$NON-NLS-1$
508:                }
509:                init(pattern, null, Integer.valueOf(limit), Integer
510:                        .valueOf(count));
511:            }
512:
513:            /**
514:             * Construct a <code>FileHandler</code>, the given name pattern is used
515:             * as output filename, the file limit is set to given limit argument, the
516:             * file count is set to given count argument, and the append mode is set to
517:             * given append argument, other configuration using <code>LogManager</code>
518:             * properties or their default value
519:             * 
520:             * This handler is configured to write to a rotating set of count files,
521:             * when the limit of bytes has been written to one output file, another file
522:             * will be opened instead.
523:             * 
524:             * @param pattern
525:             *            the name pattern of output file
526:             * @param limit
527:             *            the data amount limit in bytes of one output file, cannot less
528:             *            than one
529:             * @param count
530:             *            the maximum number of files can be used, cannot less than one
531:             * @param append
532:             *            the append mode
533:             * @throws IOException
534:             *             if any IO exception happened
535:             * @throws SecurityException
536:             *             if security manager exists and it determines that caller does
537:             *             not have the required permissions to control this handler,
538:             *             required permissions include
539:             *             <code>LogPermission("control")</code> and other permission
540:             *             like <code>FilePermission("write")</code>, etc.
541:             * @throws NullPointerException
542:             *             if pattern is <code>null</code>.
543:             * @throws IllegalArgumentException
544:             *             if count<1, or limit<0
545:             */
546:            public FileHandler(String pattern, int limit, int count,
547:                    boolean append) throws IOException {
548:                if (pattern.equals("")) { //$NON-NLS-1$
549:                    throw new IllegalArgumentException(Messages
550:                            .getString("logging.19")); //$NON-NLS-1$ 
551:                }
552:                if (limit < 0 || count < 1) {
553:                    // logging.1B=The limit and count property must be larger than 0 and
554:                    // 1, respectively
555:                    throw new IllegalArgumentException(Messages
556:                            .getString("logging.1B")); //$NON-NLS-1$
557:                }
558:                init(pattern, Boolean.valueOf(append), Integer.valueOf(limit),
559:                        Integer.valueOf(count));
560:            }
561:
562:            /**
563:             * Flush and close all opened files.
564:             * 
565:             * @throws SecurityException
566:             *             if security manager exists and it determines that caller does
567:             *             not have the required permissions to control this handler,
568:             *             required permissions include
569:             *             <code>LogPermission("control")</code> and other permission
570:             *             like <code>FilePermission("write")</code>, etc.
571:             */
572:            @Override
573:            public void close() {
574:                // release locks
575:                super .close();
576:                allLocks.remove(fileName);
577:                try {
578:                    FileChannel channel = lock.channel();
579:                    lock.release();
580:                    channel.close();
581:                    File file = new File(fileName + LCK_EXT);
582:                    file.delete();
583:                } catch (IOException e) {
584:                    // ignore
585:                }
586:            }
587:
588:            /**
589:             * Publish a <code>LogRecord</code>
590:             * 
591:             * @param record
592:             *            the log record to be published
593:             */
594:            @Override
595:            public void publish(LogRecord record) {
596:                super .publish(record);
597:                flush();
598:                if (limit > 0 && output.getLength() >= limit) {
599:                    AccessController
600:                            .doPrivileged(new PrivilegedAction<Object>() {
601:                                public Object run() {
602:                                    findNextGeneration();
603:                                    return null;
604:                                }
605:                            });
606:                }
607:            }
608:
609:            /**
610:             * This output stream use decorator pattern to add measure feature to
611:             * OutputStream which can detect the total size(in bytes) of output, the
612:             * initial size can be set
613:             */
614:            static class MeasureOutputStream extends OutputStream {
615:
616:                OutputStream wrapped;
617:
618:                long length;
619:
620:                public MeasureOutputStream(OutputStream stream,
621:                        long currentLength) {
622:                    wrapped = stream;
623:                    length = currentLength;
624:                }
625:
626:                public MeasureOutputStream(OutputStream stream) {
627:                    this (stream, 0);
628:                }
629:
630:                @Override
631:                public void write(int oneByte) throws IOException {
632:                    wrapped.write(oneByte);
633:                    length++;
634:                }
635:
636:                @Override
637:                public void write(byte[] bytes) throws IOException {
638:                    wrapped.write(bytes);
639:                    length += bytes.length;
640:                }
641:
642:                @Override
643:                public void write(byte[] b, int off, int len)
644:                        throws IOException {
645:                    wrapped.write(b, off, len);
646:                    length += len;
647:                }
648:
649:                @Override
650:                public void close() throws IOException {
651:                    wrapped.close();
652:                }
653:
654:                @Override
655:                public void flush() throws IOException {
656:                    wrapped.flush();
657:                }
658:
659:                public long getLength() {
660:                    return length;
661:                }
662:
663:                public void setLength(long newLength) {
664:                    length = newLength;
665:                }
666:            }
667:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.