001: package org.apache.turbine.modules;
002:
003: /*
004: * Copyright 2001-2005 The Apache Software Foundation.
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License")
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */
018:
019: import java.util.List;
020:
021: import org.apache.commons.logging.Log;
022: import org.apache.commons.logging.LogFactory;
023:
024: import org.apache.ecs.ConcreteElement;
025:
026: import org.apache.turbine.Turbine;
027: import org.apache.turbine.TurbineConstants;
028: import org.apache.turbine.services.assemblerbroker.AssemblerBrokerService;
029: import org.apache.turbine.services.assemblerbroker.TurbineAssemblerBroker;
030: import org.apache.turbine.util.ObjectUtils;
031: import org.apache.turbine.util.RunData;
032:
033: /**
034: * The purpose of this class is to allow one to load and execute
035: * Navigation modules.
036: *
037: * @author <a href="mailto:mbryson@mont.mindspring.com">Dave Bryson</a>
038: * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
039: * @version $Id: NavigationLoader.java 264148 2005-08-29 14:21:04Z henning $
040: */
041: public class NavigationLoader extends GenericLoader implements Loader {
042: /** Serial Version UID */
043: private static final long serialVersionUID = 5062299200802529612L;
044:
045: /** Logging */
046: private static Log log = LogFactory.getLog(NavigationLoader.class);
047:
048: /** The single instance of this class. */
049: private static NavigationLoader instance = new NavigationLoader(
050: Turbine.getConfiguration().getInt(
051: TurbineConstants.NAVIGATION_CACHE_SIZE_KEY,
052: TurbineConstants.NAVIGATION_CACHE_SIZE_DEFAULT));
053:
054: /** The Assembler Broker Service */
055: private static AssemblerBrokerService ab = TurbineAssemblerBroker
056: .getService();
057:
058: /**
059: * These ctor's are private to force clients to use getInstance()
060: * to access this class.
061: */
062: private NavigationLoader() {
063: super ();
064: }
065:
066: /**
067: * These ctor's are private to force clients to use getInstance()
068: * to access this class.
069: */
070: private NavigationLoader(int i) {
071: super (i);
072: }
073:
074: /**
075: * Adds an instance of an object into the hashtable.
076: *
077: * @param name Name of object.
078: * @param navigation Navigation to be associated with name.
079: */
080: private void addInstance(String name, Navigation navigation) {
081: if (cache()) {
082: this .put(name, (Navigation) navigation);
083: }
084: }
085:
086: /**
087: * Attempts to load and execute the external Navigation. This is
088: * used when you want to execute a Navigation which returns its
089: * output via a MultiPartElement instead of out the data.getPage()
090: * value. This allows you to easily chain the execution of
091: * Navigation modules together.
092: *
093: * @param data Turbine information.
094: * @param name Name of object that will execute the navigation.
095: * @exception Exception a generic exception.
096: */
097: public ConcreteElement eval(RunData data, String name)
098: throws Exception {
099: // Execute Navigation
100: return getInstance(name).build(data);
101: }
102:
103: /**
104: * Attempts to load and execute the external Navigation.
105: *
106: * @param data Turbine information.
107: * @param name Name of object instance.
108: * @exception Exception a generic exception.
109: */
110: public void exec(RunData data, String name) throws Exception {
111: this .eval(data, name);
112: }
113:
114: /**
115: * Pulls out an instance of the object by name. Name is just the
116: * single name of the object. This is equal to getInstance but
117: * returns an Assembler object and is needed to fulfil the Loader
118: * interface.
119: *
120: * @param name Name of object instance.
121: * @return A Layout with the specified name, or null.
122: * @exception Exception a generic exception.
123: */
124: public Assembler getAssembler(String name) throws Exception {
125: return getInstance(name);
126: }
127:
128: /**
129: * Pulls out an instance of the Navigation by name. Name is just the
130: * single name of the Navigation.
131: *
132: * @param name Name of requested Navigation
133: * @return A Navigation with the specified name, or null.
134: * @exception Exception a generic exception.
135: */
136: public Navigation getInstance(String name) throws Exception {
137: Navigation navigation = null;
138:
139: // Check if the navigation is already in the cache
140: if (cache() && this .containsKey(name)) {
141: navigation = (Navigation) this .get(name);
142: log.debug("Found Navigation " + name + " in the cache!");
143: } else {
144: log.debug("Loading Navigation " + name
145: + " from the Assembler Broker");
146:
147: try {
148: if (ab != null) {
149: // Attempt to load the navigation
150: navigation = (Navigation) ab.getAssembler(
151: AssemblerBrokerService.NAVIGATION_TYPE,
152: name);
153: }
154: } catch (ClassCastException cce) {
155: // This can alternatively let this exception be thrown
156: // So that the ClassCastException is shown in the
157: // browser window. Like this it shows "Screen not Found"
158: navigation = null;
159: }
160:
161: if (navigation == null) {
162: // If we did not find a screen we should try and give
163: // the user a reason for that...
164: // FIX ME: The AssemblerFactories should each add it's
165: // own string here...
166: List packages = Turbine.getConfiguration().getList(
167: TurbineConstants.MODULE_PACKAGES);
168:
169: ObjectUtils.addOnce(packages, GenericLoader
170: .getBasePackage());
171:
172: throw new ClassNotFoundException(
173: "\n\n\tRequested Navigation not found: "
174: + name
175: + "\n\tTurbine looked in the following "
176: + "modules.packages path: \n\t"
177: + packages.toString() + "\n");
178: } else if (cache()) {
179: // The new instance is added to the cache
180: addInstance(name, navigation);
181: }
182: }
183: return navigation;
184: }
185:
186: /**
187: * The method through which this class is accessed.
188: *
189: * @return The single instance of this class.
190: */
191: public static NavigationLoader getInstance() {
192: return instance;
193: }
194: }
|