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.render;
019:
020: import java.io.IOException;
021: import java.io.Writer;
022: import java.util.Collection;
023: import java.util.HashMap;
024: import java.util.Iterator;
025: import java.util.Map;
026:
027: import de.finix.contelligent.CallData;
028: import de.finix.contelligent.Component;
029: import de.finix.contelligent.ComponentContext;
030: import de.finix.contelligent.ComponentManager;
031: import de.finix.contelligent.ComponentNotFoundException;
032: import de.finix.contelligent.ComponentPath;
033: import de.finix.contelligent.category.CategoryCombinationNotSupportedException;
034: import de.finix.contelligent.category.CategoryManager;
035: import de.finix.contelligent.core.ContelligentSession;
036: import de.finix.contelligent.core.security.ComponentPermission;
037: import de.finix.contelligent.core.security.User;
038: import de.finix.contelligent.exception.ContelligentException;
039: import de.finix.contelligent.exception.NoReadPermissionException;
040: import de.finix.contelligent.logging.LoggingService;
041: import de.finix.contelligent.resource.TextResource;
042: import de.finix.contelligent.util.ThreadedMem;
043:
044: public class TemplateRenderer implements Renderer {
045: final static org.apache.log4j.Logger log = LoggingService
046: .getLogger(TemplateRenderer.class);
047:
048: public final static String MODE = "mode";
049:
050: public final static String MODE_MARKUP = "markup";
051:
052: public final static String MODE_PATH = "path";
053:
054: public final static String MODE_REF = "ref"; // this is the default
055:
056: public final static String MODE_LINK = "link";
057:
058: public final static String MODE_REF_PARAMETER = "refAppendParameter";
059:
060: public final static String MODE_PARAM_DESCRIPTION = "mode_description";
061:
062: final static public String TEXT = "text";
063:
064: final static public String TARGET = "target";
065:
066: // HTTP variant switch
067: public final static String FORCE_PROTOCOL = "forceProtocol";
068:
069: public final static String FORCE_PROTOCOL_HTTP = "HTTP";
070:
071: public final static String FORCE_PROTOCOL_HTTPS = "HTTPS";
072:
073: public final static String FORCE_PROTOCOL_PARAM_DESCRIPTION = "force_protocol_description";
074:
075: // HTTP Auth switch
076: public final static String USE_HTTP_AUTH = "forceHTTPAuth";
077:
078: public final static String USE_HTTP_AUTH_WEB = "WEB";
079:
080: public final static String USE_HTTP_AUTH_HTTP = "HTTP";
081:
082: public final static String USE_HTTP_AUTH_PARAM_DESCRIPTION = "use_http_auth_param_description";
083:
084: protected final boolean isBlueprintRoot;
085:
086: protected final Component component;
087:
088: protected final ComponentPath blueprintPath;
089:
090: protected final Collection sensitiveCategories;
091:
092: protected final Map templateMap;
093:
094: protected final CategoryManager categoryManager;
095:
096: protected String extension = Renderable.TYPE_SUFFIX;
097:
098: public TemplateRenderer(Component component) throws Exception {
099: this .component = component;
100: ComponentContext ctx = component.getComponentContext();
101: this .categoryManager = ctx.getSystem().getCategoryManager();
102: blueprintPath = ctx.getType().getBlueprintPath();
103: if (blueprintPath == null
104: || ctx.getPath().equals(blueprintPath)) {
105: // either component defines blueprint or component is no instance of
106: // any blueprint, in both cases
107: // use my template:
108: isBlueprintRoot = true;
109: sensitiveCategories = ctx.getSensitiveTemplateCategories();
110: templateMap = new HashMap();
111: Iterator it = ctx.getTemplateResourceIdentifiers()
112: .iterator();
113: while (it.hasNext()) {
114: String identifier = (String) it.next();
115: templateMap.put(identifier, new Template(
116: ((TextResource) ctx
117: .getTemplateResource(identifier))
118: .getString()));
119: }
120: categoryManager.completeCategoryToResourceMapping(
121: sensitiveCategories, templateMap);
122: } else {
123: isBlueprintRoot = false;
124: templateMap = null;
125: sensitiveCategories = null;
126: }
127: }
128:
129: public Collection getSensitiveCategories() {
130: if (!isBlueprintRoot) {
131: try {
132: ComponentManager manager = ThreadedMem
133: .getActualManager();
134: Component blueprintRoot = manager.getComponent(
135: blueprintPath, ThreadedMem.getCallData());
136: return blueprintRoot.getComponentContext()
137: .getSensitiveTemplateCategories();
138: } catch (ComponentNotFoundException e) {
139: log.warn("Could not find blueprint component "
140: + blueprintPath);
141: return sensitiveCategories;
142: }
143: }
144: return sensitiveCategories;
145: }
146:
147: public ParameterDescription[] getParameterDescription() {
148: return new ParameterDescription[] {
149: new ParameterDescription(MODE, MODE_PARAM_DESCRIPTION,
150: ParameterDescription.OPTIONAL,
151: ParameterDescription.CONSTRAINED, new String[] {
152: MODE_MARKUP, MODE_REF,
153: MODE_REF_PARAMETER, MODE_PATH,
154: MODE_LINK }),
155: new ParameterDescription(FORCE_PROTOCOL,
156: FORCE_PROTOCOL_PARAM_DESCRIPTION,
157: ParameterDescription.OPTIONAL,
158: ParameterDescription.CONSTRAINED, new String[] {
159: FORCE_PROTOCOL_HTTP,
160: FORCE_PROTOCOL_HTTPS }),
161: new ParameterDescription(USE_HTTP_AUTH,
162: USE_HTTP_AUTH_PARAM_DESCRIPTION,
163: ParameterDescription.OPTIONAL,
164: ParameterDescription.CONSTRAINED, new String[] {
165: USE_HTTP_AUTH_HTTP, USE_HTTP_AUTH_WEB }) };
166: }
167:
168: protected CategoryManager getCategoryManager() {
169: return categoryManager;
170: }
171:
172: public void render(Writer writer, Map parameterMap,
173: CallData callData) throws ContelligentException,
174: IOException {
175: if (parameterMap != null && parameterMap.containsKey(MODE)) {
176: if (log.isDebugEnabled()) {
177: log.debug("render() - parameter '" + MODE
178: + "' found with value '"
179: + ((String[]) parameterMap.get(MODE))[0] + "'");
180: }
181:
182: boolean forceProtocolHttp = false;
183: boolean forceProtocolHttps = false;
184:
185: if (parameterMap != null
186: && parameterMap.containsKey(FORCE_PROTOCOL)) {
187: if (((String[]) parameterMap.get(FORCE_PROTOCOL))[0]
188: .equals(FORCE_PROTOCOL_HTTPS)) {
189: forceProtocolHttps = true;
190: } else if (((String[]) parameterMap.get(FORCE_PROTOCOL))[0]
191: .equals(FORCE_PROTOCOL_HTTP)) {
192: forceProtocolHttp = true;
193: } else {
194: log
195: .error("FORCE_PROTOCOL parameter map value set to illegal Value! [Source Component: "
196: + component.getComponentContext()
197: .getPath().toString() + "]");
198: }
199: }
200:
201: boolean useAuthWeb = false;
202: boolean useAuthHttp = false;
203:
204: if (parameterMap != null
205: && parameterMap.containsKey(USE_HTTP_AUTH)) {
206: if (((String[]) parameterMap.get(USE_HTTP_AUTH))[0]
207: .equals(USE_HTTP_AUTH_HTTP)) {
208: useAuthHttp = true;
209: } else if (((String[]) parameterMap.get(USE_HTTP_AUTH))[0]
210: .equals(USE_HTTP_AUTH_WEB)) {
211: useAuthWeb = true;
212: } else {
213: log
214: .error("USE_AUTH parameter map value set to illegal Value! [Source Component: "
215: + component.getComponentContext()
216: .getPath().toString() + "]");
217: }
218: }
219:
220: if (((String[]) parameterMap.get(MODE))[0].equals(MODE_REF)) {
221: renderReference(writer, callData, false,
222: forceProtocolHttp, forceProtocolHttps,
223: useAuthHttp, useAuthWeb);
224: return;
225: }
226: if (((String[]) parameterMap.get(MODE))[0]
227: .equals(MODE_LINK)) {
228: writer.write("<a href=\"");
229: renderReference(writer, callData, false,
230: forceProtocolHttp, forceProtocolHttps,
231: useAuthHttp, useAuthWeb);
232: if ((String[]) parameterMap.get(TARGET) != null) {
233: writer.write("\" target=\"");
234: writer
235: .write(((String[]) parameterMap.get(TARGET))[0]);
236: }
237: writer.write("\">");
238: if ((String[]) parameterMap.get(TEXT) != null) {
239: writer
240: .write(((String[]) parameterMap.get(TEXT))[0]);
241: }
242: writer.write("</a>");
243: return;
244: }
245:
246: if (((String[]) parameterMap.get(MODE))[0]
247: .equals(MODE_REF_PARAMETER)) {
248: renderReference(writer, callData, true,
249: forceProtocolHttp, forceProtocolHttps,
250: useAuthHttp, useAuthWeb);
251: return;
252: }
253: if (((String[]) parameterMap.get(MODE))[0]
254: .equals(MODE_PATH)) {
255: renderPath(writer, callData, true);
256: return;
257: }
258:
259: }
260: // if we reach this point mode was either not set or is MODE_MARKUP:
261: ContelligentSession session = (ContelligentSession) callData
262: .getContelligentSession();
263: User caller = session.getUser();
264: if (!callData.getActualManager().callerHasPermission(caller,
265: callData, component, ComponentPermission.READ)) {
266: throw new NoReadPermissionException(caller, component
267: .getComponentContext().getPath());
268: }
269: Template template = getTemplate(callData);
270: if (template != null) {
271: template.write(writer, component, callData);
272: } else {
273: log.error("'" + component.getComponentContext().getPath()
274: + "':render() - template not defined!");
275: }
276: }
277:
278: public void renderReference(Writer writer, CallData callData,
279: boolean refParameter) throws ContelligentException,
280: IOException {
281: renderReference(writer, callData, refParameter, false, false,
282: false, false);
283: }
284:
285: public void renderReference(Writer writer, CallData callData,
286: boolean refParameter, boolean forceProtocolHttp,
287: boolean forceProtocolHttps, boolean forceAuthHttp,
288: boolean forceAuthWeb) throws ContelligentException,
289: IOException {
290: StringBuffer url = new StringBuffer(256);
291:
292: String base = callData.getCurrentBaseURL(forceProtocolHttp,
293: forceProtocolHttps, forceAuthHttp, forceAuthWeb);
294:
295: url.append(base).append(
296: component.getComponentContext().getPath()).append(
297: extension);
298: if (refParameter) {
299: url.append("?");
300: }
301: writer.write(callData.encodeURL(url.toString()));
302: }
303:
304: protected void renderPath(Writer writer, CallData callData,
305: boolean refParameter) throws IOException {
306: StringBuffer url = new StringBuffer(256);
307:
308: url.append(component.getComponentContext().getPath());
309:
310: writer.write(callData.encodeURL(url.toString()));
311: }
312:
313: /**
314: * Returns the template from either the blueprint root or from templateMap
315: * if the associated component defines a blueprint itself. If the template
316: * for any category combination is not yet defined this method returns null.
317: * If the given category combination is not supported by the associated
318: * component a <code>CategoryCombinationNotSupportedException</code> is
319: * thrown.
320: */
321: public Template getTemplate(CallData callData)
322: throws CategoryCombinationNotSupportedException,
323: ContelligentException, IOException {
324: if (!isBlueprintRoot) {
325: ComponentManager manager = callData.getActualManager();
326: Component blueprintRoot = manager.getComponent(
327: blueprintPath, callData);
328: if (blueprintRoot instanceof Renderable) {
329: Renderer renderer = ((Renderable) blueprintRoot)
330: .getRenderer();
331: if (renderer instanceof TemplateRenderer) {
332: return ((TemplateRenderer) renderer)
333: .getTemplate(callData);
334: }
335: }
336: throw new ContelligentException(
337: "Could not get template from blueprint-root '"
338: + blueprintPath + "'!");
339: } else {
340: Map categoryMap = callData.getCategoryMap();
341: String identifier = categoryManager
342: .createUniqueCategoryIdentifier(
343: getSensitiveCategories(), categoryMap);
344: Template template = (Template) templateMap.get(identifier);
345: if (template != null) {
346: return template;
347: } else {
348: log
349: .warn("getTemplate(): The requested template for category combination ["
350: + identifier + "] is not yet defined!");
351: return null;
352: }
353: }
354: }
355:
356: protected Component getComponent() {
357: return component;
358: }
359:
360: public String getTypeName() {
361: return "template";
362: }
363: }
|