KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > jk > config > BaseJkConfig


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

16
17 package org.apache.jk.config;
18
19 import java.io.File JavaDoc;
20 import java.io.IOException JavaDoc;
21 import java.io.PrintWriter JavaDoc;
22
23 import org.apache.catalina.Container;
24 import org.apache.catalina.Context;
25 import org.apache.catalina.Engine;
26 import org.apache.catalina.Host;
27 import org.apache.catalina.Lifecycle;
28 import org.apache.catalina.LifecycleEvent;
29 import org.apache.catalina.LifecycleListener;
30 import org.apache.catalina.Server;
31
32
33 /**
34     Base class for automatic jk based configurations based on
35     the Tomcat server.xml settings and the war contexts
36     initialized during startup.
37     <p>
38     This config interceptor is enabled by inserting a Config
39     element in the <b>&lt;ContextManager&gt;</b> tag body inside
40     the server.xml file like so:
41     <pre>
42     * < ContextManager ... >
43     * ...
44     * <<b>???Config</b> <i>options</i> />
45     * ...
46     * < /ContextManager >
47     </pre>
48     where <i>options</i> can include any of the following attributes:
49     <ul>
50      <li><b>configHome</b> - default parent directory for the following paths.
51                              If not set, this defaults to TOMCAT_HOME. Ignored
52                              whenever any of the following paths is absolute.
53                              </li>
54      <li><b>workersConfig</b> - path to workers.properties file used by
55                                 jk connector. If not set, defaults to
56                                 "conf/jk/workers.properties".</li>
57      <li><b>jkLog</b> - path to log file to be used by jk connector.</li>
58      <li><b>jkDebug</b> - Loglevel setting. May be debug, info, error, or emerg.
59                           If not set, defaults to emerg.</li>
60      <li><b>jkWorker</b> The desired worker. Must be set to one of the workers
61                          defined in the workers.properties file. "ajp12", "ajp13"
62                          or "inprocess" are the workers found in the default
63                          workers.properties file. If not specified, defaults
64                          to "ajp13" if an Ajp13Interceptor is in use, otherwise
65                          it defaults to "ajp12".</li>
66      <li><b>forwardAll</b> - If true, forward all requests to Tomcat. This helps
67                              insure that all the behavior configured in the web.xml
68                              file functions correctly. If false, let Apache serve
69                              static resources. The default is true.
70                              Warning: When false, some configuration in
71                              the web.xml may not be duplicated in Apache.
72                              Review the mod_jk conf file to see what
73                              configuration is actually being set in Apache.</li>
74      <li><b>noRoot</b> - If true, the root context is not mapped to
75                          Tomcat. If false and forwardAll is true, all requests
76                          to the root context are mapped to Tomcat. If false and
77                          forwardAll is false, only JSP and servlets requests to
78                          the root context are mapped to Tomcat. When false,
79                          to correctly serve Tomcat's root context you may also
80                          need to modify the web server to point it's home
81                          directory to Tomcat's root context directory.
82                          Otherwise some content, such as the root index.html,
83                          may be served by the web server before the connector
84                          gets a chance to claim the request and pass it to Tomcat.
85                          The default is true.</li>
86     </ul>
87     <p>
88     @author Costin Manolache
89     @author Larry Isaacs
90     @author Bill Barker
91         @version $Revision: 1.4 $
92  */

