%line | %branch | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
org.apache.turbine.services.intake.IntakeTool |
|
|
1 | package org.apache.turbine.services.intake; |
|
2 | ||
3 | /* |
|
4 | * Copyright 2001-2005 The Apache Software Foundation. |
|
5 | * |
|
6 | * Licensed under the Apache License, Version 2.0 (the "License") |
|
7 | * you may not use this file except in compliance with the License. |
|
8 | * You may obtain a copy of the License at |
|
9 | * |
|
10 | * http://www.apache.org/licenses/LICENSE-2.0 |
|
11 | * |
|
12 | * Unless required by applicable law or agreed to in writing, software |
|
13 | * distributed under the License is distributed on an "AS IS" BASIS, |
|
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
15 | * See the License for the specific language governing permissions and |
|
16 | * limitations under the License. |
|
17 | */ |
|
18 | ||
19 | import java.util.HashMap; |
|
20 | import java.util.Iterator; |
|
21 | import java.util.List; |
|
22 | import java.util.Map; |
|
23 | ||
24 | import org.apache.commons.logging.Log; |
|
25 | import org.apache.commons.logging.LogFactory; |
|
26 | ||
27 | import org.apache.turbine.om.Retrievable; |
|
28 | import org.apache.turbine.services.intake.model.Group; |
|
29 | import org.apache.turbine.services.pull.ApplicationTool; |
|
30 | import org.apache.turbine.util.RunData; |
|
31 | import org.apache.turbine.util.TurbineException; |
|
32 | import org.apache.turbine.util.parser.ValueParser; |
|
33 | import org.apache.turbine.util.pool.Recyclable; |
|
34 | ||
35 | /** |
|
36 | * The main class through which Intake is accessed. |
|
37 | * |
|
38 | * @author <a href="mailto:jmcnally@collab.net">John D. McNally</a> |
|
39 | * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a> |
|
40 | * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a> |
|
41 | * @version $Id: IntakeTool.java 264148 2005-08-29 14:21:04Z henning $ |
|
42 | */ |
|
43 | 13 | public class IntakeTool |
44 | implements ApplicationTool, Recyclable |
|
45 | { |
|
46 | /** Used for logging */ |
|
47 | 39 | private static Log log = LogFactory.getLog(IntakeTool.class); |
48 | ||
49 | /** Constant for default key */ |
|
50 | public static final String DEFAULT_KEY = "_0"; |
|
51 | ||
52 | /** Constant for the hidden fieldname */ |
|
53 | public static final String INTAKE_GRP = "intake-grp"; |
|
54 | ||
55 | /** Groups from intake.xml */ |
|
56 | private HashMap groups; |
|
57 | ||
58 | /** ValueParser instance */ |
|
59 | private ValueParser pp; |
|
60 | ||
61 | 0 | HashMap declaredGroups = new HashMap(); |
62 | 0 | StringBuffer allGroupsSB = new StringBuffer(256); |
63 | 0 | StringBuffer groupSB = new StringBuffer(128); |
64 | ||
65 | /** The cache of PullHelpers. **/ |
|
66 | private Map pullMap; |
|
67 | ||
68 | /** |
|
69 | * Constructor |
|
70 | */ |
|
71 | public IntakeTool() |
|
72 | 0 | { |
73 | 0 | String[] groupNames = TurbineIntake.getGroupNames(); |
74 | 0 | int groupCount = 0; |
75 | 0 | if (groupNames != null) |
76 | { |
|
77 | 0 | groupCount = groupNames.length; |
78 | } |
|
79 | 0 | groups = new HashMap((int) (1.25 * groupCount + 1)); |
80 | 0 | pullMap = new HashMap((int) (1.25 * groupCount + 1)); |
81 | ||
82 | 0 | for (int i = groupCount - 1; i >= 0; i--) |
83 | { |
|
84 | 0 | pullMap.put(groupNames[i], new PullHelper(groupNames[i])); |
85 | } |
|
86 | 0 | } |
87 | ||
88 | /** |
|
89 | * Prepares intake for a single request |
|
90 | */ |
|
91 | public void init(Object runData) |
|
92 | { |
|
93 | 0 | this.pp = ((RunData) runData).getParameters(); |
94 | ||
95 | 0 | String[] groupKeys = pp.getStrings(INTAKE_GRP); |
96 | 0 | String[] groupNames = null; |
97 | 0 | if (groupKeys == null || groupKeys.length == 0) |
98 | { |
|
99 | 0 | groupNames = TurbineIntake.getGroupNames(); |
100 | } |
|
101 | else |
|
102 | { |
|
103 | 0 | groupNames = new String[groupKeys.length]; |
104 | 0 | for (int i = groupKeys.length - 1; i >= 0; i--) |
105 | { |
|
106 | 0 | groupNames[i] = TurbineIntake.getGroupName(groupKeys[i]); |
107 | } |
|
108 | ||
109 | } |
|
110 | ||
111 | 0 | for (int i = groupNames.length - 1; i >= 0; i--) |
112 | { |
|
113 | try |
|
114 | { |
|
115 | 0 | List foundGroups = TurbineIntake.getGroup(groupNames[i]) |
116 | .getObjects(pp); |
|
117 | ||
118 | 0 | if (foundGroups != null) |
119 | { |
|
120 | 0 | for (Iterator iter = foundGroups.iterator(); |
121 | 0 | iter.hasNext();) |
122 | { |
|
123 | 0 | Group group = (Group) iter.next(); |
124 | 0 | groups.put(group.getObjectKey(), group); |
125 | } |
|
126 | } |
|
127 | } |
|
128 | 0 | catch (Exception e) |
129 | { |
|
130 | 0 | log.error(e); |
131 | 0 | } |
132 | } |
|
133 | 0 | } |
134 | ||
135 | public void addGroupsToParameters(ValueParser vp) |
|
136 | { |
|
137 | 0 | for (Iterator i = groups.values().iterator(); i.hasNext();) |
138 | { |
|
139 | 0 | Group group = (Group) i.next(); |
140 | 0 | if (!declaredGroups.containsKey(group.getIntakeGroupName())) |
141 | { |
|
142 | 0 | declaredGroups.put(group.getIntakeGroupName(), null); |
143 | 0 | vp.add("intake-grp", group.getGID()); |
144 | } |
|
145 | 0 | vp.add(group.getGID(), group.getOID()); |
146 | } |
|
147 | 0 | declaredGroups.clear(); |
148 | 0 | } |
149 | ||
150 | /** |
|
151 | * A convenience method to write out the hidden form fields |
|
152 | * that notify intake of the relevant groups. It should be used |
|
153 | * only in templates with 1 form. In multiform templates, the groups |
|
154 | * that are relevant for each form need to be declared using |
|
155 | * $intake.newForm() and $intake.declareGroup($group) for the relevant |
|
156 | * groups in the form. |
|
157 | * |
|
158 | */ |
|
159 | public String declareGroups() |
|
160 | { |
|
161 | 0 | allGroupsSB.setLength(0); |
162 | 0 | for (Iterator i = groups.values().iterator(); i.hasNext();) |
163 | { |
|
164 | 0 | declareGroup((Group) i.next(), allGroupsSB); |
165 | } |
|
166 | 0 | return allGroupsSB.toString(); |
167 | } |
|
168 | ||
169 | /** |
|
170 | * A convenience method to write out the hidden form fields |
|
171 | * that notify intake of the group. |
|
172 | */ |
|
173 | public String declareGroup(Group group) |
|
174 | { |
|
175 | 0 | groupSB.setLength(0); |
176 | 0 | declareGroup(group, groupSB); |
177 | 0 | return groupSB.toString(); |
178 | } |
|
179 | ||
180 | /** |
|
181 | * xhtml valid hidden input field(s) that notifies intake of the |
|
182 | * group's presence. |
|
183 | */ |
|
184 | public void declareGroup(Group group, StringBuffer sb) |
|
185 | { |
|
186 | 0 | if (!declaredGroups.containsKey(group.getIntakeGroupName())) |
187 | { |
|
188 | 0 | declaredGroups.put(group.getIntakeGroupName(), null); |
189 | 0 | sb.append("<input type=\"hidden\" name=\"") |
190 | .append(INTAKE_GRP) |
|
191 | .append("\" value=\"") |
|
192 | .append(group.getGID()) |
|
193 | .append("\"/>\n"); |
|
194 | } |
|
195 | 0 | group.appendHtmlFormInput(sb); |
196 | 0 | } |
197 | ||
198 | public void newForm() |
|
199 | { |
|
200 | 0 | declaredGroups.clear(); |
201 | 0 | for (Iterator i = groups.values().iterator(); i.hasNext();) |
202 | { |
|
203 | 0 | ((Group) i.next()).resetDeclared(); |
204 | } |
|
205 | 0 | } |
206 | ||
207 | /** |
|
208 | * Implementation of ApplicationTool interface is not needed for this |
|
209 | * tool as it is request scoped |
|
210 | */ |
|
211 | public void refresh() |
|
212 | { |
|
213 | // empty |
|
214 | 0 | } |
215 | ||
216 | /** |
|
217 | * Inner class to present a nice interface to the template designer |
|
218 | */ |
|
219 | public class PullHelper |
|
220 | { |
|
221 | /** Name of the group used by the pull helper */ |
|
222 | String groupName; |
|
223 | ||
224 | /** |
|
225 | * Private constructor to force use of factory method. |
|
226 | * |
|
227 | * @param groupName |
|
228 | */ |
|
229 | private PullHelper(String groupName) |
|
230 | { |
|
231 | this.groupName = groupName; |
|
232 | } |
|
233 | ||
234 | /** |
|
235 | * Populates the object with the default values from the XML File |
|
236 | * |
|
237 | * @return a Group object with the default values |
|
238 | * @throws IntakeException |
|
239 | */ |
|
240 | public Group getDefault() |
|
241 | throws IntakeException |
|
242 | { |
|
243 | return setKey(DEFAULT_KEY); |
|
244 | } |
|
245 | ||
246 | /** |
|
247 | * Calls setKey(key,true) |
|
248 | * |
|
249 | * @param key |
|
250 | * @return an Intake Group |
|
251 | * @throws IntakeException |
|
252 | */ |
|
253 | public Group setKey(String key) |
|
254 | throws IntakeException |
|
255 | { |
|
256 | return setKey(key, true); |
|
257 | } |
|
258 | ||
259 | /** |
|
260 | * |
|
261 | * @param key |
|
262 | * @param create |
|
263 | * @return an Intake Group |
|
264 | * @throws IntakeException |
|
265 | */ |
|
266 | public Group setKey(String key, boolean create) |
|
267 | throws IntakeException |
|
268 | { |
|
269 | Group g = null; |
|
270 | ||
271 | String inputKey = TurbineIntake.getGroupKey(groupName) + key; |
|
272 | if (groups.containsKey(inputKey)) |
|
273 | { |
|
274 | g = (Group) groups.get(inputKey); |
|
275 | } |
|
276 | else if (create) |
|
277 | { |
|
278 | g = TurbineIntake.getGroup(groupName); |
|
279 | groups.put(inputKey, g); |
|
280 | g.init(key, pp); |
|
281 | } |
|
282 | ||
283 | return g; |
|
284 | } |
|
285 | ||
286 | /** |
|
287 | * maps an Intake Group to the values from a Retrievable object. |
|
288 | * |
|
289 | * @param obj A retrievable object |
|
290 | * @return an Intake Group |
|
291 | */ |
|
292 | public Group mapTo(Retrievable obj) |
|
293 | throws IntakeException |
|
294 | { |
|
295 | Group g = null; |
|
296 | ||
297 | try |
|
298 | { |
|
299 | String inputKey = TurbineIntake.getGroupKey(groupName) |
|
300 | + obj.getQueryKey(); |
|
301 | if (groups.containsKey(inputKey)) |
|
302 | { |
|
303 | g = (Group) groups.get(inputKey); |
|
304 | } |
|
305 | else |
|
306 | { |
|
307 | g = TurbineIntake.getGroup(groupName); |
|
308 | groups.put(inputKey, g); |
|
309 | } |
|
310 | return g.init(obj); |
|
311 | } |
|
312 | catch (Exception e) |
|
313 | { |
|
314 | log.error(e); |
|
315 | } |
|
316 | ||
317 | return null; |
|
318 | } |
|
319 | } |
|
320 | ||
321 | /** |
|
322 | * get a specific group |
|
323 | */ |
|
324 | public PullHelper get(String groupName) |
|
325 | throws IntakeException |
|
326 | { |
|
327 | 0 | return (PullHelper) pullMap.get(groupName); |
328 | } |
|
329 | ||
330 | /** |
|
331 | * Get a specific group |
|
332 | * |
|
333 | * @param throwExceptions if false, exceptions will be supressed. |
|
334 | * @throws IntakeException could not retrieve group |
|
335 | */ |
|
336 | public PullHelper get(String groupName, boolean throwExceptions) |
|
337 | throws IntakeException |
|
338 | { |
|
339 | 0 | return (PullHelper) pullMap.get(groupName); |
340 | } |
|
341 | ||
342 | /** |
|
343 | * Loops through all of the Groups and checks to see if |
|
344 | * the data within the Group is valid. |
|
345 | */ |
|
346 | public boolean isAllValid() |
|
347 | { |
|
348 | 0 | boolean allValid = true; |
349 | 0 | for (Iterator iter = groups.values().iterator(); iter.hasNext();) |
350 | { |
|
351 | 0 | Group group = (Group) iter.next(); |
352 | 0 | allValid &= group.isAllValid(); |
353 | } |
|
354 | 0 | return allValid; |
355 | } |
|
356 | ||
357 | /** |
|
358 | * Get a specific group by name and key. |
|
359 | */ |
|
360 | public Group get(String groupName, String key) |
|
361 | throws IntakeException |
|
362 | { |
|
363 | 0 | if (groupName == null) |
364 | { |
|
365 | 0 | throw new IntakeException("Intake.get: groupName == null"); |
366 | } |
|
367 | 0 | if (key == null) |
368 | { |
|
369 | 0 | throw new IntakeException("Intake.get: key == null"); |
370 | } |
|
371 | ||
372 | 0 | PullHelper ph = get(groupName); |
373 | 0 | return (ph == null) ? class="keyword">null : ph.setKey(key); |
374 | } |
|
375 | ||
376 | /** |
|
377 | * Get a specific group by name and key. Also specify |
|
378 | * whether or not you want to create a new group. |
|
379 | */ |
|
380 | public Group get(String groupName, String key, boolean create) |
|
381 | throws IntakeException |
|
382 | { |
|
383 | 0 | if (groupName == null) |
384 | { |
|
385 | 0 | throw new IntakeException("Intake.get: groupName == null"); |
386 | } |
|
387 | 0 | if (key == null) |
388 | { |
|
389 | 0 | throw new IntakeException("Intake.get: key == null"); |
390 | } |
|
391 | ||
392 | 0 | PullHelper ph = get(groupName); |
393 | 0 | return (ph == null) ? class="keyword">null : ph.setKey(key, create); |
394 | } |
|
395 | ||
396 | /** |
|
397 | * Removes group. Primary use is to remove a group that has |
|
398 | * been processed by an action and is no longer appropriate |
|
399 | * in the view (screen). |
|
400 | */ |
|
401 | public void remove(Group group) |
|
402 | { |
|
403 | 0 | if (group != null) |
404 | { |
|
405 | 0 | groups.remove(group.getObjectKey()); |
406 | 0 | group.removeFromRequest(); |
407 | ||
408 | 0 | String[] groupKeys = pp.getStrings(INTAKE_GRP); |
409 | ||
410 | 0 | pp.remove(INTAKE_GRP); |
411 | ||
412 | 0 | if (groupKeys != null) |
413 | { |
|
414 | 0 | for (int i = 0; i < groupKeys.length; i++) |
415 | { |
|
416 | 0 | if (!groupKeys[i].equals(group.getGID())) |
417 | { |
|
418 | 0 | pp.add(INTAKE_GRP, groupKeys[i]); |
419 | } |
|
420 | } |
|
421 | } |
|
422 | ||
423 | try |
|
424 | { |
|
425 | 0 | TurbineIntake.releaseGroup(group); |
426 | } |
|
427 | 0 | catch (TurbineException se) |
428 | { |
|
429 | 0 | log.error("Tried to release unknown group " |
430 | + group.getIntakeGroupName()); |
|
431 | 0 | } |
432 | } |
|
433 | 0 | } |
434 | ||
435 | /** |
|
436 | * Removes all groups. Primary use is to remove groups that have |
|
437 | * been processed by an action and are no longer appropriate |
|
438 | * in the view (screen). |
|
439 | */ |
|
440 | public void removeAll() |
|
441 | { |
|
442 | 0 | Object[] allGroups = groups.values().toArray(); |
443 | 0 | for (int i = allGroups.length - 1; i >= 0; i--) |
444 | { |
|
445 | 0 | Group group = (Group) allGroups[i]; |
446 | 0 | remove(group); |
447 | } |
|
448 | 0 | } |
449 | ||
450 | /** |
|
451 | * Get a Map containing all the groups. |
|
452 | * |
|
453 | * @return the Group Map |
|
454 | */ |
|
455 | public Map getGroups() |
|
456 | { |
|
457 | 0 | return groups; |
458 | } |
|
459 | ||
460 | // ****************** Recyclable implementation ************************ |
|
461 | ||
462 | private boolean disposed; |
|
463 | ||
464 | /** |
|
465 | * Recycles the object for a new client. Recycle methods with |
|
466 | * parameters must be added to implementing object and they will be |
|
467 | * automatically called by pool implementations when the object is |
|
468 | * taken from the pool for a new client. The parameters must |
|
469 | * correspond to the parameters of the constructors of the object. |
|
470 | * For new objects, constructors can call their corresponding recycle |
|
471 | * methods whenever applicable. |
|
472 | * The recycle methods must call their super. |
|
473 | */ |
|
474 | public void recycle() |
|
475 | { |
|
476 | 0 | disposed = false; |
477 | 0 | } |
478 | ||
479 | /** |
|
480 | * Disposes the object after use. The method is called |
|
481 | * when the object is returned to its pool. |
|
482 | * The dispose method must call its super. |
|
483 | */ |
|
484 | public void dispose() |
|
485 | { |
|
486 | 0 | for (Iterator iter = groups.values().iterator(); iter.hasNext();) |
487 | { |
|
488 | 0 | Group g = (Group) iter.next(); |
489 | ||
490 | try |
|
491 | { |
|
492 | 0 | TurbineIntake.releaseGroup(g); |
493 | } |
|
494 | 0 | catch (TurbineException se) |
495 | { |
|
496 | 0 | log.error("Tried to release unknown group " |
497 | + g.getIntakeGroupName()); |
|
498 | 0 | } |
499 | } |
|
500 | ||
501 | 0 | groups.clear(); |
502 | 0 | declaredGroups.clear(); |
503 | 0 | pp = null; |
504 | ||
505 | 0 | disposed = true; |
506 | 0 | } |
507 | ||
508 | /** |
|
509 | * Checks whether the recyclable has been disposed. |
|
510 | * |
|
511 | * @return true, if the recyclable is disposed. |
|
512 | */ |
|
513 | public boolean isDisposed() |
|
514 | { |
|
515 | 0 | return disposed; |
516 | } |
|
517 | } |
This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |