• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you 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 /*
19  * $Id$
20  */
21 
22 /*
23  *
24  * LoggingHandler.java
25  *
26  */
27 package org.apache.qetest;
28 
29 
30 /**
31  * Base class defining common functionality of logging handlers.
32  * <p>Common functionality used for testing when implementing
33  * various Handlers and Listeners.  Provides common ways to set
34  * Loggers and levels, reset, and set expected errors or the
35  * like.  Likely used to implement testing wrapper classes for
36  * things like javax.xml.transform.ErrorListener and
37  * org.xml.sax.ErrorHandler</p>
38  * <p>The best description for this class can be seen in an
39  * example; see trax.LoggingErrorHandler.java for one.</p>
40  * @author shane_curcuru@lotus.com
41  * @version $Id$
42  */
43 public class LoggingHandler
44 {
45 
46     /**
47      * Set a default handler for us to wrapper.
48      * Often you may want to keep the default handler for some
49      * operation while you're logging.  For subclasses that support
50      * this call, they will log every operation, and then simply
51      * call-through to this default handler.
52      *
53      * Subclasses should implement this and verify that the default
54      * is of an appropriate type to use.
55      *
56      * @param default Object of the correct type to pass-through to;
57      * throws IllegalArgumentException if null or incorrect type
58      */
setDefaultHandler(Object defaultHandler)59     public void setDefaultHandler(Object defaultHandler)
60     {
61         throw new java.lang.IllegalArgumentException("LoggingHandler.setDefaultHandler() is unimplemented!");
62     }
63 
64 
65     /**
66      * Accessor method for our default handler; here returns null.
67      *
68      * @return default (Object) our default handler; null if unset
69      */
getDefaultHandler()70     public Object getDefaultHandler()
71     {
72         return null;
73     }
74 
75 
76     /**
77      * Get a list of counters of all items we've logged.
78      * LoggingHandlers each will have various kinds or types of
79      * things they handle (errors, warnings, messages, URIs, etc.).
80      * They should keep a running tally of how many of each kind of
81      * item they've 'handled'.
82      *
83      * @return array of int counters for each item we log;
84      * subclasses should define constants for what each slot is
85      */
getCounters()86     public int[] getCounters()
87     {
88         return NOTHING_HANDLED_CTR;
89     }
90 
91 
92     /**
93      * Get a string representation of last item we logged.
94      * For every item that we handle, subclasses should store a
95      * String representation and return it here if asked.  Normally
96      * this will only be a copy of the very last item we logged -
97      * not necessarily what users might want, but the simplest to
98      * implement everywhere.
99      *
100      * @return String of the last item handled
101      */
getLast()102     public String getLast()
103     {
104         return NOTHING_HANDLED;
105     }
106 
107 
108     /**
109      * Reset any items or counters we've handled.
110      * Resets any data about what we've handled or logged so far,
111      * like getLast() and getCounters() data, as well as any
112      * expected items from setExpected().  Does not change our
113      * Logger or loggingLevel.
114      */
reset()115     public void reset()
116     {
117         /* no-op */;
118     }
119 
120 
121     /**
122      * Ask us to report checkPass/Fail for certain events we handle.
123      * Since we may have to handle many events between when a test
124      * will be able to call us, testers can set this to have us
125      * automatically call checkPass when we see an item that matches,
126      * or to call checkFail when we get an unexpected item.
127      * Generally, we only call check* methods when:
128      * <ul>
129      * <li>containsString is not set, reset, or is ITEM_DONT_CARE,
130      * we do nothing (i.e. never call check* for this item)</li>
131      * <li>containsString is ITEM_CHECKFAIL, we will always call
132      * checkFail with the contents of any item if it occours</li>
133      * <li>containsString is anything else, we will grab a String
134      * representation of every item of that type that comes along,
135      * and if the containsString is found, case-sensitive, within
136      * the handled item's string, call checkPass, otherwise
137      * call checkFail</li>
138      * <ul>
139      * Note that most implementations will only validate the first
140      * event of a specific type, and then will reset validation for
141      * that event type.  This is because many events may be raised
142      * in between the time that a calling Test class could tell us
143      * of the 'next' expected event.
144      * //@todo improve this paradigm to allow users to specify an
145      * expected sequence of events.
146      *
147      * @param itemType which of the various types of items we might
148      * handle; should be defined as a constant by subclasses
149      * @param containsString a string to look for within whatever
150      * item we handle - usually checked for by seeing if the actual
151      * item we handle contains the containsString
152      */
setExpected(int itemType, String containsString)153     public void setExpected(int itemType, String containsString)
154     {
155         /* no-op */;
156     }
157 
158 
159     /**
160      * Accesor method for a brief description of this service.
161      * Subclasses should obviously override to provide useful info.
162      *
163      * @return String "LoggingHandler: default implementation, does nothing"
164      */
getDescription()165     public String getDescription()
166     {
167         return "LoggingHandler: default implementation, does nothing";
168     }
169 
170 
171     /**
172      * Accesor methods for our Logger.
173      *
174      * @param l the Logger to have this test use for logging
175      * results; or null to use a default logger
176      */
setLogger(Logger l)177     public void setLogger(Logger l)
178 	{
179         // if null, set a default one
180         if (null == l)
181             logger = getDefaultLogger();
182         else
183             logger = l;
184 	}
185 
186 
187     /**
188      * Accesor methods for our Logger.
189      *
190      * @return Logger we tell all our secrets to.
191      */
getLogger()192     public Logger getLogger()
193 	{
194         return logger;
195 	}
196 
197 
198     /**
199      * Get a default Logger for use with this Handler.
200      * Gets a default ConsoleLogger (only if a Logger isn't
201      * currently set!).
202      *
203      * @return current logger; if null, then creates a
204      * Logger.DEFAULT_LOGGER and returns that; if it cannot
205      * create one, throws a RuntimeException
206      */
getDefaultLogger()207     public Logger getDefaultLogger()
208     {
209         if (logger != null)
210             return logger;
211 
212         try
213         {
214             Class rClass = Class.forName(Logger.DEFAULT_LOGGER);
215             return (Logger)rClass.newInstance();
216         }
217         catch (Exception e)
218         {
219             // Must re-throw the exception, since returning
220             //  null or the like could lead to recursion
221             e.printStackTrace();
222             throw new RuntimeException(e.toString());
223         }
224     }
225 
226 
227     /**
228      * Accesor methods for our loggingLevel.
229      *
230      * @param l what level we should call logger.logMsg()
231      */
setLoggingLevel(int l)232     public void setLoggingLevel(int l)
233     {
234         level = l;
235     }
236 
237 
238     /**
239      * Accesor methods for our loggingLevel.
240      *
241      * @return what level we call logger.logMsg()
242      */
getLoggingLevel()243     public int getLoggingLevel()
244     {
245         return level;
246     }
247 
248     //-----------------------------------------------------------
249     //---- Instance Variables and Constants
250     //-----------------------------------------------------------
251 
252     /** Our Logger, who we tell all our secrets to. */
253     protected Logger logger = null;
254 
255     /** What loggingLevel to use for reporter.logMsg(). */
256     protected int level = Logger.DEFAULT_LOGGINGLEVEL;
257 
258     /** Default return value from getCounters() after a reset(). */
259     public static final int[] NOTHING_HANDLED_CTR = { 0 };
260 
261     /** Default return value from getLast() after a reset(). */
262     public static final String NOTHING_HANDLED = "NOTHING_HANDLED";
263 
264     /** Token for setExpected that we don't care (default value) about the event. */
265     public static final String ITEM_DONT_CARE = "ITEM_DONT_CARE";
266 
267     /** Token for setExpected that we should call checkFail if we get the event. */
268     public static final String ITEM_CHECKFAIL = "ITEM_CHECKFAIL";
269 }
270