View Javadoc

1   package org.apache.turbine.modules;
2   
3   /*
4    * Copyright 2001-2004 The Apache Software Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License")
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  import java.util.List;
20  
21  import org.apache.commons.logging.Log;
22  import org.apache.commons.logging.LogFactory;
23  
24  import org.apache.ecs.ConcreteElement;
25  
26  import org.apache.turbine.Turbine;
27  import org.apache.turbine.TurbineConstants;
28  import org.apache.turbine.services.assemblerbroker.AssemblerBrokerService;
29  import org.apache.turbine.services.assemblerbroker.TurbineAssemblerBroker;
30  import org.apache.turbine.util.ObjectUtils;
31  import org.apache.turbine.util.RunData;
32  
33  /***
34   * The purpose of this class is to allow one to load and execute
35   * Navigation modules.
36   *
37   * @author <a href="mailto:mbryson@mont.mindspring.com">Dave Bryson</a>
38   * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
39   * @version $Id: NavigationLoader.java,v 1.9.2.3 2004/08/16 22:57:50 henning Exp $
40   */
41  public class NavigationLoader
42      extends GenericLoader
43      implements Loader
44  {
45      /*** Logging */
46      private static Log log = LogFactory.getLog(NavigationLoader.class);
47  
48      /*** The single instance of this class. */
49      private static NavigationLoader instance =
50          new NavigationLoader(Turbine.getConfiguration()
51                           .getInt(TurbineConstants.NAVIGATION_CACHE_SIZE_KEY,
52                                   TurbineConstants.NAVIGATION_CACHE_SIZE_DEFAULT));
53  
54      /*** The Assembler Broker Service */
55      private static AssemblerBrokerService ab = TurbineAssemblerBroker.getService();
56  
57      /***
58       * These ctor's are private to force clients to use getInstance()
59       * to access this class.
60       */
61      private NavigationLoader()
62      {
63          super();
64      }
65  
66      /***
67       * These ctor's are private to force clients to use getInstance()
68       * to access this class.
69       */
70      private NavigationLoader(int i)
71      {
72          super(i);
73      }
74  
75      /***
76       * Adds an instance of an object into the hashtable.
77       *
78       * @param name Name of object.
79       * @param navigation Navigation to be associated with name.
80       */
81      private void addInstance(String name, Navigation navigation)
82      {
83          if (cache())
84          {
85              this.put(name, (Navigation) navigation);
86          }
87      }
88  
89      /***
90       * Attempts to load and execute the external Navigation. This is
91       * used when you want to execute a Navigation which returns its
92       * output via a MultiPartElement instead of out the data.getPage()
93       * value.  This allows you to easily chain the execution of
94       * Navigation modules together.
95       *
96       * @param data Turbine information.
97       * @param name Name of object that will execute the navigation.
98       * @exception Exception a generic exception.
99       */
100     public ConcreteElement eval(RunData data, String name)
101             throws Exception
102     {
103         // Execute Navigation
104         return getInstance(name).build(data);
105     }
106 
107     /***
108      * Attempts to load and execute the external Navigation.
109      *
110      * @param data Turbine information.
111      * @param name Name of object instance.
112      * @exception Exception a generic exception.
113      */
114     public void exec(RunData data, String name)
115             throws Exception
116     {
117         this.eval(data, name);
118     }
119 
120     /***
121      * Pulls out an instance of the object by name.  Name is just the
122      * single name of the object. This is equal to getInstance but
123      * returns an Assembler object and is needed to fulfil the Loader
124      * interface.
125      *
126      * @param name Name of object instance.
127      * @return A Layout with the specified name, or null.
128      * @exception Exception a generic exception.
129      */
130     public Assembler getAssembler(String name)
131         throws Exception
132     {
133         return getInstance(name);
134     }
135 
136     /***
137      * Pulls out an instance of the Navigation by name.  Name is just the
138      * single name of the Navigation.
139      *
140      * @param name Name of requested Navigation
141      * @return A Navigation with the specified name, or null.
142      * @exception Exception a generic exception.
143      */
144     public Navigation getInstance(String name)
145             throws Exception
146     {
147         Navigation navigation = null;
148 
149         // Check if the navigation is already in the cache
150         if (cache() && this.containsKey(name))
151         {
152             navigation = (Navigation) this.get(name);
153             log.debug("Found Navigation " + name + " in the cache!");
154         }
155         else
156         {
157             log.debug("Loading Navigation " + name + " from the Assembler Broker");
158 
159             try
160             {
161                 if (ab != null)
162                 {
163                     // Attempt to load the navigation
164                     navigation = (Navigation) ab.getAssembler(
165                         AssemblerBrokerService.NAVIGATION_TYPE, name);
166                 }
167             }
168             catch (ClassCastException cce)
169             {
170                 // This can alternatively let this exception be thrown
171                 // So that the ClassCastException is shown in the
172                 // browser window.  Like this it shows "Screen not Found"
173                 navigation = null;
174             }
175 
176             if (navigation == null)
177             {
178                 // If we did not find a screen we should try and give
179                 // the user a reason for that...
180                 // FIX ME: The AssemblerFactories should each add it's
181                 // own string here...
182                 List packages = Turbine.getConfiguration()
183                     .getList(TurbineConstants.MODULE_PACKAGES);
184 
185                 ObjectUtils.addOnce(packages,
186                         GenericLoader.getBasePackage());
187 
188                 throw new ClassNotFoundException(
189                         "\n\n\tRequested Navigation not found: " + name +
190                         "\n\tTurbine looked in the following " +
191                         "modules.packages path: \n\t" + packages.toString() + "\n");
192             }
193             else if (cache())
194             {
195                 // The new instance is added to the cache
196                 addInstance(name, navigation);
197             }
198         }
199         return navigation;
200     }
201 
202     /***
203      * The method through which this class is accessed.
204      *
205      * @return The single instance of this class.
206      */
207     public static NavigationLoader getInstance()
208     {
209         return instance;
210     }
211 }