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 items in the given list as its
35 * Note: the elements will be copied from the {@link List}, you cannot
36 * manage the {@link List} from outside
39 * the descendants of this object, or NULL if none
41 protected BaseClass(List
<E
> list
) {
42 this.list
= new ArrayList
<E
>();
45 this.list
.addAll(list
);
48 for (E child
: this) {
54 * Check if this element has unsaved changes.
56 * @return TRUE if it has
58 public boolean isDirty() {
63 * Delete this element from its parent if any.
65 * @return TRUE in case of success
67 public boolean delete() {
69 return parent
.remove(this);
76 * Replace the elements contained in this with those in the given
79 * Note: the elements will be copied from the {@link List}, you cannot
80 * manage the {@link List} from outside
83 * the list of new elements
85 public void replaceListContent(List
<E
> list
) {
86 List
<E
> del
= new ArrayList
<E
>();
87 List
<E
> add
= new ArrayList
<E
>();
89 for (E oldChild
: this) {
90 if (!list
.contains(oldChild
)) {
94 for (E newChild
: list
) {
95 if (!contains(newChild
)) {
105 * Notify that this element has unsaved changes.
109 if (parent
!= null) {
115 * Notify this element <i>and all its descendants</i> that it is in pristine
116 * state (as opposed to dirty).
120 for (E child
: this) {
126 * Set the parent of this element <i>and all its descendants</i>.
131 void setParent(BaseClass
<?
> parent
) {
132 this.parent
= parent
;
133 for (E child
: this) {
134 child
.setParent(this);
139 * Each element that leaves the parent will pass trough here.
142 * the element to remove from this
144 private void _leave(E child
) {
149 * Each element that enters the parent will pass trough here.
152 * the element to add to this
154 private void _enter(E child
) {
155 _enter(child
, false);
159 * Each element that enters the parent will pass trough here.
162 * the element to add to this
164 private void _enter(E child
, boolean initialLoad
) {
165 child
.setParent(this);
173 public boolean add(E e
) {
179 @SuppressWarnings("unchecked")
180 public boolean remove(Object o
) {
181 if (list
.remove(o
)) {
182 if (o
instanceof BaseClass
<?
>) {
183 _leave((E
) o
); // expected warning
192 public boolean addAll(Collection
<?
extends E
> c
) {
197 return list
.addAll(c
);
201 public boolean addAll(int index
, Collection
<?
extends E
> c
) {
206 return list
.addAll(index
, c
);
210 public boolean removeAll(Collection
<?
> c
) {
211 boolean changed
= false;
222 public boolean retainAll(Collection
<?
> c
) {
223 ArrayList
<Object
> del
= new ArrayList
<Object
>();
227 return removeAll(del
);
231 public void clear() {
232 for (E child
: this) {
240 public E
set(int index
, E element
) {
241 E child
= get(index
);
246 return list
.set(index
, element
);
250 public void add(int index
, E element
) {
252 list
.add(index
, element
);
256 public E
remove(int index
) {
257 E child
= get(index
);
259 return list
.remove(index
);
263 public Iterator
<E
> iterator() {
264 return listIterator(0);
268 public ListIterator
<E
> listIterator() {
269 return listIterator(0);
273 public ListIterator
<E
> listIterator(int index
) {
275 return new ListIterator
<E
>() {
276 ListIterator
<E
> base
= list
.listIterator(i
);
280 public boolean hasNext() {
281 return base
.hasNext();
291 public boolean hasPrevious() {
292 return base
.hasPrevious();
296 public E
previous() {
297 last
= base
.previous();
302 public int nextIndex() {
303 return base
.nextIndex();
307 public int previousIndex() {
308 return base
.previousIndex();
312 public void remove() {
318 public void set(E e
) {
325 public void add(E e
) {
333 public Object
[] toArray() {
334 return list
.toArray();
338 public <T
> T
[] toArray(T
[] a
) {
339 return list
.toArray(a
);
348 public boolean isEmpty() {
349 return list
.isEmpty();
353 public boolean contains(Object o
) {
354 return list
.contains(o
);
358 public boolean containsAll(Collection
<?
> c
) {
359 return list
.containsAll(c
);
363 public E
get(int index
) {
364 return list
.get(index
);
368 public int indexOf(Object o
) {
369 return list
.indexOf(o
);
373 public int lastIndexOf(Object o
) {
374 return list
.lastIndexOf(o
);
378 public List
<E
> subList(int fromIndex
, int toIndex
) {
379 return list
.subList(fromIndex
, toIndex
);