001: /* ***** BEGIN LICENSE BLOCK *****
002: * Version: MPL 1.1
003: * The contents of this file are subject to the Mozilla Public License Version
004: * 1.1 (the "License"); you may not use this file except in compliance with
005: * the License. You may obtain a copy of the License at
006: * http://www.mozilla.org/MPL/
007: *
008: * Software distributed under the License is distributed on an "AS IS" basis,
009: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
010: * for the specific language governing rights and limitations under the
011: * License.
012: *
013: * The Original Code is Riot.
014: *
015: * The Initial Developer of the Original Code is
016: * Neteye GmbH.
017: * Portions created by the Initial Developer are Copyright (C) 2006
018: * the Initial Developer. All Rights Reserved.
019: *
020: * Contributor(s):
021: * Felix Gnass [fgnass at neteye dot de]
022: *
023: * ***** END LICENSE BLOCK ***** */
024: package org.riotfamily.components.controller.render;
025:
026: import java.io.IOException;
027: import java.util.Iterator;
028: import java.util.List;
029:
030: import javax.servlet.http.HttpServletRequest;
031: import javax.servlet.http.HttpServletResponse;
032:
033: import org.apache.commons.logging.Log;
034: import org.apache.commons.logging.LogFactory;
035: import org.riotfamily.components.config.ComponentListConfiguration;
036: import org.riotfamily.components.config.ComponentRepository;
037: import org.riotfamily.components.config.component.AbstractComponent;
038: import org.riotfamily.components.config.component.Component;
039: import org.riotfamily.components.dao.ComponentDao;
040: import org.riotfamily.components.model.ComponentList;
041: import org.riotfamily.components.model.ComponentVersion;
042: import org.riotfamily.components.model.Location;
043: import org.riotfamily.components.model.VersionContainer;
044:
045: public class AbstractRenderStrategy implements RenderStrategy {
046:
047: public static final String INHERTING_COMPONENT = "inherit";
048:
049: protected Log log = LogFactory.getLog(getClass());
050:
051: protected ComponentDao dao;
052:
053: protected ComponentRepository repository;
054:
055: protected ComponentListConfiguration config;
056:
057: public AbstractRenderStrategy(ComponentDao dao,
058: ComponentRepository repository,
059: ComponentListConfiguration config) {
060:
061: this .dao = dao;
062: this .repository = repository;
063: this .config = config;
064: }
065:
066: public final void render(HttpServletRequest request,
067: HttpServletResponse response) throws Exception {
068:
069: Location location = getLocation(request);
070: render(location, request, response);
071: }
072:
073: protected void render(Location location,
074: HttpServletRequest request, HttpServletResponse response)
075: throws Exception {
076:
077: ComponentList list = getComponentList(location, request);
078: if (list != null) {
079: renderComponentList(list, request, response);
080: } else {
081: onListNotFound(location, request, response);
082: }
083: }
084:
085: public void render(ComponentList list, HttpServletRequest request,
086: HttpServletResponse response) throws Exception {
087:
088: renderComponentList(list, request, response);
089: }
090:
091: protected final Location getLocation(HttpServletRequest request) {
092: Location location = config.getLocator().getLocation(request);
093: log.debug("List location: " + location);
094: return location;
095: }
096:
097: protected void onListNotFound(Location location,
098: HttpServletRequest request, HttpServletResponse response)
099: throws Exception {
100:
101: log.debug("No ComponentList found for " + location);
102: }
103:
104: protected VersionContainer getParentContainer(
105: HttpServletRequest request) {
106: return (VersionContainer) request
107: .getAttribute(AbstractComponent.CONTAINER);
108: }
109:
110: /**
111: * Returns the ComponentList to be rendered. The default implementation
112: * uses the controller's ComponentDao to look up a list for the given
113: * location.
114: */
115: protected ComponentList getComponentList(Location location,
116: HttpServletRequest request) {
117:
118: VersionContainer parent = getParentContainer(request);
119: if (parent != null) {
120: return dao.findComponentList(parent, location.getSlot());
121: }
122: return dao.findComponentList(location);
123: }
124:
125: /**
126: * Renders the given list. The default implementation calls
127: * {@link #getComponentsToRender(ComponentList)} and passes the result
128: * to {@link #renderComponents(List)}.
129: */
130: protected void renderComponentList(ComponentList list,
131: HttpServletRequest request, HttpServletResponse response)
132: throws Exception {
133:
134: List components = getComponentsToRender(list);
135: renderComponents(components, request, response);
136: }
137:
138: /**
139: * Renders the given list. The default implementation iterates over the
140: * given list and calls {@link #renderContainer(VersionContainer, String)}
141: * for each item. If the list is empty or null,
142: * {@link #onEmptyComponentList(HttpServletRequest, HttpServletResponse)} is invoked.
143: */
144: protected final void renderComponents(List components,
145: HttpServletRequest request, HttpServletResponse response)
146: throws Exception {
147:
148: if (components == null || components.isEmpty()) {
149: onEmptyComponentList(request, response);
150: return;
151: }
152:
153: int i = 0;
154: Iterator it = components.iterator();
155: while (it.hasNext()) {
156: VersionContainer container = (VersionContainer) it.next();
157: renderContainer(container, getPositionalClassName(i++, !it
158: .hasNext()), request, response);
159: }
160: }
161:
162: protected void onEmptyComponentList(HttpServletRequest request,
163: HttpServletResponse response) throws Exception {
164:
165: }
166:
167: /**
168: * Returns a list of VersionContainers. The default implementation
169: * simply returns the list's live components.
170: */
171: protected List getComponentsToRender(ComponentList list) {
172: return list.getLiveContainers();
173: }
174:
175: /**
176: * Renders the given VersionContainer. The default implementation calls
177: * {@link #getVersionToRender(VersionContainer) getVersionToRender()} and
178: * passes the result to {@link #renderComponentVersion(ComponentVersion, String)
179: * renderComponentVersion()} (if not null).
180: */
181: protected void renderContainer(VersionContainer container,
182: String positionClassName, HttpServletRequest request,
183: HttpServletResponse response) throws Exception {
184:
185: ComponentVersion version = getVersionToRender(container);
186: if (version != null) {
187: renderComponentVersion(version, positionClassName, request,
188: response);
189: }
190: }
191:
192: /**
193: * Returns the ComponentVersion to render. The default implementation
194: * simply returns the component's live version.
195: */
196: protected ComponentVersion getVersionToRender(
197: VersionContainer container) {
198: return container.getLiveVersion();
199: }
200:
201: /**
202: * Renders the given ComponentVersion.
203: */
204: protected final void renderComponentVersion(
205: ComponentVersion version, String positionClassName,
206: HttpServletRequest request, HttpServletResponse response)
207: throws Exception {
208:
209: String type = version.getType();
210: if (INHERTING_COMPONENT.equals(type)) {
211: renderParentList(version.getContainer().getList(), request,
212: response);
213: } else {
214: Component component = repository.getComponent(type);
215: renderComponent(component, version, positionClassName,
216: request, response);
217: }
218: }
219:
220: protected final void renderParentList(ComponentList list,
221: HttpServletRequest request, HttpServletResponse response)
222: throws Exception {
223:
224: Location location = list.getLocation();
225: Location parentLocation = config.getLocator()
226: .getParentLocation(location);
227: log.debug("Parent location: " + parentLocation);
228:
229: if (parentLocation != null) {
230: if (location.equals(parentLocation)) {
231: log.warn("Parent location is the same");
232: return;
233: }
234: ComponentList parentList = getComponentList(parentLocation,
235: request);
236: if (parentList != null) {
237: getStrategyForParentList().render(parentList, request,
238: response);
239: } else {
240: onListNotFound(parentLocation, request, response);
241: }
242: }
243: }
244:
245: protected RenderStrategy getStrategyForParentList()
246: throws IOException {
247: return this ;
248: }
249:
250: protected void renderComponent(Component component,
251: ComponentVersion version, String positionClassName,
252: HttpServletRequest request, HttpServletResponse response)
253: throws Exception {
254:
255: component.render(version, positionClassName, request, response);
256: }
257:
258: protected String getPositionalClassName(int position, boolean last) {
259: StringBuffer sb = new StringBuffer("component-")
260: .append(position + 1);
261: if (last) {
262: sb.append(" last-component");
263: }
264: return sb.toString();
265: }
266:
267: }
|