KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > log > output > MemoryTarget


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

17 package org.apache.log.output;
18
19 import org.apache.log.LogEvent;
20 import org.apache.log.LogTarget;
21 import org.apache.log.Priority;
22
23 /**
24  * Output LogEvents into an buffer in memory.
25  * At a later stage these LogEvents can be forwarded or
26  * pushed to another target. This pushing is triggered
27  * when buffer is full, the priority of a LogEvent reaches a threshold
28  * or when another class calls the push method.
29  *
30  * This is based on specification of MemoryHandler in Logging JSR47.
31  *
32  * @author <a HREF="mailto:dev@avalon.apache.org">Avalon Development Team</a>
33  * @author Peter Donald
34  */

35 public class MemoryTarget
36     extends AbstractTarget
37 {
38     ///Buffer for all the LogEvents
39
private final LogEvent[] m_buffer;
40
41     ///Priority at which to push LogEvents to next LogTarget
42
private Priority m_threshold;
43
44     ///Target to push LogEvents to
45
private LogTarget m_target;
46
47     ///Count of used events
48
private int m_used;
49
50     ///Position of last element inserted
51
private int m_index;
52
53     ///Flag indicating whether it is possible to overite elements in array
54
private boolean m_overwrite;
55
56     /**
57      * Creation of a new instance of the memory target.
58      * @param target the target to push LogEvents to
59      * @param size the event buffer size
60      * @param threshold the priority at which to push LogEvents to next LogTarget
61      */

62     public MemoryTarget( final LogTarget target,
63                          final int size,
64                          final Priority threshold )
65     {
66         m_target = target;
67         m_buffer = new LogEvent[ size ];
68         m_threshold = threshold;
69         open();
70     }
71
72     /**
73      * Set flag indicating whether it is valid to overwrite memory buffer.
74      *
75      * @param overwrite true if buffer should overwrite logevents in buffer, false otherwise
76      */

77     protected synchronized void setOverwrite( final boolean overwrite )
78     {
79         m_overwrite = overwrite;
80     }
81
82     /**
83      * Process a log event, via formatting and outputting it.
84      *
85      * @param event the log event
86      */

87     protected synchronized void doProcessEvent( final LogEvent event )
88     {
89         //Check if it is full
90
if( isFull() )
91         {
92             if( m_overwrite )
93             {
94                 m_used--;
95             }
96             else
97             {
98                 getErrorHandler().error( "Memory buffer is full", null, event );
99                 return;
100             }
101         }
102
103         if( 0 == m_used )
104         {
105             m_index = 0;
106         }
107         else
108         {
109             m_index = ( m_index + 1 ) % m_buffer.length;
110         }
111         m_buffer[ m_index ] = event;
112         m_used++;
113
114         if( shouldPush( event ) )
115         {
116             push();
117         }
118     }
119
120     /**
121      * Check if memory buffer is full.
122      *
123      * @return true if buffer is full, false otherwise
124      */

125     public final synchronized boolean isFull()
126     {
127         return m_buffer.length == m_used;
128     }
129
130     /**
131      * Determine if LogEvent should initiate a push to target.
132      * Subclasses can overide this method to change the conditions
133      * under which a push occurs.
134      *
135      * @param event the incoming LogEvent
136      * @return true if should push, false otherwise
137      */

138     protected synchronized boolean shouldPush( final LogEvent event )
139     {
140         return ( m_threshold.isLowerOrEqual( event.getPriority() ) || isFull() );
141     }
142
143     /**
144      * Push log events to target.
145      */

146     public synchronized void push()
147     {
148         if( null == m_target )
149         {
150             getErrorHandler().error( "Can not push events to a null target", null, null );
151             return;
152         }
153
154         try
155         {
156             final int size = m_used;
157             int base = m_index - m_used + 1;
158             if( base < 0 )
159             {
160                 base += m_buffer.length;
161             }
162
163             for( int i = 0; i < size; i++ )
164             {
165                 final int index = ( base + i ) % m_buffer.length;
166
167                 //process event in buffer
168
m_target.processEvent( m_buffer[ index ] );
169
170                 //help GC
171
m_buffer[ index ] = null;
172                 m_used--;
173             }
174         }
175         catch( final Throwable JavaDoc throwable )
176         {
177             getErrorHandler().error( "Unknown error pushing events.", throwable, null );
178         }
179     }
180 }
181
Popular Tags