Commits

Tuukka Norri committed d114852

Moved files out of the Framework folder

Comments (0)

Files changed (419)

Contrib/Log4Cocoa/AllTests.h

+//
+//  AllTests.h
+//  Log4Cocoa
+//
+//  Created by bob frank on Sun May 04 2003.
+//  Copyright (c) 2003 __MyCompanyName__. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface AllTests : NSObject {
+}
+
++ (TestSuite *)suite;
+
+@end

Contrib/Log4Cocoa/AllTests.m

+//
+//  AllTests.m
+//  Log4Cocoa
+//
+//  Created by bob frank on Sun May 04 2003.
+//  Copyright (c) 2003 __MyCompanyName__. All rights reserved.
+//
+
+#import "AllTests.h"
+#import "L4LevelTest.h"
+#import "L4PatternLayoutTest.h"
+#import "L4FileAppenderTest.h"
+#import "L4RollingFileAppenderTest.h"
+#import "L4DailyRollingFileAppenderTest.h"
+
+@implementation AllTests
+
++ (TestSuite *) suite
+{
+    TestSuite *suite = [TestSuite suiteWithName: @"My Tests"];
+
+    // Add your tests here ...
+    //
+    [suite addTest: [TestSuite suiteWithClass: [L4LevelTest class]]];
+	[suite addTest: [TestSuite suiteWithClass: [L4PatternLayoutTest class]]];
+	[suite addTest: [TestSuite suiteWithClass: [L4FileAppenderTest class]]];
+	[suite addTest: [TestSuite suiteWithClass: [L4RollingFileAppenderTest class]]];
+	[suite addTest: [TestSuite suiteWithClass: [L4DailyRollingFileAppenderTest class]]];
+
+    return suite;
+}
+
+
+@end

Contrib/Log4Cocoa/AllTests_Prefix.h

+/*
+ *  AllTests_Prefix.h
+ *  
+ *
+ *  Created by bob frank on Sun May 04 2003.
+ *  Copyright (c) 2003 __MyCompanyName__. All rights reserved.
+ *
+ */
+
+#ifdef __OBJC__
+//    #import <Cocoa/Cocoa.h>
+    #import <Foundation/Foundation.h>
+    #import <ObjcUnit/ObjcUnit.h>
+    #import "Log4Cocoa.h"
+#endif
+

Contrib/Log4Cocoa/English.lproj/InfoPlist.strings

Binary file added.

Contrib/Log4Cocoa/Info-Log4Cocoa__Upgraded_.plist

+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>Log4Cocoa</string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string></string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundlePackageType</key>
+	<string>FMWK</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>0.0.1d1</string>
+	<key>NSPrincipalClass</key>
+	<string></string>
+</dict>
+</plist>

Contrib/Log4Cocoa/L4AppenderAttachableImpl.h

+/****************************
+*
+* Copyright (c) 2002, 2003, Bob Frank
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+*  - Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*  - Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the distribution.
+*
+*  - Neither the name of Log4Cocoa nor the names of its contributors or owners
+*    may be used to endorse or promote products derived from this software
+*    without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+****************************/
+
+// #import "Log4Cocoa.h"
+#import <Foundation/Foundation.h>
+#import "L4LoggingEvent.h"
+#import "L4AppenderProtocols.h"
+
+#define APPENDER_ADDED_EVENT   @"AppenderAddedEvent"
+#define APPENDER_REMOVED_EVENT @"AppenderRemovedEvent"
+
+
+@interface L4AppenderAttachableImpl : NSObject  {
+    NSMutableArray *appenderList;
+}
+
+- (int) appendLoopOnAppenders: (L4LoggingEvent *) event;
+
+@end
+
+@interface L4AppenderAttachableImpl (L4AppenderAttachableMethods) <L4AppenderAttachable>
+
+- (void) addAppender: (id <L4Appender>) newAppender;
+
+- (NSEnumerator *) allAppenders;
+- (NSArray *) allAppendersArray;
+
+- (id <L4Appender>) appenderWithName: (NSString *) aName;
+- (BOOL) isAttached: (id <L4Appender>) appender;
+
+- (void) removeAppenderWithName: (NSString *) aName;
+- (void) removeAppender: (id <L4Appender>) appender;
+- (void) removeAllAppenders;
+
+@end

Contrib/Log4Cocoa/L4AppenderAttachableImpl.m

