View Javadoc

1   /*
2    * To change this template, choose Tools | Templates
3    * and open the template in the editor.
4    */
5   
6   package com.rc.celeritas.controller;
7   
8   import com.oreilly.servlet.multipart.FilePart;
9   import com.oreilly.servlet.multipart.MultipartParser;
10  import com.oreilly.servlet.multipart.ParamPart;
11  import com.oreilly.servlet.multipart.Part;
12  import com.rc.celeritas.db.DBHelper;
13  import com.rc.celeritas.exception.CeleritasException;
14  import com.rc.celeritas.exception.ImpleoAlreadyExistException;
15  import com.rc.celeritas.exception.ImpleoMapEmptyException;
16  import com.rc.celeritas.impleo.DeleteImpleo;
17  import com.rc.celeritas.impleo.Impleo;
18  import com.rc.celeritas.impleo.InsertImpleo;
19  import com.rc.celeritas.impleo.SearchImpleo;
20  import com.rc.celeritas.impleo.UpdateImpleo;
21  import com.rc.celeritas.generics.PropertyHelper;
22  import com.rc.celeritas.impleo.DetailImpleo;
23  import com.rc.celeritas.impleo.ExportImpleo;
24  import java.io.ByteArrayOutputStream;
25  import java.io.IOException;
26  import java.io.InputStream;
27  import java.util.ArrayList;
28  import java.util.Enumeration;
29  import java.util.HashMap;
30  import java.util.Hashtable;
31  import java.util.Properties;
32  import javax.servlet.ServletContext;
33  import javax.servlet.ServletRequest;
34  import javax.servlet.http.HttpServletRequest;
35  import javax.servlet.http.HttpServletResponse;
36  import javax.servlet.http.HttpSession;
37  import org.apache.commons.collections.MapUtils;
38  import org.apache.commons.lang.StringUtils;
39  import org.apache.log4j.Logger;
40  import org.webmacro.Template;
41  import org.webmacro.servlet.HandlerException;
42  import org.webmacro.servlet.WMServlet;
43  import org.webmacro.servlet.WebContext;
44  
45  /**
46   *
47   * @author rchoudhary
48   */
49  public class CrudWMServlet extends WMServlet {
50  
51      private ServletContext srvCtx;
52      private static Logger log = Logger.getLogger(CrudWMServlet.class);
53      private String characterEncoding = "UTF-8";
54      private static HashMap<String, Impleo> impleoMap = new HashMap<String, Impleo>();
55      private static Properties sqlMap;
56      private static Properties globalVarsMap;
57      private static Properties luMap, iluRefMap;
58      private static Properties exportAuthMap;
59      private HashMap<String, HashMap<String, String>> iluMap, iluOptsMap;
60      private static int max_file_size = 200000000;
61  
62  
63      /**
64       *
65       */
66      @Override
67      public void start(){
68          //get servlet context
69          srvCtx = getServletContext();
70          //set character encoding
71          characterEncoding = StringUtils.defaultString(srvCtx.getInitParameter("character-encoding"),characterEncoding);
72  
73          try{
74              impleoMap.put(Constants.NAMEKEY_INSERT, new InsertImpleo());
75              impleoMap.put(Constants.NAMEKEY_UPDATE, new UpdateImpleo());
76              impleoMap.put(Constants.NAMEKEY_SEARCH, new SearchImpleo());
77              impleoMap.put(Constants.NAMEKEY_DELETE, new DeleteImpleo());
78              impleoMap.put(Constants.NAMEKEY_EXPORT, new ExportImpleo());
79              impleoMap.put(Constants.NAMEKEY_DETAILS, new DetailImpleo());
80              log.info("\n|--------------------------------------------------------------------|\n" +
81                       "|                      Impleo Map Initialized                        |\n" +
82                       "|--------------------------------------------------------------------|\n");
83          }catch(Exception e) {
84              log.fatal(">>>>>>>>>>>>>>>>>Impleo Map cannot be initialized.<<<<<<<<<<<<<<<<<<< \n"  + e.toString());
85              return;
86          }
87          String sqlRef = StringUtils.defaultIfEmpty(srvCtx.getInitParameter("file-sql"), "celeritas-sql.xml");
88          try{
89              sqlMap = PropertyHelper.loadProperty(sqlRef);
90              if(sqlMap == null || sqlMap.size() == 0){
91                  throw new CeleritasException("SQL Map is blank");
92              }
93              log.info("SQL Map Initialized with " + sqlMap.size());
94          }catch (CeleritasException ce){
95              log.warn(">>>>>>>>>>>>>> Unable to Initialize SQL Property Map <<<<<<<<<<<<<<\n" + ce.toString());
96          }
97  
98          String globalVarRef = StringUtils.defaultIfEmpty(srvCtx.getInitParameter("global-vars"), "golbal-vars.xml");
99          try{
100             globalVarsMap = PropertyHelper.loadProperty(globalVarRef);
101             if(globalVarsMap == null || globalVarsMap.size() == 0){
102                 throw new CeleritasException("Global Var Map is blank");
103             }
104             log.info("\n|--------------------------------------------------------------------|\n" +
105                      "|                Global Var Map Initialized with " + globalVarsMap.size() + "                 |\n" +
106                      "|--------------------------------------------------------------------|\n");
107         }catch (CeleritasException ce) {
108             log.warn(">>>>>>>>>>>>>> Unable to Initialize Global Vars Property Map <<<<<<<<<<<<<<\n" + ce.toString());
109         }
110 
111         try {
112             DBHelper.init();
113             log.info("\n|--------------------------------------------------------------------|\n" +
114                      "|                          DBHelper Initialized                      |\n" +
115                      "|--------------------------------------------------------------------|\n");
116         } catch (CeleritasException e) {
117             log.fatal(">>>>>>>>>>>>>>>>>>>>>DBHelper cannot be initialized<<<<<<<<<<<<<<<<<<<<<<<<\n" + e.toString());
118         }
119 
120         String luRef = StringUtils.defaultIfEmpty(srvCtx.getInitParameter("file-lu"), "celeritas-lu.xml");
121         try {
122             luMap = PropertyHelper.loadProperty(luRef);
123             if(MapUtils.isEmpty(luMap)){
124                 throw new CeleritasException("Lu Map is empty lu params will not work.");
125             }
126             log.info("\n|--------------------------------------------------------------------|\n" +
127                      "|                          Look Up Initialized                       |\n" +
128                      "|--------------------------------------------------------------------|\n");
129         } catch (CeleritasException ce) {
130             log.warn(">>>>>>>>>>>>>>>>Look ups cannot be loaded<<<<<<<<<<<<<<<<<<<<<");
131         }
132 
133         String iluRef = StringUtils.defaultIfEmpty(srvCtx.getInitParameter("file-ilu"), "celeritas-ilu.xml");
134         try {
135             iluRefMap = PropertyHelper.loadProperty(iluRef);
136             if(MapUtils.isEmpty(iluRefMap)){
137                 throw new CeleritasException("Instant Look Up Map is empty ilu params will not work.");
138             }
139             iluMap = PropertyHelper.generateMap(iluRefMap);
140             //TO-DO Initialize iluOptsMap too
141             log.info("\n|--------------------------------------------------------------------|\n" +
142                      "|                      Instant Look Up Initialized                   |\n" +
143                      "|--------------------------------------------------------------------|\n");
144         } catch (CeleritasException ce) {
145             log.warn(">>>>>>>>>>>>>>>>Instant Look ups cannot be loaded<<<<<<<<<<<<<<<<<<<<<");
146         }
147 
148         String exportAuthRef = StringUtils.defaultIfEmpty(srvCtx.getInitParameter("file-export"), "celeritas-export.xml");
149         try{
150             exportAuthMap = PropertyHelper.loadProperty(exportAuthRef);
151             if(exportAuthMap == null || exportAuthMap.size() == 0){
152                 throw new CeleritasException("Export Auth Map is blank");
153             }
154             log.info("\n|--------------------------------------------------------------------|\n" +
155                      "|                Export Auth Map Initialized with " + exportAuthMap.size() + "                  |\n" +
156                      "|--------------------------------------------------------------------|\n");
157         }catch (CeleritasException ce) {
158             log.warn(">>>>>>>>>>>>>> Unable to Initialize Export Auth Property Map <<<<<<<<<<<<<<\n" + ce.toString());
159         }
160 
161         try{
162             PropertyHelper.init();
163             log.info("\n|--------------------------------------------------------------------|\n" +
164                      "|                   Property Helper Initialized                      |\n" +
165                      "|--------------------------------------------------------------------|\n");
166         } catch (CeleritasException ce){
167             log.warn(">>>>>>>>>>>>>>> Unable to initialize Property Helper <<<<<<<<<<<<<<<");
168         }
169 
170     }
171 
172     /**
173      *
174      * @param context
175      * @return
176      * @throws org.webmacro.servlet.HandlerException
177      */
178     public Template handle(WebContext context) throws HandlerException{
179         HttpServletRequest req = context.getRequest();
180         HttpServletResponse res = context.getResponse();
181         HttpSession ses = req.getSession();
182         String servPath = StringUtils.substringAfter(req.getPathInfo(),"/");
183         String impleo = StringUtils.substringBeforeLast(StringUtils.substringBefore(servPath,"/"),"/");
184         String template = StringUtils.substringAfter(servPath,"/");
185 
186         Template t = null;
187         Hashtable reqMap = getParameterMap(req);
188         String export = MapUtils.getString(reqMap, Constants.EXPORT_TO, Constants.EMPTY_STRING);
189 
190         String username = StringUtils.isNotEmpty(req.getRemoteUser())?req.getRemoteUser():Constants.GUEST;
191         context.put(Constants.USERNAME, username);
192         
193         if(StringUtils.isNotEmpty(export)){
194             if(StringUtils.equals(export, Constants.EXCEL)){
195                 res.setContentType(Constants.EXCEL_MIME_TYPE);
196             }
197         }
198 
199         String lu = MapUtils.getString(reqMap, Constants.LU, Constants.EMPTY_STRING);
200         if(StringUtils.isNotEmpty(lu)){
201             /*
202              * SQL Lookups are processed at the request time since they can be
203              * modified with some other operation in the program
204              */
205             processLookups(lu, context);
206         }
207         
208         String ilu = MapUtils.getString(reqMap, Constants.ILU, Constants.EMPTY_STRING);
209         if(StringUtils.isNotEmpty(ilu)){
210             processInstantLookups(ilu, context);
211         }
212         context.put("rMap", reqMap);
213         //Loading all global vars into the Context
214         context.putAll(globalVarsMap);
215         try {
216 
217             // call the handler (handler may or may not return a new template)
218             String return_template = "";
219             if(impleoMap.containsKey(impleo)){
220                 return_template = impleoMap.get(impleo).implied(context);
221             }
222             //t = getOutputTemplate(context,res);
223             if (t == null) {
224                 t = getTemplate(StringUtils.isNotEmpty(return_template)?return_template:template);
225             }
226 
227         } catch (Exception e) {
228             //log the error
229             log.error(e);
230             try {
231                 t = getTemplate("error.html");
232             } catch (Exception inE) {
233                 log.error(inE);
234             }
235             String subject = " encountered Celeritas error...";
236             //sendException(context,req,e,user_name,subject);
237         }
238 
239         return t;
240     }
241 
242     /**
243      * 
244      * @param key
245      * @return
246      */
247     public static synchronized String getSqlProperty(String key){
248         if(sqlMap != null)
249             return sqlMap.getProperty(key);
250         else
251             return null;
252     }
253 
254     /**
255      * 
256      * @param nameKey
257      * @param impleo
258      * @return
259      * @throws com.rc.celeritas.exception.ImpleoAlreadyExistException
260      * @throws com.rc.celeritas.exception.ImpleoMapEmptyException
261      */
262     public synchronized boolean registerImpleo(String nameKey, Impleo impleo) throws ImpleoAlreadyExistException, ImpleoMapEmptyException{
263         if(checkImpleoExists(nameKey)){
264             throw new ImpleoAlreadyExistException("Impleo exists for name key : " + nameKey + " please try to register by a different name");
265         }else {
266             impleoMap.put(nameKey, impleo);
267         }
268         return true;
269     }
270 
271     /**
272      * 
273      * @param nameKey
274      * @return
275      * @throws com.rc.celeritas.exception.ImpleoMapEmptyException
276      */
277     public synchronized boolean checkImpleoExists(String nameKey) throws ImpleoMapEmptyException {
278         if(impleoMap != null){
279             return impleoMap.containsKey(nameKey);
280         }
281         throw new ImpleoMapEmptyException("Impleo Map is null, CrudWMServlet is not initialized properly.");
282     }
283 
284     /**
285      * Get a parameter map from HttpRequest object
286      *
287      * @param req   HttpRequest object
288      * @return Hashtable key value pairs in URL request
289      */
290     public static Hashtable getParameterMap(HttpServletRequest req) {
291         String cType = StringUtils.defaultString(req.getContentType(),Constants.STANDARD_FORM);
292         //log.info("Content Type: "+cType);
293         Hashtable retMap = null;
294         try {
295             retMap = cType.startsWith(Constants.MULTIPART_FORM) ? getMultipart(req) : getRequestMap(req);
296         } catch (IOException ioe) {
297             log.error(ioe);
298             retMap = new Hashtable();
299         }
300         return retMap;
301     }
302 
303     /**
304      * Get a parameter map from HttpRequest object
305      *
306      * @param req   HttpRequest object
307      * @return Hashtable key value pairs in URL request
308      */
309     public static Hashtable getRequestMap(ServletRequest req) {
310         //Hashtable retMap = new Hashtable(req.getParameterMap().size());
311         //setCharacterEncoding(req);
312         Hashtable retMap = new Hashtable();
313         StringBuffer sb = new StringBuffer();
314         for (Enumeration e = req.getParameterNames(); e.hasMoreElements();) {
315             String paramName = e.nextElement().toString();
316             String[] paramValue = req.getParameterValues(paramName);
317             if (paramValue.length == 1) {
318                 retMap.put(paramName,paramValue[0]);
319             } else {
320                 for (int i = 0; i < paramValue.length; ++i) {
321                     //sb.append(paramValue[i]).append(Constants.COMMA_SPACE);
322                     sb.append(paramValue[i]).append(Constants.COMMA);
323                 }
324                 retMap.put(paramName,StringUtils.chomp(sb.toString(),Constants.COMMA_SPACE));
325                 sb.setLength(0);
326             }
327 
328         }
329         return retMap;
330     }
331 
332     /**
333      * Get a multipart web request into a hashtable.  The files are converted
334      * to ByteArrayOutputStreams.  Parameters are stored as name / value strings.
335      * @param   req     HttpServletRequest
336      * @return Hashtable
337      * @throws IOException
338      */
339     public static Hashtable getMultipart(HttpServletRequest req)
340     throws IOException {
341         //setCharacterEncoding(req);
342         MultipartParser mp = new MultipartParser(req,max_file_size,true,true);
343         Hashtable rMap = new Hashtable();
344         ArrayList fKeys = new ArrayList();
345         byte[] buff = new byte[1024];
346         for (Part pt = mp.readNextPart(); pt != null; pt = mp.readNextPart()) {
347             String pKey = pt.getName();
348             if (pt.isFile()) {
349                 FilePart fpt = (FilePart) pt;
350                 String file_name = fpt.getFileName();
351                 if (StringUtils.isNotEmpty(file_name)) {
352                     try {
353                         InputStream iStr = fpt.getInputStream();
354                         ByteArrayOutputStream bFile = new ByteArrayOutputStream();
355                         for (int i = iStr.read(buff); i > 0; i = iStr.read(buff)) {
356                             bFile.write(buff,0,i);
357                         }
358                         iStr.close();
359                         if (StringUtils.isNotEmpty(file_name)) {
360                             rMap.put(pKey,bFile);
361 
362                             if (pKey.equals(Constants.FILE_BLOB)) {
363                                 rMap.put(Constants.FILE_NAME,file_name);
364                                 rMap.put(Constants.BLOB_NAME,file_name);
365                             } else if (pKey.equals(Constants.FILE_CLOB)) {
366                                 rMap.put(Constants.FILE_NAME,file_name);
367                                 rMap.put(Constants.CLOB_NAME,file_name);
368                             } else {
369                                 String fKey = StringUtils.substringAfterLast(pKey,Constants.UNDERSCORE);
370                                 fKeys.add(fKey);
371                                 String fName = Constants.FILE_NAME + Constants.UNDERSCORE + fKey;
372                                 rMap.put(fName,file_name);
373                             }
374                         }
375                     } catch (IOException ioe) {
376                         log.warn(ioe);
377                     }
378                 }
379             } else if (pt.isParam()) {
380                 ParamPart ppt = (ParamPart) pt;
381                 if (rMap.containsKey(pKey)) {
382                     rMap.put(pKey,MapUtils.getString(rMap,pKey,Constants.EMPTY_STRING) + Constants.COMMA_SPACE + ppt.getStringValue());
383                 } else {
384                     rMap.put(pKey,ppt.getStringValue());
385                 }
386             }
387         }
388         rMap.put(Constants.FILE_INDEX,fKeys);
389         rMap.put(Constants.IS_MULTIPART,Constants.ZERO);
390         return rMap;
391     }
392 
393     /**
394      * Process Instant Lookups, basically split the ilu string into array
395      * Search for appropriate LU in the iluMap and place in the web context
396      * @param ilu
397      * @param context
398      */
399     private void processInstantLookups(String ilu, WebContext context) {
400         String iluArray[] = ilu.split(Constants.COMMA);
401         for(int i = 0; i < iluArray.length; i++){
402             HashMap lookups = (HashMap)MapUtils.getMap(iluMap, iluArray[i], null);
403             if(MapUtils.isNotEmpty(lookups)){
404                 context.put(iluArray[i], lookups);
405             }else{
406                 log.warn("Instant Look up for : " + iluArray[i] + " is not defined in the configuration files");
407             }
408         }
409     }
410 
411     /**
412      * Process Lookups, basically split the lu string into array
413      * Search for appropriate LU sql in the luMap, execute the sql and place the
414      * result in the web context.
415      * @param lu
416      * @param context
417      */
418     private void processLookups(String lu, WebContext context) {
419         String luArray []  =  lu.split(Constants.COMMA);
420         for(int i = 0; i < luArray.length; i++){
421             String sql = MapUtils.getString(luMap, luArray[i], null);
422             HashMap lookups = DBHelper.generateLU(sql);
423             if(MapUtils.isNotEmpty(lookups)){
424                 context.put(luArray[i], lookups);
425             }else{
426                 log.warn("Look up for : " + luArray[i] + " is not defined in the configuration files");
427             }
428         }
429     }
430 
431     /**
432      * This method will return the comma seperated list of values in
433      * celeritas-export.xml file for this table.
434      * @param table
435      * @return
436      */
437     public static synchronized String getAllowedPrincipals(String table) {
438         return MapUtils.getString(exportAuthMap, table, Constants.NULL);
439     }
440 
441     /**
442      * SQL String for the given SQL Key Reference
443      * @param sqlRef
444      * @return java.lang.String
445      */
446     public String getSql(String sqlRef){
447         return (String)sqlMap.get(sqlRef);
448     }
449 }