aboutsummaryrefslogtreecommitdiffstats
path: root/server/src/com/vaadin/data/Container.java
blob: 28d6cad18d7651720f7971d44bfc24fde8d24433 (plain)
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
26
27
28
29
30
31
32
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
/* 
 * Copyright 2011 Vaadin Ltd.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package com.vaadin.data;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

import com.vaadin.data.util.filter.SimpleStringFilter;
import com.vaadin.data.util.filter.UnsupportedFilterException;

/**
 * <p>
 * A specialized set of identified Items. Basically the Container is a set of
 * {@link Item}s, but it imposes certain constraints on its contents. These
 * constraints state the following:
 * </p>
 * 
 * <ul>
 * <li>All Items in the Container must have the same number of Properties.
 * <li>All Items in the Container must have the same Property ID's (see
 * {@link Item#getItemPropertyIds()}).
 * <li>All Properties in the Items corresponding to the same Property ID must
 * have the same data type.
 * <li>All Items within a container are uniquely identified by their non-null
 * IDs.
 * </ul>
 * 
 * <p>
 * The Container can be visualized as a representation of a relational database
 * table. Each Item in the Container represents a row in the table, and all
 * cells in a column (identified by a Property ID) have the same data type. Note
 * that as with the cells in a database table, no Property in a Container may be
 * empty, though they may contain <code>null</code> values.
 * </p>
 * 
 * <p>
 * Note that though uniquely identified, the Items in a Container are not
 * necessarily {@link Container.Ordered ordered} or {@link Container.Indexed
 * indexed}.
 * </p>
 * 
 * <p>
 * Containers can derive Item ID's from the item properties or use other,
 * container specific or user specified identifiers.
 * </p>
 * 
 * <p>
 * If a container is {@link Filterable filtered} or {@link Sortable sorted},
 * most of the the methods of the container interface and its subinterfaces
 * (container size, {@link #containsId(Object)}, iteration and indices etc.)
 * relate to the filtered and sorted view, not to the full container contents.
 * See individual method javadoc for exceptions to this (adding and removing
 * items).
 * </p>
 * 
 * <p>
 * <img src=doc-files/Container_full.gif>
 * </p>
 * 
 * <p>
 * The Container interface is split to several subinterfaces so that a class can
 * implement only the ones it needs.
 * </p>
 * 
 * @author Vaadin Ltd
 * @since 3.0
 */
public interface Container extends Serializable {

    /**
     * Gets the {@link Item} with the given Item ID from the Container. If the
     * Container does not contain the requested Item, <code>null</code> is
     * returned.
     * 
     * Containers should not return Items that are filtered out.
     * 
     * @param itemId
     *            ID of the {@link Item} to retrieve
     * @return the {@link Item} with the given ID or <code>null</code> if the
     *         Item is not found in the Container
     */
    public Item getItem(Object itemId);

    /**
     * Gets the ID's of all Properties stored in the Container. The ID's cannot
     * be modified through the returned collection.
     * 
     * @return unmodifiable collection of Property IDs
     */
    public Collection<?> getContainerPropertyIds();

    /**
     * Gets the ID's of all visible (after filtering and sorting) Items stored
     * in the Container. The ID's cannot be modified through the returned
     * collection.
     * 
     * If the container is {@link Ordered}, the collection returned by this
     * method should follow that order. If the container is {@link Sortable},
     * the items should be in the sorted order.
     * 
     * Calling this method for large lazy containers can be an expensive
     * operation and should be avoided when practical.
     * 
     * @return unmodifiable collection of Item IDs
     */
    public Collection<?> getItemIds();

    /**
     * Gets the Property identified by the given itemId and propertyId from the
     * Container. If the Container does not contain the item or it is filtered
     * out, or the Container does not have the Property, <code>null</code> is
     * returned.
     * 
     * @param itemId
     *            ID of the visible Item which contains the Property
     * @param propertyId
     *            ID of the Property to retrieve
     * @return Property with the given ID or <code>null</code>
     */
    public Property<?> getContainerProperty(Object itemId, Object propertyId);

    /**
     * Gets the data type of all Properties identified by the given Property ID.
     * 
     * @param propertyId
     *            ID identifying the Properties
     * @return data type of the Properties
     */
    public Class<?> getType(Object propertyId);

    /**
     * Gets the number of visible Items in the Container.
     * 
     * Filtering can hide items so that they will not be visible through the
     * container API.
     * 
     * @return number of Items in the Container
     */
    public int size();

