1
2
3
4
5
6
7
8
9
10
11
12 package ca.spaz.cron.datasource;
13
14 import java.util.*;
15 import java.util.List;
16
17 import ca.spaz.cron.database.*;
18
19 /***
20 * This is a partial implementation of the <code>IFoodDatasource</code>
21 * interface, providing checking for proper sources for <code>Food</code>
22 * parameters and basic naming. Protected abstract implementation methods
23 * are provided for all public methods that this class handles.
24 *
25 * @author Chris Rose
26 */
27 public abstract class AbstractFoodDataSource implements IFoodDatasource {
28
29 private String name;
30 private FoodDatasourceException throwable;
31
32 /***
33 * Construct a new instance of this class, with the name supplied.
34 * @param name the name of this datasource.
35 */
36 protected AbstractFoodDataSource(String name) {
37 this.name = name;
38 }
39
40 /***
41 * Gatekeeper method to ensure that the <code>Food</code> object is from
42 * a different Datasource.
43 *
44 * @param food a food object to test.
45 * @throws IllegalArgumentException if the food object is from this datasource.
46 */
47 protected void diffSource(Food food) {
48 if (food != null && this == food.getDataSource()) {
49 throw new IllegalArgumentException(
50 "Food may not come from this source");
51 }
52 }
53
54 /***
55 * Gatekeeper method to ensure that an object is not null.
56 * @param testedObject
57 */
58 protected void notNull(Object testedObject) {
59 if (testedObject == null) {
60 throw new IllegalArgumentException("Illegal NULL argument.");
61 }
62 }
63
64 /***
65 * Retrieve a list of all foods in this datasource.
66 * @return a List of <code>Food</code> objects consisting of every food in the datasource.
67 * @throws <code>UnsupportedOperationException</code> if the datasource does not
68 * support listing. (if <code>isListable()</code> is false)
69 */
70 protected abstract List doFindAllFoods();
71
72 /***
73 * Retrieve a <code>List</code> of all foods in this particular Datasource.
74 *
75 * @param keys the keys to search on. This searches with an AND relation.
76 * @return a List of <code>Food</code> objects matching the criteria.
77 * @throws <code>UnsupportedOperationException</code> if the datasource does not
78 * support searching. (if <code>isSearchable()</code> is false)
79 */
80 protected abstract List doFindFoods(String[] keys);
81
82 /***
83 * Retrieve a <code>List</code> of all foods in this particular Datasource having
84 * the given food group and source.
85 *
86 * @param keys the keys to search on. This searches with an AND relation.
87 * @param foodGroup the food group to search for. <code>null</code> to ignore.
88 * @param source the source of this food item. <code>null</code> to ignore.
89 * @return a List of <code>Food</code> objects matching the criteria.
90 * @throws <code>UnsupportedOperationException</code> if the datasource does not
91 * support searching. (if <code>isSearchable()</code> is false)
92 */
93 protected abstract List doFindFoods(String[] keys, String foodGroup,
94 String source);
95
96 /***
97 * Return a <code>List</code> of <code>Measure</code> objects for the provided food.
98 * @param food a <code>Food</code> object to find the measures for
99 * @return a <code>List</code> that is guaranteed to contain only <code>Measure</code>
100 * objects.
101 */
102 protected abstract List doGetMeasuresFor(Food food);
103
104 /***
105 * Fill the provided <code>NutrientTable</code> with the nutrients associated with the
106 * <code>Food</code>.
107 * @param food The food item to load from
108 * @param nutrients the <code>NutrientTable</code> to fill.
109 */
110 protected abstract void doGetNutrientsFor(Food food, NutrientTable nutrients);
111
112
113
114
115
116
117 public final List findAllFoods() {
118 if (isListable()) {
119 return Collections.unmodifiableList(doFindAllFoods());
120 } else {
121 throw new UnsupportedOperationException(getClass().getName()
122 + " does not support listing");
123 }
124 }
125
126
127
128
129
130
131 public final List findFoods(String[] keys) {
132 if (isSearchable()) {
133 return Collections.unmodifiableList(doFindFoods(keys));
134 } else {
135 throw new UnsupportedOperationException(getClass().getName()
136 + " does not support searching");
137 }
138 }
139
140
141
142
143
144
145
146 public final List findFoods(String[] keys, String foodGroup, String source) {
147 if (isSearchable()) {
148 return Collections.unmodifiableList(doFindFoods(keys, foodGroup, source));
149 } else {
150 throw new UnsupportedOperationException(getClass().getName()
151 + " does not support searching");
152 }
153 }
154
155
156
157
158
159
160 public final List getMeasuresFor(Food food) {
161 sameSource(food);
162 return Collections.unmodifiableList(doGetMeasuresFor(food));
163 }
164
165
166
167
168
169
170 public String getName() {
171 return name;
172 }
173
174
175
176
177
178
179
180 public final void getNutrientsFor(Food food, NutrientTable nutrients) {
181 sameSource(food);
182 doGetNutrientsFor(food, nutrients);
183 }
184
185 /***
186 * Gatekeeper method to ensure that the <code>Food</code> object is from
187 * this Datasource.
188 *
189 * @param food a food object to test.
190 * @throws IllegalArgumentException if the food object is from another datasource.
191 */
192 protected void sameSource(Food food) {
193 if (food != null && food.getDataSource() != this) {
194 throw new IllegalArgumentException("Food must come from this source");
195 }
196 }
197
198
199
200
201
202
203 public final String toString() {
204 return getName();
205 }
206
207
208
209 public FoodDatasourceException getLastError() {
210 FoodDatasourceException ret = throwable;
211 throwable = null;
212 return ret;
213 }
214
215 /***
216 * Set the last error message to the supplied Throwable.
217 * @param t the exception that just happened.
218 */
219 protected void registerError(Throwable t) {
220 this.throwable = new FoodDatasourceException(t);
221 }
222 }