+/****************************
+*
+* Copyright (c) 2002, 2003, Bob Frank
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+*  - Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*  - Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the distribution.
+*
+*  - Neither the name of Log4Cocoa nor the names of its contributors or owners
+*    may be used to endorse or promote products derived from this software
+*    without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+****************************/
+
+#import "L4AppenderAttachableImpl.h"
+
+
+@implementation L4AppenderAttachableImpl
+
+- (int) appendLoopOnAppenders: (L4LoggingEvent *) event
+{
+    int size = 0;
+
+    if( appenderList != nil )
+    {
+        int i;
+        size = [appenderList count];
+        for( i = 0; i < size; i++ )
+        {
+            [[appenderList objectAtIndex: i] doAppend: event];
+        }
+    }
+    return size;
+}
+
+@end
+
+
+@implementation L4AppenderAttachableImpl (L4AppenderAttachableMethods)
+
+- (void) addAppender: (id <L4Appender>) newAppender
+{
+    if( newAppender == nil )
+    {
+        return; // sanity check
+    }
+
+    if( appenderList == nil )
+    {
+        // only place appenderList array is recreated if its nil.
+        appenderList = [[NSMutableArray alloc] init];
+    }
+
+    if(![appenderList containsObject: newAppender])
+    {
+        [appenderList addObject: newAppender];
+        [[NSNotificationCenter defaultCenter] postNotificationName: APPENDER_ADDED_EVENT
+                                                            object: newAppender];
+    }
+}
+
+- (NSEnumerator *) allAppenders
+{
+    return [appenderList objectEnumerator];
+}
+
+- (NSArray *) allAppendersArray
+{
+    return appenderList;
+}
+
+- (id <L4Appender>) appenderWithName: (NSString *) aName
+{
+    NSEnumerator *enumerator = [appenderList objectEnumerator];
+    id <L4Appender> anAppender;
+
+    while ((anAppender = (id <L4Appender>)[enumerator nextObject]))
+    {
+        if( [[anAppender name] isEqualToString: aName ])
+        {
+            return anAppender;
+        }
+    }
+    return nil;
+}
+
+- (BOOL) isAttached: (id <L4Appender>) appender
+{
+    if((appender == nil) || (appenderList == nil))
+    {
+        return NO; // short circuit the test
+    }
+    return [appenderList containsObject: appender]; 
+}
+
+- (void) removeAppenderWithName: (NSString *) aName
+{
+    [self removeAppender: [self appenderWithName: aName]];
+}
+
+- (void) removeAppender: (id <L4Appender>) appender
+{
+    [appenderList removeObject: appender];
+    [[NSNotificationCenter defaultCenter] postNotificationName: APPENDER_REMOVED_EVENT
+                                                        object: appender];
+}
+
+- (void) removeAllAppenders
+{
+    NSEnumerator *enumerator = [appenderList objectEnumerator];
+    id <L4Appender> anAppender;
+
+    while ((anAppender = (id <L4Appender>)[enumerator nextObject]))
+    {
+        // why only call close in removeAllAppenders & not removeAppender: ????
+        // just doing it like they did it in Log4J ... will figure out later.
+        //
+        [anAppender close];
+        [[NSNotificationCenter defaultCenter] postNotificationName: APPENDER_REMOVED_EVENT
+                                                            object: anAppender];
+    }
+    [appenderList removeAllObjects];
+    [appenderList release];
+    appenderList = nil;
+}
+
+@end

Contrib/Log4Cocoa/L4AppenderProtocols.h