    /**
     * Tests if the Container contains the specified Item.
     * 
     * Filtering can hide items so that they will not be visible through the
     * container API, and this method should respect visibility of items (i.e.
     * only indicate visible items as being in the container) if feasible for
     * the container.
     * 
     * @param itemId
     *            ID the of Item to be tested
     * @return boolean indicating if the Container holds the specified Item
     */
    public boolean containsId(Object itemId);

    /**
     * Creates a new Item with the given ID in the Container.
     * 
     * <p>
     * The new Item is returned, and it is ready to have its Properties
     * modified. Returns <code>null</code> if the operation fails or the
     * Container already contains a Item with the given ID.
     * </p>
     * 
     * <p>
     * This functionality is optional.
     * </p>
     * 
     * @param itemId
     *            ID of the Item to be created
     * @return Created new Item, or <code>null</code> in case of a failure
     * @throws UnsupportedOperationException
     *             if adding an item with an explicit item ID is not supported
     *             by the container
     */
    public Item addItem(Object itemId) throws UnsupportedOperationException;

    /**
     * Creates a new Item into the Container, and assign it an automatic ID.
     * 
     * <p>
     * The new ID is returned, or <code>null</code> if the operation fails.
     * After a successful call you can use the {@link #getItem(Object ItemId)
     * <code>getItem</code>}method to fetch the Item.
     * </p>
     * 
     * <p>
     * This functionality is optional.
     * </p>
     * 
     * @return ID of the newly created Item, or <code>null</code> in case of a
     *         failure
     * @throws UnsupportedOperationException
     *             if adding an item without an explicit item ID is not
     *             supported by the container
     */
    public Object addItem() throws UnsupportedOperationException;

    /**
     * Removes the Item identified by <code>ItemId</code> from the Container.
     * 
     * <p>
     * Containers that support filtering should also allow removing an item that
     * is currently filtered out.
     * </p>
     * 
     * <p>
     * This functionality is optional.
     * </p>
     * 
     * @param itemId
     *            ID of the Item to remove
     * @return <code>true</code> if the operation succeeded, <code>false</code>
     *         if not
     * @throws UnsupportedOperationException
     *             if the container does not support removing individual items
     */
    public boolean removeItem(Object itemId)
            throws UnsupportedOperationException;

    /**
     * Adds a new Property to all Items in the Container. The Property ID, data
     * type and default value of the new Property are given as parameters.
     * 
     * This functionality is optional.
     * 
     * @param propertyId
     *            ID of the Property
     * @param type
     *            Data type of the new Property
     * @param defaultValue
     *            The value all created Properties are initialized to
     * @return <code>true</code> if the operation succeeded, <code>false</code>
     *         if not
     * @throws UnsupportedOperationException
     *             if the container does not support explicitly adding container
     *             properties
     */
    public boolean addContainerProperty(Object propertyId, Class<?> type,
            Object defaultValue) throws UnsupportedOperationException;

    /**
     * Removes a Property specified by the given Property ID from the Container.
     * Note that the Property will be removed from all Items in the Container.
     * 
     * This functionality is optional.
     * 
     * @param propertyId
     *            ID of the Property to remove
     * @return <code>true</code> if the operation succeeded, <code>false</code>
     *         if not
     * @throws UnsupportedOperationException
     *             if the container does not support removing container
     *             properties
     */
    public boolean removeContainerProperty(Object propertyId)
            throws UnsupportedOperationException;

    /**
     * Removes all Items from the Container.
     * 
     * <p>
     * Note that Property ID and type information is preserved. This
     * functionality is optional.
     * </p>
     * 
     * @return <code>true</code> if the operation succeeded, <code>false</code>
     *         if not
     * @throws UnsupportedOperationException
     *             if the container does not support removing all items
     */
    public boolean removeAllItems() throws UnsupportedOperationException;

    /**
     * Interface for Container classes whose {@link Item}s can be traversed in
     * order.
     * 
     * <p>
     * If the container is filtered or sorted, the traversal applies to the
     * filtered and sorted view.
     * </p>
     * <p>
     * The <code>addItemAfter()</code> methods should apply filters to the added
     * item after inserting it, possibly hiding it immediately. If the container
     * is being sorted, they may add items at the correct sorted position
     * instead of the given position. See also {@link Filterable} and
     * {@link Sortable} for more information.
     * </p>
     */
    public interface Ordered extends Container {