93 public class BaseJkConfig implements LifecycleListener {
94     private static org.apache.commons.logging.Log log =
95         org.apache.commons.logging.LogFactory.getLog(BaseJkConfig.class);
96
97     protected File JavaDoc configHome = null;
98     protected File JavaDoc workersConfig = null;
99
100     protected File JavaDoc jkLog = null;
101     protected String JavaDoc jkDebug="emerg";
102     protected String JavaDoc jkWorker = "ajp13";
103
104     protected boolean noRoot=true;
105     protected boolean forwardAll=true;
106
107     protected String JavaDoc tomcatHome;
108     protected boolean regenerate=false;
109     protected boolean append=false;
110     protected boolean legacy=true;
111
112     // -------------------- Tomcat callbacks --------------------
113

114
115     // Auto-config should be able to react to dynamic config changes,
116
// and regenerate the config.
117

118     /**
119      * Generate the configuration - only when the server is
120      * completely initialized ( before starting )
121      */

122     public void lifecycleEvent(LifecycleEvent evt) {
123         if(Lifecycle.START_EVENT.equals(evt.getType())) {
124            execute( evt );
125         }
126     }
127
128     /**
129      * Generate configuration files. Override with method to generate
130      * web server specific configuration.
131      */

132     public void execute(LifecycleEvent evt) {
133         initProperties();
134         PrintWriter JavaDoc mod_jk = null;
135         try {
136             mod_jk = getWriter();
137         } catch(IOException JavaDoc iex) {
138             log.warn("Unable to open config file");
139             return;
140         }
141         Lifecycle who = evt.getLifecycle();
142         if( who instanceof Server ) {
143             executeServer((Server)who, mod_jk);
144         } else if(who instanceof Engine) {
145             executeEngine((Engine)who, mod_jk);
146         } else if ( who instanceof Host ) {
147             executeHost((Host)who, mod_jk);
148         } else if( who instanceof Context ) {
149             executeContext((Context)who, mod_jk);
150         }
151         mod_jk.close();
152     }
153     /**
154      * Generate configuration files. Override with method to generate
155      * web server specific configuration.
156      */

157     public void executeServer(Server svr, PrintWriter JavaDoc mod_jk) {
158         if(! append ) {
159             if( ! generateJkHead(mod_jk) )
160                 return;
161             generateSSLConfig(mod_jk);
162             generateJkTail(mod_jk);
163         }
164     }
165
166     /**
167      * Generate SSL options
168      */

169     protected void generateSSLConfig(PrintWriter JavaDoc mod_jk) {
170     }
171
172     /**
173      * Generate general options
174      */

175     protected boolean generateJkHead(PrintWriter JavaDoc mod_jk) {
176         return true;
177     }
178
179     /**
180      * Generate general options
181      */

182     protected void generateJkTail(PrintWriter JavaDoc mod_jk) {
183     }
184
185     /**
186      * Generate Virtual Host start
187      */

188     protected void generateVhostHead(Host host, PrintWriter JavaDoc mod_jk) {
189     }
190
191     /**
192      * Generate Virtual Host end
193      */

194     protected void generateVhostTail(Host host, PrintWriter JavaDoc mod_jk) {
195     }
196
197     /**
198      * Generate configuration files. Override with method to generate
199      * web server specific configuration.
200      */

201     protected void executeEngine(Engine egn, PrintWriter JavaDoc mod_jk) {
202         if(egn.getJvmRoute() != null) {
203             jkWorker = egn.getJvmRoute();
204         }
205         executeServer(egn.getService().getServer(), mod_jk);
206         Container [] children = egn.findChildren();
207         for(int ii=0; ii < children.length; ii++) {
208             if( children[ii] instanceof Host ) {
209                 executeHost((Host)children[ii], mod_jk);
210             } else if( children[ii] instanceof Context ) {
211                 executeContext((Context)children[ii], mod_jk);
212             }
213         }
214     }
215     /**
216      * Generate configuration files. Override with method to generate
217      * web server specific configuration.
218      */

219     protected void executeHost(Host hst, PrintWriter JavaDoc mod_jk) {
220         generateVhostHead(hst, mod_jk);
221         Container [] children = hst.findChildren();
222         for(int ii=0; ii < children.length; ii++) {
223             if(children[ii] instanceof Context) {
224                 executeContext((Context)children[ii],mod_jk);
225             }
226         }
227         generateVhostTail(hst, mod_jk);
228     }
229     /**
230      * executes the ApacheConfig interceptor. This method generates apache
231      * configuration files for use with mod_jk.
232      * @param context a Context object.
233      * @param mod_jk Writer for output.
234     */

235     public void executeContext(Context context, PrintWriter JavaDoc mod_jk){
236
237         if(context.getPath().length() > 0 || ! noRoot ) {
238             String JavaDoc docRoot = context.getServletContext().getRealPath("/");
239             if( forwardAll || docRoot == null)
240                 generateStupidMappings( context, mod_jk );
241             else
242                 generateContextMappings( context, mod_jk);
243         }
244     }
245
246     protected void generateStupidMappings(Context context, PrintWriter JavaDoc mod_jk){
247     }
248     protected void generateContextMappings(Context context, PrintWriter JavaDoc mod_jk){
249     }
250
251     /**
252      * Get the output Writer. Override with method to generate
253      * web server specific configuration.
254      */

255     protected PrintWriter JavaDoc getWriter() throws IOException JavaDoc {
256         return null;
257     }
258
259     /**
260      * Get the host associated with this Container (if any).
261      */

262     protected Host getHost(Container child) {
263         while(child != null && ! (child instanceof Host) ) {
264             child = child.getParent();
265         }
266         return (Host)child;
267     }
268
269     //-------------------- Properties --------------------
270

271     /**
272      * Append to config file.
273      * Set to <code>true</code> if the config information should be
274      * appended.
275      */

276     public void setAppend(boolean apnd) {
277         append = apnd;
278     }
279
280     /**
281      * If false, we'll try to generate a config that will
282      * let apache serve static files.
283      * The default is true, forward all requests in a context
284      * to tomcat.
285      */

286     public void setForwardAll( boolean b ) {
287         forwardAll=b;
288     }
289
290     /**
291      * Special option - do not generate mappings for the ROOT
292      * context. The default is true, and will not generate the mappings,
293      * not redirecting all pages to tomcat (since /* matches everything).
294      * This means that the web server's root remains intact but isn't
295      * completely servlet/JSP enabled. If the ROOT webapp can be configured
296      * with the web server serving static files, there's no problem setting
297      * this option to false. If not, then setting it true means the web
298      * server will be out of picture for all requests.
299      */

300     public void setNoRoot( boolean b ) {
301         noRoot=b;
302     }
303     
304     /**
305      * set a path to the parent directory of the
306      * conf folder. That is, the parent directory
307      * within which path setters would be resolved against,
308      * if relative. For example if ConfigHome is set to "/home/tomcat"
309      * and regConfig is set to "conf/mod_jk.conf" then the resulting
310      * path used would be:
311      * "/home/tomcat/conf/mod_jk.conf".</p>
312      * <p>
313      * However, if the path is set to an absolute path,
314      * this attribute is ignored.
315      * <p>
316      * If not set, execute() will set this to TOMCAT_HOME.
317      * @param dir - path to a directory
318      */

319     public void setConfigHome(String JavaDoc dir){
320         if( dir==null ) return;
321         File JavaDoc f=new File JavaDoc(dir);
322         if(!f.isDirectory()){
323             throw new IllegalArgumentException JavaDoc(
324                 "BaseConfig.setConfigHome(): "+
325                 "Configuration Home must be a directory! : "+dir);
326         }
327         configHome = f;
328     }
329
330     /**
331      * set a path to the workers.properties file.
332      * @param path String path to workers.properties file
333      */

334     public void setWorkersConfig(String JavaDoc path){
335         workersConfig= (path==null?null:new File JavaDoc(path));
336     }
337
338     /**
339      * set the path to the log file
340      * @param path String path to a file
341      */

342     public void setJkLog(String JavaDoc path){
343         jkLog = ( path==null ? null : new File JavaDoc(path));
344     }
345
346     /**
347      * Set the verbosity level
348      * ( use debug, error, etc. ) If not set, no log is written.
349      */

350     public void setJkDebug( String JavaDoc level ) {
351         jkDebug=level;
352     }
353
354     /**
355      * Sets the JK worker.
356      * @param worker The worker
357      */

358     public void setJkWorker(String JavaDoc worker){
359         jkWorker = worker;
360     }
361
362     public void setLegacy(boolean legacy) {
363         this.legacy = legacy;
364     }
365
366     // -------------------- Initialize/guess defaults --------------------
367

368     /**
369      * Initialize defaults for properties that are not set
370      * explicitely
371      */

372     protected void initProperties() {
373         tomcatHome = System.getProperty("catalina.home");
374         File JavaDoc tomcatDir = new File JavaDoc(tomcatHome);
375         if(configHome==null){
376             configHome=tomcatDir;
377         }
378     }
379
380     // -------------------- Config Utils --------------------
381

382
383     /**
384      * Add an extension mapping. Override with method to generate
385      * web server specific configuration
386      */

387     protected boolean addExtensionMapping( String JavaDoc ctxPath, String JavaDoc ext,
388                                          PrintWriter JavaDoc pw ) {
389         return true;
390     }
391     
392     
393     /**
394      * Add a fulling specified mapping. Override with method to generate
395      * web server specific configuration
396      */

397     protected boolean addMapping( String JavaDoc fullPath, PrintWriter JavaDoc pw ) {
398         return true;
399     }
400
401     // -------------------- General Utils --------------------
402

403     protected String JavaDoc getAbsoluteDocBase(Context context) {
404         // Calculate the absolute path of the document base
405
String JavaDoc docBase = context.getServletContext().getRealPath("/");
406         docBase = docBase.substring(0,docBase.length()-1);
407         if (!isAbsolute(docBase)){
408             docBase = tomcatHome + "/" + docBase;
409         }
410         docBase = patch(docBase);
411         return docBase;
412     }
413
414     // ------------------ Grabbed from FileUtil -----------------
415
public static File JavaDoc getConfigFile( File JavaDoc base, File JavaDoc configDir, String JavaDoc defaultF )
416     {
417         if( base==null )
418             base=new File JavaDoc( defaultF );
419         if( ! base.isAbsolute() ) {
420             if( configDir != null )
421                 base=new File JavaDoc( configDir, base.getPath());
422             else
423                 base=new File JavaDoc( base.getAbsolutePath()); //??
424
}
425         File JavaDoc parent=new File JavaDoc(base.getParent());
426         if(!parent.exists()){
427             if(!parent.mkdirs()){
428                 throw new RuntimeException JavaDoc(
429                     "Unable to create path to config file :"+
430                     base.getAbsolutePath());
431             }
432         }
433         return base;
434     }
435
436     public static String JavaDoc patch(String JavaDoc path) {
437         String JavaDoc patchPath = path;
438
439         // Move drive spec to the front of the path
440
if (patchPath.length() >= 3 &&
441             patchPath.charAt(0) == '/' &&
442             Character.isLetter(patchPath.charAt(1)) &&
443             patchPath.charAt(2) == ':') {
444             patchPath=patchPath.substring(1,3)+"/"+patchPath.substring(3);
445         }
446
447         // Eliminate consecutive slashes after the drive spec
448
if (patchPath.length() >= 2 &&
449             Character.isLetter(patchPath.charAt(0)) &&
450             patchPath.charAt(1) == ':') {
451             char[] ca = patchPath.replace('/', '\\').toCharArray();
452             char c;
453             StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
454
455             for (int i = 0; i < ca.length; i++) {
456                 if ((ca[i] != '\\') ||
457                     (ca[i] == '\\' &&
458                         i > 0 &&
459                         ca[i - 1] != '\\')) {
460                     if (i == 0 &&
461                         Character.isLetter(ca[i]) &&
462                         i < ca.length - 1 &&
463                         ca[i + 1] == ':') {
464                         c = Character.toUpperCase(ca[i]);
465                     } else {
466                         c = ca[i];
467                     }
468
469                     sb.append(c);
470                 }
471             }
472
473             patchPath = sb.toString();
474         }
475
476         // fix path on NetWare - all '/' become '\\' and remove duplicate '\\'
477
if (System.getProperty("os.name").startsWith("NetWare") &&
478             path.length() >=3 &&
479             path.indexOf(':') > 0) {
480             char[] ca = patchPath.replace('/', '\\').toCharArray();
481             StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
482
483             for (int i = 0; i < ca.length; i++) {
484                 if ((ca[i] != '\\') ||
485                     (ca[i] == '\\' && i > 0 && ca[i - 1] != '\\')) {
486                     sb.append(ca[i]);
487                 }
488             }
489             patchPath = sb.toString();
490         }
491
492         return patchPath;
493     }
494
495     public static boolean isAbsolute( String JavaDoc path ) {
496         // normal file
497
if( path.startsWith("/" ) ) return true;
498
499         if( path.startsWith(File.separator ) ) return true;
500
501         // win c:
502
if (path.length() >= 3 &&
503             Character.isLetter(path.charAt(0)) &&
504             path.charAt(1) == ':')
505             return true;
506
507         // NetWare volume:
508
if (System.getProperty("os.name").startsWith("NetWare") &&
509             path.length() >=3 &&
510             path.indexOf(':') > 0)
511             return true;
512
513         return false;
514     }
515 }
516
Popular Tags