1 package be
.nikiroo
.jvcard
;
3 import java
.util
.ArrayList
;
4 import java
.util
.Collection
;
5 import java
.util
.Iterator
;
7 import java
.util
.ListIterator
;
10 * This class is basically a List with a parent and a "dirty" state check. It
11 * sends all commands down to the initial list, but will mark itself and its
12 * children as dirty or not when needed.
14 * All child elements can identify their parent.
16 * The dirty state is bubbling up (when dirty = true) or down (when dirty =
17 * false) -- so, making changes to a child element will also mark its parent as
18 * "dirty", and marking an element as pristine will also affect all its child
24 * the type of the child elements
26 public abstract class BaseClass
<E
extends BaseClass
<?
>> implements List
<E
> {
27 protected boolean dirty
;
28 protected BaseClass
<?
> parent
;
32 * Create a new {@link BaseClass} with the given list as its descendants.
35 * the descendants of this object, or NULL if none
37 protected BaseClass(List
<E
> list
) {
38 this.list
= new ArrayList
<E
>();
41 this.list
.addAll(list
);
44 for (E child
: this) {
50 * Check if this element has unsaved changes.
52 * @return TRUE if it has
54 public boolean isDirty() {
59 * Delete this element from its parent if any.
61 * @return TRUE in case of success
63 public boolean delete() {
65 return parent
.remove(this);
72 * Replace the elements contained in this with those in the given
75 * Note: the elements will be copied from the {@link List}, you cannot
76 * manage the {@link List} from outside
79 * the list of new elements
81 public void replaceListContent(List
<E
> list
) {
82 List
<E
> del
= new ArrayList
<E
>();
83 List
<E
> add
= new ArrayList
<E
>();
85 for (E oldChild
: this) {
86 if (!list
.contains(oldChild
)) {
90 for (E newChild
: list
) {
91 if (!contains(newChild
)) {
101 * Notify that this element has unsaved changes.
108 * Notify this element <i>and all its descendants</i> that it is in pristine
109 * state (as opposed to dirty).
113 for (E child
: this) {
119 * Set the parent of this element <i>and all its descendants</i>.
124 void setParent(BaseClass
<?
> parent
) {
125 this.parent
= parent
;
126 for (E child
: this) {
127 child
.setParent(this);
132 * Each element that leaves the parent will pass trough here.
135 * the element to remove from this
137 private void _leave(E child
) {
142 * Each element that enters the parent will pass trough here.
145 * the element to add to this
147 private void _enter(E child
) {
148 _enter(child
, false);
152 * Each element that enters the parent will pass trough here.
155 * the element to add to this
157 private void _enter(E child
, boolean initialLoad
) {
158 child
.setParent(this);
164 public boolean add(E e
) {
170 @SuppressWarnings("unchecked")
171 public boolean remove(Object o
) {
172 if (list
.remove(o
)) {
173 if (o
instanceof BaseClass
<?
>) {
174 _leave((E
) o
); // expected warning
183 public boolean addAll(Collection
<?
extends E
> c
) {
188 return list
.addAll(c
);
192 public boolean addAll(int index
, Collection
<?
extends E
> c
) {
197 return list
.addAll(index
, c
);
201 public boolean removeAll(Collection
<?
> c
) {
202 boolean changed
= false;
213 public boolean retainAll(Collection
<?
> c
) {
214 ArrayList
<Object
> del
= new ArrayList
<Object
>();
218 return removeAll(del
);
222 public void clear() {
223 for (E child
: this) {
231 public E
set(int index
, E element
) {
232 E child
= get(index
);
237 return list
.set(index
, element
);
241 public void add(int index
, E element
) {
243 list
.add(index
, element
);
247 public E
remove(int index
) {
248 E child
= get(index
);
250 return list
.remove(index
);
254 public Iterator
<E
> iterator() {
255 return listIterator(0);
259 public ListIterator
<E
> listIterator() {
260 return listIterator(0);
264 public ListIterator
<E
> listIterator(int index
) {
266 return new ListIterator
<E
>() {
267 ListIterator
<E
> base
= list
.listIterator(i
);
271 public boolean hasNext() {
272 return base
.hasNext();
282 public boolean hasPrevious() {
283 return base
.hasPrevious();
287 public E
previous() {
288 last
= base
.previous();
293 public int nextIndex() {
294 return base
.nextIndex();
298 public int previousIndex() {
299 return base
.previousIndex();
303 public void remove() {
309 public void set(E e
) {
316 public void add(E e
) {
324 public Object
[] toArray() {
325 return list
.toArray();
329 public <T
> T
[] toArray(T
[] a
) {
330 return list
.toArray(a
);
339 public boolean isEmpty() {
340 return list
.isEmpty();
344 public boolean contains(Object o
) {
345 return list
.contains(o
);
349 public boolean containsAll(Collection
<?
> c
) {
350 return list
.containsAll(c
);
354 public E
get(int index
) {
355 return list
.get(index
);
359 public int indexOf(Object o
) {
360 return list
.indexOf(o
);
364 public int lastIndexOf(Object o
) {
365 return list
.lastIndexOf(o
);
369 public List
<E
> subList(int fromIndex
, int toIndex
) {
370 return list
.subList(fromIndex
, toIndex
);