001: /*
002: * Copyright 1999-2001,2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.catalina.startup;
018:
019: import java.lang.reflect.Constructor;
020:
021: import org.apache.catalina.Container;
022: import org.apache.catalina.Loader;
023: import org.apache.commons.digester.Digester;
024: import org.apache.commons.digester.Rule;
025: import org.apache.commons.digester.RuleSetBase;
026: import org.xml.sax.Attributes;
027:
028: /**
029: * <p><strong>RuleSet</strong> for processing the contents of a
030: * Context or DefaultContext definition element. To enable parsing of a
031: * DefaultContext, be sure to specify a prefix that ends with "/Default".</p>
032: *
033: * @author Craig R. McClanahan
034: * @version $Revision: 1.7 $ $Date: 2004/02/27 14:58:48 $
035: */
036:
037: public class ContextRuleSet extends RuleSetBase {
038:
039: // ----------------------------------------------------- Instance Variables
040:
041: /**
042: * The matching pattern prefix to use for recognizing our elements.
043: */
044: protected String prefix = null;
045:
046: // ------------------------------------------------------------ Constructor
047:
048: /**
049: * Construct an instance of this <code>RuleSet</code> with the default
050: * matching pattern prefix.
051: */
052: public ContextRuleSet() {
053:
054: this ("");
055:
056: }
057:
058: /**
059: * Construct an instance of this <code>RuleSet</code> with the specified
060: * matching pattern prefix.
061: *
062: * @param prefix Prefix for matching pattern rules (including the
063: * trailing slash character)
064: */
065: public ContextRuleSet(String prefix) {
066:
067: super ();
068: this .namespaceURI = null;
069: this .prefix = prefix;
070:
071: }
072:
073: // --------------------------------------------------------- Public Methods
074:
075: /**
076: * <p>Add the set of Rule instances defined in this RuleSet to the
077: * specified <code>Digester</code> instance, associating them with
078: * our namespace URI (if any). This method should only be called
079: * by a Digester instance.</p>
080: *
081: * @param digester Digester instance to which the new Rule instances
082: * should be added.
083: */
084: public void addRuleInstances(Digester digester) {
085:
086: if (!isDefaultContext()) {
087: digester.addObjectCreate(prefix + "Context",
088: "org.apache.catalina.core.StandardContext",
089: "className");
090: } else {
091: digester.addObjectCreate(prefix + "Context",
092: "org.apache.catalina.core.StandardDefaultContext",
093: "className");
094: }
095: digester.addSetProperties(prefix + "Context");
096: if (!isDefaultContext()) {
097: digester.addRule(prefix + "Context",
098: new CopyParentClassLoaderRule());
099: digester
100: .addRule(
101: prefix + "Context",
102: new LifecycleListenerRule(
103: "org.apache.catalina.startup.ContextConfig",
104: "configClass"));
105: digester.addRule(prefix + "Context", new SetDocBaseRule());
106: digester.addSetNext(prefix + "Context", "addChild",
107: "org.apache.catalina.Container");
108: } else {
109: digester.addSetNext(prefix + "Context",
110: "addDefaultContext",
111: "org.apache.catalina.DefaultContext");
112: }
113:
114: digester.addCallMethod(prefix + "Context/InstanceListener",
115: "addInstanceListener", 0);
116:
117: digester.addObjectCreate(prefix + "Context/Listener", null, // MUST be specified in the element
118: "className");
119: digester.addSetProperties(prefix + "Context/Listener");
120: digester.addSetNext(prefix + "Context/Listener",
121: "addLifecycleListener",
122: "org.apache.catalina.LifecycleListener");
123:
124: digester.addRule(prefix + "Context/Loader",
125: new CreateLoaderRule(
126: "org.apache.catalina.loader.WebappLoader",
127: "className"));
128: digester.addSetProperties(prefix + "Context/Loader");
129: digester.addSetNext(prefix + "Context/Loader", "setLoader",
130: "org.apache.catalina.Loader");
131:
132: digester.addObjectCreate(prefix + "Context/Logger", null, // MUST be specified in the element
133: "className");
134: digester.addSetProperties(prefix + "Context/Logger");
135: digester.addSetNext(prefix + "Context/Logger", "setLogger",
136: "org.apache.catalina.Logger");
137:
138: digester.addObjectCreate(prefix + "Context/Manager",
139: "org.apache.catalina.session.StandardManager",
140: "className");
141: digester.addSetProperties(prefix + "Context/Manager");
142: digester.addSetNext(prefix + "Context/Manager", "setManager",
143: "org.apache.catalina.Manager");
144:
145: digester.addObjectCreate(prefix + "Context/Manager/Store",
146: null, // MUST be specified in the element
147: "className");
148: digester.addSetProperties(prefix + "Context/Manager/Store");
149: digester.addSetNext(prefix + "Context/Manager/Store",
150: "setStore", "org.apache.catalina.Store");
151:
152: digester.addObjectCreate(prefix + "Context/Parameter",
153: "org.apache.catalina.deploy.ApplicationParameter");
154: digester.addSetProperties(prefix + "Context/Parameter");
155: digester.addSetNext(prefix + "Context/Parameter",
156: "addApplicationParameter",
157: "org.apache.catalina.deploy.ApplicationParameter");
158:
159: digester.addObjectCreate(prefix + "Context/Realm", null, // MUST be specified in the element
160: "className");
161: digester.addSetProperties(prefix + "Context/Realm");
162: digester.addSetNext(prefix + "Context/Realm", "setRealm",
163: "org.apache.catalina.Realm");
164:
165: digester.addObjectCreate(prefix + "Context/ResourceLink",
166: "org.apache.catalina.deploy.ContextResourceLink");
167: digester.addSetProperties(prefix + "Context/ResourceLink");
168: digester.addSetNext(prefix + "Context/ResourceLink",
169: "addResourceLink",
170: "org.apache.catalina.deploy.ContextResourceLink");
171:
172: digester.addObjectCreate(prefix + "Context/Resources",
173: "org.apache.naming.resources.FileDirContext",
174: "className");
175: digester.addSetProperties(prefix + "Context/Resources");
176: digester.addSetNext(prefix + "Context/Resources",
177: "setResources", "javax.naming.directory.DirContext");
178:
179: digester.addObjectCreate(prefix + "Context/Valve", null, // MUST be specified in the element
180: "className");
181: digester.addSetProperties(prefix + "Context/Valve");
182: digester.addSetNext(prefix + "Context/Valve", "addValve",
183: "org.apache.catalina.Valve");
184:
185: digester.addCallMethod(prefix + "Context/WrapperLifecycle",
186: "addWrapperLifecycle", 0);
187:
188: digester.addCallMethod(prefix + "Context/WrapperListener",
189: "addWrapperListener", 0);
190:
191: }
192:
193: // ------------------------------------------------------ Protected Methods
194:
195: /**
196: * Are we processing a DefaultContext element?
197: */
198: protected boolean isDefaultContext() {
199:
200: return (prefix.endsWith("/Default"));
201:
202: }
203:
204: }
205:
206: // ----------------------------------------------------------- Private Classes
207:
208: /**
209: * Rule that creates a new <code>Loader</code> instance, with the parent
210: * class loader associated with the top object on the stack (which must be
211: * a <code>Container</code>), and pushes it on to the stack.
212: */
213:
214: final class CreateLoaderRule extends Rule {
215:
216: public CreateLoaderRule(String loaderClass, String attributeName) {
217:
218: this .loaderClass = loaderClass;
219: this .attributeName = attributeName;
220:
221: }
222:
223: private String attributeName;
224:
225: private String loaderClass;
226:
227: public void begin(String namespace, String name,
228: Attributes attributes) throws Exception {
229:
230: // Look up the required parent class loader
231: ClassLoader parentClassLoader = null;
232: Object ojb = digester.peek();
233: if (ojb instanceof Container) {
234: parentClassLoader = ((Container) ojb)
235: .getParentClassLoader();
236: }
237:
238: // Instantiate a new Loader implementation object
239: String className = loaderClass;
240: if (attributeName != null) {
241: String value = attributes.getValue(attributeName);
242: if (value != null)
243: className = value;
244: }
245: Class clazz = Class.forName(className);
246: Class types[] = { ClassLoader.class };
247: Object args[] = { parentClassLoader };
248: Constructor constructor = clazz.getDeclaredConstructor(types);
249: Loader loader = (Loader) constructor.newInstance(args);
250:
251: // Push the new loader onto the stack
252: digester.push(loader);
253: if (digester.getLogger().isDebugEnabled())
254: digester.getLogger().debug(
255: "new " + loader.getClass().getName());
256:
257: }
258:
259: public void end(String namespace, String name) throws Exception {
260:
261: Loader loader = (Loader) digester.pop();
262: if (digester.getLogger().isDebugEnabled())
263: digester.getLogger().debug(
264: "pop " + loader.getClass().getName());
265:
266: }
267:
268: }
|