+/****************************
+*
+* Copyright (c) 2002, 2003, Bob Frank
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+*  - Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*  - Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the distribution.
+*
+*  - Neither the name of Log4Cocoa nor the names of its contributors or owners
+*    may be used to endorse or promote products derived from this software
+*    without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+****************************/
+
+#import <Foundation/Foundation.h>
+// #import "L4Logger.h"
+// #import "L4LoggingEvent.h"
+// #import "L4Layout.h"
+// #import "L4Filter.h"
+
+@class L4Logger, L4Filter, L4Layout, L4LoggingEvent;
+
+@protocol L4OptionHandler <NSObject>
+
+- (void) activateOptions;
+
+@end
+
+@protocol L4ErrorHandler <L4OptionHandler>
+
+- (void) activateOptions; // in Java ErrorHandler extends OptionHanlder, but for now I just copied the method
+
+- (void) setLogger: (L4Logger *) aLogger;
+
+- (void) error: (NSString *) message;
+
+- (void) error: (NSString *) message
+     exception: (NSException *) e
+     errorCode: (int) errorCode;
+
+- (void) error: (NSString *) message
+     exception: (NSException *) e
+     errorCode: (int) errorCode
+         event: (L4LoggingEvent *) event;
+
+- (void) setAppender: (id) appender; // can't forward declare protocols, so check to see if the object responds
+- (void) setBackupAppender: (id) appender;
+
+@end
+
+
+@protocol L4Appender <NSObject>
+
+- (void) doAppend: (L4LoggingEvent *) anEvent;   // appender log this event
+
+- (void) addFilter: (L4Filter *) newFilter;      // adds to end of list
+- (L4Filter *) headFilter;   // returns first filter or nil of there are none
+- (void) clearFilters;       // removes all filters from list
+- (void) close;              // it is a programing error to append to a close appender
+
+- (BOOL) requiresLayout;
+
+- (NSString *) name;      // unique name of this appender
+- (void) setName: (NSString *) aName;
+
+- (L4Layout *) layout;
+- (void) setLayout: (L4Layout *) aLayout;
+
+- (id <L4ErrorHandler>) errorHandler;
+- (void) setErrorHandler: (id <L4ErrorHandler>) anErrorHandler;
+
+@end
+
+
+@protocol L4AppenderAttachable <NSObject>
+
+- (void) addAppender: (id <L4Appender>) newAppender;
+
+- (NSEnumerator *) allAppenders;
+- (NSArray *) allAppendersArray;
+
+- (id <L4Appender>) appenderWithName: (NSString *) aName;
+- (BOOL) isAttached: (id <L4Appender>) appender;
+
+- (void) removeAllAppenders;
+- (void) removeAppender: (id <L4Appender>) appender;
+- (void) removeAppenderWithName: (NSString *) aName;
+
+@end

Contrib/Log4Cocoa/L4AppenderSkeleton.h

+/****************************
+*
+* Copyright (c) 2002, 2003, Bob Frank
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+*  - Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*  - Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the distribution.
+*
+*  - Neither the name of Log4Cocoa nor the names of its contributors or owners
+*    may be used to endorse or promote products derived from this software
+*    without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+****************************/
+
+#import <Foundation/Foundation.h>
+#import "L4AppenderProtocols.h"
+#import "L4LoggingEvent.h"
+#import "L4Level.h"
+#import "L4Filter.h"
+#import "L4Layout.h"
+
+@interface L4AppenderSkeleton : NSObject {
+    NSString *name;
+    L4Layout *layout;
+    L4Level *threshold;
+    L4Filter *headFilter;
+    L4Filter *tailFilter;
+    id errorHandler;
+    BOOL closed;
+}
+
+- (void) append: (L4LoggingEvent *) anEvent;
+- (BOOL) isAsSevereAsThreshold: (L4Level *) aLevel;
+
+- (L4Level *) threshold;
+- (void) setThreshold: (L4Level *) aLevel;
+
+@end
+
+
+@interface L4AppenderSkeleton (L4OptionHandlerCategory) <L4OptionHandler>
+
+- (void) activateOptions;
+
+@end
+
+
+@interface L4AppenderSkeleton (L4AppenderCategory) <L4Appender>
+
+- (void) doAppend: (L4LoggingEvent *) anEvent;
+// calls [self append: anEvent] after doing threshold checks
+
+- (void) addFilter: (L4Filter *) aFilter;
+- (L4Filter *) headFilter;
+- (void) clearFilters;
+- (void) close;
+
+- (BOOL) requiresLayout;
+
+- (NSString *) name;
+- (void) setName: (NSString *) aName;
+
+- (L4Layout *) layout;
+- (void) setLayout: (L4Layout *) aLayout;
+
+- (id <L4ErrorHandler>) errorHandler;
+- (void) setErrorHandler: (id <L4ErrorHandler>) anErrorHandler;
+
+@end

Contrib/Log4Cocoa/L4AppenderSkeleton.m

