/*
* Copyright 2001-2006 C:1 Financial Services GmbH
*
* This software is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License Version 2.1, as published by the Free Software Foundation.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
*/
package de.finix.contelligent.render;
import java.io.IOException;
import java.io.Writer;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import de.finix.contelligent.CallData;
import de.finix.contelligent.Component;
import de.finix.contelligent.ComponentContext;
import de.finix.contelligent.ComponentManager;
import de.finix.contelligent.ComponentNotFoundException;
import de.finix.contelligent.ComponentPath;
import de.finix.contelligent.category.CategoryCombinationNotSupportedException;
import de.finix.contelligent.category.CategoryManager;
import de.finix.contelligent.core.ContelligentSession;
import de.finix.contelligent.core.security.ComponentPermission;
import de.finix.contelligent.core.security.User;
import de.finix.contelligent.exception.ContelligentException;
import de.finix.contelligent.exception.NoReadPermissionException;
import de.finix.contelligent.logging.LoggingService;
import de.finix.contelligent.resource.TextResource;
import de.finix.contelligent.util.ThreadedMem;
public class TemplateRenderer implements Renderer {
final static org.apache.log4j.Logger log = LoggingService.getLogger(TemplateRenderer.class);
public final static String MODE = "mode";
public final static String MODE_MARKUP = "markup";
public final static String MODE_PATH = "path";
public final static String MODE_REF = "ref"; // this is the default
public final static String MODE_LINK = "link";
public final static String MODE_REF_PARAMETER = "refAppendParameter";
public final static String MODE_PARAM_DESCRIPTION = "mode_description";
final static public String TEXT = "text";
final static public String TARGET = "target";
// HTTP variant switch
public final static String FORCE_PROTOCOL = "forceProtocol";
public final static String FORCE_PROTOCOL_HTTP = "HTTP";
public final static String FORCE_PROTOCOL_HTTPS = "HTTPS";
public final static String FORCE_PROTOCOL_PARAM_DESCRIPTION = "force_protocol_description";
// HTTP Auth switch
public final static String USE_HTTP_AUTH = "forceHTTPAuth";
public final static String USE_HTTP_AUTH_WEB = "WEB";
public final static String USE_HTTP_AUTH_HTTP = "HTTP";
public final static String USE_HTTP_AUTH_PARAM_DESCRIPTION = "use_http_auth_param_description";
protected final boolean isBlueprintRoot;
protected final Component component;
protected final ComponentPath blueprintPath;
protected final Collection sensitiveCategories;
protected final Map templateMap;
protected final CategoryManager categoryManager;
protected String extension = Renderable.TYPE_SUFFIX;
public TemplateRenderer(Component component) throws Exception {
this.component = component;
ComponentContext ctx = component.getComponentContext();
this.categoryManager = ctx.getSystem().getCategoryManager();
blueprintPath = ctx.getType().getBlueprintPath();
if (blueprintPath == null || ctx.getPath().equals(blueprintPath)) {
// either component defines blueprint or component is no instance of
// any blueprint, in both cases
// use my template:
isBlueprintRoot = true;
sensitiveCategories = ctx.getSensitiveTemplateCategories();
templateMap = new HashMap();
Iterator it = ctx.getTemplateResourceIdentifiers().iterator();
while (it.hasNext()) {
String identifier = (String) it.next();
templateMap.put(identifier, new Template(((TextResource) ctx.getTemplateResource(identifier))
.getString()));
}
categoryManager.completeCategoryToResourceMapping(sensitiveCategories, templateMap);
} else {
isBlueprintRoot = false;
templateMap = null;
sensitiveCategories = null;
}
}
public Collection getSensitiveCategories() {
if (!isBlueprintRoot) {
try {
ComponentManager manager = ThreadedMem.getActualManager();
Component blueprintRoot = manager.getComponent(blueprintPath, ThreadedMem.getCallData());
return blueprintRoot.getComponentContext().getSensitiveTemplateCategories();
} catch (ComponentNotFoundException e) {
log.warn("Could not find blueprint component " + blueprintPath);
return sensitiveCategories;
}
}
return sensitiveCategories;
}
public ParameterDescription[] getParameterDescription() {
return new ParameterDescription[] {
new ParameterDescription(MODE, MODE_PARAM_DESCRIPTION, ParameterDescription.OPTIONAL,
ParameterDescription.CONSTRAINED, new String[] { MODE_MARKUP, MODE_REF, MODE_REF_PARAMETER,
MODE_PATH, MODE_LINK }),
new ParameterDescription(FORCE_PROTOCOL, FORCE_PROTOCOL_PARAM_DESCRIPTION,
ParameterDescription.OPTIONAL, ParameterDescription.CONSTRAINED, new String[] {
FORCE_PROTOCOL_HTTP, FORCE_PROTOCOL_HTTPS }),
new ParameterDescription(USE_HTTP_AUTH, USE_HTTP_AUTH_PARAM_DESCRIPTION, ParameterDescription.OPTIONAL,
ParameterDescription.CONSTRAINED, new String[] { USE_HTTP_AUTH_HTTP, USE_HTTP_AUTH_WEB }) };
}
protected CategoryManager getCategoryManager() {
return categoryManager;
}
public void render(Writer writer, Map parameterMap, CallData callData) throws ContelligentException, IOException {
if (parameterMap != null && parameterMap.containsKey(MODE)) {
if (log.isDebugEnabled()) {
log.debug("render() - parameter '" + MODE + "' found with value '"
+ ((String[]) parameterMap.get(MODE))[0] + "'");
}
boolean forceProtocolHttp = false;
boolean forceProtocolHttps = false;
if (parameterMap != null && parameterMap.containsKey(FORCE_PROTOCOL)) {
if (((String[]) parameterMap.get(FORCE_PROTOCOL))[0].equals(FORCE_PROTOCOL_HTTPS)) {
forceProtocolHttps = true;
} else if (((String[]) parameterMap.get(FORCE_PROTOCOL))[0].equals(FORCE_PROTOCOL_HTTP)) {
forceProtocolHttp = true;
} else {
log.error("FORCE_PROTOCOL parameter map value set to illegal Value! [Source Component: "
+ component.getComponentContext().getPath().toString() + "]");
}
}
boolean useAuthWeb = false;
boolean useAuthHttp = false;
if (parameterMap != null && parameterMap.containsKey(USE_HTTP_AUTH)) {
if (((String[]) parameterMap.get(USE_HTTP_AUTH))[0].equals(USE_HTTP_AUTH_HTTP)) {
useAuthHttp = true;
} else if (((String[]) parameterMap.get(USE_HTTP_AUTH))[0].equals(USE_HTTP_AUTH_WEB)) {
useAuthWeb = true;
} else {
log.error("USE_AUTH parameter map value set to illegal Value! [Source Component: "
+ component.getComponentContext().getPath().toString() + "]");
}
}
if (((String[]) parameterMap.get(MODE))[0].equals(MODE_REF)) {
renderReference(writer, callData, false, forceProtocolHttp, forceProtocolHttps, useAuthHttp, useAuthWeb);
return;
}
if (((String[]) parameterMap.get(MODE))[0].equals(MODE_LINK)) {
writer.write("<a href=\"");
renderReference(writer, callData, false, forceProtocolHttp, forceProtocolHttps, useAuthHttp, useAuthWeb);
if ((String[]) parameterMap.get(TARGET) != null) {
writer.write("\" target=\"");
writer.write(((String[]) parameterMap.get(TARGET))[0]);
}
writer.write("\">");
if ((String[]) parameterMap.get(TEXT) != null) {
writer.write(((String[]) parameterMap.get(TEXT))[0]);
}
writer.write("</a>");
return;
}
if (((String[]) parameterMap.get(MODE))[0].equals(MODE_REF_PARAMETER)) {
renderReference(writer, callData, true, forceProtocolHttp, forceProtocolHttps, useAuthHttp, useAuthWeb);
return;
}
if (((String[]) parameterMap.get(MODE))[0].equals(MODE_PATH)) {
renderPath(writer, callData, true);
return;
}
}
// if we reach this point mode was either not set or is MODE_MARKUP:
ContelligentSession session = (ContelligentSession) callData.getContelligentSession();
User caller = session.getUser();
if (!callData.getActualManager().callerHasPermission(caller, callData, component, ComponentPermission.READ)) {
throw new NoReadPermissionException(caller, component.getComponentContext().getPath());
}
Template template = getTemplate(callData);
if (template != null) {
template.write(writer, component, callData);
} else {
log.error("'" + component.getComponentContext().getPath() + "':render() - template not defined!");
}
}
public void renderReference(Writer writer, CallData callData, boolean refParameter) throws ContelligentException,
IOException {
renderReference(writer, callData, refParameter, false, false, false, false);
}
public void renderReference(Writer writer, CallData callData, boolean refParameter, boolean forceProtocolHttp,
boolean forceProtocolHttps, boolean forceAuthHttp, boolean forceAuthWeb) throws ContelligentException,
IOException {
StringBuffer url = new StringBuffer(256);
String base = callData.getCurrentBaseURL(forceProtocolHttp, forceProtocolHttps, forceAuthHttp, forceAuthWeb);
url.append(base).append(component.getComponentContext().getPath()).append(extension);
if (refParameter) {
url.append("?");
}
writer.write(callData.encodeURL(url.toString()));
}
protected void renderPath(Writer writer, CallData callData, boolean refParameter) throws IOException {
StringBuffer url = new StringBuffer(256);
url.append(component.getComponentContext().getPath());
writer.write(callData.encodeURL(url.toString()));
}
/**
* Returns the template from either the blueprint root or from templateMap
* if the associated component defines a blueprint itself. If the template
* for any category combination is not yet defined this method returns null.
* If the given category combination is not supported by the associated
* component a <code>CategoryCombinationNotSupportedException</code> is
* thrown.
*/
public Template getTemplate(CallData callData) throws CategoryCombinationNotSupportedException,
ContelligentException, IOException {
if (!isBlueprintRoot) {
ComponentManager manager = callData.getActualManager();
Component blueprintRoot = manager.getComponent(blueprintPath, callData);
if (blueprintRoot instanceof Renderable) {
Renderer renderer = ((Renderable) blueprintRoot).getRenderer();
if (renderer instanceof TemplateRenderer) {
return ((TemplateRenderer) renderer).getTemplate(callData);
}
}
throw new ContelligentException("Could not get template from blueprint-root '" + blueprintPath + "'!");
} else {
Map categoryMap = callData.getCategoryMap();
String identifier = categoryManager.createUniqueCategoryIdentifier(getSensitiveCategories(), categoryMap);
Template template = (Template) templateMap.get(identifier);
if (template != null) {
return template;
} else {
log.warn("getTemplate(): The requested template for category combination [" + identifier
+ "] is not yet defined!");
return null;
}
}
}
protected Component getComponent() {
return component;
}
public String getTypeName() {
return "template";
}
}
|