2009/05/20 - Apache Shale has been retired.

For more information, please explore the Attic.

View Javadoc

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  
18  package org.apache.shale.view.faces;
19  
20  import java.util.ArrayList;
21  import java.util.Enumeration;
22  import java.util.Iterator;
23  import java.util.List;
24  import javax.faces.context.FacesContext;
25  import javax.servlet.ServletContextAttributeEvent;
26  import javax.servlet.ServletContextAttributeListener;
27  import javax.servlet.ServletContextEvent;
28  import javax.servlet.ServletContextListener;
29  import javax.servlet.ServletRequest;
30  import javax.servlet.ServletRequestAttributeEvent;
31  import javax.servlet.ServletRequestAttributeListener;
32  import javax.servlet.ServletRequestEvent;
33  import javax.servlet.ServletRequestListener;
34  import javax.servlet.http.HttpSessionActivationListener;
35  import javax.servlet.http.HttpSessionAttributeListener;
36  import javax.servlet.http.HttpSessionBindingEvent;
37  import javax.servlet.http.HttpSessionEvent;
38  import javax.servlet.http.HttpSessionListener;
39  import org.apache.commons.logging.Log;
40  import org.apache.commons.logging.LogFactory;
41  import org.apache.shale.view.AbstractApplicationBean;
42  import org.apache.shale.view.AbstractRequestBean;
43  import org.apache.shale.view.AbstractSessionBean;
44  import org.apache.shale.view.Constants;
45  import org.apache.shale.view.ExceptionHandler;
46  import org.apache.shale.view.ViewController;
47  
48  
49  /***
50   * <p><strong>LifecycleListener</strong> implements the lifecycle startup
51   * and shutdown calls (<code>init()</code> and <code>destroy()</code>) for
52   * subclasses of {@link AbstractApplicationBean}, {@link AbstractRequestBean},
53   * and {@link AbstractSessionBean}.</p>
54   *
55   * <p>It must be registered with the servlet container as a listener,
56   * through an entry in either the <code>/WEB-INF/web.xml</code> resource
57   * or a tag library descriptor included in the web application.</p>
58   *
59   * $Id: LifecycleListener.java 489966 2006-12-24 01:43:42Z craigmcc $
60   *
61   * @since 1.0.3
62   */
63  public class LifecycleListener
64      implements ServletContextAttributeListener,
65                 ServletContextListener,
66                 HttpSessionActivationListener,
67                 HttpSessionAttributeListener,
68                 HttpSessionListener,
69                 ServletRequestAttributeListener,
70                 ServletRequestListener {
71  
72  
73      // ------------------------------------------------------------- Constructor
74  
75  
76      /***
77       * <p>Create a new lifecycle listener.</p>
78       */
79      public LifecycleListener() {
80          if (log.isInfoEnabled()) {
81              log.info("Initializing org.apache.shale.view.faces.LifecycleListener");
82          }
83      }
84  
85  
86      // -------------------------------------------------------- Static Variables
87  
88  
89      /***
90       * <p>The <code>Log</code> instance for this class.</p>
91       */
92      private static final Log log = LogFactory.getLog(LifecycleListener.class);
93  
94  
95      // ------------------------------------------------------ Manifest Constants
96  
97  
98      /***
99       * <p>The fully qualified class name of the <em>Tiger Extensions</em>
100      * verison of this listener class.</p>
101      */
102     private static final String TIGER_LISTENER =
103             "org.apache.shale.tiger.view.faces.LifecycleListener2";
104 
105 
106     // ------------------------------------------------------ Instance Variables
107 
108 
109     /***
110      * <p>The <em>Tiger Extensions</em> implementation of this listener, if
111      * such a class exists in the application classpath.  This value is lazily
112      * instantiated.</p>
113      */
114     private LifecycleListener tiger = null;
115 
116 
117     /***
118      * <p>Flag indicating whether the <code>tiger</code> value has been calculated
119      * already.</p>
120      */
121     private boolean tigerInitialized = false;
122 
123 
124     // ------------------------------------------ ServletContextListener Methods
125 
126 
127     /***
128      * <p>Respond to a context created event.  No special processing
129      * is required.</p>
130      *
131      * @param event Event to be processed
132      */
133     public void contextInitialized(ServletContextEvent event) {
134 
135         // Delegate to the Tiger Extensions instance if it exists
136         LifecycleListener tiger = tiger();
137         if (tiger != null) {
138             tiger.contextInitialized(event);
139         }
140 
141     }
142 
143 
144     /***
145      * <p>Respond to a context destroyed event.  Causes any application
146      * scope attribute that implements {@link AbstractApplicationBean}
147      * to be removed, triggering an <code>attributeRemoved()</code> event.</p>
148      *
149      * @param event Event to be processed
150      */
151     public void contextDestroyed(ServletContextEvent event) {
152 
153         // Delegate to the Tiger Extensions instance if it exists
154         LifecycleListener tiger = tiger();
155         if (tiger != null) {
156             tiger.contextDestroyed(event);
157         }
158 
159         // Remove any AbstractApplicationBean attributes, which will
160         // trigger an attributeRemoved event
161         List list = new ArrayList();
162         Enumeration names = event.getServletContext().getAttributeNames();
163         while (names.hasMoreElements()) {
164             String name = (String) names.nextElement();
165             list.add(name);
166         }
167         Iterator keys = list.iterator();
168         while (keys.hasNext()) {
169             String key = (String) keys.next();
170             event.getServletContext().removeAttribute(key);
171         }
172 
173     }
174 
175 
176     // --------------------------------- ServletContextAttributeListener Methods
177 
178 
179     /***
180      * <p>Respond to an application scope attribute being added.  If the
181      * value is an {@link AbstractApplicationBean}, call its
182      * <code>init()</code> method.</p>
183      *
184      * @param event Event to be processed
185      */
186     public void attributeAdded(ServletContextAttributeEvent event) {
187 
188         // Delegate to the Tiger Extensions instance if it exists
189         LifecycleListener tiger = tiger();
190         if (tiger != null) {
191             tiger.attributeAdded(event);
192             return; // Tiger logic replaces our own
193         }
194 
195         // If the new value is an AbstractApplicationBean, notify it
196         Object value = event.getValue();
197         if (value != null) {
198             fireApplicationInit(value);
199         }
200 
201     }
202 
203 
204     /***
205      * <p>Respond to an application scope attribute being replaced.
206      * If the old value was an {@link AbstractApplicationBean}, call
207      * its <code>destroy()</code> method.  If the new value is an
208      * {@link AbstractApplicationBean}, call its <code>init()</code>
209      * method.</p>
210      *
211      * @param event Event to be processed
212      */
213     public void attributeReplaced(ServletContextAttributeEvent event) {
214 
215         // Delegate to the Tiger Extensions instance if it exists
216         LifecycleListener tiger = tiger();
217         if (tiger != null) {
218             tiger.attributeReplaced(event);
219             return; // Tiger logic replaces our own
220         }
221 
222         // If the old value is an AbstractApplicationBean, notify it
223         Object value = event.getValue();
224         if (value != null) {
225             fireApplicationDestroy(value);
226         }
227 
228         // If the new value is an AbstractApplicationBean, notify it
229         value = event.getServletContext().getAttribute(event.getName());
230         if (value != null) {
231             fireApplicationInit(value);
232         }
233 
234     }
235 
236 
237     /***
238      * <p>Respond to an application scope attribute being removed.
239      * If the old value was an {@link AbstractApplicationBean}, call
240      * its <code>destroy()</code> method.</p>
241      *
242      * @param event Event to be processed
243      */
244     public void attributeRemoved(ServletContextAttributeEvent event) {
245 
246         // Delegate to the Tiger Extensions instance if it exists
247         LifecycleListener tiger = tiger();
248         if (tiger != null) {
249             tiger.attributeRemoved(event);
250             return; // Tiger logic replaces our own
251         }
252 
253         // If the old value is an AbstractApplicationBean, notify it
254         Object value = event.getValue();
255         if (value != null) {
256             fireApplicationDestroy(value);
257         }
258 
259     }
260 
261 
262     // --------------------------------------------- HttpSessionListener Methods
263 
264 
265     /***
266      * <p>Respond to a session created event.  No special processing
267      * is required.</p>
268      *
269      * @param event Event to be processed
270      */
271     public void sessionCreated(HttpSessionEvent event) {
272 
273         // Delegate to the Tiger Extensions instance if it exists
274         LifecycleListener tiger = tiger();
275         if (tiger != null) {
276             tiger.sessionCreated(event);
277         }
278 
279     }
280 
281 
282     /***
283      * <p>Respond to a session destroyed event.  Causes any session
284      * scope attribute that implements {@link AbstractSessionBean}
285      * to be removed, triggering an <code>attributeRemoved()</code> event.</p>
286      *
287      * @param event Event to be processed
288      */
289     public void sessionDestroyed(HttpSessionEvent event) {
290 
291         // Delegate to the Tiger Extensions instance if it exists
292         LifecycleListener tiger = tiger();
293         if (tiger != null) {
294             tiger.sessionDestroyed(event);
295         }
296 
297         // Remove any AbstractSessionBean attributes, which will
298         // trigger an attributeRemoved event
299         List list = new ArrayList();
300         try {
301             Enumeration names = event.getSession().getAttributeNames();
302             while (names.hasMoreElements()) {
303                 String name = (String) names.nextElement();
304                 list.add(name);
305             }
306             Iterator keys = list.iterator();
307             while (keys.hasNext()) {
308                 String key = (String) keys.next();
309                 event.getSession().removeAttribute(key);
310             }
311         } catch (IllegalStateException e) {
312             // If the session has already been invalidated, there is nothing
313             // we can do.  In a Servlet 2.4 or later container, this should not
314             // happen, because the event handler is supposed to be called before
315             // invalidation occurs, rather than after.
316             ;
317         }
318 
319     }
320 
321 
322     // ----------------------------------- HttpSessionActivationListener Methods
323 
324 
325     /***
326      * <p>Respond to a "session will passivate" event.  Notify all session
327      * scope attributes that are {@link AbstractSessionBean}s.</p>
328      *
329      * @param event Event to be processed
330      */
331     public void sessionWillPassivate(HttpSessionEvent event) {
332 
333         // Delegate to the Tiger Extensions instance if it exists
334         LifecycleListener tiger = tiger();
335         if (tiger != null) {
336             tiger.sessionWillPassivate(event);
337             return; // Tiger logic replaces our own
338         }
339 
340         // Notify any AbstractSessionBean attributes
341         Enumeration names = event.getSession().getAttributeNames();
342         while (names.hasMoreElements()) {
343             String name = (String) names.nextElement();
344             Object value = event.getSession().getAttribute(name);
345             if (value != null) {
346                 fireSessionPassivate(value);
347             }
348         }
349 
350     }
351 
352 
353     /***
354      * <p>Respond to a "session did activate" event.  Notify all session
355      * scope attributes that are {@link AbstractSessionBean}s.</p>
356      *
357      * @param event Event to be processed
358      */
359     public void sessionDidActivate(HttpSessionEvent event) {
360 
361         // Delegate to the Tiger Extensions instance if it exists
362         LifecycleListener tiger = tiger();
363         if (tiger != null) {
364             tiger.sessionDidActivate(event);
365             return; // Tiger logic replaces our own
366         }
367 
368         // Notify any AbstractSessionBean attributes
369         Enumeration names = event.getSession().getAttributeNames();
370         while (names.hasMoreElements()) {
371             String name = (String) names.nextElement();
372             Object value = event.getSession().getAttribute(name);
373             if (value != null) {
374                 fireSessionActivate(value);
375             }
376         }
377 
378     }
379 
380 
381     // ------------------------------------ HttpSessionAttributeListener Methods
382 
383 
384     /***
385      * <p>Respond to a session scope attribute being added.  If the
386      * value is an {@link AbstractSessionBean}, call its
387      * <code>init()</code> method.</p>
388      *
389      * @param event Event to be processed
390      */
391     public void attributeAdded(HttpSessionBindingEvent event) {
392 
393         // Delegate to the Tiger Extensions instance if it exists
394         LifecycleListener tiger = tiger();
395         if (tiger != null) {
396             tiger.attributeAdded(event);
397             return; // Tiger logic replaces our own
398         }
399 
400         // If the new value is an AbstractSessionBean, notify it
401         Object value = event.getValue();
402         if (value != null) {
403             fireSessionInit(value);
404         }
405 
406     }
407 
408 
409     /***
410      * <p>Respond to a session scope attribute being replaced.
411      * If the old value was an {@link AbstractSessionBean}, call
412      * its <code>destroy()</code> method.  If the new value is an
413      * {@link AbstractSessionBean}, call its <code>init()</code>
414      * method.</p>
415      *
416      * @param event Event to be processed
417      */
418     public void attributeReplaced(HttpSessionBindingEvent event) {
419 
420         // Delegate to the Tiger Extensions instance if it exists
421         LifecycleListener tiger = tiger();
422         if (tiger != null) {
423             tiger.attributeReplaced(event);
424             return; // Tiger logic replaces our own
425         }
426 
427         // If the old value is an AbstractSessionBean, notify it
428         Object value = event.getValue();
429         if (value != null) {
430             fireSessionDestroy(value);
431         }
432 
433         // If the new value is an AbstractSessionBean, notify it
434         value = event.getSession().getAttribute(event.getName());
435         if (value != null) {
436             fireSessionInit(value);
437         }
438 
439     }
440 
441 
442     /***
443      * <p>Respond to a session scope attribute being removed.
444      * If the old value was an {@link AbstractSessionBean}, call
445      * its <code>destroy()</code> method.</p>
446      *
447      * @param event Event to be processed
448      */
449     public void attributeRemoved(HttpSessionBindingEvent event) {
450 
451         // Delegate to the Tiger Extensions instance if it exists
452         LifecycleListener tiger = tiger();
453         if (tiger != null) {
454             tiger.attributeRemoved(event);
455             return; // Tiger logic replaces our own
456         }
457 
458         // If the old value is an AbstractSessionBean, notify it
459         Object value = event.getValue();
460         if (value != null) {
461             fireSessionDestroy(value);
462         }
463 
464     }
465 
466 
467     // ------------------------------------------ ServletRequestListener Methods
468 
469 
470     /***
471      * <p>Respond to a request created event.  No special processing
472      * is required.</p>
473      *
474      * @param event Event to be processed
475      */
476     public void requestInitialized(ServletRequestEvent event) {
477 
478         // Delegate to the Tiger Extensions instance if it exists
479         LifecycleListener tiger = tiger();
480         if (tiger != null) {
481             tiger.requestInitialized(event);
482         }
483 
484     }
485 
486 
487     /***
488      * <p>Respond to a request destroyed event.  Causes any request
489      * scope attribute that implements {@link AbstractRequestBean}
490      * or {@link AbstractFragmentBean} to be removed, triggering an
491      * <code>attributeRemoved()</code> event.</p>
492      *
493      * @param event Event to be processed
494      */
495     public void requestDestroyed(ServletRequestEvent event) {
496 
497         // Delegate to the Tiger Extensions instance if it exists
498         LifecycleListener tiger = tiger();
499         if (tiger != null) {
500             tiger.requestDestroyed(event);
501             return;
502         }
503 
504         // Remove any AbstractRequestBean or ViewController attributes,
505         // which will trigger an attributeRemoved event
506         List list = new ArrayList();
507         ServletRequest request = event.getServletRequest();
508         Enumeration names = request.getAttributeNames();
509         while (names.hasMoreElements()) {
510             String name = (String) names.nextElement();
511             Object value = request.getAttribute(name);
512             if ((value instanceof AbstractRequestBean) || (value instanceof ViewController)) {
513                 list.add(name);
514             }
515         }
516         Iterator keys = list.iterator();
517         while (keys.hasNext()) {
518             String key = (String) keys.next();
519             event.getServletRequest().removeAttribute(key);
520         }
521 
522     }
523 
524 
525     // --------------------------------- ServletRequestAttributeListener Methods
526 
527 
528     /***
529      * <p>Respond to a request scope attribute being added.  If the
530      * value is an {@link AbstractRequestBean}, call its <code>init()</code> method.
531      * </p>
532      *
533      * @param event Event to be processed
534      */
535     public void attributeAdded(ServletRequestAttributeEvent event) {
536 
537         if (log.isDebugEnabled()) {
538             log.debug("ServletRequestAttributeAdded(" + event.getName()
539               + "," + event.getValue() + ")");
540         }
541 
542         // Delegate to the Tiger Extensions instance if it exists
543         LifecycleListener tiger = tiger();
544         if (tiger != null) {
545             tiger.attributeAdded(event);
546             return; // Tiger logic replaces our own
547         }
548 
549         Object value = event.getValue();
550         if (value != null) {
551             fireRequestInit(value);
552         }
553 
554     }
555 
556 
557     /***
558      * <p>Respond to a request scope attribute being replaced.
559      * If the old value was an {@link AbstractRequestBean},
560      * call its <code>destroy()</code> method.  If the new value is an
561      * {@link AbstractRequestBean}, call its <code>init()</code> method.</p>
562      *
563      * @param event Event to be processed
564      */
565     public void attributeReplaced(ServletRequestAttributeEvent event) {
566 
567         if (log.isDebugEnabled()) {
568             log.debug("ServletRequestAttributeReplaced(" + event.getName()
569               + "," + event.getValue()
570               + "," + event.getServletRequest().getAttribute(event.getName())
571               + ")");
572         }
573 
574         // Delegate to the Tiger Extensions instance if it exists
575         LifecycleListener tiger = tiger();
576         if (tiger != null) {
577             tiger.attributeReplaced(event);
578             return; // Tiger logic replaces our own
579         }
580 
581         Object value = event.getValue();
582         if (value != null) {
583             fireRequestDestroy(value);
584         }
585 
586         value = event.getServletRequest().getAttribute(event.getName());
587         if (value != null) {
588             fireRequestInit(value);
589         }
590 
591     }
592 
593 
594     /***
595      * <p>Respond to a request scope attribute being removed.
596      * If the old value was an {@link AbstractRequestBean},
597      * call its <code>destroy()</code> method.</p>
598      *
599      * @param event Event to be processed
600      */
601     public void attributeRemoved(ServletRequestAttributeEvent event) {
602 
603         if (log.isDebugEnabled()) {
604             log.debug("ServletRequestAttributeRemoved(" + event.getName()
605               + "," + event.getValue() + ")");
606         }
607 
608         // Delegate to the Tiger Extensions instance if it exists
609         LifecycleListener tiger = tiger();
610         if (tiger != null) {
611             tiger.attributeRemoved(event);
612             return; // Tiger logic replaces our own
613         }
614 
615         Object value = event.getValue();
616         if (value != null) {
617             fireRequestDestroy(value);
618         }
619 
620     }
621 
622 
623     // ------------------------------------------------------- Protected Methods
624 
625 
626     /***
627      * <p>Fire a destroy event on an @{link AbstractApplicationBean}.</p>
628      *
629      * @param bean {@link AbstractApplicationBean} to fire event on
630      */
631     protected void fireApplicationDestroy(Object bean) {
632 
633         try {
634             if (bean instanceof AbstractApplicationBean) {
635                 ((AbstractApplicationBean) bean).destroy();
636             }
637         } catch (Exception e) {
638             handleException(FacesContext.getCurrentInstance(), e);
639         }
640 
641     }
642 
643 
644     /***
645      * <p>Fire an init event on an {@link AbstractApplicationBean}.</p>
646      *
647      * @param bean {@link AbstractApplicationBean} to fire event on
648      */
649     protected void fireApplicationInit(Object bean) {
650 
651         try {
652             if (bean instanceof AbstractApplicationBean) {
653                 ((AbstractApplicationBean) bean).init();
654             }
655         } catch (Exception e) {
656             handleException(FacesContext.getCurrentInstance(), e);
657         }
658 
659     }
660 
661 
662     /***
663      * <p>Fire a destroy event on an @{link AbstractRequestBean}.</p>
664      *
665      * @param bean {@link AbstractRequestBean} to fire event on
666      */
667     protected void fireRequestDestroy(Object bean) {
668 
669         try {
670             if (bean instanceof AbstractRequestBean) {
671                 ((AbstractRequestBean) bean).destroy();
672             } else if (bean instanceof ViewController) {
673                 ((ViewController) bean).destroy();
674             }
675         } catch (Exception e) {
676             handleException(FacesContext.getCurrentInstance(), e);
677         }
678 
679     }
680 
681 
682     /***
683      * <p>Fire an init event on an {@link AbstractRequestBean}.</p>
684      *
685      * @param bean {@link AbstractRequestBean} to fire event on
686      */
687     protected void fireRequestInit(Object bean) {
688 
689         try {
690             if (bean instanceof AbstractRequestBean) {
691                 ((AbstractRequestBean) bean).init();
692             } else if (bean instanceof ViewController) {
693                 ((ViewController) bean).init();
694             }
695         } catch (Exception e) {
696             handleException(FacesContext.getCurrentInstance(), e);
697         }
698 
699     }
700 
701 
702     /***
703      * <p>Fire an activate event on an @{link AbstractSessionBean}.</p>
704      *
705      * @param bean {@link AbstractSessionBean} to fire event on
706      */
707     protected void fireSessionActivate(Object bean) {
708 
709         try {
710             if (bean instanceof AbstractSessionBean) {
711                 ((AbstractSessionBean) bean).activate();
712             }
713         } catch (Exception e) {
714             handleException(FacesContext.getCurrentInstance(), e);
715         }
716 
717     }
718 
719 
720     /***
721      * <p>Fire a destroy event on an @{link AbstractSessionBean}.</p>
722      *
723      * @param bean {@link AbstractSessionBean} to fire event on
724      */
725     protected void fireSessionDestroy(Object bean) {
726 
727         try {
728             if (bean instanceof AbstractSessionBean) {
729                 ((AbstractSessionBean) bean).destroy();
730             }
731         } catch (Exception e) {
732             handleException(FacesContext.getCurrentInstance(), e);
733         }
734 
735     }
736 
737 
738     /***
739      * <p>Fire an init event on an {@link AbstractSessionBean}.</p>
740      *
741      * @param bean {@link AbstractSessionBean} to fire event on
742      */
743     protected void fireSessionInit(Object bean) {
744 
745         try {
746             if (bean instanceof AbstractSessionBean) {
747                 ((AbstractSessionBean) bean).init();
748             }
749         } catch (Exception e) {
750             handleException(FacesContext.getCurrentInstance(), e);
751         }
752 
753     }
754 
755 
756     /***
757      * <p>Fire an passivate event on an @{link AbstractSessionBean}.</p>
758      *
759      * @param bean {@link AbstractSessionBean} to fire event on
760      */
761     protected void fireSessionPassivate(Object bean) {
762 
763         try {
764             if (bean instanceof AbstractSessionBean) {
765                 ((AbstractSessionBean) bean).passivate();
766             }
767         } catch (Exception e) {
768             handleException(FacesContext.getCurrentInstance(), e);
769         }
770 
771     }
772 
773 
774     /***
775      * <p>Handle the specified exception according to the strategy
776      * defined by our current {@link ExceptionHandler}.</p>
777      *
778      * @param context FacesContext for the current request
779      * @param exception Exception to be handled
780      */
781     protected void handleException(FacesContext context, Exception exception) {
782 
783         if (context == null) {
784             exception.printStackTrace(System.out);
785             return;
786         }
787         ExceptionHandler handler = (ExceptionHandler)
788           context.getApplication().getVariableResolver().resolveVariable
789                 (context, Constants.EXCEPTION_HANDLER);
790         handler.handleException(exception);
791 
792     }
793 
794 
795     // --------------------------------------------------------- Private Methods
796 
797 
798     /***
799      * <p>Return the <em>Tiger Extensions</em> implementation of this listener
800      * if one exists; otherwise, return <code>null</code>.</p>
801      */
802     private LifecycleListener tiger() {
803 
804         // If we have already attempted to load the Tiger Extensions version
805         // of this class, return the calculated result
806         if (tigerInitialized) {
807             return tiger;
808         }
809 
810         // Attempt to load the Tiger Extensions version of this class, and
811         // instantiate an appropriate instance
812         try {
813             Class clazz = this.getClass().getClassLoader().loadClass(TIGER_LISTENER);
814             tiger = (LifecycleListener) clazz.newInstance();
815         } catch (Exception e) {
816             ; // Swallow any class not found or instantiation exception
817         }
818 
819         // Return the calculated result
820         tigerInitialized = true;
821         return tiger;
822 
823     }
824 
825 
826 }