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 }