001/*
002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 *     Nuxeo - initial API and implementation
011 *
012 * $Id: JOOoConvertPluginImpl.java 18651 2007-05-13 20:28:53Z sfermigier $
013 */
014
015package org.nuxeo.ecm.core.api;
016
017import java.io.Serializable;
018import java.util.ArrayList;
019import java.util.Arrays;
020import java.util.List;
021
022/**
023 * A list that is detached from its data source so all modifications on the list are recorded so that the data source
024 * will be updated later when the list will be reconnected to it.
025 * <p>
026 * It purposedly doesn't implement the List interface.
027 *
028 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
029 */
030public class ListDiff implements Serializable {
031
032    public static final int ADD = 1;
033
034    public static final int INSERT = 2;
035
036    public static final int REMOVE = 3;
037
038    public static final int MODIFY = 4;
039
040    public static final int MOVE = 5;
041
042    public static final int CLEAR = 6;
043
044    private static final long serialVersionUID = 2239608903749525011L;
045
046    final List<Entry> diff = new ArrayList<Entry>();
047
048    public ListDiff() {
049
050    }
051
052    public ListDiff(ListDiff listDiff) {
053        if (listDiff != null) {
054            diff.addAll(Arrays.asList(listDiff.diff()));
055        }
056    }
057
058    public void add(Object value) {
059        diff.add(new Entry(ADD, 0, value));
060    }
061
062    public void insert(int index, Object value) {
063        diff.add(new Entry(INSERT, index, value));
064    }
065
066    public void modify(int index, Object value) {
067        diff.add(new Entry(MODIFY, index, value));
068    }
069
070    public void move(int fromIndex, int toIndex) {
071        // XXX AT: here value is the toIndex, not strange?
072        diff.add(new Entry(MOVE, fromIndex, toIndex));
073    }
074
075    public void remove(int index) {
076        diff.add(new Entry(REMOVE, index, null));
077    }
078
079    public void removeAll() {
080        diff.add(new Entry(CLEAR, 0, null));
081    }
082
083    public void reset() {
084        diff.clear();
085    }
086
087    public boolean isDirty() {
088        return !diff.isEmpty();
089    }
090
091    public Entry[] diff() {
092        return diff.toArray(new Entry[diff.size()]);
093    }
094
095    @Override
096    public String toString() {
097        return String.format("ListDiff { %s }", diff.toString());
098    }
099
100    public static String typeToString(int type) {
101        if (type == 1) {
102            return "ADD";
103        } else if (type == 2) {
104            return "INSERT";
105        } else if (type == 3) {
106            return "REMOVE";
107        } else if (type == 4) {
108            return "MODIFY";
109        } else if (type == 5) {
110            return "MOVE";
111        } else if (type == 6) {
112            return "CLEAR";
113        } else {
114            return "invalid type: " + Integer.toString(type);
115        }
116    }
117
118    public static class Entry implements Serializable {
119
120        private static final long serialVersionUID = -3261465349877937657L;
121
122        public int index;
123
124        public int type;
125
126        public Object value;
127
128        public Entry() {
129        }
130
131        public Entry(int type, int index, Object value) {
132            this.index = index;
133            this.type = type;
134            this.value = value;
135        }
136
137        @Override
138        public String toString() {
139            return String.format("Entry {%s, %s, %s}", index, ListDiff.typeToString(type), value);
140        }
141
142    }
143
144}