        /**
         * Gets the ID of the Item following the Item that corresponds to
         * <code>itemId</code>. If the given Item is the last or not found in
         * the Container, <code>null</code> is returned.
         * 
         * @param itemId
         *            ID of a visible Item in the Container
         * @return ID of the next visible Item or <code>null</code>
         */
        public Object nextItemId(Object itemId);

        /**
         * Gets the ID of the Item preceding the Item that corresponds to
         * <code>itemId</code>. If the given Item is the first or not found in
         * the Container, <code>null</code> is returned.
         * 
         * @param itemId
         *            ID of a visible Item in the Container
         * @return ID of the previous visible Item or <code>null</code>
         */
        public Object prevItemId(Object itemId);

        /**
         * Gets the ID of the first Item in the Container.
         * 
         * @return ID of the first visible Item in the Container
         */
        public Object firstItemId();

        /**
         * Gets the ID of the last Item in the Container..
         * 
         * @return ID of the last visible Item in the Container
         */
        public Object lastItemId();

        /**
         * Tests if the Item corresponding to the given Item ID is the first
         * Item in the Container.
         * 
         * @param itemId
         *            ID of an Item in the Container
         * @return <code>true</code> if the Item is first visible item in the
         *         Container, <code>false</code> if not
         */
        public boolean isFirstId(Object itemId);

        /**
         * Tests if the Item corresponding to the given Item ID is the last Item
         * in the Container.
         * 
         * @return <code>true</code> if the Item is last visible item in the
         *         Container, <code>false</code> if not
         */
        public boolean isLastId(Object itemId);

        /**
         * Adds a new item after the given item.
         * <p>
         * Adding an item after null item adds the item as first item of the
         * ordered container.
         * </p>
         * 
         * @see Ordered Ordered: adding items in filtered or sorted containers
         * 
         * @param previousItemId
         *            Id of the visible item in ordered container after which to
         *            insert the new item.
         * @return item id the the created new item or null if the operation
         *         fails.
         * @throws UnsupportedOperationException
         *             if the operation is not supported by the container
         */
        public Object addItemAfter(Object previousItemId)
                throws UnsupportedOperationException;

        /**
         * Adds a new item after the given item.
         * <p>
         * Adding an item after null item adds the item as first item of the
         * ordered container.
         * </p>
         * 
         * @see Ordered Ordered: adding items in filtered or sorted containers
         * 
         * @param previousItemId
         *            Id of the visible item in ordered container after which to
         *            insert the new item.
         * @param newItemId
         *            Id of the new item to be added.
         * @return new item or null if the operation fails.
         * @throws UnsupportedOperationException
         *             if the operation is not supported by the container
         */
        public Item addItemAfter(Object previousItemId, Object newItemId)
                throws UnsupportedOperationException;

    }

    /**
     * Interface for Container classes whose {@link Item}s can be sorted.
     * <p>
     * When an {@link Ordered} or {@link Indexed} container is sorted, all
     * relevant operations of these interfaces should only use the filtered and
     * sorted contents and the filtered indices to the container. Indices or
     * item identifiers in the public API refer to the visible view unless
     * otherwise stated. However, the <code>addItem*()</code> methods may add
     * items that will be filtered out after addition or moved to another
     * position based on sorting.
     * </p>
     * <p>
     * How sorting is performed when a {@link Hierarchical} container implements
     * {@link Sortable} is implementation specific and should be documented in
     * the implementing class. However, the recommended approach is sorting the
     * roots and the sets of children of each item separately.
     * </p>
     * <p>
     * Depending on the container type, sorting a container may permanently
     * change the internal order of items in the container.
     * </p>
     */
    public interface Sortable extends Ordered {

        /**
         * Sort method.
         * 
         * Sorts the container items.
         * 
         * Sorting a container can irreversibly change the order of its items or
         * only change the order temporarily, depending on the container.
         * 
         * @param propertyId
         *            Array of container property IDs, whose values are used to
         *            sort the items in container as primary, secondary, ...
         *            sorting criterion. All of the item IDs must be in the
         *            collection returned by
         *            {@link #getSortableContainerPropertyIds()}
         * @param ascending
         *            Array of sorting order flags corresponding to each
         *            property ID used in sorting. If this array is shorter than
         *            propertyId array, ascending order is assumed for items
         *            where the order is not specified. Use <code>true</code> to
         *            sort in ascending order, <code>false</code> to use
         *            descending order.
         */
        void sort(Object[] propertyId, boolean[] ascending);

        /**
         * Gets the container property IDs which can be used to sort the items.
         * 
         * @return the IDs of the properties that can be used for sorting the
         *         container
         */
        Collection<?> getSortableContainerPropertyIds();

    }