+/****************************
+*
+* Copyright (c) 2002, 2003, Bob Frank
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+*  - Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*  - Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the distribution.
+*
+*  - Neither the name of Log4Cocoa nor the names of its contributors or owners
+*    may be used to endorse or promote products derived from this software
+*    without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+****************************/
+
+#import "L4AppenderSkeleton.h"
+
+
+@implementation L4AppenderSkeleton
+
+- (void) dealloc
+{
+    [name release];
+    [layout release];
+    [threshold release];
+    [headFilter release];
+    [tailFilter release];
+    [super dealloc];
+}
+
+- (void) append: (L4LoggingEvent *) anEvent
+{
+}
+
+- (BOOL) isAsSevereAsThreshold: (L4Level *) aLevel
+{
+    return ((threshold == nil) || ([aLevel isGreaterOrEqual: threshold]));
+}
+
+- (L4Level *) threshold
+{
+    return threshold;
+}
+
+- (void) setThreshold: (L4Level *) aLevel
+{
+    if( threshold != aLevel )
+    {
+        [threshold autorelease];
+        threshold = [aLevel retain];
+    }
+}
+
+@end
+
+
+@implementation L4AppenderSkeleton (L4OptionHandlerCategory)
+
+- (void) activateOptions
+{
+}
+
+@end
+
+
+@implementation L4AppenderSkeleton (L4AppenderCategory)
+
+// calls [self append: anEvent] after doing threshold checks
+- (void) doAppend: (L4LoggingEvent *) anEvent
+{
+    L4Filter *aFilter = [self headFilter];
+    BOOL breakLoop = NO;
+    
+    if( closed )
+    {
+        [L4LogLog error:
+            [@"Attempted to append to closed appender named: " stringByAppendingString: name]];
+        return;
+    }
+
+    if(![self isAsSevereAsThreshold: [anEvent level]])
+    {
+        return;
+    }
+
+    while((aFilter != nil) && !breakLoop)
+    {
+        switch([aFilter decide: anEvent])
+        {
+            case FILTER_DENY:
+                return;
+            case FILTER_ACCEPT:
+                breakLoop = YES;
+                break;
+            case FILTER_NEUTRAL:
+            default:
+                aFilter = [aFilter next];
+                break;
+        }
+    }
+    [self append: anEvent]; // passed all threshold checks, append event.
+}
+
+- (void) addFilter: (L4Filter *) newFilter
+{
+    if( headFilter == nil )
+    {
+        headFilter = [newFilter retain];
+        tailFilter = newFilter; // don't retain at the tail, just the head.
+    }
+    else
+    {
+        [tailFilter setNext: newFilter];
+        tailFilter = newFilter;
+    }
+    
+}
+
+- (L4Filter *) headFilter
+{
+    return headFilter;
+}
+
+- (void) clearFilters
+{
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    
+    id aFilter = [headFilter next];
+    [headFilter autorelease];
+    for( aFilter = headFilter; aFilter != nil; aFilter = [headFilter next] )
+    {
+        [aFilter setNext: nil];
+    }
+    headFilter = nil;
+    tailFilter = nil;
+
+    [pool release];
+}
+
+- (void) close
+{
+}
+
+- (BOOL) requiresLayout
+{
+    return NO;
+}
+
+- (NSString *) name
+{
+    return name;
+}
+
+- (void) setName: (NSString *) aName
+{
+    if( name != aName )
+    {
+        [name autorelease];
+        name = [aName retain];
+    }
+}
+
+- (L4Layout *) layout
+{
+    return layout;
+}
+
+- (void) setLayout: (L4Layout *) aLayout
+{
+    if( layout != aLayout )
+    {
+        [layout autorelease];
+        layout = [aLayout retain];
+    }
+}
+
+- (id <L4ErrorHandler>) errorHandler
+{
+    return errorHandler;
+}
+
+- (void) setErrorHandler: (id <L4ErrorHandler>) anErrorHandler
+{
+    if( anErrorHandler == nil )
+    {
+        [L4LogLog warn: @"You have tried to set a null error-handler."];
+    }
+    else if( errorHandler != (id) anErrorHandler )
+    {
+        [errorHandler autorelease];
+        errorHandler = [anErrorHandler retain];
+    }
+}
+
+@end

Contrib/Log4Cocoa/L4CLogger.h

