Source Code Cross Referenced for MMBaseServlet.java in  » Database-ORM » MMBase » org » mmbase » servlet » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database ORM » MMBase » org.mmbase.servlet 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:
003:        This software is OSI Certified Open Source Software.
004:        OSI Certified is a certification mark of the Open Source Initiative.
005:
006:        The license (Mozilla version 1.0) can be read at the MMBase site.
007:        See http://www.MMBase.org/license
008:
009:         */
010:        package org.mmbase.servlet;
011:
012:        import org.mmbase.module.Module;
013:        import org.mmbase.module.core.MMBase;
014:        import org.mmbase.module.core.MMBaseContext;
015:
016:        import javax.servlet.ServletContext;
017:        import javax.servlet.ServletException;
018:
019:        import javax.servlet.http.HttpServlet;
020:        import javax.servlet.http.HttpServletRequest;
021:        import javax.servlet.http.HttpServletResponse;
022:
023:        import java.io.IOException;
024:        import java.io.PrintWriter;
025:
026:        import java.util.*;
027:
028:        import org.w3c.dom.*;
029:        import org.xml.sax.InputSource;
030:        import org.mmbase.util.logging.Logging;
031:        import org.mmbase.util.logging.Logger;
032:        import org.mmbase.util.xml.DocumentReader;
033:
034:        /**
035:         * MMBaseServlet is a base class for other MMBase servlets (like ImageServlet). Its main goal is to
036:         * store a MMBase instance for all its descendants, but it can also be used as a serlvet itself, to
037:         * show MMBase version information.
038:         *
039:         * @version $Id: MMBaseServlet.java,v 1.71 2007/11/28 17:10:04 michiel Exp $
040:         * @author Michiel Meeuwissen
041:         * @since  MMBase-1.6
042:         */
043:        public class MMBaseServlet extends HttpServlet implements  MMBaseStarter {
044:
045:            private static final Logger log = Logging
046:                    .getLoggerInstance(MMBaseServlet.class);
047:            /**
048:             * MMBase reference. While null, servlet does not accept request.
049:             */
050:            protected MMBase mmbase = null;
051:            // private   static String context;
052:
053:            // ----------------
054:            // members needed for refcount functionality.
055:
056:            /**
057:             * To keep track of the currently running servlets, you can use this logger.
058:             *
059:             */
060:            private static final Logger servletsLog = Logging
061:                    .getLoggerInstance("org.mmbase.SERVLETS");
062:
063:            private static int servletCount; // Number of running servlets
064:            /**
065:             *  Lock to sync add and remove of threads
066:             */
067:            private static final Object servletCountLock = new Object();
068:            /**
069:             * Map containing currently running servlets
070:             */
071:            private static Map<MMBaseServlet, ServletReferenceCount> runningServlets = new HashMap<MMBaseServlet, ServletReferenceCount>();
072:            /**
073:             * Toggle to print running servlets to log.
074:             * @javadoc Not clear, I don't understand it.
075:             */
076:            private static int printCount;
077:
078:            private static int servletInstanceCount = 0;
079:            // servletname -> servletmapping
080:            // obtained from web.xml
081:            private static Map<String, List<String>> servletMappings = new HashMap<String, List<String>>();
082:            // topic -> servletname
083:            // set by isntantiated servlets
084:            private static Map<String, ServletEntry> associatedServlets = new HashMap<String, ServletEntry>();
085:            // topic -> servletmapping
086:            // set by instantiated servlets
087:            private static Map<String, ServletEntry> associatedServletMappings = new HashMap<String, ServletEntry>();
088:            // mapping to servlet instance
089:            private static Map<String, HttpServlet> mapToServlet = new HashMap<String, HttpServlet>();
090:
091:            private long start = System.currentTimeMillis();
092:
093:            /**
094:             * Boolean indicating whether MMBase has been started. Used by {@link #checkInited}, set to true {@link #by setMMBase}.
095:             * @since MMBase-1.7
096:             */
097:            private static boolean mmbaseInited = false;
098:
099:            /**
100:             * If MMBase has not been started, a 503 is given, with this value for the 'Retry-After' header.
101:             * See <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.4">rfc 2616, section 10.5.4</a>.
102:             * Defaults to 60 seconds, can be configured in web.xml with the 'retry-after' propery on the servlets.
103:             * @since MMBase-1.7.2
104:             */
105:            protected int retryAfter = 60;
106:
107:            /**
108:             * Thread starting MMBase
109:             */
110:            private Thread initThread;
111:
112:            /**
113:             * On default, servlets are not associated with any function.
114:             *
115:             * This function is called in the init method.
116:             *
117:             * @return A map of Strings (function) -> Integer (priority). Never null.
118:             */
119:
120:            protected Map<String, Integer> getAssociations() {
121:                return new HashMap<String, Integer>();
122:            }
123:
124:            /**
125:             * Used in association map
126:             */
127:            private static class ServletEntry {
128:                ServletEntry(String n) {
129:                    this (n, null);
130:                }
131:
132:                ServletEntry(String n, Integer p) {
133:                    name = n;
134:                    if (p == null) {
135:                        priority = 0;
136:                    } else {
137:                        priority = p.intValue();
138:                    }
139:                }
140:
141:                String name;
142:                int priority;
143:            }
144:
145:            /**
146:             * Returns the MMBase instance.
147:             * @since MMBase-1.7
148:             */
149:            public MMBase getMMBase() {
150:                return mmbase;
151:            }
152:
153:            /**
154:             * Sets the mmbase member. Can be overriden to implement extra initalization for the servlet which needs a running MMBase.
155:             * @since MMBase-1.7
156:             */
157:            public void setMMBase(MMBase mmb) {
158:                Calendar cal = Calendar.getInstance();
159:                cal.setTime(new java.util.Date(System.currentTimeMillis()
160:                        - start));
161:                if (!mmbaseInited) {
162:                    log
163:                            .info("MMBase servlets are ready to receive requests, started in "
164:                                    + cal.get(Calendar.MINUTE)
165:                                    + " min "
166:                                    + cal.get(Calendar.SECOND) + " sec.");
167:                }
168:
169:                mmbase = mmb;
170:                mmbaseInited = true;
171:                initThread = null;
172:            }
173:
174:            /**
175:             * Used in checkInited.
176:             */
177:            private static ServletException initException = null;
178:
179:            /**
180:             * Called by MMBaseStartThread, if something went wrong during
181:             * initialization of MMBase. It will be thrown by checkInited
182:             * then.
183:             * @since MMBase-1.7
184:             */
185:            public void setInitException(ServletException e) {
186:                initException = e;
187:            }
188:
189:            /**
190:             * The init of an MMBaseServlet checks if MMBase is running. It not then it is started.
191:             */
192:            public void init() throws ServletException {
193:
194:                ServletContext servletContext = getServletConfig()
195:                        .getServletContext();
196:
197:                String retryAfterParameter = servletContext
198:                        .getInitParameter("retry-after");
199:                if (retryAfterParameter == null) {
200:                    // default: one minute
201:                    retryAfter = 60;
202:                } else {
203:                    retryAfter = Integer.valueOf(retryAfterParameter);
204:                }
205:
206:                if (!MMBaseContext.isInitialized()) {
207:                    MMBaseContext.init(servletContext);
208:                    MMBaseContext.initHtmlRoot();
209:                }
210:
211:                log.info("Init of servlet " + getServletName() + ".");
212:                boolean initialize = false;
213:                // for retrieving servletmappings, determine status
214:                synchronized (servletMappings) {
215:                    initialize = (servletInstanceCount == 0);
216:                    servletInstanceCount++;
217:                }
218:                if (initialize) {
219:                    // used to determine the accurate way to access a servlet
220:                    try {
221:
222:                        MMBaseContext.initHtmlRoot();
223:                        // get config and do stuff.
224:                        java.net.URL url;
225:                        try {
226:                            url = getServletConfig().getServletContext()
227:                                    .getResource("/WEB-INF/web.xml");
228:                        } catch (NoSuchMethodError nsme) {
229:                            // for old app-servers.
230:                            log.error(nsme);
231:                            url = (new java.io.File(getServletConfig()
232:                                    .getServletContext().getRealPath(
233:                                            "/WEB-INF/web.xml"))).toURL();
234:                        }
235:                        if (url == null) {
236:                            log.warn("No web.xml found");
237:                        } else {
238:                            InputSource path = new InputSource(url.openStream());
239:                            log.service("Reading servlet mappings from " + url);
240:                            DocumentReader webDotXml = new DocumentReader(path,
241:                                    false);
242:
243:                            for (Element mapping : webDotXml.getChildElements(
244:                                    "web-app", "servlet-mapping")) {
245:                                Element servName = webDotXml
246:                                        .getElementByPath(mapping,
247:                                                "servlet-mapping.servlet-name");
248:                                String name = webDotXml
249:                                        .getElementValue(servName);
250:                                if (!(name.equals(""))) {
251:                                    Element urlPattern = webDotXml
252:                                            .getElementByPath(mapping,
253:                                                    "servlet-mapping.url-pattern");
254:                                    String pattern = webDotXml
255:                                            .getElementValue(urlPattern);
256:                                    if (!(pattern.equals(""))) {
257:                                        List<String> ls = servletMappings
258:                                                .get(name);
259:                                        if (ls == null) {
260:                                            ls = new ArrayList<String>();
261:                                            servletMappings.put(name, ls);
262:                                        }
263:                                        ls.add(pattern);
264:                                    }
265:                                }
266:                            }
267:                        }
268:                    } catch (Exception e) {
269:                        log.error(e.getMessage(), e);
270:                    }
271:                    log.debug("Loaded servlet mappings");
272:                }
273:                log.debug("Associating this servlet with functions");
274:                for (Map.Entry<String, Integer> e : getAssociations()
275:                        .entrySet()) {
276:                    associate(e.getKey(), getServletName(), e.getValue());
277:                }
278:                log.debug("Associating this servlet with mappings");
279:                for (String mapping : getServletMappings(getServletConfig()
280:                        .getServletName())) {
281:                    mapToServlet.put(mapping, this );
282:                }
283:
284:                String hold = servletContext.getInitParameter("stall-server");
285:                if ("yes".equals(hold) || "true".equals(hold)) {
286:                    log.service(getServletName()
287:                            + ": Waiting until MMBase is started");
288:                    Runnable starter = new MMBaseStartThread.Job(this );
289:                    starter.run();
290:                    log.service(getServletName()
291:                            + ": Ready to receive requests.");
292:                } else {
293:                    // stuff that can take indefinite amount of time (database down and so on) is done in separate thread
294:                    initThread = new MMBaseStartThread(this );
295:                    initThread.start();
296:                }
297:            }
298:
299:            /**
300:             * Gets the servlet that belongs to the given mapping
301:             *
302:             * @param mapping the mapping used to access the servlet
303:             * @return the Servlet that handles the mapping
304:             */
305:            public static HttpServlet getServletByMapping(String mapping) {
306:                return mapToServlet.get(mapping);
307:            }
308:
309:            /**
310:             * Gets all the mappings for a given servlet. So, this is a method to obtain info from web.xml.
311:             *
312:             * @param servletName the name of the servlet
313:             * @return an unmodifiable list of servlet mappings for this servlet
314:             */
315:            public static List<String> getServletMappings(String servletName) {
316:                List<String> ls = servletMappings.get(servletName);
317:                if (ls == null) {
318:                    return Collections.emptyList();
319:                } else {
320:                    return Collections.unmodifiableList(ls);
321:                }
322:            }
323:
324:            /**
325:             * Gets all the mappings for a given association.
326:             *
327:             * Use this to find out how to call a servlet to handle a certain
328:             * type of operation or data (i.e 'images', 'attachments').
329:             *
330:             *
331:             * @param function the function that identifies the type of association
332:             * @return an unmodifiable list of servlet mappings associated with the function
333:             */
334:            public static List<String> getServletMappingsByAssociation(
335:                    String function) {
336:                // check if any mappings were explicitly set for this function
337:                // if so, return that list.
338:                ServletEntry mapping = associatedServletMappings.get(function);
339:                if (mapping != null) {
340:                    List<String> mappings = new ArrayList<String>();
341:                    mappings.add(mapping.name);
342:                    return mappings;
343:                }
344:                // otherwise, get the associated servet
345:                String name = getServletByAssociation(function);
346:                if (name != null) {
347:                    return getServletMappings(name);
348:                } else {
349:                    return Collections.emptyList();
350:                }
351:            }
352:
353:            /**
354:             * Gets the name of the servlet that performs actions associated with the
355:             * the given function.
356:             *
357:             * Use this to find a servlet to handle a certain type of
358:             * operation or data (i.e 'imageservlet', 'myimageservlet',
359:             * 'images');
360:             *
361:             * @param function the function that identifies the type of association
362:             * @return the name of the servlet associated with the function, or null if there is none
363:             */
364:            public static String getServletByAssociation(String function) {
365:                ServletEntry e = associatedServlets.get(function);
366:                if (e != null) {
367:                    return e.name;
368:                } else {
369:                    return null;
370:                }
371:            }
372:
373:            /**
374:             * @since MMBase-1.8.5
375:             */
376:            public static String getBasePath(String function) {
377:                List<String> ls = MMBaseServlet
378:                        .getServletMappingsByAssociation(function);
379:                if (ls.size() == 0)
380:                    return null;
381:                String baseUrl = ls.get(0);
382:                int pos = baseUrl.lastIndexOf("*");
383:                if (pos > 0) {
384:                    baseUrl = baseUrl.substring(0, pos);
385:                }
386:                pos = baseUrl.indexOf("*");
387:                if (pos == 0) {
388:                    baseUrl = baseUrl.substring(pos + 1);
389:                }
390:                return baseUrl;
391:            }
392:
393:            /**
394:             * Associate a given servlet with the given function.
395:             * Use this to set a servlet to handle a certain type of operation or data (i.e 'image-processing');
396:             * For now, only one servlet can be registered.
397:             * @param function the function that deidentifies the type of association
398:             * @param servletname name of the servlet to associate with the function
399:             * @param priority priority of this association, the association only occurs if no servlet or servletmapping
400:             *                    with higher priority for the same function is present already
401:             */
402:            private static synchronized void associate(String function,
403:                    String servletName, Integer priority) {
404:                if (priority == null)
405:                    priority = 0;
406:                ServletEntry m = associatedServletMappings.get(function);
407:                if (m != null && (priority.intValue() < m.priority))
408:                    return;
409:                ServletEntry e = associatedServlets.get(function);
410:                if (e != null && (priority.intValue() < e.priority))
411:                    return;
412:                log.service("Associating function '"
413:                        + function
414:                        + "' with servlet name "
415:                        + servletName
416:                        + (e == null ? "" : " (previous assocation was with "
417:                                + e.name + ")")
418:                        + (m == null ? "" : " (previous assocation was with "
419:                                + m.name + ")"));
420:                associatedServlets.put(function, new ServletEntry(servletName,
421:                        priority));
422:                if (m != null) {
423:                    associatedServletMappings.remove(function);
424:                }
425:            }
426:
427:            /**
428:             * Associate a given servletmapping with the given function.
429:             * Use this to set a servletmapping to call for a certain type of operation or data (i.e 'image-processing');
430:             * For now, only one servletmapping can be registered.
431:             * @param function the function that identifies the type of association
432:             * @param servletMapping mapping of the servlet to associate with the function
433:             * @param priority    priority of this association, the association only occurs if no servlet or servletmapping
434:             *                    with higher priority for the same function is present already
435:             */
436:            protected static synchronized void associateMapping(
437:                    String function, String servletMapping, Integer priority) {
438:                if (priority == null)
439:                    priority = 0;
440:                ServletEntry m = associatedServletMappings.get(function);
441:                if (m != null && (priority.intValue() < m.priority))
442:                    return;
443:                ServletEntry e = associatedServlets.get(function);
444:                if (e != null && (priority.intValue() < e.priority))
445:                    return;
446:                log.service("Associating function '"
447:                        + function
448:                        + "' with servlet mapping "
449:                        + servletMapping
450:                        + (e == null ? "" : " (previous assocation was with "
451:                                + e.name + ")")
452:                        + (m == null ? "" : " (previous assocation was with "
453:                                + m.name + ")"));
454:                associatedServletMappings.put(function, new ServletEntry(
455:                        servletMapping, priority));
456:                if (e != null) {
457:                    associatedServlets.remove(function);
458:                }
459:            }
460:
461:            /**
462:             * Serves MMBase version information. This doesn't do much usefull
463:             * yet, but one could image lots of cool stuff here. Any other
464:             * MMBase servlet will probably override this method.
465:             */
466:            protected void doGet(HttpServletRequest req, HttpServletResponse res)
467:                    throws ServletException, IOException {
468:                res.setContentType("text/plain");
469:                PrintWriter pw = res.getWriter();
470:                pw.print(org.mmbase.Version.get());
471:                String q = req.getQueryString();
472:                if ("starttime".equals(q)) {
473:                    res.setHeader("Cache-Control", "no-cache");
474:                    pw.print("\nUp since "
475:                            + new Date((long) MMBase.startTime * 1000));
476:                } else if ("uptime".equals(q)) {
477:                    res.setHeader("Cache-Control", "no-cache");
478:                    int seconds = (int) (System.currentTimeMillis() / 1000)
479:                            - MMBase.startTime;
480:                    int days = seconds / (60 * 60 * 24);
481:                    seconds %= 60 * 60 * 24;
482:                    int hours = seconds / (60 * 60);
483:                    seconds %= 60 * 60;
484:                    int minutes = seconds / 60;
485:                    seconds %= 60;
486:                    pw.print("\nUptime: "
487:                            + (days == 1 ? "1 day" : (days > 1 ? "" + days
488:                                    + " days" : ""))
489:                            + (hours > 0 || days > 0 ? " "
490:                                    + (hours == 1 ? "1 hour" : "" + hours
491:                                            + " hours") : "")
492:                            + (minutes > 0 || hours > 0 ? " "
493:                                    + (minutes == 1 ? "1 minute" : "" + minutes
494:                                            + " minutes") : "")
495:                            + (seconds > 0 || minutes > 0 ? " "
496:                                    + (seconds == 1 ? "1 second" : "" + seconds
497:                                            + " seconds") : ""));
498:
499:                } else if ("server".equals(q)) {
500:                    String appserver = System.getProperty("catalina.base"); // to do: similar arrangment for
501:                    // other ap-servers.
502:                    String root = "" + getServletContext().getResource("/");
503:                    pw.print("\n"
504:                            + getServletContext().getServerInfo()
505:                            + " "
506:                            + System.getProperty("java.version")
507:                            + " ("
508:                            + System.getProperty("java.vendor")
509:                            + ") "
510:                            + (appserver == null ? "" : appserver)
511:                            + "@"
512:                            + java.net.InetAddress.getLocalHost()
513:                                    .getCanonicalHostName() + " "
514:                            + System.getProperty("os.name") + " "
515:                            + System.getProperty("os.version") + " "
516:                            + System.getProperty("os.arch") + "\n" + root);
517:
518:                }
519:                pw.close();
520:            }
521:
522:            /**
523:             * This methods can be (and is) called in the beginning of
524:             * service. It sends an UNAVAILABLE error if MMBase has not bee
525:             * started, or throws an exeption if that was unsuccessful.
526:             * @return A boolean. If false, then service must return immediately (because mmbase has not been inited yet).
527:             * @since MMBase-1.7.2
528:             */
529:            protected boolean checkInited(HttpServletResponse res)
530:                    throws ServletException, IOException {
531:                if (initException != null) {
532:                    throw initException;
533:                }
534:
535:                if (!mmbaseInited) {
536:                    res.setHeader("Retry-After", "" + retryAfter);
537:                    res
538:                            .sendError(
539:                                    HttpServletResponse.SC_SERVICE_UNAVAILABLE,
540:                                    "MMBase not yet, or not successfully initialized (check mmbase log)");
541:                }
542:                return mmbaseInited;
543:            }
544:
545:            /**
546:             * The service method is extended with calls for the refCount
547:             * functionality (for performance related debugging).  So you can
548:             * simply override doGet in extension classes, and this stays
549:             * working, without having to think about it.
550:             */
551:            public void service(HttpServletRequest req, HttpServletResponse res)
552:                    throws ServletException, IOException {
553:                if (!checkInited(res)) {
554:                    return;
555:                }
556:                incRefCount(req);
557:                try {
558:                    super .service(req, res);
559:                } finally { // whatever happens, decrease the refcount:
560:                    decRefCount(req);
561:                }
562:            }
563:
564:            /**
565:             * Returns information about this servlet. Don't forget to override it.
566:             */
567:
568:            public String getServletInfo() {
569:                return "Serves MMBase version information";
570:            }
571:
572:            // ----------------------
573:            // functions needed for refcount functionality.
574:
575:            /**
576:             * Return URI with QueryString appended
577:             * @param req The HttpServletRequest.
578:             */
579:            protected static String getRequestURL(HttpServletRequest req) {
580:                String result = req.getRequestURI();
581:                String queryString = req.getQueryString();
582:                if (queryString != null)
583:                    result += "?" + queryString;
584:                return result;
585:            }
586:
587:            /**
588:             * Decrease the reference count of the servlet
589:             * @param req The HttpServletRequest.
590:             */
591:
592:            protected void decRefCount(HttpServletRequest req) {
593:                if (servletsLog.isDebugEnabled()) {
594:                    String url = getRequestURL(req) + " " + req.getMethod();
595:                    synchronized (servletCountLock) {
596:                        servletCount--;
597:                        ServletReferenceCount s = runningServlets.get(this );
598:                        if (s != null) {
599:                            if (s.refCount == 0) {
600:                                runningServlets.remove(this );
601:                            } else {
602:                                s.refCount--;
603:                                int i = s.uris.indexOf(url);
604:                                if (i >= 0)
605:                                    s.uris.remove(i);
606:                            }
607:
608:                        }// s!=null
609:                    }//sync
610:                }// if (logServlets)
611:            }
612:
613:            /**
614:             * Increase the reference count of the servlet (for debugging)
615:             * and send running servlets to log once every 32 requests
616:             * @param req The HttpServletRequest.
617:             * @scope private
618:             * @bad-constant  31 should be configurable.
619:             */
620:
621:            protected void incRefCount(HttpServletRequest req) {
622:                if (servletsLog.isDebugEnabled()) {
623:                    String url = getRequestURL(req) + " " + req.getMethod();
624:                    int curCount;
625:                    synchronized (servletCountLock) {
626:                        servletCount++;
627:                        curCount = servletCount;
628:                        printCount++;
629:                        ServletReferenceCount s = runningServlets.get(this );
630:                        if (s == null) {
631:                            runningServlets.put(this ,
632:                                    new ServletReferenceCount(url, 0));
633:                        } else {
634:                            s.refCount++;
635:                            s.uris.add(url);
636:                        }
637:                    }// sync
638:
639:                    if ((printCount & 31) == 0) { // Why not (printCount % <configurable number>) == 0?
640:                        if (curCount > 0) {
641:                            synchronized (servletCountLock) {
642:                                servletsLog.debug("Running servlets: "
643:                                        + curCount);
644:                                for (Object element : runningServlets.values())
645:                                    servletsLog.debug(element);
646:                            }
647:
648:                        }// curCount>0
649:                    }
650:                }
651:            }
652:
653:            public void destroy() {
654:                log.info("Servlet " + getServletName()
655:                        + " is taken out of service");
656:                if (initThread != null) {
657:                    initThread.interrupt();
658:                } else {
659:                    log.debug(" " + getServletName() + " was not initialized");
660:                }
661:                log.debug("Disassociating this servlet with mappings");
662:                for (String mapping : getServletMappings(getServletConfig()
663:                        .getServletName())) {
664:                    mapToServlet.remove(mapping);
665:                }
666:                super .destroy();
667:                // for retrieving servletmappings, determine status
668:                synchronized (servletMappings) {
669:
670:                    servletInstanceCount--;
671:                    if (servletInstanceCount == 0) {
672:                        try {
673:                            log.info("Unloaded servlet mappings");
674:                            associatedServlets.clear();
675:                            servletMappings.clear();
676:                            log
677:                                    .info("No MMBase servlets left; modules can be shut down");
678:                            MMBase.getMMBase().shutdown();
679:                            Module.shutdownModules();
680:                        } catch (Throwable t) {
681:                            log.error(t.getMessage(), t);
682:                        }
683:                        try {
684:                            ThreadGroup threads = MMBaseContext
685:                                    .getThreadGroup();
686:                            log.service("Send interrupt to "
687:                                    + threads.activeCount() + " threads in "
688:                                    + threads + " of " + threads.getParent());
689:                            threads.interrupt();
690:                            Thread.yield();
691:                        } catch (Throwable t) {
692:                            log.error(t.getMessage(), t);
693:                        }
694:                        try {
695:                            org.mmbase.util.FileWatcher.shutdown();
696:                        } catch (Throwable t) {
697:                            log.error(t.getMessage(), t);
698:                        }
699:                        try {
700:                            org.mmbase.cache.CacheManager.shutdown();
701:                        } catch (Throwable t) {
702:                            log.error(t.getMessage(), t);
703:                        }
704:                        try {
705:                            Logging.shutdown();
706:                        } catch (Throwable t) {
707:                            System.err.println(t.getMessage());
708:                        }
709:                    }
710:                }
711:            }
712:
713:            /**
714:             * This class maintains current state information for a running servlet.
715:             * It contains a reference count, as well as a list of URI's being handled by the servlet.
716:             */
717:            private class ServletReferenceCount {
718:                /**
719:                 * List of URIs that call the servlet
720:                 */
721:                final List<String> uris = new ArrayList<String>();
722:                /**
723:                 * Nr. of references
724:                 */
725:                int refCount;
726:
727:                /**
728:                 * Create a new ReferenceCountServlet using the jamesServlet
729:                 */
730:                ServletReferenceCount(String uri, int refCount) {
731:                    uris.add(uri);
732:                    this .refCount = refCount;
733:                }
734:
735:                /**
736:                 * Return a description containing servlet info and URI's
737:                 */
738:                public String toString() {
739:                    return "servlet(" + MMBaseServlet.this  + "), refcount("
740:                            + (refCount + 1) + "), uri's(" + uris + ")";
741:                }
742:            }
743:
744:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.