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

17 package org.apache.catalina;
18
19 import java.beans.PropertyChangeListener;
20 import java.io.File;
21
22 import javax.management.ObjectName;
23
24 import org.apache.catalina.connector.Request;
25 import org.apache.catalina.connector.Response;
26 import org.apache.juli.logging.Log;
27
28
29 /**
30  * A <b>Container</b> is an object that can execute requests received from
31  * a client, and return responses based on those requests.  A Container may
32  * optionally support a pipeline of Valves that process the request in an
33  * order configured at runtime, by implementing the <b>Pipeline</b> interface
34  * as well.
35  * <p>
36  * Containers will exist at several conceptual levels within Catalina.  The
37  * following examples represent common cases:
38  * <ul>
39  * <li><b>Engine</b> - Representation of the entire Catalina servlet engine,
40  *     most likely containing one or more subcontainers that are either Host
41  *     or Context implementations, or other custom groups.
42  * <li><b>Host</b> - Representation of a virtual host containing a number
43  *     of Contexts.
44  * <li><b>Context</b> - Representation of a single ServletContext, which will
45  *     typically contain one or more Wrappers for the supported servlets.
46  * <li><b>Wrapper</b> - Representation of an individual servlet definition
47  *     (which may support multiple servlet instances if the servlet itself
48  *     implements SingleThreadModel).
49  * </ul>
50  * A given deployment of Catalina need not include Containers at all of the
51  * levels described above.  For example, an administration application
52  * embedded within a network device (such as a router) might only contain
53  * a single Context and a few Wrappers, or even a single Wrapper if the
54  * application is relatively small.  Therefore, Container implementations
55  * need to be designed so that they will operate correctly in the absence
56  * of parent Containers in a given deployment.
57  * <p>
58  * A Container may also be associated with a number of support components
59  * that provide functionality which might be shared (by attaching it to a
60  * parent Container) or individually customized.  The following support
61  * components are currently recognized:
62  * <ul>
63  * <li><b>Loader</b> - Class loader to use for integrating new Java classes
64  *     for this Container into the JVM in which Catalina is running.
65  * <li><b>Logger</b> - Implementation of the <code>log()</code> method
66  *     signatures of the <code>ServletContext</code> interface.
67  * <li><b>Manager</b> - Manager for the pool of Sessions associated with
68  *     this Container.
69  * <li><b>Realm</b> - Read-only interface to a security domain, for
70  *     authenticating user identities and their corresponding roles.
71  * <li><b>Resources</b> - JNDI directory context enabling access to static
72  *     resources, enabling custom linkages to existing server components when
73  *     Catalina is embedded in a larger server.
74  * </ul>
75  *
76  * @author Craig R. McClanahan
77  * @author Remy Maucherat
78  */

79 public interface Container extends Lifecycle {
80
81
82     // ----------------------------------------------------- Manifest Constants
83
84
85     /**
86      * The ContainerEvent event type sent when a child container is added
87      * by <code>addChild()</code>.
88      */

89     public static final String ADD_CHILD_EVENT = "addChild";
90
91
92     /**
93      * The ContainerEvent event type sent when a valve is added
94      * by <code>addValve()</code>, if this Container supports pipelines.
95      */

96     public static final String ADD_VALVE_EVENT = "addValve";
97
98
99     /**
100      * The ContainerEvent event type sent when a child container is removed
101      * by <code>removeChild()</code>.
102      */

103     public static final String REMOVE_CHILD_EVENT = "removeChild";
104
105
106     /**
107      * The ContainerEvent event type sent when a valve is removed
108      * by <code>removeValve()</code>, if this Container supports pipelines.
109      */

110     public static final String REMOVE_VALVE_EVENT = "removeValve";
111
112
113     // ------------------------------------------------------------- Properties
114
115     /**
116      * Obtain the log to which events for this container should be logged.
117      *
118      * @return The Logger with which this Container is associated.  If there is
119      *         no associated Logger, return the Logger associated with the
120      *         parent Container (if any); otherwise return <code>null</code>.
121      */

122     public Log getLogger();
123
124
125     /**
126      * Return the logger name that the container will use.
127      * @return the abbreviated name of this container for logging messages
128      */

129     public String getLogName();
130
131
132     /**
133      * Obtain the JMX name for this container.
134      *
135      * @return the JMX name associated with this container.
136      */

137     public ObjectName getObjectName();
138
139
140     /**
141      * Obtain the JMX domain under which this container will be / has been
142      * registered.
143      *
144      * @return The JMX domain name
145      */

146     public String getDomain();
147
148
149     /**
150      * Calculate the key properties string to be added to an object's
151      * {@link ObjectName} to indicate that it is associated with this container.
152      *
153      * @return          A string suitable for appending to the ObjectName
154      *
155      */

156     public String getMBeanKeyProperties();
157
158
159     /**
160      * Return the Pipeline object that manages the Valves associated with
161      * this Container.
162      *
163      * @return The Pipeline
164      */

165     public Pipeline getPipeline();
166
167
168     /**
169      * Get the Cluster for this container.
170      *
171      * @return The Cluster with which this Container is associated. If there is
172      *         no associated Cluster, return the Cluster associated with our
173      *         parent Container (if any); otherwise return <code>null</code>.
174      */

175     public Cluster getCluster();
176
177
178     /**
179      * Set the Cluster with which this Container is associated.
180      *
181      * @param cluster the Cluster with which this Container is associated.
182      */

183     public void setCluster(Cluster cluster);
184
185
186     /**
187      * Get the delay between the invocation of the backgroundProcess method on
188      * this container and its children. Child containers will not be invoked if
189      * their delay value is positive (which would mean they are using their own
190      * thread). Setting this to a positive value will cause a thread to be
191      * spawned. After waiting the specified amount of time, the thread will
192      * invoke the {@link #backgroundProcess()} method on this container and all
193      * children with non-positive delay values.
194      *
195      * @return The delay between the invocation of the backgroundProcess method
196      *         on this container and its children. A non-positive value
197      *         indicates that background processing will be managed by the
198      *         parent.
199      */

200     public int getBackgroundProcessorDelay();
201
202
203     /**
204      * Set the delay between the invocation of the execute method on this
205      * container and its children.
206      *
207      * @param delay The delay in seconds between the invocation of
208      *              backgroundProcess methods
209      */

210     public void setBackgroundProcessorDelay(int delay);
211
212
213     /**
214      * Return a name string (suitable for use by humans) that describes this
215      * Container.  Within the set of child containers belonging to a particular
216      * parent, Container names must be unique.
217      *
218      * @return The human readable name of this container.
219      */

220     public String getName();
221
222
223     /**
224      * Set a name string (suitable for use by humans) that describes this
225      * Container.  Within the set of child containers belonging to a particular
226      * parent, Container names must be unique.
227      *
228      * @param name New name of this container
229      *
230      * @exception IllegalStateException if this Container has already been
231      *  added to the children of a parent Container (after which the name
232      *  may not be changed)
233      */

234     public void setName(String name);
235
236
237     /**
238      * Get the parent container.
239      *
240      * @return Return the Container for which this Container is a child, if
241      *         there is one. If there is no defined parent, return
242      *         <code>null</code>.
243      */

244     public Container getParent();
245
246
247     /**
248      * Set the parent Container to which this Container is being added as a
249      * child.  This Container may refuse to become attached to the specified
250      * Container by throwing an exception.
251      *
252      * @param container Container to which this Container is being added
253      *  as a child
254      *
255      * @exception IllegalArgumentException if this Container refuses to become
256      *  attached to the specified Container
257      */

258     public void setParent(Container container);
259
260
261     /**
262      * Get the parent class loader.
263      *
264      * @return the parent class loader for this component. If not set, return
265      *         {@link #getParent()}.{@link #getParentClassLoader()}. If no
266      *         parent has been set, return the system class loader.
267      */

268     public ClassLoader getParentClassLoader();
269
270
271     /**
272      * Set the parent class loader for this component. For {@link Context}s
273      * this call is meaningful only <strong>before</strong> a Loader has
274      * been configured, and the specified value (if non-null) should be
275      * passed as an argument to the class loader constructor.
276      *
277      * @param parent The new parent class loader
278      */

279     public void setParentClassLoader(ClassLoader parent);
280
281
282     /**
283      * Obtain the Realm with which this Container is associated.
284      *
285      * @return The associated Realm; if there is no associated Realm, the
286      *         Realm associated with the parent Container (if any); otherwise
287      *         return <code>null</code>.
288      */

289     public Realm getRealm();
290
291
292     /**
293      * Set the Realm with which this Container is associated.
294      *
295      * @param realm The newly associated Realm
296      */

297     public void setRealm(Realm realm);
298
299
300     /**
301      * Find the configuration path where a configuration resource
302      * is located.
303      * @param container The container
304      * @param resourceName The resource file name
305      * @return the configuration path
306      */

307     public static String getConfigPath(Container container, String resourceName) {
308         StringBuffer result = new StringBuffer();
309         Container host = null;
310         Container engine = null;
311         while (container != null) {
312             if (container instanceof Host) {
313                 host = container;
314             } else if (container instanceof Engine) {
315                 engine = container;
316             }
317             container = container.getParent();
318         }
319         if (host != null && ((Host) host).getXmlBase() != null) {
320             result.append(((Host) host).getXmlBase()).append('/');
321         } else {
322             result.append("conf/");
323             if (engine != null) {
324                 result.append(engine.getName()).append('/');
325             }
326             if (host != null) {
327                 result.append(host.getName()).append('/');
328             }
329         }
330         result.append(resourceName);
331         return result.toString();
332     }
333
334
335     /**
336      * Return the Service to which this container belongs.
337      * @param container The container to start from
338      * @return the Service, or null if not found
339      */

340     public static Service getService(Container container) {
341         while (container != null && !(container instanceof Engine)) {
342             container = container.getParent();
343         }
344         if (container == null) {
345             return null;
346         }
347         return ((Engine) container).getService();
348     }
349
350
351     // --------------------------------------------------------- Public Methods
352
353
354     /**
355      * Execute a periodic task, such as reloading, etc. This method will be
356      * invoked inside the classloading context of this container. Unexpected
357      * throwables will be caught and logged.
358      */

359     public void backgroundProcess();
360
361
362     /**
363      * Add a new child Container to those associated with this Container,
364      * if supported.  Prior to adding this Container to the set of children,
365      * the child's <code>setParent()</code> method must be called, with this
366      * Container as an argument.  This method may thrown an
367      * <code>IllegalArgumentException</code> if this Container chooses not
368      * to be attached to the specified Container, in which case it is not added
369      *
370      * @param child New child Container to be added
371      *
372      * @exception IllegalArgumentException if this exception is thrown by
373      *  the <code>setParent()</code> method of the child Container
374      * @exception IllegalArgumentException if the new child does not have
375      *  a name unique from that of existing children of this Container
376      * @exception IllegalStateException if this Container does not support
377      *  child Containers
378      */

379     public void addChild(Container child);
380
381
382     /**
383      * Add a container event listener to this component.
384      *
385      * @param listener The listener to add
386      */

387     public void addContainerListener(ContainerListener listener);
388
389
390     /**
391      * Add a property change listener to this component.
392      *
393      * @param listener The listener to add
394      */

395     public void addPropertyChangeListener(PropertyChangeListener listener);
396
397
398     /**
399      * Obtain a child Container by name.
400      *
401      * @param name Name of the child Container to be retrieved
402      *
403      * @return The child Container with the given name or <code>null</code> if
404      *         no such child exists.
405      */

406     public Container findChild(String name);
407
408
409     /**
410      * Obtain the child Containers associated with this Container.
411      *
412      * @return An array containing all children of this container. If this
413      *         Container has no children, a zero-length array is returned.
414      */

415     public Container[] findChildren();
416
417
418     /**
419      * Obtain the container listeners associated with this Container.
420      *
421      * @return An array containing the container listeners associated with this
422      *         Container. If this Container has no registered container
423      *         listeners, a zero-length array is returned.
424      */

425     public ContainerListener[] findContainerListeners();
426
427
428     /**
429      * Remove an existing child Container from association with this parent
430      * Container.
431      *
432      * @param child Existing child Container to be removed
433      */

434     public void removeChild(Container child);
435
436
437     /**
438      * Remove a container event listener from this component.
439      *
440      * @param listener The listener to remove
441      */

442     public void removeContainerListener(ContainerListener listener);
443
444
445     /**
446      * Remove a property change listener from this component.
447      *
448      * @param listener The listener to remove
449      */

450     public void removePropertyChangeListener(PropertyChangeListener listener);
451
452
453     /**
454      * Notify all container event listeners that a particular event has
455      * occurred for this Container.  The default implementation performs
456      * this notification synchronously using the calling thread.
457      *
458      * @param type Event type
459      * @param data Event data
460      */

461     public void fireContainerEvent(String type, Object data);
462
463
464     /**
465      * Log a request/response that was destined for this container but has been
466      * handled earlier in the processing chain so that the request/response
467      * still appears in the correct access logs.
468      * @param request       Request (associated with the response) to log
469      * @param response      Response (associated with the request) to log
470      * @param time          Time taken to process the request/response in
471      *                      milliseconds (use 0 if not known)
472      * @param   useDefault  Flag that indicates that the request/response should
473      *                      be logged in the engine's default access log
474      */

475     public void logAccess(Request request, Response response, long time,
476             boolean useDefault);
477
478
479     /**
480      * Obtain the AccessLog to use to log a request/response that is destined
481      * for this container. This is typically used when the request/response was
482      * handled (and rejected) earlier in the processing chain so that the
483      * request/response still appears in the correct access logs.
484      *
485      * @return The AccessLog to use for a request/response destined for this
486      *         container
487      */

488     public AccessLog getAccessLog();
489
490
491     /**
492      * Obtain the number of threads available for starting and stopping any
493      * children associated with this container. This allows start/stop calls to
494      * children to be processed in parallel.
495      *
496      * @return The currently configured number of threads used to start/stop
497      *         children associated with this container
498      */

499     public int getStartStopThreads();
500
501
502     /**
503      * Sets the number of threads available for starting and stopping any
504      * children associated with this container. This allows start/stop calls to
505      * children to be processed in parallel.
506      * @param   startStopThreads    The new number of threads to be used
507      */

508     public void setStartStopThreads(int startStopThreads);
509
510
511     /**
512      * Obtain the location of CATALINA_BASE.
513      *
514      * @return  The location of CATALINA_BASE.
515      */

516     public File getCatalinaBase();
517
518
519     /**
520      * Obtain the location of CATALINA_HOME.
521      *
522      * @return The location of CATALINA_HOME.
523      */

524     public File getCatalinaHome();
525 }
526