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 as published by
5    * the Free Software Foundation. This program is distributed in the hope
6    * that it will be useful, but WITHOUT ANY WARRANTY; without even the
7    * 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: 2005
18   *     The copyright to this program is held by it's authors.
19   *
20   * ID: $Id: SwordDictionary.java 1887 2008-07-08 03:15:12Z dmsmith $
21   */
22  package org.crosswire.jsword.book.sword;
23  
24  import java.util.ArrayList;
25  import java.util.Iterator;
26  import java.util.List;
27  
28  import org.crosswire.common.activate.Activator;
29  import org.crosswire.common.activate.Lock;
30  import org.crosswire.jsword.book.BookException;
31  import org.crosswire.jsword.book.OSISUtil;
32  import org.crosswire.jsword.book.basic.AbstractBook;
33  import org.crosswire.jsword.book.filter.FilterException;
34  import org.crosswire.jsword.passage.DefaultKeyList;
35  import org.crosswire.jsword.passage.DefaultLeafKeyList;
36  import org.crosswire.jsword.passage.Key;
37  import org.crosswire.jsword.passage.NoSuchKeyException;
38  import org.jdom.Element;
39  
40  /**
41   * A Sword version of Dictionary.
42   *
43   * @see gnu.lgpl.License for license details.
44   *      The copyright to this program is held by it's authors.
45   * @author Joe Walker [joe at eireneh dot com]
46   */
47  public class SwordDictionary extends AbstractBook
48  {
49      /**
50       * Start and to as much checking as we can without using memory.
51       * (i.e. actually reading the indexes)
52       */
53      protected SwordDictionary(SwordBookMetaData sbmd, AbstractBackend backend)
54      {
55          super(sbmd);
56  
57          this.sbmd = sbmd;
58          this.backend = (AbstractKeyBackend) backend;
59          active = false;
60      }
61  
62      /* (non-Javadoc)
63       * @see org.crosswire.jsword.book.Book#getOsisIterator(org.crosswire.jsword.passage.Key, boolean)
64       */
65      public Iterator getOsisIterator(Key key, boolean allowEmpty) throws BookException
66      {
67          checkActive();
68  
69          assert key != null;
70          assert backend != null;
71  
72          try
73          {
74              List content = new ArrayList();
75              Element title = OSISUtil.factory().createTitle();
76              title.addContent(key.getName());
77              content.add(title);
78  
79              String txt = backend.getRawText(key);
80  
81              List osisContent = sbmd.getFilter().toOSIS(this, key, txt);
82              content.addAll(osisContent);
83  
84              return content.iterator();
85          }
86          catch (FilterException ex)
87          {
88              throw new BookException(Msg.FILTER_FAIL, ex);
89          }
90      }
91  
92      /* (non-Javadoc)
93       * @see org.crosswire.jsword.book.Book#contains(org.crosswire.jsword.passage.Key)
94       */
95      public boolean contains(Key key)
96      {
97          return backend != null && backend.contains(key);
98      }
99  
100     /* (non-Javadoc)
101      * @see org.crosswire.jsword.book.Book#getRawText(org.crosswire.jsword.passage.Key)
102      */
103     public String getRawText(Key key) throws BookException
104     {
105         checkActive();
106 
107         assert key != null;
108         assert backend != null;
109 
110         return backend.getRawText(key);
111     }
112 
113     /* (non-Javadoc)
114      * @see org.crosswire.jsword.book.Book#isWritable()
115      */
116     public boolean isWritable()
117     {
118         return backend.isWritable();
119     }
120 
121     /* (non-Javadoc)
122      * @see org.crosswire.jsword.book.basic.AbstractPassageBook#setRawText(org.crosswire.jsword.passage.Key, java.lang.String)
123      */
124     public void setRawText(Key key, String rawData) throws BookException
125     {
126         throw new BookException(Msg.DRIVER_READONLY);
127     }
128 
129     /* (non-Javadoc)
130      * @see org.crosswire.jsword.book.Book#setAliasKey(org.crosswire.jsword.passage.Key, org.crosswire.jsword.passage.Key)
131      */
132     public void setAliasKey(Key alias, Key source) throws BookException
133     {
134         throw new BookException(Msg.DRIVER_READONLY);
135     }
136 
137     /* (non-Javadoc)
138      * @see org.crosswire.jsword.passage.KeyFactory#getGlobalKeyList()
139      */
140     public Key getGlobalKeyList()
141     {
142         checkActive();
143 
144         return backend;
145     }
146 
147     /* (non-Javadoc)
148      * @see org.crosswire.jsword.passage.KeyFactory#isValidKey(java.lang.String)
149      */
150     public Key getValidKey(String name)
151     {
152         try
153         {
154             return getKey(name);
155         }
156         catch (NoSuchKeyException e)
157         {
158             return createEmptyKeyList();
159         }
160     }
161 
162     /* (non-Javadoc)
163      * @see org.crosswire.jsword.passage.KeyFactory#getKey(java.lang.String)
164      */
165     public Key getKey(String text) throws NoSuchKeyException
166     {
167         checkActive();
168 
169         int pos = backend.indexOf(new DefaultLeafKeyList(text));
170         if (pos < 0)
171         {
172             if (backend.getCardinality() > -pos - 1)
173             {
174                 return backend.get(-pos - 1);
175             }
176             return backend.get(backend.getCardinality() - 1);
177         }
178         return backend.get(pos);
179     }
180 
181     /* (non-Javadoc)
182      * @see org.crosswire.jsword.passage.KeyFactory#getEmptyKeyList()
183      */
184     public Key createEmptyKeyList()
185     {
186         return new DefaultKeyList();
187     }
188 
189     /* (non-Javadoc)
190      * @see org.crosswire.common.activate.Activatable#activate(org.crosswire.common.activate.Lock)
191      */
192     /* @Override */
193     public final void activate(Lock lock)
194     {
195         super.activate(lock);
196         active = true;
197 
198         // We don't need to activate the backend because it should be capable
199         // of doing it for itself.
200     }
201 
202     /* (non-Javadoc)
203      * @see org.crosswire.common.activate.Activatable#deactivate(org.crosswire.common.activate.Lock)
204      */
205     /* @Override */
206     public final void deactivate(Lock lock)
207     {
208         super.deactivate(lock);
209         Activator.deactivate(backend);
210         active = false;
211     }
212 
213     /**
214      * Helper method so we can quickly activate ourselves on access
215      */
216     private void checkActive()
217     {
218         if (!active)
219         {
220             Activator.activate(this);
221         }
222     }
223 
224     /**
225      * Are we active
226      */
227     private boolean active;
228 
229     /**
230      * To read the data from the disk
231      */
232     private AbstractKeyBackend backend;
233 
234     /**
235      * The Sword configuration file
236      */
237     private SwordBookMetaData sbmd;
238 }
239