Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/jcorporate/expresso/services/controller/dbmaint/Lookup.java


1   /* ====================================================================
2    * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
3    *
4    * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
5    *
6    * Redistribution and use in source and binary forms, with or without
7    * modification, are permitted provided that the following conditions
8    * are met:
9    *
10   * 1. Redistributions of source code must retain the above copyright
11   *    notice, this list of conditions and the following disclaimer.
12   *
13   * 2. Redistributions in binary form must reproduce the above copyright
14   *    notice, this list of conditions and the following disclaimer in
15   *    the documentation and/or other materials provided with the
16   *    distribution.
17   *
18   * 3. The end-user documentation included with the redistribution,
19   *    if any, must include the following acknowledgment:
20   *       "This product includes software developed by Jcorporate Ltd.
21   *        (http://www.jcorporate.com/)."
22   *    Alternately, this acknowledgment may appear in the software itself,
23   *    if and wherever such third-party acknowledgments normally appear.
24   *
25   * 4. "Jcorporate" and product names such as "Expresso" must
26   *    not be used to endorse or promote products derived from this
27   *    software without prior written permission. For written permission,
28   *    please contact info@jcorporate.com.
29   *
30   * 5. Products derived from this software may not be called "Expresso",
31   *    or other Jcorporate product names; nor may "Expresso" or other
32   *    Jcorporate product names appear in their name, without prior
33   *    written permission of Jcorporate Ltd.
34   *
35   * 6. No product derived from this software may compete in the same
36   *    market space, i.e. framework, without prior written permission
37   *    of Jcorporate Ltd. For written permission, please contact
38   *    partners@jcorporate.com.
39   *
40   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
41   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
42   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43   * DISCLAIMED.  IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
44   * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
45   * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
46   * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
47   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
49   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
50   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51   * SUCH DAMAGE.
52   * ====================================================================
53   *
54   * This software consists of voluntary contributions made by many
55   * individuals on behalf of the Jcorporate Ltd. Contributions back
56   * to the project(s) are encouraged when you make modifications.
57   * Please send them to support@jcorporate.com. For more information
58   * on Jcorporate Ltd. and its products, please see
59   * <http://www.jcorporate.com/>.
60   *
61   * Portions of this software are based upon other open source
62   * products and are subject to their respective licenses.
63   */
64  
65  /**
66   * [Currently not used.... volunteers to integrate?]
67   *
68   *
69   * can filter its lookup popup according to some conditions. For example: list
70   * only cities within a given state.
71   *
72   *
73   * Some note on the design:
74   *
75   * - modifying getValidValues() to some extend (to allow filtering) would be
76   * great. But I still haven't had a clear picture how things work out. That's
77   * one of the reasons that I came up with this 'surgical operation'.
78   *
79   * - One advantage of this surgical operation is that, extending
80   * functionality of getValidValues will still not able to solve the
81   * 'MultiDBObjects-lookup' problem. So I thought it is necessary to put all
82   * this kind of lookup into one place.
83   *
84   * Talking about conditional lookup, I think that flexibility is most
85   * important. The lookup function should allow user to do ORed-condition
86   * lookup on joined tables and views. My plan is to use the same lookup
87   * interface (API), both in add and search, for all cases mentioned above:
88   * full lookup (no filter), partial lookup (with simple/advanced filtering
89   * condition(s)), and MultiDBObjects lookups. The difference of the HashMap
90   * controls the different behavior.
91   *
92   * @version  $Revision: 1.12 $  $Date: 2004/11/18 02:03:30 $
93   * @author  Tong Sun
94   *
95   */
96  
97  // ========================================================= &declare ===
98  
99  package com.jcorporate.expresso.services.controller.dbmaint;
100 
101 import com.jcorporate.expresso.core.controller.session.HTTPPersistentSession;
102 import com.jcorporate.expresso.core.db.DBException;
103 import com.jcorporate.expresso.core.dbobj.DBObject;
104 import com.jcorporate.expresso.core.dbobj.ValidValue;
105 import com.jcorporate.expresso.core.misc.SerializableString;
106 import com.jcorporate.expresso.core.misc.StringUtil;
107 import org.apache.log4j.Logger;
108 
109 import javax.servlet.http.HttpServletRequest;
110 import java.io.IOException;
111 import java.io.ObjectInputStream;
112 import java.io.ObjectOutputStream;
113 import java.io.Serializable;
114 import java.lang.reflect.Method;
115 import java.util.HashMap;
116 import java.util.Iterator;
117 import java.util.Vector;
118 
119 // ======================================================= &class_def ===
120 
121 public class Lookup implements Serializable {
122 
123     /* the logs */
124     transient private static Logger log = Logger.getLogger(Lookup.class);
125 
126     public static final String DBF_DBNAME = "dbf_dbname";
127     public static final String DBF_DBKEY = "dbf_dbkey";
128     public static final String DBF_DBDESC = "dbf_dbdesc";
129     public static final String DBF_DB_FILTER_FNAME = "dbf_db_filter_fname";
130     public static final String DBF_DB_FILTER_VALUE = "dbf_db_filter_value";
131     public static final String DBF_DB_FILTER_WHERE = "dbf_db_filter_where";
132 
133     public static final String DBM_ACTION_KEY = "dbm_action";
134     public static final String DBM_ACTION_SEARCH = "search";
135 
136     protected HashMap theFilter;
137 
138 
139 // -------------------------------------------------------------- &mf ---
140 // .................................................. member function ...
141     /**
142      * Default Constructor
143      */
144     public Lookup() {
145         super();
146         theFilter = new HashMap();
147     }
148 
149 // -------------------------------------------------------------- &mf ---
150 // .................................................. member function ...
151     /**
152      * Get property: theFilter
153      *
154      * @return java.util.HashMap
155      */
156     public HashMap getTheFilter() {
157         return theFilter;
158     }
159 
160 // -------------------------------------------------------------- &mf ---
161 // .................................................. member function ...
162     /**
163      * Adding simple partial lookup filter.
164      * <p/>
165      * Parameters are: lookup db name, key field name, description
166      * field name, filter field name and filter field value.
167      *
168      * @param dbname          the data context
169      * @param dbkey           The key field name
170      * @param dbdesc          The description field name
171      * @param db_filter_fname The field name to filter against
172      * @param db_filter_value The value field name to filter against
173      */
174     public void setFilter(String dbname, String dbkey, String dbdesc,
175                           String db_filter_fname, String db_filter_value) {
176         theFilter.put(DBF_DBNAME, dbname);
177         theFilter.put(DBF_DBKEY, dbkey);
178         theFilter.put(DBF_DBDESC, dbdesc);
179         theFilter.put(DBF_DB_FILTER_FNAME, db_filter_fname);
180         theFilter.put(DBF_DB_FILTER_VALUE, db_filter_value);
181     }
182 
183 // -------------------------------------------------------------- &mf ---
184 // .................................................. member function ...
185     /**
186      * Adding advanced partial lookup filter.
187      * <p/>
188      * Parameters are: lookup db name, key field name, description
189      * field name, filter where clause.
190      *
191      * @param dbname          the data context name
192      * @param dbkey           The key field name
193      * @param dbdesc          Description Field Name
194      * @param db_filter_where the where clause to filter against.
195      */
196     public void setFilter(String dbname, String dbkey, String dbdesc,
197                           String db_filter_where) {
198         theFilter.put(DBF_DBNAME, dbname);
199         theFilter.put(DBF_DBKEY, dbkey);
200         theFilter.put(DBF_DBDESC, dbdesc);
201         theFilter.put(DBF_DB_FILTER_WHERE, db_filter_where);
202     }
203 
204 // -------------------------------------------------------------- &mf ---
205 // .................................................. member function ...
206 
207     /**
208      * Performs the lookup.
209      * <p/>
210      * The basic idea is pre-setting some session variables, i.e.,
211      * &lt;DBObjectName&gt;_filter_&lt;fieldName&gt;. They are HashMap objects that contain
212      * information such as lookup db name, key field name, description field
213      * name, filter field name and filter field value, etc. It is used by
214      * Lookup.java to return ValidValue pairs.
215      * <p/>
216      * The Lookup.java object will be intelligent enough to handle cases like
217      * full lookup (no filter), partial lookup (with simple/advanced filtering
218      * condition(s)), and MultiDBObjects lookups.
219      *
220      * @param myDBObj   The DBObject to get the lookup Values from.
221      * @param fieldName ?
222      * @param mySession ?
223      * @return a Vector of lookup values
224      */
225     public static Vector getLookupValues
226             (DBObject myDBObj, String fieldName, HTTPPersistentSession mySession)
227             throws DBException {
228 
229         Vector values = null;
230         String sessionString;
231 
232         //System.err.println("\n*** getLookupValues entered");
233         if (log.isDebugEnabled()) {
234             log.debug("*** getLookupValues entered");
235         }
236 
237         sessionString = myDBObj.getMetaData().getName().replace('.', '_')
238                 + "_filter_" + fieldName;
239         //System.err.println("DB: "+ myDBObj.getDBName()+ "\nName: " + sessionString);
240 
241         HashMap dbFilter = null;
242         boolean getPersistentAttribute_bug_fixed;
243 
244         getPersistentAttribute_bug_fixed = true;
245         getPersistentAttribute_bug_fixed = false;
246 
247         if (getPersistentAttribute_bug_fixed) {
248             // FIXME: unable to get back the Lookup Javabean!
249             /*
250              * I suspect that there's a minor bug in the 'getPersistentAttribute'
251              * function, because I can use it to retrieve plain JSP session
252              * variables, but not Javabean variables. Both kinds of variables can be
253              * retrieved correctly within JSP, using 'session.getAttribute'. It
254              * seems to me there is a glitch between State.getSession() and
255              * HTTPPersistentSession.getPersistentAttribute(). No javabeans defined
256              * as <jsp:useBean /> in JSP can be retrieved that way. After spending
257              * for over 3 days exploring different ways to do it, I'm now curious
258              * whether anybody has eventually retrieve any javabeans defined in JSP
259              * or not. This bug is beyond my capability to solve. So I'm just
260              * leaving my test code here, until someone can find a
261              * solution. Meanwhile, please define plain JSP session variables.
262              */
263             sessionString += "_";
264             Object lookup_obj = mySession.getPersistentAttribute(sessionString);
265             Lookup lookup = (Lookup) lookup_obj;
266             dbFilter = lookup.getTheFilter();
267         } else {
268             dbFilter = (HashMap) mySession.getPersistentAttribute(sessionString);
269         }
270 
271         //System.err.println("HashMap: " + dbFilter);
272         if (dbFilter == null) {
273             // full lookup (no filter)
274             values = myDBObj.getValidValues(fieldName);
275         } else {
276             // partial lookup (with filtering)
277             // getValidValues according to user provided filter
278             values = new Vector();
279 
280             try {
281                 Class c = Class.forName((String) dbFilter.get(DBF_DBNAME));
282                 Object dbo = c.newInstance();
283 
284                 //System.err.println("DBO: "+ dbo);
285                 // setDBName. CALL it ONLY if it exists in the class.  It
286                 // might not be necessary across contexts.
287                 try {
288                     Class params[] = {java.lang.String.class};
289                     Method m = c.getMethod("setDBName", params);
290                     if (m != null) {
291                         Object paramValues[] = {myDBObj.getDataContext()};
292                         m.invoke(dbo, paramValues);
293                     }
294                 } catch (NoSuchMethodException nsme) {
295                     //Do nothing, the method just doesn't exist.
296                 } catch (SecurityException se) {
297                     throw new DBException("Security Exception trying to call"
298                             + " setDBName in loading lookup object", se);
299                 } catch (java.lang.reflect.InvocationTargetException ive) {
300                     ive.printStackTrace();
301                     throw new DBException("Error calling setDBName in " +
302                             "loading lookup object", ive.getTargetException());
303                 } catch (IllegalAccessException ilae) {
304                     //Do nothing, setDBName is not public
305                 }
306 
307                 // Get ValidValues
308                 DBObject dboList = (DBObject) dbo;
309                 DBObject oneRecord = null;
310                 // set user provided filter
311                 String dbf_key;
312                 String dbf_val;
313                 //System.err.println("Key: "+ (String)dbFilter.get(DBF_DB_FILTER_FNAME) + "\nVal: " + (String)dbFilter.get(DBF_DB_FILTER_VALUE));
314                 dboList.setField((String) dbFilter.get(DBF_DB_FILTER_FNAME),
315                         (String) dbFilter.get(DBF_DB_FILTER_VALUE));
316                 dbf_key = (String) dbFilter.get(DBF_DBKEY);
317                 dbf_val = (String) dbFilter.get(DBF_DBDESC);
318                 //System.err.println("Key: "+ dbf_key + "\nVal: " + dbf_val);
319                 Iterator ii = dboList.searchAndRetrieveList().iterator();
320                 while (ii.hasNext()) {
321                     oneRecord = (DBObject) ii.next();
322                     values.addElement(new
323                             ValidValue(oneRecord.getField(dbf_key),
324                                     oneRecord.getField(dbf_val)));
325                 }
326             } catch (ClassNotFoundException cn) {
327                 throw new DBException("Lookup object not found", cn);
328             } catch (InstantiationException ie) {
329                 throw new DBException("Lookup object cannot be instantiated", ie);
330             } catch (IllegalAccessException iae) {
331                 throw new DBException("llegal access loading Lookup object", iae);
332             }
333 
334         } // !dbFilter
335 
336         //System.err.println("Values: "+ values);
337         if (values == null) {
338             throw new DBException("Valid values for field "
339                     + fieldName + " from object "
340                     + myDBObj.getMetaData().getName() + " were null");
341         }
342 
343         // Add "All Values" entry if searching
344         sessionString = StringUtil.notNull
345                 ((SerializableString) mySession.getPersistentAttribute(DBM_ACTION_KEY));
346         if (DBM_ACTION_SEARCH.equalsIgnoreCase(sessionString)) {
347             values.add(new ValidValue("", "All Values"));
348         }
349         return values;
350     }
351 
352 // -------------------------------------------------------------- &mf ---
353 // .................................................. member function ...
354 
355     public String toString() {
356         return theFilter.toString();
357     }
358 
359 // -------------------------------------------------------------- &mf ---
360 // .................................................. member function ...
361 
362     /* ************  Serialization Functions *********************** */
363     private void writeObject(ObjectOutputStream oos) throws IOException {
364         oos.defaultWriteObject();
365     }
366 
367     private void readObject(ObjectInputStream ois) throws IOException,
368             ClassNotFoundException {
369         ois.defaultReadObject();
370     }
371 
372 // -------------------------------------------------------------- &mf ---
373 // .................................................. member function ...
374 
375     /**
376      * Remove lookup session variable.
377      *
378      * @param request The Servlet Request
379      */
380     private void remove(HttpServletRequest request) {
381         // TODO: how to?
382     }
383 }
384 
385 
386