View Javadoc

1   package pl.aislib.fm.shepherds;
2   
3   import java.util.HashMap;
4   import java.util.Iterator;
5   import java.util.List;
6   import java.util.Map;
7   
8   import java.lang.reflect.Constructor;
9   
10  import org.apache.commons.collections.Predicate;
11  import org.apache.commons.logging.Log;
12  
13  import pl.aislib.lang.Loader;
14  
15  /***
16   * Defines how Shepherds are trained.
17   * @author <a href='mailto:warlock@ais.pl'>Michal Jastak</a>
18   * @version $Revision: 1.6 $
19   * @since AISLIB 0.4
20   * @see Shepherd
21   * @see ShepherdsDog
22   */
23  public class ShepherdsSchool {
24  
25    private static final String DEFAULT_PREDICATE_CLASS = "pl.aislib.util.predicates.IsNotNullPredicate";
26  
27    private Map knownDogBreeds;
28    private Map  knownShepherds;
29  
30    /***
31     * Constructs new ShepherdsSchool object.
32     */
33    public ShepherdsSchool() {
34      knownShepherds = new HashMap();
35      knownShepherds.put("isNull",    "pl.aislib.util.predicates.IsNullPredicate");
36      knownShepherds.put("isNotNull", "pl.aislib.util.predicates.IsNotNullPredicate");
37  
38      knownDogBreeds = new HashMap(4);
39      registerDogBreed(new DogWatchingHttpRequestParameters());
40      registerDogBreed(new DogWatchingHttpRequestAttributes());
41      registerDogBreed(new DogWatchingHttpSessionAttributes());
42      registerDogBreed(new DogWatchingHttpRequest());
43    }
44  
45    private void registerDogBreed(ShepherdsDog dog) {
46      knownDogBreeds.put(dog.getBreed(), dog);
47    }
48  
49    /***
50     * Creates new Shepherd. 
51     * <p>New <code>Shepherd</code> is created using <code>Predicate</code>, <code>dogsBreed</code> 
52     * and <code>pageRef</code> (see {@link Shepherd} class description). <br />
53     * <code>Predicate</code> mentioned above is created by instatiating class found in following way:
54     * <ul>
55     *   <li>given <code>predicateName</code> is checked against known predicate names, if found, 
56     *   Class corresponding to it is used for constructing new <code>Predicate</code> object,</li>
57     *   <li>unknown <code>predicateName</code> is treated as some Class name and used for 
58     *   constructing new <code>Predicate</code> object</li>
59     * </ul></p>
60     * <p>Well known predicates are listed below, their names may be used as <code>predicateName</code>.
61     * <table border='0' cellspacing='4' cellpadding='4'>
62     *   <tr><th style='background-color: Navy; color: White; font-size: small;'>Predicate Name</th>
63     *       <th style='background-color: Navy; color: White; font-size: small;'>Implementing class</th></tr>
64     *   <tr style='background-color: #f0f0f0; font-size: small;'><td><code>isNull</code></td>
65     *                                         <td>{@link pl.aislib.util.predicates.IsNullPredicate}</td></tr>
66     *   <tr style='background-color: #d0d0d0; font-size: small;'><td><code>isNotNull</code></td>
67     *                                         <td>{@link pl.aislib.util.predicates.IsNotNullPredicate}</td></tr>
68     * </table>
69     * </p>
70     * <p>Every <code>Shepherd</code> has its own <code>ShepherdsDog</code> associated, helping him to mind the sheeps.
71     * Such a <it>Dog</it> object is used by <code>Shepherd</code> for reading values of watched properties
72     * for specific <code>sheep</code> object. <br /> <it>Dogs</it> available now are listed below, their breeds
73     * may be used as <code>dogsBreed</code> parameter.
74     * <table border='0' cellspacing='4' cellpadding='4'>
75     *   <tr><th style='background-color: Navy; color: White; font-size: small;'>Breed</th>
76     *       <th style='background-color: Navy; color: White; font-size: small;'>Implementing class</th></tr>
77     *   <tr style='background-color: #f0f0f0; font-size: small;'><td><code>request-attr</code></td>
78     *                                         <td>{@link DogWatchingHttpRequestAttributes}</td></tr>
79     *   <tr style='background-color: #d0d0d0; font-size: small;'><td><code>request-param</code></td>
80     *                                         <td>{@link DogWatchingHttpRequestParameters}</td></tr>
81     *   <tr style='background-color: #f0f0f0; font-size: small;'><td><code>session-attr</code></td>
82     *                                         <td>{@link DogWatchingHttpSessionAttributes}</td></tr>
83     * </table>
84     * </p>
85     * @param propertyName name of property which will be watched by Shepherd and its Dog
86     * @param predicateName well known <code>Predicate</code> name or <code>Predicate</code> class name (defines how
87     *        properties will be checked)
88     * @param dogsBreed breed of the dog which will help Shepherd (defines what kind of properties will be watched)
89     * @param pageRef action key for {@link pl.aislib.fm.Page} which will be used as target for all operations controlled
90     *                by <code>Shepherd</code> when <code>Predicate</code> will be matched
91     * @return trained Shepherd or <code>null</code>
92     * @see Predicate
93     * @see Shepherd
94     * @see ShepherdsDog
95     */
96    public static Shepherd newShepherd(String propertyName, String pageRef,
97        String predicateName, String dogsBreed, Log log) throws Exception {
98      Predicate       predicate          = null;
99      ShepherdsSchool school             = new ShepherdsSchool();
100 
101     ShepherdsDog    shepherdsDog       = school.newShepherdsDog(dogsBreed);
102     String          predicateClassName = school.getPredicateClassName(predicateName);
103 
104     Class clazz = Loader.findClass(predicateClassName); 
105     Constructor constructor = clazz.getConstructor(new Class[0]);
106     predicate = (Predicate) constructor.newInstance(new Object[0]);
107     shepherdsDog.setWatchedProperty(propertyName);
108     shepherdsDog.setLog(log);
109     return new Shepherd(predicate, shepherdsDog, pageRef, log);
110   }
111 
112   /***
113    * @deprecated, use {@link ShepherdsSchool#egzamine(List, Pasture, Object, String)
114    */
115   public static String egzamine(List shepherds, Pasture pasture, Object sheep, String defaultResult) {
116     return examine(shepherds, pasture, sheep, defaultResult);
117   }
118 
119   public static String examine(List shepherds, Pasture pasture, Object sheep, String defaultResult) {
120     for (Iterator it = shepherds.iterator(); it.hasNext();) {
121       Shepherd shepherd = (Shepherd) it.next();
122       String result = shepherd.mindTheSheep(pasture, sheep);
123       if (result != null) {
124         return result;
125       }
126     }
127     return defaultResult;
128   }
129 
130 
131   /***
132    *
133    */
134   private ShepherdsDog newShepherdsDog(String dogsBreed) {
135     ShepherdsDog result = null;
136     if (dogsBreed != null) {
137       result = (ShepherdsDog) knownDogBreeds.get(dogsBreed);
138     }
139     if (result == null) {
140       result = new DogWatchingHttpRequestParameters();
141     } 
142     return result;
143   }
144 
145   /***
146    *
147    */
148   private String getPredicateClassName(String predicateName) {
149     String result = (String) knownShepherds.get(predicateName);
150     if (result == null) {
151       result = predicateName;
152     }
153     if (result == null) {
154       result = DEFAULT_PREDICATE_CLASS;
155     }
156     return result;
157   }
158 
159 } // class