    /**
     * Interface for Container classes whose {@link Item}s can be accessed by
     * their position in the container.
     * <p>
     * If the container is filtered or sorted, all indices refer to the filtered
     * and sorted view. However, the <code>addItemAt()</code> methods may add
     * items that will be filtered out after addition or moved to another
     * position based on sorting.
     * </p>
     */
    public interface Indexed extends Ordered {

        /**
         * Gets the index of the Item corresponding to the itemId. The following
         * is <code>true</code> for the returned index: 0 <= index < size(), or
         * index = -1 if there is no visible item with that id in the container.
         * 
         * @param itemId
         *            ID of an Item in the Container
         * @return index of the Item, or -1 if (the filtered and sorted view of)
         *         the Container does not include the Item
         */
        public int indexOfId(Object itemId);

        /**
         * Get the item id for the item at the position given by
         * <code>index</code>. <br>
         * <br>
         * <b>Throws:</b> {@link IndexOutOfBoundsException} if
         * <code>index</code> is outside the range of the container. (i.e.
         * <code>index &lt; 0 || container.size()-1 &lt; index</code>)
         * 
         * @param index
         *            the index of the requested item id
         * @return the item id of the item at the given index
         */
        public Object getIdByIndex(int index);

        /**
         * Get <code>numberOfItems</code> consecutive item ids from the
         * container, starting with the item id at <code>startIndex</code>. <br>
         * <br>
         * 
         * Implementations should return the exact number of item ids given by
         * <code>numberOfItems</code>. The returned list must hence contain all
         * of the item ids from the range: <br>
         * <br>
         * <code>startIndex</code> to
         * <code>startIndex + (numberOfItems-1)</code>. <br>
         * <br>
         * 
         * The returned list must contain all of the requested item ids or throw
         * a {@link RangeOutOfContainerBoundsException} to indicate that the
         * container does not contain all the requested item ids.<br>
         * <br>
         * For quick migration to new API see:
         * {@link ContainerHelpers#getItemIdsUsingGetIdByIndex(int, int, Indexed)}
         * . <br>
         * <br>
         * <b>Throws:</b> {@link IllegalArgumentException} if
         * <code>numberOfItems</code> is < 0 <br>
         * <b>Throws:</b> {@link RangeOutOfContainerBoundsException} if all of
         * the requested item ids cannot be fetched <br>
         * <b>Throws:</b> {@link IndexOutOfBoundsException} if
         * <code>startIndex</code> is outside the range of the container. (i.e.
         * <code>startIndex &lt; 0 || container.size()-1 &lt; startIndex</code>)
         * 
         * @param startIndex
         *            the index for the first item which id to include
         * @param numberOfItems
         *            the number of consecutive item ids to get from the given
         *            start index, must be >= 0
         * @return List containing all of the requested item ids or empty list
         *         if <code>numberOfItems</code> == 0; not null
         * 
         * @since 7.0
         */
        public List<?> getItemIds(int startIndex, int numberOfItems);

        /**
         * Adds a new item at given index (in the filtered view).
         * <p>
         * The indices of the item currently in the given position and all the
         * following items are incremented.
         * </p>
         * <p>
         * This method should apply filters to the added item after inserting
         * it, possibly hiding it immediately. If the container is being sorted,
         * the item may be added at the correct sorted position instead of the
         * given position. See {@link Indexed}, {@link Ordered},
         * {@link Filterable} and {@link Sortable} for more information.
         * </p>
         * 
         * @param index
         *            Index (in the filtered and sorted view) to add the new
         *            item.
         * @return item id of the created item or null if the operation fails.
         * @throws UnsupportedOperationException
         *             if the operation is not supported by the container
         */
        public Object addItemAt(int index) throws UnsupportedOperationException;

        /**
         * Adds a new item at given index (in the filtered view).
         * <p>
         * The indexes of the item currently in the given position and all the
         * following items are incremented.
         * </p>
         * <p>
         * This method should apply filters to the added item after inserting
         * it, possibly hiding it immediately. If the container is being sorted,
         * the item may be added at the correct sorted position instead of the
         * given position. See {@link Indexed}, {@link Filterable} and
         * {@link Sortable} for more information.
         * </p>
         * 
         * @param index
         *            Index (in the filtered and sorted view) at which to add
         *            the new item.
         * @param newItemId
         *            Id of the new item to be added.
         * @return new {@link Item} or null if the operation fails.
         * @throws UnsupportedOperationException
         *             if the operation is not supported by the container
         */
        public Item addItemAt(int index, Object newItemId)
                throws UnsupportedOperationException;

    }

