001    package com.khubla.pragmatach.framework.controller.impl;
002    
003    import java.io.InputStream;
004    import java.util.HashMap;
005    import java.util.Map;
006    
007    import javax.servlet.http.HttpServletRequest;
008    
009    import com.khubla.pragmatach.framework.annotation.CacheControl;
010    import com.khubla.pragmatach.framework.annotation.Controller;
011    import com.khubla.pragmatach.framework.api.PragmatachException;
012    import com.khubla.pragmatach.framework.api.Request;
013    import com.khubla.pragmatach.framework.api.Response;
014    import com.khubla.pragmatach.framework.application.Application;
015    import com.khubla.pragmatach.framework.controller.PragmatachController;
016    import com.khubla.pragmatach.framework.controller.SessionScopedControllers;
017    import com.khubla.pragmatach.framework.controller.impl.redirect.RedirectController;
018    import com.khubla.pragmatach.framework.controller.impl.trivial.TrivialResponse;
019    import com.khubla.pragmatach.framework.resourceloader.DefaultResourceLoaderImpl;
020    import com.khubla.pragmatach.framework.resourceloader.ResourceLoader;
021    import com.khubla.pragmatach.framework.router.PragmatachRoute;
022    
023    /**
024     * @author tome
025     */
026    public abstract class AbstractController implements PragmatachController {
027       /**
028        * build a path from a wildcard path
029        */
030       public static String buildWildcardResourceURI(String[] resource) {
031          String ret = "";
032          for (final String s : resource) {
033             ret += "/" + s;
034          }
035          return ret;
036       }
037    
038       /**
039        * get the name of the controller from the annotation
040        */
041       public static String getControllerName(Class<?> clazz) {
042          final Controller controller = clazz.getAnnotation(Controller.class);
043          if (null != controller) {
044             String name = controller.name();
045             if (name.length() == 0) {
046                /*
047                 * *this* is a proxy, so we need the superclass name
048                 */
049                // name = this.getClass().getSuperclass().getSimpleName();
050                name = clazz.getSimpleName();
051             }
052             return name;
053          }
054          return null;
055       }
056    
057       /**
058        * get the name of the controller from the annotation
059        */
060       public static String getControllerName(PragmatachController pragmatachController) {
061          final Controller controller = pragmatachController.getClass().getAnnotation(Controller.class);
062          if (null != controller) {
063             String name = controller.name();
064             if (name.length() == 0) {
065                /*
066                 * *this* is a proxy, so we need the superclass name
067                 */
068                // name = this.getClass().getSuperclass().getSimpleName();
069                name = pragmatachController.getClass().getSimpleName();
070             }
071             return name;
072          }
073          return null;
074       }
075    
076       /**
077        * request
078        */
079       private Request request;
080       /**
081        * cache control
082        */
083       private static final String CACHECONTROL = "Cache-Control: ";
084       /**
085        * route
086        */
087       private PragmatachRoute pragmatachRoute;
088    
089       /**
090        * bad; HTTP 400
091        */
092       public Response bad() throws PragmatachException {
093          return new TrivialResponse(null, 400);
094       }
095    
096       /**
097        * forward to another controller uri
098        */
099       public Response forward(String uri) throws PragmatachException {
100          final String forwardURI = request.getHttpServletRequest().getContextPath() + uri;
101          return new RedirectController(forwardURI).render();
102       }
103    
104       /**
105        * get the base URI of this application
106        */
107       public String getApplicationURL() {
108          final HttpServletRequest httpServletRequest = getRequest().getHttpServletRequest();
109          return httpServletRequest.getScheme() + "://" + httpServletRequest.getServerName() + ":" + httpServletRequest.getServerPort() + httpServletRequest.getContextPath();
110       }
111    
112       /**
113        * generate the cache headers
114        */
115       protected Map<String, String> getCacheHeaders() throws PragmatachException {
116          try {
117             final CacheControl cacheControl = this.getClass().getAnnotation(CacheControl.class);
118             if (null != cacheControl) {
119                final Map<String, String> ret = new HashMap<String, String>();
120                String cacheControlHeader = "";
121                boolean first = true;
122                /*
123                 * max age
124                 */
125                if (-1 != cacheControl.maxAge()) {
126                   cacheControlHeader += "max-age=" + cacheControl.maxAge();
127                   first = false;
128                }
129                /*
130                 * s-max
131                 */
132                if (-1 != cacheControl.sMaxAge()) {
133                   if (false == first) {
134                      cacheControlHeader += ",";
135                   }
136                   cacheControlHeader += "s-maxage=" + cacheControl.sMaxAge();
137                   first = false;
138                }
139                /*
140                 * policy
141                 */
142                if (false == first) {
143                   cacheControlHeader += ",";
144                }
145                cacheControlHeader += cacheControl.policy().toString().toLowerCase().trim();
146                /*
147                 * done
148                 */
149                ret.put(CACHECONTROL, cacheControlHeader);
150                return ret;
151             } else {
152                return null;
153             }
154          } catch (final Exception e) {
155             throw new PragmatachException("Exception in getCacheHeaders", e);
156          }
157       }
158    
159       /**
160        * get a configuration parameter from the pragmatatch configuration
161        */
162       public String getConfigurationParameter(String name) throws PragmatachException {
163          return Application.getConfiguration().getParameter(name);
164       }
165    
166       public PragmatachRoute getPragmatachRoute() {
167          return pragmatachRoute;
168       }
169    
170       /**
171        * get the request
172        */
173       public Request getRequest() {
174          return request;
175       }
176    
177       /**
178        * get a resource using the servlet's class loader
179        */
180       protected InputStream getResource(String resource) throws PragmatachException {
181          try {
182             final ResourceLoader resourceLoader = new DefaultResourceLoaderImpl(request.getServletContext());
183             return resourceLoader.getResource(resource);
184          } catch (final Exception e) {
185             throw new PragmatachException("Exception in getResource", e);
186          }
187       }
188    
189       /**
190        * get the instance of a session-bound controller
191        */
192       @SuppressWarnings("unchecked")
193       public <T> T getSessionScopedController(Class<T> clazz) {
194          return (T) SessionScopedControllers.getController(request.getSession(), clazz);
195       }
196    
197       /**
198        * ok; HTTP 200
199        */
200       public Response ok() throws PragmatachException {
201          return new TrivialResponse(null, 200);
202       }
203    
204       /**
205        * redirect. This API requires a full URL including authority, hostname, port, etc.
206        */
207       public Response redirect(String uri) throws PragmatachException {
208          return new RedirectController(uri).render();
209       }
210    
211       @Override
212       public void setPragmatachRoute(PragmatachRoute pragmatachRoute) {
213          this.pragmatachRoute = pragmatachRoute;
214       }
215    
216       /**
217        * set the request
218        */
219       @Override
220       public void setRequest(Request request) {
221          this.request = request;
222       }
223    }