View Javadoc
1   /*
2    * This file is part of ***  M y C o R e  ***
3    * See http://www.mycore.de/ for details.
4    *
5    * MyCoRe is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    *
10   * MyCoRe is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with MyCoRe.  If not, see <http://www.gnu.org/licenses/>.
17   */
18  
19  package org.mycore.frontend.basket;
20  
21  import java.util.ArrayList;
22  import java.util.Collection;
23  import java.util.Iterator;
24  import java.util.List;
25  import java.util.ListIterator;
26  import java.util.Set;
27  import java.util.Spliterator;
28  import java.util.stream.Collectors;
29  
30  import org.jdom2.Element;
31  
32  /**
33   * Implements a basket of entries.
34   * The basket has a type attribute that allows to
35   * distinguish multiple baskets within the same session.
36   * The basket implements the List and Set interfaces,
37   * it behaves like an ordered Set of entries. 
38   * Entries already contained in the basket can not be 
39   * re-added, each entry can be contained only once in the basket. 
40   * 
41   * @author Frank L\u00FCtzenkirchen
42   */
43  public class MCRBasket implements List<MCRBasketEntry>, Set<MCRBasketEntry> {
44  
45      /** The internal list of basket entries */
46      private List<MCRBasketEntry> list = new ArrayList<>();
47  
48      /** The type of basket */
49      private String type;
50  
51      /** The ID of the derivate that holds the persistent data of this basket */
52      private String derivateID;
53  
54      /**
55       * Creates a new basket of the given type.
56       * 
57       * @param type the type of basket, an attribute that can be used by the application to distinguish
58       *            multiple basket within the same session.
59       */
60      public MCRBasket(String type) {
61          this.type = type;
62      }
63  
64      /**
65       * Returns the type of basket.
66       */
67      public String getType() {
68          return type;
69      }
70  
71      /** 
72       * Returns the ID of the derivate that holds the persistent data of this basket, or null
73       */
74      public String getDerivateID() {
75          return derivateID;
76      }
77  
78      /**
79       * Sets the ID of the derivate that holds the persistent data of this basket
80       */
81      public void setDerivateID(String derivateID) {
82          this.derivateID = derivateID;
83      }
84  
85      @Override
86      public void add(int index, MCRBasketEntry entry) {
87          if (!contains(entry)) {
88              list.add(index, entry);
89          }
90      }
91  
92      @Override
93      public boolean add(MCRBasketEntry entry) {
94          return !contains(entry) && list.add(entry);
95      }
96  
97      @Override
98      public boolean addAll(Collection<? extends MCRBasketEntry> collection) {
99          boolean changed = false;
100         for (MCRBasketEntry entry : collection) {
101             if (!contains(entry)) {
102                 changed = true;
103                 add(entry);
104             }
105         }
106         return changed;
107     }
108 
109     @Override
110     public boolean addAll(int index, Collection<? extends MCRBasketEntry> collection) {
111         return list.addAll(index, collection.stream().filter(entry -> !contains(entry)).collect(Collectors.toList()));
112     }
113 
114     @Override
115     public void clear() {
116         list.clear();
117     }
118 
119     @Override
120     public boolean contains(Object o) {
121         return list.contains(o);
122     }
123 
124     @Override
125     public boolean containsAll(Collection<?> c) {
126         return list.containsAll(c);
127     }
128 
129     @Override
130     public MCRBasketEntry get(int index) {
131         return list.get(index);
132     }
133 
134     /**
135      * Returns the basket entry with the given ID, or null.
136      *
137      * @param id the ID of the basket entry.
138      */
139     public MCRBasketEntry get(String id) {
140         return this.stream().filter(entry -> id.equals(entry.getID())).findFirst().orElse(null);
141     }
142 
143     @Override
144     public int indexOf(Object o) {
145         return list.indexOf(o);
146     }
147 
148     @Override
149     public boolean isEmpty() {
150         return list.isEmpty();
151     }
152 
153     @Override
154     public Iterator<MCRBasketEntry> iterator() {
155         return list.iterator();
156     }
157 
158     @Override
159     public int lastIndexOf(Object o) {
160         return list.lastIndexOf(o);
161     }
162 
163     @Override
164     public ListIterator<MCRBasketEntry> listIterator() {
165         return list.listIterator();
166     }
167 
168     @Override
169     public ListIterator<MCRBasketEntry> listIterator(int index) {
170         return list.listIterator(index);
171     }
172 
173     @Override
174     public MCRBasketEntry remove(int index) {
175         return list.remove(index);
176     }
177 
178     @Override
179     public boolean remove(Object o) {
180         return list.remove(o);
181     }
182 
183     /**
184      * Removes the entry with the given ID from the basket.
185      * 
186      * @return true, if the basket entry was removed successfully.
187      */
188     public boolean removeEntry(String id) {
189         MCRBasketEntry entry = get(id);
190         if (entry == null) {
191             return false;
192         }
193         return remove(entry);
194     }
195 
196     @Override
197     public boolean removeAll(Collection<?> c) {
198         return list.removeAll(c);
199     }
200 
201     @Override
202     public boolean retainAll(Collection<?> c) {
203         return list.retainAll(c);
204     }
205 
206     @Override
207     public MCRBasketEntry set(int index, MCRBasketEntry entry) {
208         return (contains(entry) ? null : list.set(index, entry));
209     }
210 
211     @Override
212     public int size() {
213         return list.size();
214     }
215 
216     @Override
217     public List<MCRBasketEntry> subList(int fromIndex, int toIndex) {
218         return list.subList(fromIndex, toIndex);
219     }
220 
221     @Override
222     public Object[] toArray() {
223         return list.toArray();
224     }
225 
226     @Override
227     public <T> T[] toArray(T[] a) {
228         return list.toArray(a);
229     }
230 
231     /**
232      * Moves the basket entry one position up in the
233      * list of basket entries.
234      */
235     public void up(MCRBasketEntry entry) {
236         move(entry, -1);
237     }
238 
239     /**
240      * Moves the basket entry one position down in the
241      * list of basket entries.
242      */
243     public void down(MCRBasketEntry entry) {
244         move(entry, 1);
245     }
246 
247     /**
248      * Moves a basket entry up or down in the
249      * list of basket entries.
250      * 
251      * @param change the number of index positions to move the entry.
252      */
253     public void move(MCRBasketEntry entry, int change) {
254         int posOld = indexOf(entry);
255         int posNew = posOld + change;
256         if ((posNew < 0) || (posNew > list.size() - 1)) {
257             return;
258         }
259 
260         remove(posOld);
261         add(posNew, entry);
262     }
263 
264     /**
265      * For all basket entries, if their XML content is not resolved yet, 
266      * resolves the XML from the given URI in the entry.
267      */
268     public void resolveContent() {
269         for (MCRBasketEntry entry : list) {
270             Element content = entry.getContent();
271             if (content == null) {
272                 entry.resolveContent();
273             }
274         }
275     }
276 
277     @Override
278     public Spliterator<MCRBasketEntry> spliterator() {
279         return list.spliterator();
280     }
281 }