001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package com.sun.rave.web.ui.renderer.template;
042:
043: import com.sun.rave.web.ui.component.util.descriptors.LayoutDefinition;
044:
045: import java.lang.reflect.InvocationTargetException;
046: import java.io.IOException;
047: import java.util.HashMap;
048: import java.util.Iterator;
049: import java.util.List;
050: import java.util.Map;
051:
052: import javax.faces.context.FacesContext;
053: import javax.faces.context.ResponseWriter;
054: import javax.faces.component.UIColumn;
055: import javax.faces.component.UIComponent;
056: import javax.faces.component.UIData;
057: import javax.faces.component.UIViewRoot;
058: import javax.faces.render.Renderer;
059:
060: /**
061: * <P> This abstract class provides the base functionality for all
062: * <code>LayoutDefinitionManager</code> implementations. It provides an
063: * static method used to obtain an instance of a concrete
064: * <code>LayoutDefinitionManager</code>: {@link #getManager(FacesContext)}.
065: * It also provides another version of this method which allows a specific
066: * instance to be specified by classname:
067: * {@link #getManager(String className)} (typically not used, the
068: * environment should be setup to provide the correct
069: * <code>LayoutDefinitionManager</code>). Once an instance is obtained,
070: * the {@link #getLayoutDefinition(String key)} method can be invoked to
071: * obtain a {@link com.sun.rave.web.ui.component.util.descriptors.LayoutDefinition}.
072: * </P>
073: *
074: * @author Ken Paulsen (ken.paulsen@sun.com)
075: */
076: public abstract class LayoutDefinitionManager {
077:
078: /**
079: * Constructor.
080: */
081: protected LayoutDefinitionManager() {
082: super ();
083: }
084:
085: /**
086: * This method is responsible for finding/creating the requested
087: * LayoutDefinition.
088: *
089: * @param key The key used to identify the requested LayoutDefintion
090: */
091: public abstract LayoutDefinition getLayoutDefinition(String key);
092:
093: /**
094: * This is a factory method for obtaining the LayoutDefinitionManager.
095: * This implementation uses the external context's initParams to look for
096: * the LayoutDefinitionManager class. If it exists, the specified
097: * concrete LayoutDefinitionManager class will be used. Otherwise, the
098: * default LayoutDefinitionManager will be used. The initParam key is:
099: * {@link #LAYOUT_DEFINITION_MANAGER_KEY}.
100: *
101: * @param context The FacesContext
102: *
103: * @see #LAYOUT_DEFINITION_MANAGER_KEY
104: */
105: public static LayoutDefinitionManager getManager(
106: FacesContext context) {
107: // FIXME: Decide how to define the LAYOUT_DEFINITION_MANAGER
108: // FIXME: Properties should be settable on the LDM, such as entity resolvers...
109: Map initParams = context.getExternalContext()
110: .getInitParameterMap();
111: String className = DEFAULT_LAYOUT_DEFINITION_MANAGER_IMPL;
112: if (initParams.containsKey(LAYOUT_DEFINITION_MANAGER_KEY)) {
113: className = (String) initParams
114: .get(LAYOUT_DEFINITION_MANAGER_KEY);
115: }
116: return getManager(className);
117: }
118:
119: /**
120: * This method is a singleton factory method for obtaining an instance of
121: * a LayoutDefintionManager. It is possible that multiple different
122: * implementations of LayoutDefinitionManagers will be used within the
123: * same JVM. This is OK, the purpose of the LayoutDefinitionManager is
124: * primarily performance. Someone may provide a different
125: * LayoutDefinitionManager to locate LayoutDefiniton's in a different way
126: * (XML, database, file, java code, etc.).
127: */
128: public static LayoutDefinitionManager getManager(String className) {
129: LayoutDefinitionManager ldm = (LayoutDefinitionManager) _instances
130: .get(className);
131: if (ldm == null) {
132: try {
133: ldm = (LayoutDefinitionManager) Class
134: .forName(className).getMethod("getInstance",
135: null).invoke(null, null);
136: } catch (ClassNotFoundException ex) {
137: throw new RuntimeException(ex);
138: } catch (NoSuchMethodException ex) {
139: throw new RuntimeException(ex);
140: } catch (IllegalAccessException ex) {
141: throw new RuntimeException(ex);
142: } catch (InvocationTargetException ex) {
143: throw new RuntimeException(ex);
144: } catch (NullPointerException ex) {
145: throw new RuntimeException(ex);
146: } catch (ClassCastException ex) {
147: throw new RuntimeException(ex);
148: }
149: _instances.put(className, ldm);
150: }
151: return ldm;
152: }
153:
154: /**
155: * Retrieve an attribute by key
156: *
157: * @param key The key used to retrieve the attribute
158: *
159: * @return The requested attribute or null
160: */
161: public Object getAttribute(String key) {
162: return _attributes.get(key);
163: }
164:
165: /**
166: * Associate the given key with the given Object as an attribute.
167: *
168: * @param key The key associated with the given object (if this key
169: * is already in use, it will replace the previously set attribute
170: * object).
171: *
172: * @param value The Object to store.
173: */
174: public void setAttribute(String key, Object value) {
175: _attributes.put(key, value);
176: }
177:
178: /**
179: * This map contains sub-class specific attributes that may be needed by
180: * specific implementations of LayoutDefinitionManagers. For example,
181: * setting an EntityResolver on a LayoutDefinitionManager that creates
182: * LayoutDefinitions from XML files.
183: */
184: private Map _attributes = new HashMap();
185:
186: // FIXME: Rethink this... since I am allowing LDM's to be parameterized via
187: // FIXME: attributes, it is not enough to have 1 LDM... we will need 1 per
188: // FIXME: application. Or... I need to move the attributes.
189: /**
190: * Static map of LayoutDefinitionManagers. Normally this will only
191: * contain the default LayoutManager.
192: */
193: private static Map _instances = new HashMap(2);
194:
195: /**
196: * This constant defines the default layout definition manager
197: * implementation class name.
198: */
199: public static final String DEFAULT_LAYOUT_DEFINITION_MANAGER_IMPL = "com.sun.rave.web.ui.renderer.template.xml.XMLLayoutDefinitionManager";
200:
201: /**
202: * This constant defines the layout definition manager implementation key
203: * for initParams. ("layoutManagerImpl")
204: */
205: public static final String LAYOUT_DEFINITION_MANAGER_KEY = "layoutManagerImpl";
206: }
|