+/****************************
+*
+* Copyright (c) 2002, 2003, Bob Frank
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+*  - Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*  - Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the distribution.
+*
+*  - Neither the name of Log4Cocoa nor the names of its contributors or owners
+*    may be used to endorse or promote products derived from this software
+*    without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+****************************/
+
+#import <Foundation/Foundation.h>
+#import "L4Logger.h"
+
+/**
+ *  ### TODO -- add pure C cover functions to call into Log4Cocoa.  I plan to convert the __FILE__
+ *              argument into the logger name, but I'll need to parse out the final "." (i.e. file.c)
+ *              probably convert it to a dash "-".  Also need to handle the pure C types being passed in.
+ */
+
+
+/* DEBUG < INFO < WARN < ERROR < FATAL */
+
+// #define cLogError(message) l4CLogError( __LINE__, __FILE__, __PRETTY_FUNCTION__, message)
+
+
+@interface L4CLogger : L4Logger {
+
+}
+
+// (void) l4CLogError( int lineNumber, cString fileName, cString prettyFunction, cString message );
+
+
+@end

Contrib/Log4Cocoa/L4CLogger.m

+/****************************
+*
+* Copyright (c) 2002, 2003, Bob Frank
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+*  - Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*  - Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the distribution.
+*
+*  - Neither the name of Log4Cocoa nor the names of its contributors or owners
+*    may be used to endorse or promote products derived from this software
+*    without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+****************************/
+
+#import "L4CLogger.h"
+
+
+@implementation L4CLogger
+
+@end

Contrib/Log4Cocoa/L4Configurator.h

+/****************************
+*
+* Copyright (c) 2002, 2003, Bob Frank
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+*  - Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*  - Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the distribution.
+*
+*  - Neither the name of Log4Cocoa nor the names of its contributors or owners
+*    may be used to endorse or promote products derived from this software
+*    without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+****************************/
+
+#import <Foundation/Foundation.h>
+
+#define LINE_BREAK_SEPERATOR_KEY @"LINE_BREAK_SEPERATOR_KEY"
+
+extern NSString* const L4ConfigurationFilePath;
+extern NSString* const L4ConfigurationFileName;
+
+@class L4Logger;
+
+@interface L4Configurator : NSObject {
+
+}
+
++ (void) initialize;
+
++ (void) basicConfiguration;
++ (void) autoConfigure;
++ (id) propertyForKey: (NSString *) aKey;
+
++ (void) resetLineBreakChar;
++ (NSData *) lineBreakChar;
+
++ (NSString *) configurationFilePath;
+
+@end

Contrib/Log4Cocoa/L4Configurator.m

