001: /*
002: * Copyright 2001-2006 C:1 Financial Services GmbH
003: *
004: * This software is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License Version 2.1, as published by the Free Software Foundation.
007: *
008: * This software is distributed in the hope that it will be useful,
009: * but WITHOUT ANY WARRANTY; without even the implied warranty of
010: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
011: * Lesser General Public License for more details.
012: *
013: * You should have received a copy of the GNU Lesser General Public
014: * License along with this library; if not, write to the Free Software
015: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
016: */
017:
018: package de.finix.contelligent.components.util;
019:
020: import java.io.IOException;
021: import java.io.Writer;
022: import java.io.StringWriter;
023: import java.util.ArrayList;
024: import java.util.Collection;
025: import java.util.Collections;
026: import java.util.List;
027: import java.util.Map;
028:
029: import javax.servlet.http.HttpServletResponse;
030:
031: import de.finix.contelligent.CallData;
032: import de.finix.contelligent.Component;
033: import de.finix.contelligent.ComponentManager;
034: import de.finix.contelligent.ComponentNotFoundException;
035: import de.finix.contelligent.ComponentPath;
036: import de.finix.contelligent.ExtensionProvider;
037: import de.finix.contelligent.ExternalRelationSource;
038: import de.finix.contelligent.HTTPCallData;
039: import de.finix.contelligent.ModificationVetoException;
040: import de.finix.contelligent.components.Folder;
041: import de.finix.contelligent.exception.CircularRenderException;
042: import de.finix.contelligent.exception.ContelligentException;
043: import de.finix.contelligent.logging.LoggingService;
044: import de.finix.contelligent.render.ParameterDescription;
045: import de.finix.contelligent.render.Renderable;
046: import de.finix.contelligent.render.Renderer;
047:
048: public class RedirectRenderer extends Folder implements Renderable,
049: Renderer, ExternalRelationSource {
050:
051: final static org.apache.log4j.Logger log = LoggingService
052: .getLogger(RedirectRenderer.class);
053: final static public String URL_COMPONENT_NAME = "url";
054:
055: public final static String FORCE_PROTOCOL_HTTP = "HTTP";
056: public final static String FORCE_PROTOCOL_HTTPS = "HTTPS";
057:
058: public final static String USE_HTTP_AUTH_WEB = "WEB";
059: public final static String USE_HTTP_AUTH_HTTP = "HTTP";
060:
061: private ComponentPath targetPath;
062:
063: String forceProtocolProperty = "current";
064: String forceHttpAuthProperty = "current";
065: boolean readSubcomponent = false;
066:
067: private static ParameterDescription[] parameters = new ParameterDescription[] {};
068:
069: public void setTargetPath(ComponentPath targetPath) {
070: this .targetPath = targetPath;
071: }
072:
073: public ComponentPath getTargetPath() {
074: return targetPath;
075: }
076:
077: public void setForceProtocol(String forceProtocol) {
078: this .forceProtocolProperty = forceProtocol;
079: }
080:
081: public String getForceProtocol() {
082: return forceProtocolProperty;
083: }
084:
085: public void setForceHttpAuth(String forceHttpAuth) {
086: this .forceHttpAuthProperty = forceHttpAuth;
087: }
088:
089: public String getForceHttpAuth() {
090: return forceHttpAuthProperty;
091: }
092:
093: public void setReadSubcomponent(boolean readSubcomponent) {
094: this .readSubcomponent = readSubcomponent;
095: }
096:
097: public boolean getReadSubcomponent() {
098: return readSubcomponent;
099: }
100:
101: public ParameterDescription[] getParameterDescription() {
102: return parameters;
103: }
104:
105: /**
106: * Implementation of {@link Component#mayChangeContent}. This
107: * implementation always returns false.
108: */
109: public boolean mayChangeContent() {
110: return false;
111: }
112:
113: public Renderer getRenderer() {
114: return this ;
115: }
116:
117: public Collection getSensitiveCategories() {
118: return Collections.EMPTY_SET;
119: }
120:
121: public void render(Writer writer, Map parameterMap,
122: CallData callData) throws IOException,
123: ContelligentException {
124:
125: boolean forceProtocolHttp = false;
126: boolean forceProtocolHttps = false;
127: if (forceProtocolProperty.equals(FORCE_PROTOCOL_HTTPS)) {
128: forceProtocolHttps = true;
129: } else if (forceProtocolProperty.equals(FORCE_PROTOCOL_HTTP)) {
130: forceProtocolHttp = true;
131: }
132: boolean useAuthWeb = false;
133: boolean useAuthHttp = false;
134: if (forceHttpAuthProperty.equals(USE_HTTP_AUTH_HTTP)) {
135: useAuthHttp = true;
136: } else if (forceHttpAuthProperty.equals(USE_HTTP_AUTH_WEB)) {
137: useAuthWeb = true;
138: }
139: if (callData instanceof HTTPCallData) {
140:
141: HTTPCallData httpCallData = (HTTPCallData) callData;
142: HttpServletResponse response = httpCallData
143: .getHttpServletResponse();
144: ComponentPath target = getTargetPath();
145:
146: if (target.isRelative()) {
147: target = target.toAbsolutePath(getComponentContext()
148: .getPath());
149: }
150:
151: String extension = Renderable.TYPE_SUFFIX;
152: try {
153: Component comp = callData.getActualManager()
154: .getComponent(target, callData);
155: if (comp instanceof ExtensionProvider) {
156: extension = ((ExtensionProvider) comp)
157: .getExtension(callData);
158: }
159: } catch (ComponentNotFoundException cne) {
160: log.error("Unable to find component.", cne);
161: // Still, continue...
162: }
163:
164: String targetURL = "";
165: if (getReadSubcomponent()) {
166: // property readSubcomponent is "true" - renderable subcomponent url ist expected
167:
168: ComponentManager cm = callData.getActualManager();
169: Component urlSubcomponent = cm.getSubcomponent(this ,
170: URL_COMPONENT_NAME, callData, true);
171: if (urlSubcomponent instanceof Renderable) {
172:
173: Writer urlWriter = new StringWriter();
174: Renderer urlRenderer = ((Renderable) urlSubcomponent)
175: .getRenderer();
176:
177: // Circular render check
178: ComponentPath urlSubCompPath = urlSubcomponent
179: .getComponentContext().getPath();
180: if (callData.checkRenderStack(urlSubCompPath)) {
181: throw new CircularRenderException();
182: }
183:
184: callData.pushRenderStack(urlSubCompPath);
185: urlRenderer.render(urlWriter, parameterMap,
186: callData);
187: callData.popRenderStack();
188:
189: urlWriter.close();
190: targetURL = urlWriter.toString();
191: } else {
192: throw new ContelligentException("Subcomponent "
193: + URL_COMPONENT_NAME
194: + " is not renderable.");
195: }
196: } else {
197: // property readSubcomponent is "false" - use property targetPath
198: targetURL = callData.getCurrentBaseURL(
199: forceProtocolHttp, forceProtocolHttps,
200: useAuthHttp, useAuthWeb)
201: + target.toString() + extension;
202: }
203:
204: response
205: .sendRedirect(callData.encodeRedirectURL(targetURL));
206: }
207: }
208:
209: public synchronized List relatedPaths() {
210: List relatedPaths = new ArrayList(1);
211: relatedPaths.add(getTargetPath());
212: return relatedPaths;
213: }
214:
215: public synchronized void relatedPaths(List newRelatedPaths)
216: throws ModificationVetoException {
217: ComponentPath oldPath = getTargetPath();
218: if (newRelatedPaths.size() != 1) {
219: throw new ModificationVetoException();
220: }
221: ComponentPath newPath = (ComponentPath) newRelatedPaths.get(0);
222: if (newPath != null) {
223: setTargetPath(newPath);
224: log
225: .debug("'"
226: + this
227: + "':updateRelationSources() - changed old folder '"
228: + oldPath + "' to '" + newPath + "'");
229: }
230: }
231:
232: }
|