1 | package org.apache.velocity.runtime.log; |
2 | |
3 | /* |
4 | * Copyright 2001,2004 The Apache Software Foundation. |
5 | * |
6 | * Licensed under the Apache License, Version 2.0 (the "License"); |
7 | * you may not use this file except in compliance with the License. |
8 | * You may obtain a copy of the License at |
9 | * |
10 | * http://www.apache.org/licenses/LICENSE-2.0 |
11 | * |
12 | * Unless required by applicable law or agreed to in writing, software |
13 | * distributed under the License is distributed on an "AS IS" BASIS, |
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
15 | * See the License for the specific language governing permissions and |
16 | * limitations under the License. |
17 | */ |
18 | |
19 | import java.util.List; |
20 | import java.util.ArrayList; |
21 | import java.util.Iterator; |
22 | |
23 | import org.apache.velocity.runtime.RuntimeServices; |
24 | import org.apache.velocity.runtime.RuntimeConstants; |
25 | |
26 | /** |
27 | * <p> |
28 | * This class is responsible for instantiating the correct LoggingSystem |
29 | * </p> |
30 | * |
31 | * <p> |
32 | * The approach is : |
33 | * </p> |
34 | * <ul> |
35 | * <li> |
36 | * First try to see if the user is passing in a living object |
37 | * that is a LogSystem, allowing the app to give is living |
38 | * custom loggers. |
39 | * </li> |
40 | * <li> |
41 | * Next, run through the (possible) list of classes specified |
42 | * specified as loggers, taking the first one that appears to |
43 | * work. This is how we support finding either log4j or |
44 | * logkit, whichever is in the classpath, as both are |
45 | * listed as defaults. |
46 | * </li> |
47 | * <li> |
48 | * Finally, we turn to 'faith-based' logging, and hope that |
49 | * logkit is in the classpath, and try for an AvalonLogSystem |
50 | * as a final gasp. After that, there is nothing we can do. |
51 | * </li> |
52 | * |
53 | * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> |
54 | * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a> |
55 | * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a> |
56 | * @version $Id: LogManager.java,v 1.10.4.1 2004/03/03 23:22:56 geirm Exp $ |
57 | */ |
58 | public class LogManager |
59 | { |
60 | /** |
61 | * Creates a new logging system or returns an existing one |
62 | * specified by the application. |
63 | */ |
64 | public static LogSystem createLogSystem( RuntimeServices rsvc ) |
65 | throws Exception |
66 | { |
67 | /* |
68 | * if a logSystem was set as a configuation value, use that. |
69 | * This is any class the user specifies. |
70 | */ |
71 | |
72 | Object o = rsvc.getProperty( RuntimeConstants.RUNTIME_LOG_LOGSYSTEM ); |
73 | |
74 | if (o != null && o instanceof LogSystem) |
75 | { |
76 | ((LogSystem) o).init( rsvc ); |
77 | |
78 | return (LogSystem) o; |
79 | } |
80 | |
81 | /* |
82 | * otherwise, see if a class was specified. You |
83 | * can put multiple classes, and we use the first one we find. |
84 | * |
85 | * Note that the default value of this property contains both the |
86 | * AvalonLogSystem and the SimpleLog4JLogSystem for convenience - |
87 | * so we use whichever we find. |
88 | */ |
89 | |
90 | List classes = null; |
91 | Object obj = rsvc.getProperty( RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS ); |
92 | |
93 | /* |
94 | * we might have a list, or not - so check |
95 | */ |
96 | |
97 | if ( obj instanceof List) |
98 | { |
99 | classes = (List) obj; |
100 | } |
101 | else if ( obj instanceof String) |
102 | { |
103 | classes = new ArrayList(); |
104 | classes.add( obj ); |
105 | } |
106 | |
107 | /* |
108 | * now run through the list, trying each. It's ok to |
109 | * fail with a class not found, as we do this to also |
110 | * search out a default simple file logger |
111 | */ |
112 | |
113 | for( Iterator ii = classes.iterator(); ii.hasNext(); ) |
114 | { |
115 | String claz = (String) ii.next(); |
116 | |
117 | if (claz != null && claz.length() > 0 ) |
118 | { |
119 | rsvc.info("Trying to use logger class " + claz ); |
120 | |
121 | try |
122 | { |
123 | o = Class.forName( claz ).newInstance(); |
124 | |
125 | if ( o instanceof LogSystem ) |
126 | { |
127 | ((LogSystem) o).init( rsvc ); |
128 | |
129 | rsvc.info("Using logger class " + claz ); |
130 | |
131 | return (LogSystem) o; |
132 | } |
133 | else |
134 | { |
135 | rsvc.error("The specifid logger class " + claz + |
136 | " isn't a valid LogSystem"); |
137 | } |
138 | } |
139 | catch( NoClassDefFoundError ncdfe ) |
140 | { |
141 | rsvc.debug("Couldn't find class " + claz |
142 | + " or necessary supporting classes in " |
143 | + "classpath. Exception : " + ncdfe); |
144 | } |
145 | } |
146 | } |
147 | |
148 | /* |
149 | * if the above failed, then we are in deep doo-doo, as the |
150 | * above means that either the user specified a logging class |
151 | * that we can't find, there weren't the necessary |
152 | * dependencies in the classpath for it, or there were no |
153 | * dependencies for the default loggers, log4j and logkit. |
154 | * Since we really don't know, |
155 | * then take a wack at the AvalonLogSystem as a last resort. |
156 | */ |
157 | |
158 | LogSystem als = null; |
159 | |
160 | try |
161 | { |
162 | als = new AvalonLogSystem(); |
163 | |
164 | als.init( rsvc ); |
165 | } |
166 | catch( NoClassDefFoundError ncdfe ) |
167 | { |
168 | String errstr = "PANIC : Velocity cannot find any of the" |
169 | + " specified or default logging systems in the classpath," |
170 | + " or the classpath doesn't contain the necessary classes" |
171 | + " to support them." |
172 | + " Please consult the documentation regarding logging." |
173 | + " Exception : " + ncdfe; |
174 | |
175 | System.out.println( errstr ); |
176 | System.err.println( errstr ); |
177 | |
178 | throw ncdfe; |
179 | } |
180 | |
181 | rsvc.info("Using AvalonLogSystem as logger of final resort."); |
182 | |
183 | return als; |
184 | } |
185 | } |
186 | |