+/****************************
+*
+* Copyright (c) 2002, 2003, Bob Frank
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+*  - Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*  - Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the distribution.
+*
+*  - Neither the name of Log4Cocoa nor the names of its contributors or owners
+*    may be used to endorse or promote products derived from this software
+*    without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+****************************/
+
+#import "L4Configurator.h"
+#import "L4Logger.h"
+#import "L4Level.h"
+#import "L4ConsoleAppender.h"
+#import "L4Layout.h"
+#import <stdlib.h>
+
+NSString* const L4ConfigurationFilePath = @"L4ConfigurationFilePath";
+NSString* const L4ConfigurationFileName = @"Log4CocoaConfiguration";
+
+static NSData *lineBreakChar = nil;
+static NSRecursiveLock *configurationLock = nil;
+static volatile BOOL haveConfiguration = NO;
+
+@implementation L4Configurator
+
++ (void) initialize
+{
+	static BOOL tooLate = NO;
+	if (NO == tooLate)
+	{
+		tooLate = YES;
+		
+		// Making sure that we capture the startup time of
+		// this application.  This sanity check is also in
+		// +[L4Logger initialize] too.
+		//
+		[L4LoggingEvent startTime];
+		
+		configurationLock = [[NSRecursiveLock alloc] init];
+	}
+}
+
++ (void) basicConfiguration
+{
+	[configurationLock lock];
+	if (NO == haveConfiguration)
+	{
+		L4Logger* rootLogger = [L4Logger rootLogger];
+		id appender = [[[L4ConsoleAppender alloc] initStandardOutWithLayout: [L4Layout simpleLayout]] autorelease];
+		[rootLogger addAppender: appender];
+#if defined(RELEASE_BUILD)
+		[rootLogger setLevel: [L4Level error]];
+#else
+		[rootLogger setLevel: [L4Level info]];
+#endif
+		
+		haveConfiguration = YES;
+	}
+	[configurationLock unlock];
+}
+
++ (void) autoConfigure
+{
+	[configurationLock lock];
+	if (NO == haveConfiguration)
+	{		
+		// [[NSFileManager defaultManager] currentDirectoryPath];
+		NSString* path = [self configurationFilePath];
+		if (nil == path)
+			[self basicConfiguration];
+		else
+		{
+			L4Logger* rootLogger = [L4Logger rootLogger];
+			NSDictionary* configuration = [NSDictionary dictionaryWithContentsOfFile: path];
+			[rootLogger parseConfiguration: [configuration objectForKey: @"DefaultConfiguration"]];
+			
+			//Add a basic appender in case one wasn't configured
+			if (0 < [[rootLogger allAppendersArray] count])
+				[self basicConfiguration];
+			
+			NSEnumerator* e = nil;
+			id currentKey = nil;
+			NSDictionary* dict = nil;
+			
+			{
+				dict = [configuration objectForKey: @"ConfigurationByClass"];
+				e = [dict keyEnumerator];
+				while ((currentKey = [e nextObject]))
+				{
+					L4Logger* logger = [L4Logger loggerForClass: NSClassFromString (currentKey)];
+					[logger parseConfiguration: [dict objectForKey: currentKey]];
+				}
+			}
+			
+			{
+				dict = [configuration objectForKey: @"ConfigurationByName"];
+				e = [dict keyEnumerator];
+				while ((currentKey = [e nextObject]))
+				{
+					L4Logger* logger = [L4Logger loggerForName: currentKey];
+					[logger parseConfiguration: [dict objectForKey: currentKey]];
+				}
+			}
+		}
+		haveConfiguration = YES;
+	}
+	[configurationLock unlock];
+}
+
+/**
+ * Look up a configuration file.
+ * First check an environment variable, then the user defaults and finally the resources folder.
+ */
++ (NSString *) configurationFilePath
+{
+    NSFileManager* fm = [NSFileManager defaultManager];
+    NSString* path = nil;
+    
+    char* envPath = getenv ("Log4CocoaConfigurationFile");
+    if (NULL != envPath)
+    {
+        path = [NSString stringWithUTF8String: envPath];
+        if (nil != path && [fm fileExistsAtPath: path])
+            return path;
+    }
+    
+    NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
+    path = [defaults objectForKey: L4ConfigurationFilePath];
+    if (nil != path && [fm fileExistsAtPath: path])
+        return path;
+    
+    path = [[NSBundle mainBundle] pathForResource: L4ConfigurationFileName ofType: @"plist"];
+    
+    return path;
+}
+
++ (id) propertyForKey: (NSString *) aKey
+{
+    return nil;
+}
+
++ (void) resetLineBreakChar
+{
+    [lineBreakChar autorelease];
+    lineBreakChar = nil;
+}
+
++ (NSData *) lineBreakChar
+{
+    if( lineBreakChar == nil )
+    {
+        id breakChar = [self propertyForKey: LINE_BREAK_SEPERATOR_KEY];
+        if( breakChar != nil )
+        {
+            lineBreakChar = [[breakChar dataUsingEncoding: NSASCIIStringEncoding
+                                     allowLossyConversion: YES] retain];
+        }
+        else
+        {
+            // DEFAULT VALUE
+            lineBreakChar = [[@"\n" dataUsingEncoding: NSASCIIStringEncoding
+                                 allowLossyConversion: YES] retain];
+        }
+    }
+
+    return lineBreakChar;
+}
+
+@end

Contrib/Log4Cocoa/L4ConsoleAppender.h

+/****************************
+*
+* Copyright (c) 2002, 2003, Bob Frank
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+*  - Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*  - Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the distribution.
+*
+*  - Neither the name of Log4Cocoa nor the names of its contributors or owners
+*    may be used to endorse or promote products derived from this software
+*    without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+****************************/
+
+// #import "Log4Cocoa.h"
+#import <Foundation/Foundation.h>
+#import "L4Layout.h"
+#import "L4WriterAppender.h"
+
+@interface L4ConsoleAppender : L4WriterAppender {
+    BOOL isStandardOut;
+}
+
++ (L4ConsoleAppender *) standardOutWithLayout: (L4Layout *) aLayout;
++ (L4ConsoleAppender *) standardErrWithLayout: (L4Layout *) aLayout;
+
+- (id) init;
+
+- (id) initTarget: (BOOL) standardOut
+       withLayout: (L4Layout *) aLayout;
+
+- (id) initStandardOutWithLayout: (L4Layout *) aLayout;
+- (id) initStandardErrWithLayout: (L4Layout *) aLayout;
+
+- (void) setStandardOut;
+- (void) setStandardErr;
+
+- (NSFileHandle *) target;
+- (BOOL) isStandardOut;
+
+@end

