1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package org.equanda.tapestry5.components;
26
27 import org.apache.tapestry.commons.components.Hidden;
28 import org.apache.tapestry5.*;
29 import org.apache.tapestry5.annotations.*;
30 import org.apache.tapestry5.corelib.components.Delegate;
31 import org.apache.tapestry5.corelib.components.Loop;
32 import org.apache.tapestry5.ioc.annotations.Inject;
33 import org.apache.tapestry5.services.ComponentDefaultProvider;
34 import org.apache.tapestry5.services.Environment;
35 import org.apache.tapestry5.services.FormSupport;
36 import org.apache.tapestry5.services.Request;
37 import org.equanda.tapestry5.base.ObjectCreatorDelegate;
38 import org.slf4j.Logger;
39
40 import java.util.ArrayList;
41 import java.util.Collection;
42 import java.util.List;
43
44
45
46
47
48
49 public class JSPagedLoop
50 implements ClientElement
51 {
52 @Environmental
53 private RenderSupport renderSupport;
54
55 @Inject
56 private Environment environment;
57
58 @Inject
59 private Logger logger;
60
61 @Inject
62 private ComponentResources resources;
63
64 @Environmental
65 private FormSupport formSupport;
66
67 @Inject
68 private Request request;
69
70 @Inject
71 private ComponentDefaultProvider componentDefaultProvider;
72
73 @Parameter( value = "prop:componentResources.id", defaultPrefix = BindingConstants.LITERAL )
74 private String clientId;
75
76
77
78
79
80 @Parameter( value = "prop:componentResources.elementName", defaultPrefix = BindingConstants.LITERAL )
81 private String elementName;
82
83
84
85
86 @Parameter( required = true, principal = true )
87 private Collection<Object> source;
88
89 @Persist
90 private List<Object> addedRowsList;
91
92 @Persist
93 private List<Object> pagedSource;
94
95
96
97
98
99 @Parameter( "25" )
100 private int rowsPerPage;
101
102 @Persist
103 private int currentPage = 1;
104
105
106 private int addedRowCount;
107
108
109
110
111 @SuppressWarnings( "unused" )
112 @Parameter
113 private Object value;
114
115
116
117
118
119 @SuppressWarnings( "unused" )
120 @Parameter
121 private boolean _volatile;
122
123 @Parameter( defaultPrefix = BindingConstants.PROP )
124 private ObjectCreatorDelegate objectCreatorDelegate;
125
126
127
128
129 @Parameter
130 private int index;
131
132 @Parameter
133 private int additionalRowCount;
134
135
136
137
138
139 @SuppressWarnings( "unused" )
140 @Parameter
141 private PrimaryKeyEncoder<?, ?> encoder;
142
143 @SuppressWarnings( "unused" )
144 @Component( parameters = { "source=pagedSource", "elementName=prop:elementName", "value=inherit:value",
145 "volatile=inherit:volatile", "encoder=inherit:encoder", "index=index",
146 "additionalRowCount=inherit:additionalRowCount" } )
147 private Loop loop;
148
149 @Component( parameters = { "source=pagedSource", "rowsPerPage=rowsPerPage", "currentPage=currentPage" } )
150 private JSPager internalPager;
151
152 @Component( id = "CurrentPageHidden", parameters = { "value=currentPage", "translate=translate:integer" } )
153 private Hidden currentPageHidden;
154
155 @Component( id = "AddedRowsHidden", parameters = { "value=addedRowCount", "translate=translate:integer" } )
156 private Hidden addedRowHidden;
157
158 @SuppressWarnings( "unused" )
159 @Component( parameters = "to=pagerBottom" )
160 private Delegate pagerBottom;
161
162
163
164
165
166
167 @Parameter( value = "block:empty" )
168 private Block empty;
169
170 @Parameter( value = "block:bottomBlock" )
171 private Block bottomBlock;
172
173 @Parameter( value = "message:add.title.label", defaultPrefix = BindingConstants.LITERAL )
174 private String addRowLinkTitle;
175
176 private String assignedClientId;
177
178 private List<String> rowIds;
179
180 private String addedRowCountHiddenName;
181
182 static class FormSubmitAction
183 implements ComponentAction<JSPagedLoop>
184 {
185
186 private static final long serialVersionUID = 456056528334001727L;
187
188 public void execute( JSPagedLoop component )
189 {
190 component.processFormAction();
191 }
192 }
193
194 static class SetupAction
195 implements ComponentAction<JSPagedLoop>
196 {
197
198 private static final long serialVersionUID = 6727709013577574475L;
199 private final String _addedRowCountHiddenName;
200
201 public SetupAction ( String controlName )
202 {
203 _addedRowCountHiddenName = controlName;
204 }
205
206 public void execute( JSPagedLoop component )
207 {
208 component.setupAddedRowCountHiddenName( _addedRowCountHiddenName );
209 }
210 }
211
212 private static final FormSubmitAction FORM_SUBMIT_ACTION = new FormSubmitAction();
213
214 private void setupAddedRowCountHiddenName( String name )
215 {
216 addedRowCountHiddenName = name;
217 }
218
219 Binding defaultSource()
220 {
221 return componentDefaultProvider.defaultBinding( "source", resources );
222 }
223
224 void setSource( Collection<Object> source )
225 {
226 this.source = source;
227 }
228
229 public String getAddRowLinkTitle()
230 {
231 return addRowLinkTitle;
232 }
233
234 public int getIndex()
235 {
236 return index;
237 }
238
239 public void setIndex( int index )
240 {
241 this.index = index;
242 }
243
244 public String getElementName()
245 {
246 return elementName;
247 }
248
249 public Block getBottomBlock()
250 {
251 return bottomBlock;
252 }
253
254 public Object getPagerBottom()
255 {
256 return internalPager;
257 }
258
259 public List<Object> getPagedSource()
260 {
261 return pagedSource;
262 }
263
264 public int getRowsPerPage()
265 {
266 return rowsPerPage;
267 }
268
269 public void setRowsPerPage( int rowsPerPage )
270 {
271 this.rowsPerPage = rowsPerPage;
272 }
273
274 public int getCurrentPage()
275 {
276 return currentPage;
277 }
278
279 public void setCurrentPage( int currentPage )
280 {
281 this.currentPage = currentPage;
282 }
283
284 public int getAddedRowCount()
285 {
286 return addedRowCount;
287 }
288
289 public void setAddedRowCount( int addedRowCount )
290 {
291 this.addedRowCount = addedRowCount;
292 }
293
294 public int getAdditionalRowCount()
295 {
296 return additionalRowCount;
297 }
298
299 public void setAdditionalRowCount( int additionalRowCount )
300 {
301 this.additionalRowCount = additionalRowCount;
302 }
303
304 public String getCurrentRowId()
305 {
306 String newId = renderSupport.allocateClientId( assignedClientId );
307 String rowId = String.format( "%s_row_%s", assignedClientId, newId.toLowerCase() );
308 rowIds.add( rowId );
309 return rowId;
310 }
311
312 public String getCurrentPageFieldName()
313 {
314 return currentPageHidden.getClientId();
315 }
316
317 public String getAddedRowFieldName()
318 {
319 return addedRowHidden.getClientId();
320 }
321
322 @SetupRender
323 Object setupRender()
324 {
325 rowIds = new ArrayList<String>();
326 assignedClientId = renderSupport.allocateClientId( clientId );
327
328 addedRowsList = new ArrayList<Object>();
329 pagedSource = new ArrayList<Object>();
330
331 if ( source != null )
332 {
333 for ( Object item : source )
334 {
335 pagedSource.add( item );
336 }
337 }
338
339 if ( objectCreatorDelegate != null )
340 {
341 for ( int i = 0; i < additionalRowCount; i++ )
342 {
343 Object object = objectCreatorDelegate.createObject();
344 pagedSource.add( object );
345 addedRowsList.add( object );
346 }
347 }
348
349
350 if ( pagedSource.size() == 0 )
351 {
352 return empty;
353 }
354
355 return null;
356 }
357
358 @BeginRender
359 Object begin( MarkupWriter writer )
360 {
361 environment.push( JSPagedLoop.class, this );
362
363
364
365 return pagedSource.size() != 0;
366
367 }
368
369 @AfterRender
370 void afterRender()
371 {
372 formSupport.storeAndExecute( this, new SetupAction( addedRowHidden.getControlName() ) );
373 formSupport.store( this, FORM_SUBMIT_ACTION );
374 }
375
376 @CleanupRender
377 void cleanupRender()
378 {
379 environment.pop( JSPagedLoop.class );
380 }
381
382 void onActionFromAdd()
383 {
384
385 private void processFormAction()
386 {
387 int count = 0;
388 String sCount = null;
389 try
390 {
391 if ( addedRowCountHiddenName != null )
392 {
393 sCount = request.getParameter( addedRowCountHiddenName );
394 if ( sCount != null && sCount.trim().length() > 0 )
395 {
396 count = Integer.parseInt( sCount.trim() );
397 }
398 }
399 }
400 catch ( Exception e )
401 {
402 logger.error( "Unable to parse AddedRowCount parameter: " + sCount );
403 }
404
405 if ( objectCreatorDelegate != null )
406 {
407 for ( int i = 0; i < count && i < addedRowsList.size(); i++ )
408 {
409 objectCreatorDelegate.addNewObject( addedRowsList.get( i ) );
410 }
411 }
412 addedRowsList.clear();
413 addedRowCount = count;
414 }
415
416
417
418
419
420
421 public String getClientId()
422 {
423 return assignedClientId;
424 }
425
426 public String getFixedClientId()
427 {
428 return assignedClientId != null ? assignedClientId.toLowerCase() : "";
429 }
430
431 }