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