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