Contrib/Log4Cocoa/L4ConsoleAppender.m

+/****************************
+*
+* Copyright (c) 2002, 2003, Bob Frank
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+*  - Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*  - Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the distribution.
+*
+*  - Neither the name of Log4Cocoa nor the names of its contributors or owners
+*    may be used to endorse or promote products derived from this software
+*    without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+****************************/
+
+#import "L4ConsoleAppender.h"
+
+
+@implementation L4ConsoleAppender
+
++ (L4ConsoleAppender *) standardOutWithLayout: (L4Layout *) aLayout
+{
+    return (L4ConsoleAppender *) [[[L4ConsoleAppender alloc] initTarget: YES
+                                                             withLayout: aLayout] autorelease];
+}
+
++ (L4ConsoleAppender *) standardErrWithLayout: (L4Layout *) aLayout
+{
+    return (L4ConsoleAppender *) [[[L4ConsoleAppender alloc] initTarget: NO
+                                                             withLayout: aLayout] autorelease];
+}
+
+- (id) init
+{
+    self = [super init];
+    return self;
+}
+
+- (id) initTarget: (BOOL) standardOut
+       withLayout: (L4Layout *) aLayout
+{
+    self = [super init];
+    if( self != nil )
+    {
+        if( standardOut )
+        {
+            [self setStandardOut];
+        }
+        else
+        {
+            [self setStandardErr];
+        }
+        [self setLayout: aLayout];
+    }
+    return self;
+}
+
+- (id) initStandardOutWithLayout: (L4Layout *) aLayout
+{
+    return [self initTarget: YES
+                 withLayout: aLayout];
+}
+
+- (id) initStandardErrWithLayout: (L4Layout *) aLayout
+{
+    return [self initTarget: NO
+                 withLayout: aLayout];
+}
+
+- (void) setStandardOut
+{
+    if(!isStandardOut || (fileHandle == nil))
+    {
+        isStandardOut = YES;
+        [fileHandle autorelease];
+        fileHandle = [[NSFileHandle fileHandleWithStandardOutput] retain];
+    }
+}
+
+- (void) setStandardErr
+{
+    if(isStandardOut || (fileHandle == nil))
+    {
+        isStandardOut = NO;
+        [fileHandle autorelease];
+        fileHandle = [[NSFileHandle fileHandleWithStandardError] retain];
+    }
+}
+
+- (NSFileHandle *) target
+{
+    return fileHandle;
+}
+
+- (BOOL) isStandardOut
+{
+    return isStandardOut;
+}
+
+@end

Contrib/Log4Cocoa/L4DailyRollingFileAppender.h