    /**
     * <p>
     * Interface for <code>Container</code> classes whose Items can be arranged
     * hierarchically. This means that the Items in the container belong in a
     * tree-like structure, with the following quirks:
     * </p>
     * 
     * <ul>
     * <li>The Item structure may have more than one root elements
     * <li>The Items in the hierarchy can be declared explicitly to be able or
     * unable to have children.
     * </ul>
     */
    public interface Hierarchical extends Container {

        /**
         * Gets the IDs of all Items that are children of the specified Item.
         * The returned collection is unmodifiable.
         * 
         * @param itemId
         *            ID of the Item whose children the caller is interested in
         * @return An unmodifiable {@link java.util.Collection collection}
         *         containing the IDs of all other Items that are children in
         *         the container hierarchy
         */
        public Collection<?> getChildren(Object itemId);

        /**
         * Gets the ID of the parent Item of the specified Item.
         * 
         * @param itemId
         *            ID of the Item whose parent the caller wishes to find out.
         * @return the ID of the parent Item. Will be <code>null</code> if the
         *         specified Item is a root element.
         */
        public Object getParent(Object itemId);

        /**
         * Gets the IDs of all Items in the container that don't have a parent.
         * Such items are called <code>root</code> Items. The returned
         * collection is unmodifiable.
         * 
         * @return An unmodifiable {@link java.util.Collection collection}
         *         containing IDs of all root elements of the container
         */
        public Collection<?> rootItemIds();

        /**
         * <p>
         * Sets the parent of an Item. The new parent item must exist and be
         * able to have children. (
         * <code>{@link #areChildrenAllowed(Object)} == true</code> ). It is
         * also possible to detach a node from the hierarchy (and thus make it
         * root) by setting the parent <code>null</code>.
         * </p>
         * 
         * <p>
         * This operation is optional.
         * </p>
         * 
         * @param itemId
         *            ID of the item to be set as the child of the Item
         *            identified with <code>newParentId</code>
         * @param newParentId
         *            ID of the Item that's to be the new parent of the Item
         *            identified with <code>itemId</code>
         * @return <code>true</code> if the operation succeeded,
         *         <code>false</code> if not
         */
        public boolean setParent(Object itemId, Object newParentId)
                throws UnsupportedOperationException;

        /**
         * Tests if the Item with given ID can have children.
         * 
         * @param itemId
         *            ID of the Item in the container whose child capability is
         *            to be tested
         * @return <code>true</code> if the specified Item exists in the
         *         Container and it can have children, <code>false</code> if
         *         it's not found from the container or it can't have children.
         */
        public boolean areChildrenAllowed(Object itemId);

        /**
         * <p>
         * Sets the given Item's capability to have children. If the Item
         * identified with <code>itemId</code> already has children and
         * <code>{@link #areChildrenAllowed(Object)}</code> is false this method
         * fails and <code>false</code> is returned.
         * </p>
         * <p>
         * The children must be first explicitly removed with
         * {@link #setParent(Object itemId, Object newParentId)}or
         * {@link com.vaadin.data.Container#removeItem(Object itemId)}.
         * </p>
         * 
         * <p>
         * This operation is optional. If it is not implemented, the method
         * always returns <code>false</code>.
         * </p>
         * 
         * @param itemId
         *            ID of the Item in the container whose child capability is
         *            to be set
         * @param areChildrenAllowed
         *            boolean value specifying if the Item can have children or
         *            not
         * @return <code>true</code> if the operation succeeded,
         *         <code>false</code> if not
         */
        public boolean setChildrenAllowed(Object itemId,
                boolean areChildrenAllowed)
                throws UnsupportedOperationException;

        /**
         * Tests if the Item specified with <code>itemId</code> is a root Item.
         * The hierarchical container can have more than one root and must have
         * at least one unless it is empty. The {@link #getParent(Object itemId)}
         * method always returns <code>null</code> for root Items.
         * 
         * @param itemId
         *            ID of the Item whose root status is to be tested
         * @return <code>true</code> if the specified Item is a root,
         *         <code>false</code> if not
         */
        public boolean isRoot(Object itemId);

