001: /*
002: * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
003: *
004: * Redistribution and use in source and binary forms, with or
005: * without modification, are permitted provided that the following
006: * conditions are met:
007: *
008: * - Redistributions of source code must retain the above copyright
009: * notice, this list of conditions and the following disclaimer.
010: *
011: * - Redistribution in binary form must reproduce the above
012: * copyright notice, this list of conditions and the following
013: * disclaimer in the documentation and/or other materials
014: * provided with the distribution.
015: *
016: * Neither the name of Sun Microsystems, Inc. or the names of
017: * contributors may be used to endorse or promote products derived
018: * from this software without specific prior written permission.
019: *
020: * This software is provided "AS IS," without a warranty of any
021: * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
022: * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
023: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
024: * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY
025: * DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR
026: * RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE OR
027: * ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE
028: * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
029: * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
030: * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
031: * THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS
032: * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
033: *
034: * You acknowledge that this software is not designed, licensed or
035: * intended for use in the design, construction, operation or
036: * maintenance of any nuclear facility.
037: */
038:
039: package org.apache.cocoon.faces.samples.carstore;
040:
041: import org.apache.commons.logging.Log;
042: import org.apache.commons.logging.LogFactory;
043:
044: import org.apache.cocoon.faces.samples.components.components.AreaSelectedEvent;
045:
046: import javax.faces.context.FacesContext;
047: import javax.faces.event.ActionEvent;
048:
049: import java.util.HashMap;
050: import java.util.Iterator;
051: import java.util.Locale;
052: import java.util.Map;
053:
054: /**
055: * <p>This is the main bean for the application. It maintains a
056: * <code>Map</code> of {@link CarBean} instances, keyed by model name,
057: * and a <code>Map</code> of {@link CarCustomizer} instances, keyed by
058: * package name. The <code>CarBean</code> instances in the model
059: * <code>Map</code> are accessed from several pages, as described
060: * below.</p>
061: *
062: * <p>Several pages in the application use this bean as the target of
063: * method reference and value reference expressions.</p>
064: *
065: * <ul>
066: *
067: * <li><p>The "chooseLocale" page uses <code>actionListener</code>
068: * attributes to point to the {@link #chooseLocaleFromMap} and {@link
069: * #chooseLocaleFromLink} methods.</p></li>
070: *
071: * <li><p>The "storeFront" page uses value binding expressions to pull
072: * information about four of the known car models in the store.</p></li>
073: *
074: * <li><p>The "carDetail" page uses value binding expressions to pull
075: * information about the currently chosen model. It also uses the
076: * <code>action</code> attribute to convey the user's package
077: * choices.</p></li>
078: *
079: * <li><p>The "confirmChoices" page uses value binding expressions to
080: * pull the user's choices from the currently chosen model.</p></li>
081: *
082: * </ul>
083: */
084:
085: public class CarStore extends Object {
086:
087: protected static final Log log = LogFactory.getLog(CarStore.class);
088:
089: static final String CARSTORE_PREFIX = "org.apache.cocoon.faces.samples.carstore";
090:
091: static final String DEFAULT_MODEL = "Jalopy";
092:
093: static final String DEFAULT_PACKAGE = "Custom";
094:
095: static final String DEFAULT_MODEL_PROPERTIES = CARSTORE_PREFIX
096: + ".bundles." + DEFAULT_MODEL;
097:
098: static final String DEFAULT_PACKAGE_PROPERTIES = CARSTORE_PREFIX
099: + ".bundles." + DEFAULT_PACKAGE;
100:
101: //
102: // Relationship Instance Variables
103: //
104:
105: /**
106: * <p>The locales to be selected for each hotspot, keyed by the
107: * alternate text for that area.</p>
108: */
109: private Map locales = null;
110:
111: /**
112: * <p>The currently selected car model.</p>
113: */
114:
115: private String currentModelName = DEFAULT_MODEL;
116:
117: /**
118: * <p>The car models we offer.</p>
119: *
120: * <p>Keys: Strings that happen to correspond to the name of the
121: * packages.</p>
122: *
123: * <p>Values: CarBean instances</p>
124: */
125: private Map carModels = null;
126:
127: /**
128: * <p>Keys: Strings that happen to correspond to the name of the
129: * Properties file for the car (without the package prefix).</p>
130: *
131: * <p>Values: CarBeanCustomizer instances</p>
132: */
133:
134: private Map carCustomizers = null;
135:
136: public CarStore() {
137: if (log.isDebugEnabled()) {
138: log.debug("Creating main CarStore bean");
139: log.debug("Populating locale map");
140: }
141: locales = new HashMap();
142: locales.put("NAmerica", Locale.ENGLISH);
143: locales.put("SAmerica", new Locale("es", "es"));
144: locales.put("Germany", Locale.GERMAN);
145: locales.put("France", Locale.FRENCH);
146: }
147:
148: //
149: // ActionListener handlers
150: //
151:
152: public void chooseLocaleFromMap(ActionEvent actionEvent) {
153: AreaSelectedEvent event = (AreaSelectedEvent) actionEvent;
154: String current = event.getMapComponent().getCurrent();
155: FacesContext context = FacesContext.getCurrentInstance();
156: context.getViewRoot().setLocale((Locale) locales.get(current));
157: resetMaps();
158: }
159:
160: public void chooseLocaleFromLink(ActionEvent event) {
161: String current = event.getComponent().getId();
162: FacesContext context = FacesContext.getCurrentInstance();
163: context.getViewRoot().setLocale((Locale) locales.get(current));
164: resetMaps();
165: }
166:
167: private void resetMaps() {
168: if (null != carModels) {
169: carModels.clear();
170: carModels = null;
171: }
172: if (null != carCustomizers) {
173: carCustomizers.clear();
174: carCustomizers = null;
175: }
176: }
177:
178: public void choosePackage(ActionEvent event) {
179: String packageName = event.getComponent().getId();
180: choosePackage(packageName);
181: }
182:
183: public void choosePackage(String packageName) {
184: CarCustomizer packageCustomizer = (CarCustomizer) carCustomizers
185: .get(packageName);
186: packageCustomizer.customizeCar(getCurrentModel());
187: getCurrentModel().getCurrentPrice();
188:
189: // HERE IS WHERE WE UPDATE THE BUTTON STYLE!
190: String curName;
191: Iterator iter = carCustomizers.keySet().iterator();
192: // go through all the available packages and set the button
193: // style accordingly.
194: while (iter.hasNext()) {
195: curName = (String) iter.next();
196: packageCustomizer = (CarCustomizer) carCustomizers
197: .get(curName);
198: if (curName.equals(packageName)) {
199: packageCustomizer.setButtonStyle("package-selected");
200: } else {
201: packageCustomizer.setButtonStyle("package-unselected");
202: }
203: }
204: }
205:
206: //
207: // action handlers
208: //
209:
210: public String storeFrontJalopyPressed() {
211: setCurrentModelName("Jalopy");
212: return "carDetail";
213: }
214:
215: public String storeFrontRoadsterPressed() {
216: setCurrentModelName("Roadster");
217: return "carDetail";
218: }
219:
220: public String storeFrontLuxuryPressed() {
221: setCurrentModelName("Luxury");
222: return "carDetail";
223: }
224:
225: public String storeFrontSUVPressed() {
226: setCurrentModelName("SUV");
227: return "carDetail";
228: }
229:
230: public String buyCurrentCar() {
231: getCurrentModel().getCurrentPrice();
232: return "confirmChoices";
233: }
234:
235: //
236: // Accessors
237: //
238:
239: public CarBean getCurrentModel() {
240: CarBean result = (CarBean) carModels.get(getCurrentModelName());
241: return result;
242: }
243:
244: public Map getModels() {
245: if (null == carModels) {
246: carModels = new HashMap();
247: if (log.isDebugEnabled()) {
248: log.debug("Populating carModel map");
249: }
250: carModels.put(DEFAULT_MODEL, new CarBean(
251: DEFAULT_MODEL_PROPERTIES));
252: carModels.put("Roadster", new CarBean(CARSTORE_PREFIX
253: + ".bundles.Roadster"));
254: carModels.put("Luxury", new CarBean(CARSTORE_PREFIX
255: + ".bundles.Luxury"));
256: carModels.put("SUV", new CarBean(CARSTORE_PREFIX
257: + ".bundles.SUV"));
258: }
259:
260: return carModels;
261: }
262:
263: public Map getCustomizers() {
264: getModels();
265: if (null == carCustomizers) {
266: carCustomizers = new HashMap();
267: if (log.isDebugEnabled()) {
268: log.debug("Populating carCustomizers map");
269: }
270: carCustomizers.put("Custom", new CarCustomizer(
271: CARSTORE_PREFIX + ".bundles.Custom"));
272: carCustomizers.put("Standard", new CarCustomizer(
273: CARSTORE_PREFIX + ".bundles.Standard"));
274: carCustomizers.put("Performance", new CarCustomizer(
275: CARSTORE_PREFIX + ".bundles.Performance"));
276: carCustomizers.put("Deluxe", new CarCustomizer(
277: CARSTORE_PREFIX + ".bundles.Deluxe"));
278: choosePackage("Custom");
279: }
280: return carCustomizers;
281: }
282:
283: //
284: // private methods
285: //
286:
287: private String getCurrentModelName() {
288: return currentModelName;
289: }
290:
291: private void setCurrentModelName(String newName) {
292: currentModelName = newName;
293: }
294:
295: // package private util methods
296:
297: static Class loadClass(String name, Object fallbackClass)
298: throws ClassNotFoundException {
299: ClassLoader loader = getCurrentLoader(fallbackClass);
300: return loader.loadClass(name);
301: }
302:
303: static ClassLoader getCurrentLoader(Object fallbackClass) {
304: ClassLoader loader = Thread.currentThread()
305: .getContextClassLoader();
306: if (loader == null) {
307: loader = fallbackClass.getClass().getClassLoader();
308: }
309: return loader;
310: }
311:
312: }
|