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    }