        /**
         * <p>
         * Tests if the Item specified with <code>itemId</code> has child Items
         * or if it is a leaf. The {@link #getChildren(Object itemId)} method
         * always returns <code>null</code> for leaf Items.
         * </p>
         * 
         * <p>
         * Note that being a leaf does not imply whether or not an Item is
         * allowed to have children.
         * </p>
         * .
         * 
         * @param itemId
         *            ID of the Item to be tested
         * @return <code>true</code> if the specified Item has children,
         *         <code>false</code> if not (is a leaf)
         */
        public boolean hasChildren(Object itemId);

        /**
         * <p>
         * Removes the Item identified by <code>ItemId</code> from the
         * Container.
         * </p>
         * 
         * <p>
         * Note that this does not remove any children the item might have.
         * </p>
         * 
         * @param itemId
         *            ID of the Item to remove
         * @return <code>true</code> if the operation succeeded,
         *         <code>false</code> if not
         */
        @Override
        public boolean removeItem(Object itemId)
                throws UnsupportedOperationException;
    }

    /**
     * Interface that is implemented by containers which allow reducing their
     * visible contents based on a set of filters. This interface has been
     * renamed from {@link Filterable}, and implementing the new
     * {@link Filterable} instead of or in addition to {@link SimpleFilterable}
     * is recommended. This interface might be removed in future Vaadin
     * versions.
     * <p>
     * When a set of filters are set, only items that match all the filters are
     * included in the visible contents of the container. Still new items that
     * do not match filters can be added to the container. Multiple filters can
     * be added and the container remembers the state of the filters. When
     * multiple filters are added, all filters must match for an item to be
     * visible in the container.
     * </p>
     * <p>
     * When an {@link Ordered} or {@link Indexed} container is filtered, all
     * operations of these interfaces should only use the filtered contents and
     * the filtered indices to the container.
     * </p>
     * <p>
     * How filtering is performed when a {@link Hierarchical} container
     * implements {@link SimpleFilterable} is implementation specific and should
     * be documented in the implementing class.
     * </p>
     * <p>
     * Adding items (if supported) to a filtered {@link Ordered} or
     * {@link Indexed} container should insert them immediately after the
     * indicated visible item. The unfiltered position of items added at index
     * 0, at index {@link com.vaadin.data.Container#size()} or at an undefined
     * position is up to the implementation.
     * </p>
     * <p>
     * The functionality of SimpleFilterable can be implemented using the
     * {@link Filterable} API and {@link SimpleStringFilter}.
     * </p>
     * 
     * @since 5.0 (renamed from Filterable to SimpleFilterable in 6.6)
     */
    public interface SimpleFilterable extends Container, Serializable {

        /**
         * Add a filter for given property.
         * 
         * The API {@link Filterable#addContainerFilter(Filter)} is recommended
         * instead of this method. A {@link SimpleStringFilter} can be used with
         * the new API to implement the old string filtering functionality.
         * 
         * The filter accepts items for which toString() of the value of the
         * given property contains or starts with given filterString. Other
         * items are not visible in the container when filtered.
         * 
         * If a container has multiple filters, only items accepted by all
         * filters are visible.
         * 
         * @param propertyId
         *            Property for which the filter is applied to.
         * @param filterString
         *            String that must match the value of the property
         * @param ignoreCase
         *            Determine if the casing can be ignored when comparing
         *            strings.
         * @param onlyMatchPrefix
         *            Only match prefixes; no other matches are included.
         */
        public void addContainerFilter(Object propertyId, String filterString,
                boolean ignoreCase, boolean onlyMatchPrefix);

        /**
         * Remove all filters from all properties.
         */
        public void removeAllContainerFilters();

        /**
         * Remove all filters from the given property.
         * 
         * @param propertyId
         *            for which to remove filters
         */
        public void removeContainerFilters(Object propertyId);
    }

    /**
     * Filter interface for container filtering.
     * 
     * If a filter does not support in-memory filtering,
     * {@link #passesFilter(Item)} should throw
     * {@link UnsupportedOperationException}.
     * 
     * Lazy containers must be able to map filters to their internal
     * representation (e.g. SQL or JPA 2.0 Criteria).
     * 
     * An {@link UnsupportedFilterException} can be thrown by the container if a
     * particular filter is not supported by the container.
     * 
     * An {@link Filter} should implement {@link #equals(Object)} and
     * {@link #hashCode()} correctly to avoid duplicate filter registrations
     * etc.
     * 
     * @see Filterable
     * 
     * @since 6.6
     */
    public interface Filter extends Serializable {

