001 /*
002 * This file is part of the Echo Point Project. This project is a
003 * collection of Components that have extended the Echo Web Application
004 * Framework Version 3.
005 *
006 * Version: MPL 1.1
007 *
008 * The contents of this file are subject to the Mozilla Public License Version
009 * 1.1 (the "License"); you may not use this file except in compliance with
010 * the License. You may obtain a copy of the License at
011 * http://www.mozilla.org/MPL/
012 *
013 * Software distributed under the License is distributed on an "AS IS" basis,
014 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
015 * for the specific language governing rights and limitations under the
016 * License.
017 */
018 package echopoint;
019
020 import nextapp.echo.app.PaneContainer;
021 import nextapp.echo.app.Component;
022
023 import java.util.HashMap;
024 import java.util.Map;
025
026 import echopoint.template.TemplateDataSource;
027
028 /**
029 * <code>TemplatePanel</code> is a container that uses a
030 * <code>TemplateLayoutData</code> to render a template of content.
031 * <p>
032 * This layout data can itself contained "named" Components and "named" Text
033 * Substitutions.
034 * <p>
035 * A singleton <code>TemplateDataSource</code> can be used for more than one
036 * <code>TemplatePanel</code> and hence the memory footprint is reduced if
037 * used in this way.
038 * <p>
039 * <h3>Supplied Implementation</h3>
040 * <p>
041 * The supplied template implementation reads XHTML template data from a number
042 * of different sources including Files, Strings, Resources and JSP pages.
043 * <p>
044 * The markup :
045 *
046 * <pre><code>
047 *
048 *
049 * <component name="xxx" />
050 *
051 *
052 * </code></pre>
053 *
054 * is used to indicate where in the template a named component will be placed.
055 * <p>
056 *
057 * In EchopointNG it was possible to set style and css properties. This feature is not implemented yet.
058 *
059 */
060 public class TemplatePanel extends Component implements PaneContainer {
061
062
063 public static final String PROPERTY_TEMPLATE_DATA_SOURCE = "templateDataSource";
064 public static final String PROPERTY_COMPONENT_MAPPING = "componentmapping";
065
066 /**
067 * Constructs a <code>TemplatePanel</code> with no template data as yet.
068 */
069 public TemplatePanel() {
070 super();
071 set(PROPERTY_COMPONENT_MAPPING, new HashMap());
072 }
073
074 /**
075 * Constructs a <code>TemplatePanel</code> with the specified
076 * TemplateDataSource.
077 *
078 * @param tds -
079 * the source for the template data.
080 */
081 public TemplatePanel(TemplateDataSource tds) {
082 super();
083 setTemplateDataSource(tds);
084 set(PROPERTY_COMPONENT_MAPPING, new HashMap());
085 }
086
087
088 /**
089 * Sets the TemplateDataSource to be used
090 *
091 * @param templateDataSource
092 * the TemplateDataSource to be used
093 */
094 public void setTemplateDataSource(TemplateDataSource templateDataSource) {
095 set(PROPERTY_TEMPLATE_DATA_SOURCE, templateDataSource);
096 }
097
098 /**
099 * Returns the TemplateDataSource which contains the template data.
100 *
101 * @return the TemplateDataSource in place
102 */
103 public TemplateDataSource getTemplateDataSource()
104 {
105 return (TemplateDataSource) get(PROPERTY_TEMPLATE_DATA_SOURCE);
106 }
107
108
109 /**
110 * Adds a component to the <code>TemplatePanel</code> with the associated
111 * name which can the be references from the template data.
112 *
113 * @param component
114 * the component to add
115 * @param componentName -
116 * the name to use when referencing this component in the
117 * template data.
118 */
119 public void addNamedComponent(Component component, String componentName) {
120 if (component == null)
121 throw new IllegalArgumentException("component must be non null.");
122 if (componentName == null)
123 throw new IllegalArgumentException("componentName must be non null.");
124
125 ((Map) get(PROPERTY_COMPONENT_MAPPING)).put(componentName, component);
126 add(component);
127 }
128
129 Map getComponentMapping()
130 {
131 return (Map) get(PROPERTY_COMPONENT_MAPPING);
132 }
133
134 /**
135 * Returns the name associated with the component or null if it cant be
136 * found.
137 *
138 * @param component -
139 * the component associated with the name
140 * @return a name associated with component
141 */
142 public String getComponentName(Component component) {
143 String componentNames[] = getNamedComponents();
144 for (int i = 0; i < componentNames.length; i++) {
145 Component c = getNamedComponent(componentNames[i]);
146 if (component == c) {
147 return componentNames[i];
148 }
149 }
150 return null;
151 }
152
153
154 /**
155 * Returns a component associated with the name or null if it cant be found.
156 *
157 * @param componentName -
158 * the name associated with the component
159 * @return a component associated with componentName
160 */
161 public Component getNamedComponent(String componentName) {
162 return (Component) ((Map) get(PROPERTY_COMPONENT_MAPPING)).get((componentName));
163 }
164
165 /**
166 * @return an array of all the component names in the
167 * <code>TemplatePanel</code>.
168 */
169 public String[] getNamedComponents() {
170 Map componentNameMap = ((Map) get(PROPERTY_COMPONENT_MAPPING));
171 return (String[]) componentNameMap.keySet().toArray(new String[componentNameMap.keySet().size()]);
172 }
173
174
175 /**
176 * @see nextapp.echo.app.Component#remove(nextapp.echo.app.Component)
177 */
178 public void remove(Component c) {
179 String componentName = getComponentName(c);
180 if (componentName != null) {
181 ((Map) get(PROPERTY_COMPONENT_MAPPING)).remove(componentName);
182 }
183 super.remove(c);
184 }
185
186 /**
187 * Removes a named component from the <code>TemplatePanel</code> that was
188 * previously added via the <code>addNamedComponent()</code> method.
189 *
190 * @param componentName -
191 * the name of the component
192 */
193 public void removeNamedComponent(String componentName) {
194 if (componentName == null)
195 throw new IllegalArgumentException("componentName must be non null.");
196
197 Component child = getNamedComponent(componentName);
198 ((Map) get(PROPERTY_COMPONENT_MAPPING)).remove(componentName);
199 if (child != null) {
200 remove(child);
201 }
202 }
203
204 }