+/****************************
+*
+* Copyright (c) 2002, 2003, Bob Frank
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+*  - Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*  - Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the distribution.
+*
+*  - Neither the name of Log4Cocoa nor the names of its contributors or owners
+*    may be used to endorse or promote products derived from this software
+*    without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+****************************/
+
+
+//
+//  L4DailyRollingFileAppender.h
+//  Log4Cocoa
+//
+//  Created by Michael James on Thu Apr 29 2004.
+//  Copyright (c) 2004 __MyCompanyName__. All rights reserved.
+//
+
+/*!
+	@header L4DailyRollingFileAppender
+	@updated 2004-04-29
+*/
+
+#import <Foundation/Foundation.h>
+#import "L4FileAppender.h"
+
+/*!
+	@typedef L4RollingFrequency
+	@abstract The accepted constants for L4DailyRollingFileAppenderFrequency's <code>setFrequency:</code> method.
+	@constant never Never roll the file over (this is a default setting)
+	@constant monthly Roll the file over every month
+	@constant weekly Roll the file over every week
+	@constant daily Roll the file over every day
+	@constant half_daily Roll the file over every half day (once at midnight, once at noon)
+	@constant hourly Roll the file over every hour
+	@constant minutely Roll the file over every minute
+*/
+typedef enum L4RollingFrequency
+{
+	never,
+	monthly,
+	weekly,
+	daily,
+	half_daily,
+	hourly,
+	minutely
+} L4RollingFrequency;
+
+/*!
+	@class L4DailyRollingFileAppender
+	@discussion L4DailyRollingFileAppender extends L4FileAppender so that the underlying file is rolled over at a user-chosen frequency.
+
+		For example, if the fileName is set to /foo/bar.log and the frequency is set to daily, on 2001-02-16 at midnight, the logging file /foo/bar.log will be copied to /foo/bar.log.2001-02-16 and logging for 2001-02-17 will continue in /foo/bar.log until it rolls over the next day.
+
+		It is possible to specify monthly, weekly, half-daily, daily, hourly, or minutely rollover schedules.  
+*/
+@interface L4DailyRollingFileAppender : L4FileAppender
+{
+	L4RollingFrequency	_rollingFrequency;
+	NSCalendarDate*		_lastRolloverDate;
+}
+
+/*!
+	@method init
+	@abstract This initializer calls the <code>initWithLayout:fileName:rollingFrequency:</code> method with the respective values: nil, nil, never
+	@result An initialized instance of this class
+*/
+- (id)init;
+
+/*!
+	@method initWithLayout:fileName:rollingFrequency:
+	@abstract Initializes an instance of this class with the specified layout, file name, and rolling frequency.
+	@param aLayout The layout object for this appender
+	@param aName The file path to the file in which you want logging output recorded
+	@param rollingFrequency The frequency at which you want the log file rolled over
+	@result An initialized instance of this class
+*/
+- (id)initWithLayout: (L4Layout*)aLayout fileName: (NSString*)aName rollingFrequency: (L4RollingFrequency)rollingFrequency;
+
+/*!
+	@method rollingFrequency
+	@abstract Returns this object's rolling frequency.
+	@result This object's rolling frequency
+*/
+- (L4RollingFrequency)rollingFrequency;
+
+/*!
+	@method setRollingFrequency:
+	@abstract Sets the object's rolling frequency
+	@param rollingFrequency The desired rolling frequency for this object
+*/
+- (void)setRollingFrequency: (L4RollingFrequency)rollingFrequency;
+
+@end
+
+/*!
+	@category L4DailyRollingFileAppender (__ProtectedMethods)
+	@discussion These methods are "protected" methods and should not be called except by subclasses.
+*/
+@interface L4DailyRollingFileAppender (__ProtectedMethods)
+
+/*!
+	@method subAppend:
+	@discussion This method overrides the implementation in L4WriterAppender.  It checks if the rolling frequency has been exceeded.  If so, it rolls the file over.
+	@param event An L4LoggingEvent that contains logging specific information
+*/
+- (void)subAppend: (L4LoggingEvent*)event;
+
+@end

Contrib/Log4Cocoa/L4DailyRollingFileAppender.m

+//
+//  L4DailyRollingFileAppender.m
+//  Log4Cocoa
+//
+//  Created by Michael James on Thu Apr 29 2004.
+//  Copyright (c) 2004 __MyCompanyName__. All rights reserved.
+//
+
+#import "L4DailyRollingFileAppender.h"
+#import "L4Layout.h"
+#import <math.h>
+
+
+@interface L4DailyRollingFileAppender (__PrivateMethods)
+
+- (NSCalendarDate*)_lastRolloverDate;
+- (void)_setLastRolloverDate: (NSDate*)date;
+- (void)_rollOver;
+
+@end
+
+@implementation L4DailyRollingFileAppender
+
+- (id)init
+{
+	return [self initWithLayout: nil fileName: nil rollingFrequency: never];
+}
+
+- (id)initWithLayout: (L4Layout*)aLayout fileName: (NSString*)aName rollingFrequency: (L4RollingFrequency)rollingFrequency
+{
+	self = [super initWithLayout: aLayout fileName: aName append: YES bufferIO: NO bufferSize: 0];
+	
+	if (self != nil)
+	{
+		[self setRollingFrequency: rollingFrequency];
+	}
+	
+	return self;
+}
+
+- (void)dealloc
+{
+	[_lastRolloverDate release];
+	_lastRolloverDate = nil;
+	
+	[super dealloc];
+}
+
+- (L4RollingFrequency)rollingFrequency
+{
+	return _rollingFrequency;
+}
+
+- (void)setRollingFrequency: (L4RollingFrequency)rollingFrequency
+{	
+	_rollingFrequency = rollingFrequency;
+	[self _setLastRolloverDate: [NSCalendarDate calendarDate]];
+}
+
+@end
+
+@implementation L4DailyRollingFileAppender (__ProtectedMethods)
+
+- (v