        /**
         * Check if an item passes the filter (in-memory filtering).
         * 
         * @param itemId
         *            identifier of the item being filtered; may be null when
         *            the item is being added to the container
         * @param item
         *            the item being filtered
         * @return true if the item is accepted by this filter
         * @throws UnsupportedOperationException
         *             if the filter cannot be used for in-memory filtering
         */
        public boolean passesFilter(Object itemId, Item item)
                throws UnsupportedOperationException;

        /**
         * Check if a change in the value of a property can affect the filtering
         * result. May always return true, at the cost of performance.
         * 
         * If the filter cannot determine whether it may depend on the property
         * or not, should return true.
         * 
         * @param propertyId
         * @return true if the filtering result may/does change based on changes
         *         to the property identified by propertyId
         */
        public boolean appliesToProperty(Object propertyId);

    }

    /**
     * Interface that is implemented by containers which allow reducing their
     * visible contents based on a set of filters.
     * <p>
     * When a set of filters are set, only items that match all the filters are
     * included in the visible contents of the container. Still new items that
     * do not match filters can be added to the container. Multiple filters can
     * be added and the container remembers the state of the filters. When
     * multiple filters are added, all filters must match for an item to be
     * visible in the container.
     * </p>
     * <p>
     * When an {@link Ordered} or {@link Indexed} container is filtered, all
     * operations of these interfaces should only use the filtered and sorted
     * contents and the filtered indices to the container. Indices or item
     * identifiers in the public API refer to the visible view unless otherwise
     * stated. However, the <code>addItem*()</code> methods may add items that
     * will be filtered out after addition or moved to another position based on
     * sorting.
     * </p>
     * <p>
     * How filtering is performed when a {@link Hierarchical} container
     * implements {@link Filterable} is implementation specific and should be
     * documented in the implementing class.
     * </p>
     * <p>
     * Adding items (if supported) to a filtered {@link Ordered} or
     * {@link Indexed} container should insert them immediately after the
     * indicated visible item. However, the unfiltered position of items added
     * at index 0, at index {@link com.vaadin.data.Container#size()} or at an
     * undefined position is up to the implementation.
     * </p>
     * 
     * <p>
     * This API replaces the old Filterable interface, renamed to
     * {@link SimpleFilterable} in Vaadin 6.6.
     * </p>
     * 
     * @since 6.6
     */
    public interface Filterable extends Container, Serializable {
        /**
         * Adds a filter for the container.
         * 
         * If a container has multiple filters, only items accepted by all
         * filters are visible.
         * 
         * @throws UnsupportedFilterException
         *             if the filter is not supported by the container
         */
        public void addContainerFilter(Filter filter)
                throws UnsupportedFilterException;

        /**
         * Removes a filter from the container.
         * 
         * This requires that the equals() method considers the filters as
         * equivalent (same instance or properly implemented equals() method).
         */
        public void removeContainerFilter(Filter filter);

        /**
         * Remove all active filters from the container.
         */
        public void removeAllContainerFilters();

    }

    /**
     * Interface implemented by viewer classes capable of using a Container as a
     * data source.
     */
    public interface Viewer extends Serializable {

        /**
         * Sets the Container that serves as the data source of the viewer.
         * 
         * @param newDataSource
         *            The new data source Item
         */
        public void setContainerDataSource(Container newDataSource);

        /**
         * Gets the Container serving as the data source of the viewer.
         * 
         * @return data source Container
         */
        public Container getContainerDataSource();

    }

    /**
     * <p>
     * Interface implemented by the editor classes supporting editing the
     * Container. Implementing this interface means that the Container serving
     * as the data source of the editor can be modified through it.
     * </p>
     * <p>
     * Note that not implementing the <code>Container.Editor</code> interface
     * does not restrict the class from editing the Container contents
     * internally.
     * </p>
     */
    public interface Editor extends Container.Viewer, Serializable {

    }

    /* Contents change event */

    /**
     * An <code>Event</code> object specifying the Container whose Item set has
     * changed (items added, removed or reordered).
     * 
     * A simple property value change is not an item set change.
     */
    public interface ItemSetChangeEvent extends Serializable {

        /**
         * Gets the Property where the event occurred.
         * 
         * @return source of the event
         */
        public Container getContainer();
    }

    /**
     * Container Item set change listener interface.
     * 
     * An item set change refers to addition, removal or reordering of items in
     * the container. A simple property value change is not an item set change.
     */
    public interface ItemSetChangeListener extends Serializable {

        /**
         * Lets the listener know a Containers visible (filtered and/or sorted,
         * if applicable) Item set has changed.
         * 
         * @param event
         *            change event text
         */
        public void containerItemSetChange(Container.ItemSetChangeEvent event);
    }

