001 package com.khubla.pragmatach.framework.controller.impl.template;
002
003 import java.io.ByteArrayOutputStream;
004 import java.io.InputStream;
005 import java.net.URI;
006 import java.util.Enumeration;
007 import java.util.HashMap;
008 import java.util.Hashtable;
009 import java.util.Map;
010
011 import javax.servlet.http.HttpServletRequest;
012
013 import org.apache.commons.io.IOUtils;
014
015 import com.khubla.pragmatach.framework.annotation.Controller;
016 import com.khubla.pragmatach.framework.annotation.View;
017 import com.khubla.pragmatach.framework.api.PragmatachException;
018 import com.khubla.pragmatach.framework.controller.PragmatachController;
019 import com.khubla.pragmatach.framework.controller.SessionScopedControllers;
020 import com.khubla.pragmatach.framework.controller.impl.AbstractController;
021 import com.khubla.pragmatach.framework.i8n.I8NProviders;
022 import com.khubla.pragmatach.framework.i8n.I8NResolver;
023 import com.khubla.pragmatach.framework.plugin.PluginDescriptor;
024 import com.khubla.pragmatach.framework.plugin.PluginDescriptors;
025
026 /**
027 * @author tome
028 */
029 public class AbstractTemplateEngineController extends AbstractController {
030 /**
031 * state variables
032 */
033 private static final String SESSION = "session";
034 private static final String CONTROLLER = "controller";
035 private static final String I8N = "i8n";
036
037 /**
038 * get the Template
039 */
040 protected String getTemplate() throws PragmatachException {
041 try {
042 final String templateName = getTemplateName();
043 if ((null != templateName) && (templateName.length() > 0)) {
044 final InputStream templateInputStream = getResource(templateName);
045 if (null != templateInputStream) {
046 return getTemplateAsString(templateInputStream);
047 } else {
048 throw new Exception("Unable to load template '"
049 + templateName + "' for controller '"
050 + AbstractController.getControllerName(this) + "'");
051 }
052 } else {
053 throw new PragmatachException(
054 "Unable to get template name for controller '"
055 + AbstractController.getControllerName(this)
056 + "'. Does it have an @View annotation?");
057 }
058 } catch (final Exception e) {
059 throw new PragmatachException("Exception in getTemplate", e);
060 }
061 }
062
063 private String getTemplateAsString(InputStream templateInputStream)
064 throws PragmatachException {
065 try {
066 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
067 IOUtils.copy(templateInputStream, baos);
068 return baos.toString("UTF-8");
069 } catch (final Exception e) {
070 throw new PragmatachException("Exception in getTemplateAsString", e);
071 }
072 }
073
074 /**
075 * get the template's context
076 */
077 protected Map<String, Object> getTemplateContext() {
078 final Map<String, Object> context = new HashMap<String, Object>();
079 context.put(SESSION, getRequest().getSession());
080 context.put(CONTROLLER, this);
081 /*
082 * i8n
083 */
084 context.put(I8N, new I8NResolver(I8NProviders.getInstance().providers));
085 /*
086 * add the current controller by name
087 */
088 context.put(AbstractController.getControllerName(this), this);
089 /*
090 * add all session scoped controllers
091 */
092 final Hashtable<Class<?>, PragmatachController> sessionControllerInstances = SessionScopedControllers
093 .getMap(getRequest().getSession());
094 if (null != sessionControllerInstances) {
095 final Enumeration<Class<?>> enumer = sessionControllerInstances
096 .keys();
097 while (enumer.hasMoreElements()) {
098 final Class<?> key = enumer.nextElement();
099 final Controller controller = key
100 .getAnnotation(Controller.class);
101 if (controller.scope() == Controller.Scope.session) {
102 final PragmatachController pragmatachController = sessionControllerInstances
103 .get(key);
104 context.put(controller.name(), pragmatachController);
105 }
106 }
107 }
108 /*
109 * add all template variables contributed by plugins
110 */
111 final Map<String, PluginDescriptor> plugins = PluginDescriptors
112 .getPlugins();
113 if (null != plugins) {
114 for (final PluginDescriptor pluginDescriptor : plugins.values()) {
115 final Map<String, Object> vars = pluginDescriptor.getPlugin()
116 .getTemplateVariables();
117 if (null != vars) {
118 context.putAll(vars);
119 }
120 }
121 }
122 return context;
123 }
124
125 /**
126 * Get the name of the template to render from the @View annotation.
127 */
128 protected String getTemplateName() throws PragmatachException {
129 try {
130 final View view = getPragmatachRoute().getView();
131 if (null != view) {
132 return view.view();
133 }
134 return null;
135 } catch (final Exception e) {
136 throw new PragmatachException("Exception in getTemplateName", e);
137 }
138 }
139
140 /**
141 * get properly qualified url given the http, the context, etc
142 */
143 public String url_for(String page) throws PragmatachException {
144 try {
145 final HttpServletRequest httpServletRequest = getRequest()
146 .getHttpServletRequest();
147 final URI uri = new URI(httpServletRequest.getRequestURL()
148 .toString()).resolve(page);
149 return uri.toString();
150 } catch (final Exception e) {
151 throw new PragmatachException("Exception in getTemplateName", e);
152 }
153 }
154 }