1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.universAAL.middleware.ui.rdf;
21
22 import java.util.ArrayList;
23 import java.util.Enumeration;
24 import java.util.Iterator;
25 import java.util.List;
26
27 import org.universAAL.middleware.owl.ManagedIndividual;
28 import org.universAAL.middleware.owl.MergedRestriction;
29 import org.universAAL.middleware.rdf.PropertyPath;
30 import org.universAAL.middleware.rdf.Resource;
31 import org.universAAL.middleware.rdf.TypeMapper;
32 import org.universAAL.middleware.ui.owl.DialogType;
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76 public class Repeat extends Group {
77 public static final String MY_URI = Form.uAAL_DIALOG_NAMESPACE + "Repeat";
78
79
80
81
82
83 public static final String PROP_IS_DELETABLE = Form.uAAL_DIALOG_NAMESPACE
84 + "listEntriesDeletable";
85
86
87
88
89
90 public static final String PROP_IS_EDITABLE = Form.uAAL_DIALOG_NAMESPACE
91 + "listEntriesEditable";
92
93
94
95
96
97 public static final String PROP_IS_EXPANDABLE = Form.uAAL_DIALOG_NAMESPACE
98 + "listAcceptsNewEntries";
99
100
101
102
103
104
105
106 public static final String PROP_SEARCHABLE_FIELD = Form.uAAL_DIALOG_NAMESPACE
107 + "searchableField";
108
109 private List values = null;
110 private Object selection = null;
111 private int selectionIndex = -1;
112 private boolean submissionChecked = false;
113
114
115
116
117 private List vForms;
118
119
120
121
122 public Repeat() {
123 super();
124 }
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149 public Repeat(Group parent, Label label, PropertyPath ref,
150 MergedRestriction valueRestriction, List initialValue) {
151 super(MY_URI, parent, label, ref, valueRestriction, initialValue);
152
153 if (getMaxCardinality() == 1)
154 throw new IllegalArgumentException(
155 "Wrong restrictions disallowing repeat!");
156
157 values = initialValue;
158 }
159
160 void addChild(FormControl child) {
161 if (child == null || child instanceof Submit || child instanceof Repeat)
162 throw new IllegalArgumentException(
163 "Only Input, Output, and Group instances are allowed!");
164
165 List children = (List) props.get(PROP_CHILDREN);
166 if (children == null) {
167 children = new ArrayList();
168 props.put(PROP_CHILDREN, children);
169 } else if (children.size() > 0)
170 throw new UnsupportedOperationException(
171 "Not allowed to add more than one child to a Repeat object!");
172
173 child.changeProperty(PROP_REFERENCED_PPATH, null);
174 children.add(child);
175 }
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190 public boolean addValue() {
191 checkValues();
192
193 if (selection != null && !values.contains(selection)
194 && (selectionIndex == -1 || valuesDiffer())) {
195 selectionIndex = values.size();
196 values.add(selection);
197 if (selection instanceof Resource)
198 selection = ((Resource) selection).deepCopy();
199 submissionChecked = false;
200 return true;
201 }
202 return false;
203 }
204
205
206
207
208
209
210
211
212 public void banEntryAddition() {
213 props.put(PROP_IS_EXPANDABLE, Boolean.FALSE);
214 }
215
216
217
218
219
220
221
222
223 public void banEntryDeletion() {
224 props.put(PROP_IS_DELETABLE, Boolean.FALSE);
225 }
226
227
228
229
230
231
232
233
234 public void banEntryEdit() {
235 props.put(PROP_IS_EDITABLE, Boolean.FALSE);
236 }
237
238 boolean checkSubmission() {
239 if (!submissionChecked) {
240 checkValues();
241
242 try {
243 submissionChecked = getFormObject().setValue(
244 getReferencedPPath().getThePath(), values,
245 (MergedRestriction) props.get(PROP_VALUE_RESTRICTION));
246 } catch (Exception e) {
247 submissionChecked = false;
248 }
249 }
250 return submissionChecked;
251 }
252
253 private synchronized void checkValues() {
254 if (values == null) {
255 Object o = super.getValue();
256 if (o instanceof List)
257 values = (List) o;
258 else {
259 values = new ArrayList();
260 if (o != null)
261 values.add(o);
262 }
263 }
264 }
265
266
267
268
269
270
271
272 public List getAllValues(FormControl fc) {
273 return (fc == null) ? null : getAllValues(fc.getReferencedPPath());
274 }
275
276 List getAllValues(PropertyPath pp) {
277 checkValues();
278
279 String[] thePath = (pp == null) ? null : pp.getThePath();
280 boolean multiColumn = thePath != null && thePath.length > 0;
281 List result = new ArrayList(values.size());
282 for (Iterator i = values.iterator(); i.hasNext();) {
283 Object o = i.next();
284 if (o != null && multiColumn != (o instanceof Resource))
285 return null;
286 if (multiColumn)
287 result.add(Form.getValue(thePath, (Resource) o));
288 else
289 result.add(o);
290 }
291
292 return result;
293 }
294
295
296
297
298
299
300 public int getMaxCardinality() {
301 MergedRestriction r = getRestrictions();
302 return (r == null) ? -1 : r.getMaxCardinality();
303 }
304
305
306
307
308
309
310 public int getMinCardinality() {
311 MergedRestriction r = getRestrictions();
312 return (r == null) ? -1 : r.getMinCardinality();
313 }
314
315
316
317
318
319 public int getNumberOfValues() {
320 checkValues();
321
322 return values.size();
323 }
324
325 MergedRestriction getPPathRestriction(String[] pp) {
326 MergedRestriction r = getRestrictions();
327
328 if (r != null) {
329 if (pp == null || pp.length == 0)
330 return r.copyWithNewCardinality(1, 1);
331
332 checkValues();
333
334 if (values.isEmpty() || !(values.get(0) instanceof Resource))
335 return Form.getPPathRestriction(pp, 0, r.getPropTypeURI());
336 } else
337 checkValues();
338
339 return Form.getPPathRestriction(pp, (Resource) values.get(0));
340 }
341
342
343
344
345 public FormControl getSearchableField() {
346 Object o = props.get(PROP_SEARCHABLE_FIELD);
347 return (o instanceof FormControl) ? (FormControl) o : null;
348 }
349
350
351
352
353
354
355 public int getSelectionIndex() {
356 return selectionIndex;
357 }
358
359 String getTypeURI(String[] pp) {
360 MergedRestriction r = getPPathRestriction(pp);
361 return (r == null) ? null : r.getPropTypeURI();
362 }
363
364
365
366
367
368 public Object getValue(String[] pp) {
369 return (pp == null || pp.length == 0) ? selection
370 : (selection instanceof Resource) ? Form.getValue(pp,
371 (Resource) selection) : null;
372 }
373
374 boolean hasValue(String[] pp) {
375 checkValues();
376
377 if (values.isEmpty())
378 return false;
379
380 if (pp == null || pp.length == 0)
381 return TypeMapper.getDatatypeURI(values.get(0)) != null;
382
383 for (Iterator i = values.iterator(); i.hasNext();) {
384 Object o = i.next();
385 if (o instanceof Resource
386 && Form.getValue(pp, (Resource) o) != null)
387 return true;
388 }
389
390 return false;
391 }
392
393
394
395
396 public boolean listAcceptsNewEntries() {
397 return !Boolean.FALSE.equals(props.get(PROP_IS_EXPANDABLE));
398 }
399
400
401
402
403 public boolean listEntriesDeletable() {
404 return !Boolean.FALSE.equals(props.get(PROP_IS_DELETABLE));
405 }
406
407
408
409
410 public boolean listEntriesEditable() {
411 return !Boolean.FALSE.equals(props.get(PROP_IS_EDITABLE));
412 }
413
414
415
416
417
418
419
420
421 public void moveSelectionDown() {
422 if (values != null && selectionIndex > -1
423 && selectionIndex < values.size() - 1) {
424 int i = selectionIndex++;
425 Object o = values.get(selectionIndex);
426 values.set(selectionIndex, values.get(i));
427 values.set(i, o);
428 }
429 }
430
431
432
433
434
435
436
437
438 public void moveSelectionUp() {
439 if (selectionIndex > 0 && selectionIndex < values.size()) {
440 int i = selectionIndex--;
441 Object o = values.get(selectionIndex);
442 values.set(selectionIndex, values.get(i));
443 values.set(i, o);
444 }
445 }
446
447 private Object newValue() {
448 String type = getTypeURI();
449 if (type == null) {
450 List children = (List) props.get(PROP_CHILDREN);
451 if (children == null || children.size() != 1)
452 throw new IllegalStateException("Repeat object in wrong state!");
453 if (children.get(0) instanceof Group)
454 return new Resource();
455 } else if (TypeMapper.isRegisteredDatatypeURI(type)) {
456 Resource pr = ManagedIndividual.getInstance(type, null);
457 if (pr == null) {
458 pr = new Resource();
459 pr.addType(type, false);
460 }
461 return pr;
462 }
463 return null;
464 }
465
466
467
468
469
470
471
472
473 public boolean removeSelection() {
474 if (selectionIndex > -1 && selectionIndex < values.size()) {
475 values.remove(selectionIndex);
476 submissionChecked = false;
477 selectionIndex = -1;
478 selection = null;
479 return true;
480 }
481 return false;
482 }
483
484
485
486
487 public void setSearchableField(FormControl fc) {
488 if (fc != null)
489 props.put(PROP_SEARCHABLE_FIELD, fc);
490 }
491
492
493
494
495
496
497
498 public void setSelection(int i) {
499 checkValues();
500
501 if (i < 0 || i >= values.size()) {
502 selection = newValue();
503 selectionIndex = -1;
504 } else {
505 selection = values.get(i);
506 if (selection instanceof Resource)
507 selection = ((Resource) selection).deepCopy();
508 selectionIndex = i;
509 }
510 }
511
512 boolean setValue(String[] pp, Object value,
513 MergedRestriction valueRestrictions) {
514 if (selection == null)
515 selection = newValue();
516
517 if (selection instanceof Resource)
518 return Form.setValue((Resource) selection, pp, value,
519 valueRestrictions);
520 else if (pp == null || pp.length == 0) {
521 if (value == null) {
522 selection = null;
523 selectionIndex = -1;
524 } else {
525 Object aux = props.get(PROP_REFERENCED_PPATH);
526 String prop = (aux instanceof PropertyPath) ? ((PropertyPath) aux)
527 .getLastPathElement()
528 : null;
529 if (prop == null || valueRestrictions != null)
530
531
532
533
534
535 return false;
536 valueRestrictions = getRestrictions();
537 Resource dummy = new Resource();
538 dummy.setProperty(prop, value);
539 if (valueRestrictions != null
540 && !valueRestrictions.hasMemberIgnoreCardinality(dummy))
541 return false;
542 selection = value;
543 return true;
544 }
545 }
546 return false;
547 }
548
549
550
551
552
553
554 public boolean updateSelection() {
555 if (selection != null && selectionIndex > -1
556 && selectionIndex < values.size()) {
557 values.set(selectionIndex, selection);
558 if (selection instanceof Resource)
559 selection = ((Resource) selection).deepCopy();
560 submissionChecked = false;
561 return true;
562 }
563
564 return false;
565 }
566
567 private boolean valuesDiffer() {
568 if (selection instanceof Resource) {
569 Object o = values.get(selectionIndex);
570 for (Enumeration e = ((Resource) selection).getPropertyURIs(); e
571 .hasMoreElements();) {
572 String key = e.nextElement().toString();
573 if (!((Resource) selection).getProperty(key).equals(
574 ((Resource) o).getProperty(key)))
575 return true;
576 }
577 return false;
578 } else
579 return true;
580 }
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601 public List virtualFormExpansion() {
602 if (vForms == null){
603 vForms = generateVirtualForms();
604 }
605 return vForms;
606 }
607
608 private List generateVirtualForms(){
609 FormControl[] elems = getChildren();
610 if (elems == null || elems.length != 1 || elems[0] == null) {
611 throw new IllegalArgumentException("Malformed Repeat only allowed one valid child!");
612 }
613 if (elems[0] instanceof Group) {
614 elems = ((Group) elems[0]).getChildren();
615 if (elems == null || elems.length == 0)
616 throw new IllegalArgumentException("Malformed child group is empty!");
617 }else if (! (elems[0] instanceof FormControl)){
618 throw new IllegalArgumentException("child is not a FormControl!");
619 }
620
621 ArrayList formList = new ArrayList();
622 PropertyPath ref = (PropertyPath) getProperty(PROP_REFERENCED_PPATH);
623 Object repeatData = getFormObject().getValue(ref.getThePath());
624 List repeatList = null;
625 if (repeatData instanceof Resource) {
626
627 repeatList = new ArrayList();
628 repeatList.add(repeatData);
629 }
630 if (repeatData instanceof List) {
631 repeatList = (List) repeatData;
632 }
633 if (repeatData == null) {
634
635 repeatList = new ArrayList();
636 }
637
638 int index = 0;
639 for (Iterator i = repeatList.iterator(); i.hasNext();) {
640 Object res = i.next();
641 Form subForm = VirtualForm.createNewVirtualForm(res);
642 Group gio = (Group) subForm.getIOControls();
643 for (int j = 0; j < elems.length; j++) {
644 if (elems[j] != null) {
645 FormControl nFC = (FormControl) elems[j].copy(false);
646 gio.addChild(nFC);
647 if (elems[j] instanceof SubdialogTrigger) {
648 nFC.changeProperty(
649 SubdialogTrigger.PROP_SUBMISSION_ID,
650 nFC.getProperty(SubdialogTrigger.PROP_REPEATABLE_ID_PREFIX)
651 + Integer.toString(index));
652 }
653 else {
654 nFC.changeProperty(PROP_PARENT_CONTROL, gio);
655 }
656 }
657 }
658 formList.add(subForm);
659 index++;
660 }
661
662 return formList;
663 }
664
665
666 public FormControl searchFormControl(String formControlURI) {
667 FormControl res = super.searchFormControl(formControlURI);
668 Iterator i = vForms.iterator();
669 while (i.hasNext()
670 && res == null) {
671 Form f = (Form) i.next();
672 res = f.searchFormControl(formControlURI);
673 }
674 return res;
675 }
676
677 private static class VirtualForm extends Form {
678
679
680
681
682
683 public VirtualForm(Object dataRoot) {
684 super(uAAL_DIALOG_NAMESPACE, 5);
685 addType(MY_URI, true);
686 props.put(PROP_DIALOG_CREATION_TIME, TypeMapper.getCurrentDateTime());
687 props.put(PROP_ROOT_GROUP, new Group("Virtual Form", this));
688 props.put(PROP_DIALOG_DATA_ROOT, (dataRoot == null) ? new Resource()
689 : dataRoot);
690 }
691
692 static public Form createNewVirtualForm(Object root){
693 Form f = new VirtualForm(root);
694 f.changeProperty(PROP_DIALOG_TYPE, DialogType.stdDialog);
695 Group rootg = (Group) f.getProperty(Form.PROP_ROOT_GROUP);
696 new Group(rootg, new Label(Group.STD_IO_CONTROLS, null), null, null,
697 null);
698 return f;
699 }
700
701
702 Object getValue(String[] pp) {
703
704
705
706 if (pp == null || pp.length == 0)
707 return props.get(PROP_DIALOG_DATA_ROOT);
708 else
709 return super.getValue(pp);
710 }
711
712 }
713 }