    /**
     * The interface for adding and removing <code>ItemSetChangeEvent</code>
     * listeners. By implementing this interface a class explicitly announces
     * that it will generate a <code>ItemSetChangeEvent</code> when its contents
     * are modified.
     * 
     * An item set change refers to addition, removal or reordering of items in
     * the container. A simple property value change is not an item set change.
     * 
     * <p>
     * Note: The general Java convention is not to explicitly declare that a
     * class generates events, but to directly define the
     * <code>addListener</code> and <code>removeListener</code> methods. That
     * way the caller of these methods has no real way of finding out if the
     * class really will send the events, or if it just defines the methods to
     * be able to implement an interface.
     * </p>
     */
    public interface ItemSetChangeNotifier extends Serializable {

        /**
         * Adds an Item set change listener for the object.
         * 
         * @param listener
         *            listener to be added
         */
        public void addItemSetChangeListener(
                Container.ItemSetChangeListener listener);

        /**
         * @deprecated Since 7.0, replaced by
         *             {@link #addItemSetChangeListener(ItemSetChangeListener)}
         **/
        @Deprecated
        public void addListener(Container.ItemSetChangeListener listener);

        /**
         * Removes the Item set change listener from the object.
         * 
         * @param listener
         *            listener to be removed
         */
        public void removeItemSetChangeListener(
                Container.ItemSetChangeListener listener);

        /**
         * @deprecated Since 7.0, replaced by
         *             {@link #removeItemSetChangeListener(ItemSetChangeListener)}
         **/
        @Deprecated
        public void removeListener(Container.ItemSetChangeListener listener);
    }

    /* Property set change event */

    /**
     * An <code>Event</code> object specifying the Container whose Property set
     * has changed.
     * 
     * A property set change means the addition, removal or other structural
     * changes to the properties of a container. Changes concerning the set of
     * items in the container and their property values are not property set
     * changes.
     */
    public interface PropertySetChangeEvent extends Serializable {

        /**
         * Retrieves the Container whose contents have been modified.
         * 
         * @return Source Container of the event.
         */
        public Container getContainer();
    }

    /**
     * The listener interface for receiving <code>PropertySetChangeEvent</code>
     * objects.
     * 
     * A property set change means the addition, removal or other structural
     * change of the properties (supported property IDs) of a container. Changes
     * concerning the set of items in the container and their property values
     * are not property set changes.
     */
    public interface PropertySetChangeListener extends Serializable {

        /**
         * Notifies this listener that the set of property IDs supported by the
         * Container has changed.
         * 
         * @param event
         *            Change event.
         */
        public void containerPropertySetChange(
                Container.PropertySetChangeEvent event);
    }

    /**
     * <p>
     * The interface for adding and removing <code>PropertySetChangeEvent</code>
     * listeners. By implementing this interface a class explicitly announces
     * that it will generate a <code>PropertySetChangeEvent</code> when the set
     * of property IDs supported by the container is modified.
     * </p>
     * 
     * <p>
     * A property set change means the addition, removal or other structural
     * changes to the properties of a container. Changes concerning the set of
     * items in the container and their property values are not property set
     * changes.
     * </p>
     * 
     * <p>
     * Note that the general Java convention is not to explicitly declare that a
     * class generates events, but to directly define the
     * <code>addListener</code> and <code>removeListener</code> methods. That
     * way the caller of these methods has no real way of finding out if the
     * class really will send the events, or if it just defines the methods to
     * be able to implement an interface.
     * </p>
     */
    public interface PropertySetChangeNotifier extends Serializable {

        /**
         * Registers a new Property set change listener for this Container.
         * 
         * @param listener
         *            The new Listener to be registered
         */
        public void addPropertySetChangeListener(
                Container.PropertySetChangeListener listener);

        /**
         * @deprecated Since 7.0, replaced by
         *             {@link #addPropertySetChangeListener(PropertySetChangeListener)}
         **/
        @Deprecated
        public void addListener(Container.PropertySetChangeListener listener);

        /**
         * Removes a previously registered Property set change listener.
         * 
         * @param listener
         *            Listener to be removed
         */
        public void removePropertySetChangeListener(
                Container.PropertySetChangeListener listener);

        /**
         * @deprecated Since 7.0, replaced by
         *             {@link #removePropertySetChangeListener(PropertySetChangeListener)}
         **/
        @Deprecated
        public void removeListener(Container.PropertySetChangeListener listener);
    }
}