1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.student.common.ui.client.configurable.mvc.multiplicity;
17
18 import java.util.ArrayList;
19 import java.util.HashMap;
20 import java.util.List;
21 import java.util.Map;
22 import java.util.Set;
23 import java.util.Map.Entry;
24
25 import org.kuali.student.common.ui.client.configurable.mvc.FieldDescriptor;
26 import org.kuali.student.common.ui.client.configurable.mvc.binding.ModelWidgetBinding;
27 import org.kuali.student.common.ui.client.configurable.mvc.sections.BaseSection;
28 import org.kuali.student.common.ui.client.configurable.mvc.sections.GroupSection;
29 import org.kuali.student.common.ui.client.configurable.mvc.sections.MultiplicitySection;
30 import org.kuali.student.common.ui.client.configurable.mvc.sections.Section;
31 import org.kuali.student.common.ui.client.configurable.mvc.sections.SwapSection;
32 import org.kuali.student.common.ui.client.configurable.mvc.sections.VerticalSection;
33 import org.kuali.student.common.ui.client.mvc.Callback;
34 import org.kuali.student.common.ui.client.mvc.DataModel;
35 import org.kuali.student.common.ui.client.util.DebugIdUtils;
36 import org.kuali.student.common.ui.client.widgets.KSButton;
37 import org.kuali.student.common.ui.client.widgets.ListOfStringWidget;
38 import org.kuali.student.common.ui.client.widgets.KSButtonAbstract.ButtonStyle;
39 import org.kuali.student.common.ui.client.widgets.list.KSRadioButtonList;
40 import org.kuali.student.common.ui.client.widgets.list.KSSelectItemWidgetAbstract;
41 import org.kuali.student.common.ui.client.widgets.list.ListItems;
42 import org.kuali.student.common.ui.client.widgets.list.SelectionChangeEvent;
43 import org.kuali.student.common.ui.client.widgets.list.SelectionChangeHandler;
44 import org.kuali.student.common.ui.client.widgets.list.impl.KSRadioButtonListImpl;
45 import org.kuali.student.common.ui.client.widgets.list.impl.SimpleListItems;
46 import org.kuali.student.common.ui.client.widgets.search.KSPicker;
47 import org.kuali.student.r1.common.assembly.data.Data;
48 import org.kuali.student.r1.common.assembly.data.MetadataInterrogator;
49 import org.kuali.student.r1.common.assembly.data.QueryPath;
50
51 import com.google.gwt.core.client.GWT;
52 import com.google.gwt.event.dom.client.BlurHandler;
53 import com.google.gwt.event.dom.client.ClickEvent;
54 import com.google.gwt.event.dom.client.ClickHandler;
55 import com.google.gwt.event.dom.client.FocusHandler;
56 import com.google.gwt.event.shared.HandlerRegistration;
57 import com.google.gwt.user.client.ui.Composite;
58 import com.google.gwt.user.client.ui.FlowPanel;
59 import com.google.gwt.user.client.ui.Widget;
60
61
62 public class MultiplicityGroup extends Composite {
63
64 private MultiplicityConfiguration config;
65
66 private List<MultiplicityGroupItem> items = new ArrayList<MultiplicityGroupItem>();
67 private List<MultiplicityGroupItem> removed = new ArrayList<MultiplicityGroupItem>();
68
69 private FlowPanel mainPanel = new FlowPanel();
70 private FlowPanel itemsPanel = new FlowPanel();
71 private boolean loaded = false;
72 private int itemCount = 0;
73 private String parentPath;
74 private boolean isDirty = false;
75
76 private Map<SwapCompositeCondition, List<SwapCompositeConditionFieldConfig>> swappableFieldsDefinition;
77 private List<String> deletionParentKeys;
78
79 public MultiplicityGroup() {
80 }
81
82 public MultiplicityGroup(MultiplicityConfiguration config,
83 Map<SwapCompositeCondition, List<SwapCompositeConditionFieldConfig>> swappableFieldsDefinition,
84 List<String> deletionParentKeys) {
85 this.config = config;
86 initWidget(mainPanel);
87 this.swappableFieldsDefinition = swappableFieldsDefinition;
88 this.deletionParentKeys = deletionParentKeys;
89 }
90
91
92
93
94
95
96
97
98
99
100
101
102 public MultiplicityGroup(MultiplicityConfiguration config){
103 this.config = config;
104 initWidget(mainPanel);
105 }
106
107 protected Callback<MultiplicityGroupItem> removeCallback = new Callback<MultiplicityGroupItem>(){
108
109 public void exec(MultiplicityGroupItem itemToRemove) {
110 itemToRemove.setDeleted(true);
111 removed.add(itemToRemove);
112 itemsPanel.remove(itemToRemove);
113 }
114 };
115
116 public void onLoad() {
117 if (!loaded) {
118 mainPanel.add(itemsPanel);
119
120 if(config.isUpdateable()){
121 Widget addWidget = generateAddWidget();
122 mainPanel.add(addWidget);
123 }
124
125 loaded = true;
126 }
127
128 if (!loaded || itemCount == 0){
129 Integer minOccurs = MetadataInterrogator.getLargestMinOccurs(config.getMetaData());
130
131 if (minOccurs != null && minOccurs > 0) {
132 for (int i=0; i < minOccurs; i++){
133 createItem();
134 }
135 }
136 else if(config.getDefaultItemsCreated() != 0){
137 for (int i=0; i < config.getDefaultItemsCreated(); i++){
138 createItem();
139 }
140 }
141
142 }
143 }
144
145 private Widget generateAddWidget() {
146 KSButton addWidget;
147 if(config.getStyleType() == MultiplicityConfiguration.StyleType.TOP_LEVEL_GROUP){
148 addWidget = new KSButton(config.getAddItemLabel(), ButtonStyle.FORM_LARGE);
149 }
150 else{
151 addWidget = new KSButton(config.getAddItemLabel(), ButtonStyle.FORM_SMALL);
152 }
153 addWidget.addClickHandler(new ClickHandler(){
154 public void onClick(ClickEvent event) {
155 createItem();
156 }
157 });
158 addWidget.ensureDebugId(DebugIdUtils.createWebDriverSafeDebugId(this.getElement().getId() + "-" + config.getAddItemLabel()));
159 return addWidget;
160 }
161
162
163
164
165
166
167 public MultiplicityGroupItem createItem(){
168
169 itemCount++;
170
171 MultiplicityGroupItem item = new MultiplicityGroupItem(config.getItemLabel() + " " + itemCount, config.getStyleType(), config.isUpdateable());
172
173 Widget itemWidget = createWidget();
174
175 if (item != null){
176 item.setItemKey(new Integer(itemCount -1));
177 item.setItemWidget(itemWidget);
178 item.setRemoveCallback(removeCallback);
179 } else if (itemWidget instanceof MultiplicityGroupItem){
180 item = (MultiplicityGroupItem)itemWidget;
181 item.setItemKey(new Integer(itemCount -1));
182 }
183 items.add(item);
184 item.redraw();
185 itemsPanel.add(item);
186 isDirty = true;
187
188 return item;
189 }
190
191 public FlowPanel getItemsPanel() {
192 return itemsPanel;
193 }
194
195 private Widget createWidget() {
196
197 GroupSection section = new GroupSection();
198 final SwappableFieldsHelper helper = new SwappableFieldsHelper();
199
200 final Map<String, String> helperFieldKeys = new HashMap<String, String>();
201 SwapSection swapSection = null;
202
203
204
205 if (config.getNestedConfig() != null) {
206 MultiplicitySection ms = new MultiplicitySection(config.getNestedConfig().copy());
207 String p = config.getNestedConfig().getParentFd().getFieldKey().replace('*', Character.forDigit(itemCount-1, 10));
208 ms.setParentPath(p);
209 section.addSection(ms);
210 }
211 else {
212 for (Integer row : config.getFields().keySet()) {
213 List<MultiplicityFieldConfiguration> fieldConfigs = config.getFields().get(row);
214 for (MultiplicityFieldConfiguration fieldConfig : fieldConfigs) {
215
216 FieldDescriptor newfd = null;
217 Widget fieldWidget = null;
218 if (fieldConfig.getFieldWidgetInitializer() != null) {
219 fieldWidget = fieldConfig.getFieldWidgetInitializer().getNewWidget();
220 ModelWidgetBinding mwb = fieldConfig.getFieldWidgetInitializer()
221 .getModelWidgetBindingInstance();
222 newfd = new FieldDescriptor(
223 translatePath(fieldConfig.getFieldPath()),
224 fieldConfig.getMessageKeyInfo(),
225 fieldConfig.getMetadata(),
226 fieldWidget);
227 newfd.setWidgetBinding(mwb);
228 } else {
229 newfd = new FieldDescriptor(
230 translatePath(fieldConfig.getFieldPath()),
231 fieldConfig.getMessageKeyInfo(),
232 fieldConfig.getMetadata());
233 fieldWidget = newfd.getFieldWidget();
234 }
235 newfd.getFieldElement().setRequired(fieldConfig.isRequired());
236 section.addField(newfd);
237 helperFieldKeys.put(fieldConfig.getFieldPath(), newfd.getFieldKey());
238
239
240
241 if (fieldWidget instanceof KSSelectItemWidgetAbstract) {
242 ((KSSelectItemWidgetAbstract)fieldWidget).addSelectionChangeHandler(new SelectionChangeHandler() {
243 @Override
244 public void onSelectionChange(SelectionChangeEvent event) {
245 helper.updateFieldDisplay();
246 }
247 });
248 } else if (fieldWidget instanceof KSPicker) {
249 Widget inputWidget = ((KSPicker)fieldWidget).getInputWidget();
250 if (inputWidget instanceof KSSelectItemWidgetAbstract) {
251 ((KSSelectItemWidgetAbstract)inputWidget).addSelectionChangeHandler(new SelectionChangeHandler() {
252 @Override
253 public void onSelectionChange(SelectionChangeEvent event) {
254 helper.updateFieldDisplay();
255 }
256 });
257 }
258 }
259 }
260 section.nextLine();
261 }
262 if (swappableFieldsDefinition != null) {
263 ConditionChoices conditionChoices = new ConditionChoices(
264 new ArrayList<SwapCompositeCondition>(
265 swappableFieldsDefinition.keySet()));
266 List<String> newDeletionParentKeys = null;
267 swapSection = new SwapSection(conditionChoices);
268 if (deletionParentKeys != null) {
269 for (String deletionParentKey : deletionParentKeys) {
270 newDeletionParentKeys = (newDeletionParentKeys == null)?
271 new ArrayList<String>() : newDeletionParentKeys;
272 newDeletionParentKeys.add(translatePath(deletionParentKey));
273 }
274 }
275 swapSection.setDeletionParentKey(newDeletionParentKeys);
276 helper.setConditionChoices(conditionChoices);
277
278
279 for (Entry<SwapCompositeCondition, List<SwapCompositeConditionFieldConfig>> entry : swappableFieldsDefinition.entrySet()) {
280 SwapCompositeCondition condition = entry.getKey();
281 List<SwapCompositeConditionFieldConfig> fieldConfigs = entry.getValue();
282 Section conditionSection = new VerticalSection();
283 if (fieldConfigs != null) {
284 for (SwapCompositeConditionFieldConfig conditionFieldConfig : fieldConfigs) {
285 if (conditionFieldConfig.useMultiplicity()) {
286 MultiplicityConfiguration newSubMultiplicityConfig =
287 configSwappableMultiplicitySection(
288 conditionFieldConfig.getMultiplicityConfiguration());
289 MultiplicitySection subMultiplicitySection =
290 new MultiplicitySection(newSubMultiplicityConfig);
291 conditionSection.addSection(subMultiplicitySection);
292 } else {
293 MultiplicityFieldConfiguration fieldConfig =
294 conditionFieldConfig.getMultiplicityFieldConfiguration();
295 FieldDescriptor concreteFieldDescriptor = new FieldDescriptor(
296 translatePath(fieldConfig.getFieldPath()),
297 fieldConfig.getMessageKeyInfo(),
298 fieldConfig.getMetadata());
299 concreteFieldDescriptor.getFieldElement().setRequired(fieldConfig.isRequired());
300 if (fieldConfig.getFieldWidgetInitializer() != null) {
301 Widget fieldWidget = fieldConfig.getFieldWidgetInitializer().getNewWidget();
302 ModelWidgetBinding mwb = fieldConfig.getFieldWidgetInitializer()
303 .getModelWidgetBindingInstance();
304 concreteFieldDescriptor.setFieldWidget(fieldWidget);
305 if(fieldWidget instanceof ListOfStringWidget){
306 ((ListOfStringWidget)fieldWidget).setFd(concreteFieldDescriptor);
307 }
308
309 concreteFieldDescriptor.setWidgetBinding(mwb);
310 }
311 conditionSection.addField(concreteFieldDescriptor);
312 helperFieldKeys.put(fieldConfig.getFieldPath(), translatePath(fieldConfig.getFieldPath()));
313 }
314 }
315 }
316 swapSection.addSection(conditionSection, condition.getConditionId());
317 }
318 section.addWidget(conditionChoices);
319 section.addSection(swapSection);
320 helper.setSwapSection(swapSection);
321 }
322
323 helper.setParentSection(section);
324 helper.setSwappableFieldsDefinition(swappableFieldsDefinition);
325 helper.setHelperFieldKeys(helperFieldKeys);
326 }
327 return section;
328 }
329
330 public MultiplicityConfiguration configSwappableMultiplicitySection(MultiplicityConfiguration origConfig) {
331 MultiplicityConfiguration newSubMultiplicityConfig =
332 origConfig.copy();
333
334 FieldDescriptor parentFd = origConfig.getParentFd();
335 FieldDescriptor subMultParentConfig =
336 new FieldDescriptor(
337 translatePath(parentFd.getFieldKey()),
338 parentFd.getMessageKey(),
339 parentFd.getMetadata());
340 subMultParentConfig.getFieldElement().setRequired(parentFd.getFieldElement().isRequired());
341 newSubMultiplicityConfig.setParent(subMultParentConfig);
342 Map<Integer, List<MultiplicityFieldConfiguration>> fieldConfigsMap = newSubMultiplicityConfig.getFields();
343 Map<Integer, List<MultiplicityFieldConfiguration>> newFieldsMap = new HashMap<Integer, List<MultiplicityFieldConfiguration>>();
344 int lineCounter = 0;
345 if (fieldConfigsMap != null) {
346 for (List<MultiplicityFieldConfiguration> fieldConfigsInLine : fieldConfigsMap.values()) {
347 List<MultiplicityFieldConfiguration> newFieldConfigs = new ArrayList<MultiplicityFieldConfiguration>();
348 for (MultiplicityFieldConfiguration fieldConfig : fieldConfigsInLine) {
349 String configParentKey = (parentFd.getFieldKey() == null)? "" : parentFd.getFieldKey();
350 String configFieldKey = (fieldConfig.getFieldPath() == null)? "" : fieldConfig.getFieldPath();
351 String trimmedFieldKey = null;
352 MultiplicityFieldConfiguration newFieldConfig = null;
353 trimmedFieldKey = configFieldKey.substring(configParentKey.length());
354
355 QueryPath fieldPath = QueryPath.concat(subMultParentConfig.getFieldKey(),
356 trimmedFieldKey);;
357 newFieldConfig = new MultiplicityFieldConfiguration(
358 fieldPath.toString(), fieldConfig.getMessageKeyInfo(), fieldConfig.getMetadata(),
359 fieldConfig.getFieldWidgetInitializer());
360 newFieldConfig.setRequired(fieldConfig.isRequired());
361 newFieldConfigs.add(newFieldConfig);
362
363 }
364 newFieldsMap.put(Integer.valueOf(lineCounter), newFieldConfigs);
365 lineCounter++;
366 }
367 }
368 newSubMultiplicityConfig.setFields(newFieldsMap);
369
370 return newSubMultiplicityConfig;
371 }
372
373 public String translatePath(String path) {
374 String fieldPath;
375 if (parentPath != null) {
376 QueryPath parent = QueryPath.concat(parentPath);
377 int i = parent.size();
378
379 QueryPath subPath = QueryPath.concat(path);
380 String itemPath = subPath.subPath(i, subPath.size()).toString();
381
382 QueryPath qp = QueryPath.concat(parentPath, itemPath);
383 fieldPath = qp.toString();
384 }
385 else {
386 fieldPath = path;
387 }
388
389 fieldPath = fieldPath.replace('*', Character.forDigit(itemCount-1, 10));
390 return fieldPath;
391 }
392
393
394 public void clear(){
395 itemsPanel.clear();
396 items.clear();
397 removed.clear();
398 itemCount = 0;
399 }
400
401 public void redraw(){
402 for (MultiplicityGroupItem item:items){
403 item.redraw();
404 }
405 }
406
407 public void incrementItemKey(){
408 itemCount++;
409 }
410
411
412
413
414
415
416 public int getAddItemKey(){
417 return itemCount-1;
418 }
419
420
421 public List<MultiplicityGroupItem> getItems() {
422 return items;
423 }
424
425 public List<MultiplicityGroupItem> getRemovedItems() {
426 return removed;
427 }
428
429 public int getItemCount() {
430 return itemCount;
431 }
432
433 public void setItemCount(int itemCount) {
434 this.itemCount = itemCount;
435 }
436
437 public String getParentPath() {
438 return parentPath;
439 }
440
441
442
443
444
445
446 public void setParentPath(String parentPath) {
447 this.parentPath = parentPath;
448 }
449
450 public MultiplicityConfiguration getConfig() {
451 return config;
452 }
453
454 public void setConfig(MultiplicityConfiguration config) {
455 this.config = config;
456 }
457
458 public void resetDirtyFlags() {
459 isDirty = false;
460 for (MultiplicityGroupItem item:items){
461 item.resetDirtyFlags();
462 Widget itemWidget = item.getItemWidget();
463 if (itemWidget instanceof BaseSection){
464 ((BaseSection)itemWidget).resetDirtyFlags();
465 }
466 }
467 }
468
469 public boolean isDirty(){
470 isDirty = false;
471 if (removed != null && !removed.isEmpty()){
472 isDirty = true;
473 } else {
474 for (MultiplicityGroupItem item:items){
475 if (item.isDirty()){
476 isDirty = true;
477 break;
478 } else {
479 Widget itemWidget = item.getItemWidget();
480 if (itemWidget instanceof BaseSection && ((BaseSection)itemWidget).isDirty()){
481 isDirty = true;
482 break;
483 }
484 }
485 }
486 }
487 return isDirty;
488 }
489
490 public void setIsDirty(boolean dirty){
491 isDirty = dirty;
492 }
493
494 public class ConditionChoices extends KSRadioButtonList{
495 private KSRadioButtonListImpl selectItemWidget = GWT.create(KSRadioButtonListImpl.class);
496 public ConditionChoices(List<SwapCompositeCondition> conditions){
497 SimpleListItems choices = new SimpleListItems();
498 if (conditions != null) {
499 for (SwapCompositeCondition condition : conditions) {
500 choices.addItem(condition.getConditionId(), condition.getConditionId());
501 }
502 }
503 selectItemWidget.setListItems(choices);
504 }
505
506
507
508
509 public void deSelectItem(String id) {
510 selectItemWidget.deSelectItem(id);
511 }
512
513
514
515
516 public List<String> getSelectedItems() {
517 return selectItemWidget.getSelectedItems();
518 }
519
520
521
522
523 public void selectItem(String id) {
524 selectItemWidget.selectItem(id);
525 }
526
527 public void setListItems(ListItems listItems) {
528 selectItemWidget.setListItems(listItems);
529 }
530
531
532
533
534
535 public void setColumnSize(int cols){
536 selectItemWidget.setColumnSize(cols);
537 }
538
539 public void setMultipleSelect(boolean isMultipleSelect) {}
540
541
542
543
544
545
546 @Override
547 public void onLoad() {}
548
549 public HandlerRegistration addSelectionChangeHandler(SelectionChangeHandler handler) {
550 return selectItemWidget.addSelectionChangeHandler(handler);
551 }
552
553 public ListItems getListItems() {
554 return selectItemWidget.getListItems();
555 }
556
557 public String getName() {
558 return selectItemWidget.getName();
559 }
560
561 public void setName(String name) {
562 selectItemWidget.setName(name);
563 }
564
565 @Override
566 public void setEnabled(boolean b) {
567 selectItemWidget.setEnabled(b);
568 }
569
570 @Override
571 public boolean isEnabled() {
572 return selectItemWidget.isEnabled();
573 }
574
575 @Override
576 public boolean isMultipleSelect() {
577 return selectItemWidget.isMultipleSelect();
578 }
579
580 @Override
581 public void redraw() {
582 selectItemWidget.redraw();
583 }
584
585 @Override
586 public void clear() {
587 selectItemWidget.clear();
588 }
589
590 @Override
591 public HandlerRegistration addBlurHandler(BlurHandler handler) {
592 return selectItemWidget.addBlurHandler(handler);
593 }
594
595 @Override
596 public HandlerRegistration addFocusHandler(FocusHandler handler) {
597 return selectItemWidget.addFocusHandler(handler);
598 }
599
600 public void addWidgetReadyCallback(Callback<Widget> callback) {
601 selectItemWidget.addWidgetReadyCallback(callback);
602 }
603
604 public boolean isInitialized() {
605 return selectItemWidget.isInitialized();
606 }
607
608 public void setInitialized(boolean initialized) {
609 selectItemWidget.setInitialized(initialized);
610 }
611
612
613
614
615
616
617
618
619 public void setIgnoreMultipleAttributes(boolean ignoreMultiple){
620 selectItemWidget.setIgnoreMultipleAttributes(ignoreMultiple);
621 }
622 }
623
624 public class SwappableFieldsHelper {
625
626 private GroupSection parentSection;
627 private Map<SwapCompositeCondition, List<SwapCompositeConditionFieldConfig>> swappableFieldsDefinition =
628 new HashMap<SwapCompositeCondition, List<SwapCompositeConditionFieldConfig>>();
629 private Map<String, String> helperFieldKeys;
630 private ConditionChoices conditionChoices;
631 private SwapSection swapSection;
632 public void updateFieldDisplay() {
633 Set<Entry<SwapCompositeCondition, List<SwapCompositeConditionFieldConfig>>> entries =
634 (swappableFieldsDefinition == null)? null : swappableFieldsDefinition.entrySet();
635 if (parentSection == null) {
636 throw new RuntimeException("parentSection cannot be null");
637 }
638 if (entries != null) {
639 for (Entry<SwapCompositeCondition, List<SwapCompositeConditionFieldConfig>> entry : entries) {
640 SwapCompositeCondition condition = entry.getKey();
641 if (condition.evaluate(parentSection, helperFieldKeys)) {
642
643 List<Section> deletedSections = swapSection.getDeletedSections();
644 List<FieldDescriptor> fields = null;
645 if (deletedSections != null) {
646 for (Section deletedSection : deletedSections) {
647 fields = (fields == null)? new ArrayList() : fields;
648 fields.addAll(deletedSection.getFields());
649 }
650 }
651 if (fields != null) {
652 for (FieldDescriptor field : fields) {
653 Widget fieldWidget = field.getFieldWidget();
654 DataModel dataModel = new DataModel();
655 dataModel.setRoot(new Data());
656 ((ModelWidgetBinding)field.getModelWidgetBinding())
657 .setWidgetValue(fieldWidget,
658 dataModel, field.getFieldKey());
659 }
660 }
661
662
663 SelectionChangeEvent selectionChangeEvent =
664 new SelectionChangeEvent(conditionChoices);
665 selectionChangeEvent.setUserInitiated(true);
666 conditionChoices.selectItem(condition.getConditionId());
667 conditionChoices.fireEvent(selectionChangeEvent);
668 }
669 }
670 }
671 }
672 public GroupSection getParentSection() {
673 return parentSection;
674 }
675 public void setParentSection(GroupSection parentSection) {
676 this.parentSection = parentSection;
677 }
678 public Map<SwapCompositeCondition, List<SwapCompositeConditionFieldConfig>> getSwappableFieldsDefinition() {
679 return swappableFieldsDefinition;
680 }
681 public void setSwappableFieldsDefinition(Map<SwapCompositeCondition, List<SwapCompositeConditionFieldConfig>> swappableFieldsDefinition) {
682 this.swappableFieldsDefinition = swappableFieldsDefinition;
683 }
684 public Map<String, String> getHelperFieldKeys() {
685 return helperFieldKeys;
686 }
687 public void setHelperFieldKeys(Map<String, String> helperFieldKeys) {
688 this.helperFieldKeys = helperFieldKeys;
689 }
690 public ConditionChoices getConditionChoices() {
691 return conditionChoices;
692 }
693 public void setConditionChoices(ConditionChoices conditionChoices) {
694 this.conditionChoices = conditionChoices;
695 }
696 public SwapSection getSwapSection() {
697 return swapSection;
698 }
699 public void setSwapSection(SwapSection swapSection) {
700 this.swapSection = swapSection;
701 }
702 }
703
704 }