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

Quick Search    Search Deep

Source code: com/sample/addressbook/dumbdb/DumbDB.java


1   /*
2    * DumbDB.java
3    *
4    * Copyright (c) 2001, 2002 Aendvari, Ltd. All Rights Reserved.
5    *
6    * See the file LICENSE for terms of use.
7    *
8    */
9   
10  package com.sample.addressbook.dumbdb;
11  
12  import java.util.*;
13  import java.io.*;
14  
15  import javax.servlet.*;
16  import javax.servlet.http.*;
17  
18  import java.beans.*;
19  import java.lang.reflect.*;
20  import java.lang.NoSuchMethodException;
21  import java.lang.IllegalAccessException;
22  
23  import com.aendvari.common.model.*;
24  import com.aendvari.common.model.xalan.*;
25  
26  import com.aendvari.griffin.util.XmlUtil;
27  import com.aendvari.griffin.bean.transform.BeanTransformer;
28  import com.aendvari.griffin.bean.transform.InspectedBean;
29  
30  import com.aendvari.common.util.*;
31  
32  
33  /**
34   * <p>This class is used to fake a dumb database.</p>
35   *
36   * <p>
37   * It is only used for this application so that it can be demonstrated without
38   * the need of a proper database.
39   * </p>
40   *
41   * <p>Please <b>do not</b> use this class for anything other than testing/prototype purposes.</p>
42   *
43   * @author  Scott Milne
44   *
45   */
46  
47  public class DumbDB
48  {
49    /* Variables */
50  
51    /** The "database". */
52    private TreeMap database;
53  
54    /* The auto incremental */
55    private int increment;
56  
57    /* Path to the XML files for the data */
58    private String path;
59  
60  
61    /* Static methods */
62    public static DumbDB getDumbDB(HttpServletRequest request, String attrName)
63    {
64      return (DumbDB)request.getSession().getAttribute(attrName);
65    }
66  
67  
68    /* Internal Classes */
69  
70    private class EntryComparator implements Comparator
71    {
72      public int compare(Object object1, Object object2)
73      {
74        String data1 = (String)object1;
75        String data2 = (String)object2;
76  
77        //return Integer.parseInt(data1) < Integer.parseInt(data2);
78        return data1.compareToIgnoreCase(data2);
79      }
80    }
81  
82  
83    /* Constructors */
84  
85    /** DO NOT USE THIS DIRECTLY */
86    protected DumbDB()
87    {
88      database = new TreeMap(new EntryComparator());
89      increment = 0;
90      this.path = "";
91    }
92  
93    public DumbDB(String path)
94    {
95      database = new TreeMap(new EntryComparator());
96      increment = 0;
97      this.path = path;
98  
99      loadDumbDb(this, path);
100   }
101 
102 
103   /* Accessors */
104 
105   public TreeMap getDatabase() { return database; }
106   public void setDatabase(TreeMap db) { database = db; }
107   public ArrayList getAllEntries() { return new ArrayList(database.values()); }
108 
109   public int newIncrement() { return ++increment; }
110   public int getIncrement() { return increment; }
111   public void setIncrement(int inc) { increment = inc; }
112 
113 
114   /* Methods */
115 
116   public String toString()
117   {
118     String data = "DumbDB[";
119     data += "increment="+increment+",";
120     data += "path="+path+",";
121     data += "database="+database+"]";
122     return data;
123   }
124 
125   /**
126    * Get an object from the db by it's ID.
127    *
128    * @param  id                The id to which the object is related.
129    *
130    */
131 
132   public Object getObjectById( String id )
133   {
134     return database.get(id);
135   }
136 
137   /**
138    * Update an object in the db by it's ID.
139    *
140    * @param  id                The id to which the object is related.
141    * @param  data              The data object to store.
142    *
143    */
144 
145   public void updateObjectById( String id, Object data )
146   {
147     database.put(id, data);
148     saveDumbDb(this, path);
149   }
150 
151   /**
152    * Delete an object in the db by it's ID.
153    *
154    * @param  id                The id to which the object is related.
155    * @param  data              The data object to store.
156    *
157    */
158 
159   public void deleteObjectById( String id )
160   {
161     database.remove(id);
162     saveDumbDb(this, path);
163   }
164 
165   /**
166    * Insert an object into the db by it's ID.
167    *
168    * @param  data              The data object to store.
169    *
170    */
171 
172   public void insertObject( Object data )
173   {
174     String id = Integer.toString(getIncrement());
175 
176     database.put(id, data);
177 
178     saveDumbDb(this, path);
179   }
180 
181   /**
182    * Extract an object from the db using the value of an attribute within the object.
183    * All attributes given must match for the object to be returned.
184    *
185    * @param  attributes            A HashMap of name/value atrributes
186    * @param  likeMatch            Should a "indexOf" match be used (true).
187    *                      False means "equals" is used.
188    *
189    */
190 
191   public Object getObjectByAttributeValues(HashMap attributes, boolean likeMatch )
192   {
193     Object beanObj = null;
194 
195     // go through each value array checking for the value
196     Iterator keysIterator = attributes.keySet().iterator();
197     while (keysIterator.hasNext())
198     {
199       // create the "key" node and examine the propery for the key
200       String attributeName = (String)keysIterator.next();
201       String attributeValue = (String)attributes.get(attributeName);
202 
203       // if the value is blank, don't bother with it
204       if (attributeValue.equals(""))
205       {
206         continue;
207       }
208 
209       StringTokenizer tokens = new StringTokenizer(attributeName, ".");
210       String segment = tokens.nextToken();
211 
212       Object attribute = null;
213       Object tmpBeanObj = getObjectByAttributeValueInternal(segment, attributeValue);
214 
215       if (tmpBeanObj != null)
216       {
217         attribute = getBeanProperty(tmpBeanObj, segment);
218 
219         // stop when end of path is reached
220         while (tokens.hasMoreTokens())
221         {
222           // search children for next segment
223           segment = tokens.nextToken();
224 
225           attribute = getBeanProperty(attribute, segment);
226 
227           if (attribute != null)
228           {
229             Class valueClass = attribute.getClass();
230 
231             if( valueClass.isAssignableFrom(String.class) )
232             {
233               String attrValue = (String)attribute;
234 
235               if (likeMatch)
236               {
237                 if (attrValue.indexOf(attributeValue) != -1)
238                 {
239                   beanObj = tmpBeanObj;
240                 }
241                 else
242                 {
243                   beanObj = null;
244                 }
245               }
246               else
247               {
248                 if (attrValue.equals(attributeValue))
249                 {
250                   beanObj = tmpBeanObj;
251                 }
252                 else
253                 {
254                   beanObj = null;
255                 }
256               }
257             }
258           }
259         }
260       }
261     }
262 
263     return beanObj;
264   }
265 
266   /**
267    * Extract a collection of objects from the db using the name/value pairs within the object.
268    * All attributes given must match for the object to be returned.
269    *
270    * @param  attributes            A HashMap of name/value atrributes
271    * @param  likeMatch            Should a "indexOf" match be used (true).
272    *                      False means "equals" is used.
273    *
274    */
275 
276   public Collection getObjectsByAttributeValues(HashMap attributes, boolean likeMatch )
277   {
278     ArrayList objects = new ArrayList();
279 
280     // go through each value array checking for the value
281     Iterator keysIterator = attributes.keySet().iterator();
282     while (keysIterator.hasNext())
283     {
284       // create the "key" node and examine the propery for the key
285       String attributeName = (String)keysIterator.next();
286       String attributeValue = (String)attributes.get(attributeName);
287 
288       // ignore empty query attributes
289       if (attributeValue.length() == 0) continue;
290 
291       StringTokenizer tokens = new StringTokenizer(attributeName, ".");
292       String segment = tokens.nextToken();
293 
294       Object attribute = null;
295       Collection beanObjs = getObjectsByAttributeValueInternal(segment, attributeValue );
296 
297       Iterator beansIterator = beanObjs.iterator();
298       while (beansIterator.hasNext())
299       {
300         Object beanObj = beansIterator.next();
301         tokens = new StringTokenizer(attributeName, ".");
302 
303         segment = tokens.nextToken();
304         attribute = getBeanProperty(beanObj, segment);
305 
306         // stop when end of path is reached
307         while (tokens.hasMoreTokens())
308         {
309           // search children for next segment
310           segment = tokens.nextToken();
311 
312           attribute = getBeanProperty(attribute, segment);
313 
314           if (attribute != null)
315           {
316             Class valueClass = attribute.getClass();
317 
318             if( valueClass.isAssignableFrom(String.class) )
319             {
320               String attrValue = (String)attribute;
321 
322               if (likeMatch)
323               {
324                 if (attrValue.indexOf(attributeValue) != -1)
325                 {
326                   objects.add(beanObj);
327                 }
328                 else
329                 {
330                   objects.remove(beanObj);
331                 }
332               }
333               else
334               {
335                 if (attrValue.equals(attributeValue))
336                 {
337                   objects.add(beanObj);
338                 }
339                 else
340                 {
341                   objects.remove(beanObj);
342                 }
343               }
344             }
345           }
346         }
347       }
348     }
349 
350     return objects;
351   }
352 
353   /**
354    * Extract an object from the db using the value of an attribute within the object.
355    * This returns the first matching object.
356    *
357    * @param  attributeName          The name of the attribute.
358    * @param  attributeValue          The value of the attribute.
359    * @param  likeMatch            Should a "indexOf" match be used (true).
360    *                      False means "equals" is used.
361    *
362    */
363 
364   public Object getObjectByAttributeValue(String attributeName, String attributeValue, boolean likeMatch )
365   {
366     StringTokenizer tokens = new StringTokenizer(attributeName, ".");
367     String segment = tokens.nextToken();
368 
369     Object attribute = null;
370     Object beanObj = getObjectByAttributeValueInternal(segment, attributeValue );
371 
372     if (beanObj != null)
373     {
374       attribute = getBeanProperty(beanObj, segment);
375 
376       // stop when end of path is reached
377       while (tokens.hasMoreTokens())
378       {
379         // search children for next segment
380         segment = tokens.nextToken();
381 
382         attribute = getBeanProperty(attribute, segment);
383 
384         Class valueClass = attribute.getClass();
385         if( valueClass.isAssignableFrom(String.class) )
386         {
387           String attrValue = (String)attribute;
388 
389           if (likeMatch)
390           {
391             if (attrValue.indexOf(attributeValue) != -1)
392             {
393               return beanObj;
394             }
395           }
396           else
397           {
398             if (attrValue.equals(attributeValue))
399             {
400               return beanObj;
401             }
402           }
403         }
404       }
405     }
406 
407     return null;
408   }
409 
410   /**
411    * Extract a collection of objects from the db using the value of an attribute within the object.
412    * This returns all matching objects.
413    *
414    * @param  attributeName          The name of the attribute.
415    * @param  attributeValue          The value of the attribute.
416    * @param  likeMatch            Should a "indexOf" match be used (true).
417    *                      False means "equals" is used.
418    *
419    */
420 
421   public Collection getObjectsByAttributeValue( String attributeName, String attributeValue, boolean likeMatch )
422   {
423     StringTokenizer tokens = new StringTokenizer(attributeName, ".");
424     String segment = tokens.nextToken();
425 
426     ArrayList objects = new ArrayList();
427     Object attribute = null;
428     Collection beanObjs = getObjectsByAttributeValueInternal(segment, attributeValue );
429 
430     Iterator keysIterator = beanObjs.iterator();
431     while (keysIterator.hasNext())
432     {
433       Object beanObj = keysIterator.next();
434       tokens = new StringTokenizer(attributeName, ".");
435 
436       segment = tokens.nextToken();
437       attribute = getBeanProperty(beanObj, segment);
438 
439       // stop when end of path is reached
440       while (tokens.hasMoreTokens())
441       {
442         segment = tokens.nextToken();
443 
444         attribute = getBeanProperty(attribute, segment);
445 
446         Class valueClass = attribute.getClass();
447         if( valueClass.isAssignableFrom(String.class) )
448         {
449           String attrValue = (String)attribute;
450 
451           if (likeMatch)
452           {
453             if (attrValue.indexOf(attributeValue) != -1)
454             {
455               objects.add(beanObj);
456             }
457           }
458           else
459           {
460             if (attrValue.equals(attributeValue))
461             {
462               objects.add(beanObj);
463             }
464           }
465         }
466       }
467     }
468 
469     return objects;
470   }
471 
472 
473   /**
474    * Save the db into the given file as XML.
475    *
476    * @param  db                The database to load into.
477    * @param  path              The path to the file to use.
478    *
479    */
480 
481   private void saveDumbDb( DumbDB db, String path )
482   {
483     try
484     {
485       XalanModelTree modelTree = new XalanModelTree();
486 
487       ModelNode dbNode = modelTree.createNode("db","");
488       modelTree.getRootNode().appendChild(dbNode);
489 
490       // load the node with "data" (from the bean)
491       BeanTransformer.beanToModel( db, dbNode, true );
492 
493       String data = XmlUtil.ViewNode(modelTree.getModelTree());
494 
495       PrintWriter xmlOut
496          = new PrintWriter(new BufferedWriter(new FileWriter(path)));
497 
498       xmlOut.println(data);
499 
500       xmlOut.flush();
501       xmlOut.close();
502     }
503     catch( Exception exception )
504     {
505       exception.printStackTrace();
506     }
507   }
508 
509   /**
510    * Load the db from the given XML file.
511    *
512    * @param  db                The database to load into.
513    * @param  path              The path to the file to use.
514    *
515    */
516 
517   private void loadDumbDb( DumbDB db, String path )
518   {
519     try
520     {
521       XalanModelTree modelTree = new XalanModelTree();
522       modelTree.loadFromFile(path);
523 
524       ModelNode dbNode = modelTree.getNode(modelTree.getRootNode(), "/db");
525 
526       // update the contact with the new data
527       if (modelTree.getRootNode() != null)
528       {
529         db =
530           (DumbDB)BeanTransformer.updateBeanFromModel( db, dbNode );
531       }
532     }
533     catch( Exception exception )
534     {
535       exception.printStackTrace();
536     }
537   }
538 
539   /**
540    * Internal Method.
541    */
542 
543   private Object getObjectByAttributeValueInternal( String attributeName, String attributeValue )
544   {
545     Iterator keysIterator = database.keySet().iterator();
546     while (keysIterator.hasNext())
547     {
548       String key = (String)keysIterator.next();
549       Object dataItem = database.get(key);
550 
551       Object beanValue = getBeanProperty(dataItem, attributeName);
552       if (beanValue != null)
553       {
554         return dataItem;
555       }
556     }
557 
558     return null;
559   }
560 
561   /**
562    * Internal Method.
563    */
564 
565   private Collection getObjectsByAttributeValueInternal( String attributeName, String attributeValue )
566   {
567     ArrayList objects = new ArrayList();
568 
569     Iterator keysIterator = database.keySet().iterator();
570     while (keysIterator.hasNext())
571     {
572       String key = (String)keysIterator.next();
573       Object dataItem = database.get(key);
574 
575       Object beanValue = getBeanProperty(dataItem, attributeName);
576 
577       if (beanValue != null)
578       {
579         objects.add(dataItem);
580       }
581     }
582 
583     return objects;
584   }
585 
586   /**
587    * Internal Method.
588    */
589 
590   private Object getBeanProperty(Object beanObject, String propertyName)
591   {
592     try
593     {
594       // transverse the bean
595       BeanInfo beanInfo = Introspector.getBeanInfo( beanObject.getClass() );
596 
597       // get all the properties of the bean
598       PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
599 
600       // for each property, get the set/get methods if available
601       int index=0;
602       for (index=0; index<propertyDescriptors.length; index++)
603       {
604         PropertyDescriptor property = propertyDescriptors[index];
605 
606         // skip the type "class", it is actually the bean itself
607         if( property.getName().equals(propertyName) )
608         {
609           // use reflection to ask the bean property for it's value
610           Method getMethod = property.getReadMethod();
611           Object returnObj = getMethod.invoke( beanObject, null );
612 
613           return returnObj;
614         }
615       }
616     }
617     catch (Exception exception)
618     {
619       exception.printStackTrace();
620     }
621 
622     return null;
623   }
624 }
625