1   /**
2    * Distribution License:
3    * JSword is free software; you can redistribute it and/or modify it under
4    * the terms of the GNU Lesser General Public License, version 2.1 or later
5    * as published by the Free Software Foundation. This program is distributed
6    * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
7    * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
8    * See the GNU Lesser General Public License for more details.
9    *
10   * The License is available on the internet at:
11   *       http://www.gnu.org/copyleft/lgpl.html
12   * or by writing to:
13   *      Free Software Foundation, Inc.
14   *      59 Temple Place - Suite 330
15   *      Boston, MA 02111-1307, USA
16   *
17   * Copyright: 2008
18   *     The copyright to this program is held by it's authors.
19   *
20   */
21  package org.crosswire.jsword.book.sword;
22  
23  import java.io.IOException;
24  import java.util.Iterator;
25  import java.util.NoSuchElementException;
26  
27  import org.crosswire.jsword.book.BookException;
28  import org.crosswire.jsword.book.sword.state.OpenFileState;
29  import org.crosswire.jsword.passage.Key;
30  import org.crosswire.jsword.passage.RestrictionType;
31  
32  /**
33   * A Backend that can be used as a global key list.
34   * 
35   * @param <T> The type of the OpenFileState that this class extends.
36   * @see gnu.lgpl.License for license details.<br>
37   *      The copyright to this program is held by it's authors.
38   * @author DM Smith
39   */
40  public abstract class AbstractKeyBackend<T extends OpenFileState> extends AbstractBackend<T> implements Key {
41      /**
42       * Simple ctor
43       * 
44       * @param sbmd
45       *            the book's metadata
46       */
47      public AbstractKeyBackend(SwordBookMetaData sbmd) {
48          super(sbmd);
49      }
50  
51      /* (non-Javadoc)
52       * @see org.crosswire.jsword.passage.Key#canHaveChildren()
53       */
54      public boolean canHaveChildren() {
55          return false;
56      }
57  
58      /* (non-Javadoc)
59       * @see org.crosswire.jsword.passage.Key#getChildCount()
60       */
61      public int getChildCount() {
62          return 0;
63      }
64  
65      /* (non-Javadoc)
66       * @see org.crosswire.jsword.passage.Key#isEmpty()
67       */
68      public boolean isEmpty() {
69          return getCardinality() == 0;
70      }
71  
72      @Override
73      public boolean contains(Key key) {
74          return indexOf(key) >= 0;
75      }
76  
77      /* (non-Javadoc)
78       * @see java.lang.Iterable#iterator()
79       */
80      public Iterator<Key> iterator() {
81          return new Iterator<Key>() {
82  
83              /* (non-Javadoc)
84               * @see java.util.Iterator#hasNext()
85               */
86              public boolean hasNext() {
87                  return here < count;
88              }
89  
90              /* (non-Javadoc)
91               * @see java.util.Iterator#next()
92               */
93              public Key next() throws NoSuchElementException {
94                  if (here >= count) {
95                      throw new NoSuchElementException();
96                  }
97                  return get(here++);
98              }
99  
100             /* (non-Javadoc)
101              * @see java.util.Iterator#remove()
102              */
103             public void remove() {
104                 throw new UnsupportedOperationException();
105             }
106 
107             private int here;
108             private int count = getCardinality();
109         };
110     }
111 
112 
113     /* (non-Javadoc)
114      * @see org.crosswire.jsword.passage.Key#addAll(org.crosswire.jsword.passage.Key)
115      */
116     public void addAll(Key key) {
117         throw new UnsupportedOperationException();
118     }
119 
120     /* (non-Javadoc)
121      * @see org.crosswire.jsword.passage.Key#removeAll(org.crosswire.jsword.passage.Key)
122      */
123     public void removeAll(Key key) {
124         throw new UnsupportedOperationException();
125     }
126 
127     /* (non-Javadoc)
128      * @see org.crosswire.jsword.passage.Key#clear()
129      */
130     public void clear() {
131         throw new UnsupportedOperationException();
132     }
133 
134     public void setAliasKey(T state, Key alias, Key source) throws IOException {
135         throw new UnsupportedOperationException();
136     }
137 
138     public void setRawText(T state, Key key, String text) throws BookException, IOException {
139         throw new UnsupportedOperationException();
140     }
141 
142     /* (non-Javadoc)
143      * @see org.crosswire.jsword.passage.Key#getParent()
144      */
145     public Key getParent() {
146         return null;
147     }
148 
149     @Override
150     public AbstractKeyBackend<T> clone() {
151         AbstractKeyBackend<T> clone = null;
152         try {
153             clone = (AbstractKeyBackend<T>) super.clone();
154         } catch (CloneNotSupportedException e) {
155             assert false : e;
156         }
157         return clone;
158     }
159 
160     /* (non-Javadoc)
161      * @see org.crosswire.jsword.passage.Key#getName()
162      */
163     public String getName() {
164         return getBookMetaData().getInitials();
165     }
166 
167     /* (non-Javadoc)
168      * @see org.crosswire.jsword.passage.Key#getName(org.crosswire.jsword.passage.Key)
169      */
170     public String getName(Key base) {
171         return getName();
172     }
173 
174     /* (non-Javadoc)
175      * @see org.crosswire.jsword.passage.Key#getOsisID()
176      */
177     public String getOsisID() {
178         return getName();
179     }
180 
181     /* (non-Javadoc)
182      * @see org.crosswire.jsword.passage.Key#getOsisRef()
183      */
184     public String getOsisRef() {
185         return getName();
186     }
187 
188    /* (non-Javadoc)
189      * @see org.crosswire.jsword.passage.Key#getRootName()
190      */
191     public String getRootName() {
192         return getName();
193     }
194 
195     /* (non-Javadoc)
196      * @see org.crosswire.jsword.passage.Key#retainAll(org.crosswire.jsword.passage.Key)
197      */
198     public void retainAll(Key key) {
199         throw new UnsupportedOperationException();
200     }
201 
202     @Override
203     public boolean equals(Object obj) {
204         // Since this can not be null
205         if (obj == null) {
206             return false;
207         }
208 
209         // Check that that is the same as this
210         // Don't use instanceOf since that breaks inheritance
211         if (!obj.getClass().equals(this.getClass())) {
212             return false;
213         }
214 
215         return compareTo((Key) obj) == 0;
216     }
217 
218     @Override
219     public int hashCode() {
220         return getName().hashCode();
221     }
222 
223     /* (non-Javadoc)
224      * @see java.lang.Comparable#compareTo(java.lang.Object)
225      */
226     public int compareTo(Key that) {
227 
228         if (this == that) {
229             return 0;
230         }
231 
232         if (that == null) {
233             // he is empty, we are not so he is greater
234             return -1;
235         }
236 
237         int ret = this.getName().compareTo(that.getName());
238 
239         if (ret != 0) {
240             return ret;
241         }
242 
243         // Compare the contents.
244         Iterator<Key> thisIter = this.iterator();
245         Iterator<Key> thatIter = that.iterator();
246 
247         Key thisfirst = null;
248         Key thatfirst = null;
249 
250         if (thisIter.hasNext()) {
251             thisfirst = thisIter.next();
252         }
253 
254         if (thatIter.hasNext()) {
255             thatfirst = thatIter.next();
256         }
257 
258         if (thisfirst == null) {
259             if (thatfirst == null) {
260                 // we are both empty, and rank the same
261                 return 0;
262             }
263             // i am empty, he is not so we are greater
264             return 1;
265         }
266 
267         if (thatfirst == null) {
268             // he is empty, we are not so he is greater
269             return -1;
270         }
271 
272         return thisfirst.getName().compareTo(thatfirst.getName());
273     }
274 
275     /* (non-Javadoc)
276      * @see org.crosswire.jsword.passage.Key#blur(int, org.crosswire.jsword.passage.RestrictionType)
277      */
278     public void blur(int by, RestrictionType restrict) {
279     }
280 
281     /**
282      * Serialization ID
283      */
284     private static final long serialVersionUID = -2782112117361556089L;
285 }
286