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: DefaultBookMetaData.java 2090 2011-03-07 04:13:05Z dmsmith $
21   */
22  package org.crosswire.jsword.book.basic;
23  
24  import java.util.Map;
25  
26  import org.crosswire.common.util.Language;
27  import org.crosswire.common.util.StringUtil;
28  import org.crosswire.common.xml.XMLUtil;
29  import org.crosswire.jsword.book.Book;
30  import org.crosswire.jsword.book.BookCategory;
31  import org.crosswire.jsword.book.BookDriver;
32  import org.crosswire.jsword.book.BookMetaData;
33  import org.crosswire.jsword.book.OSISUtil;
34  import org.crosswire.jsword.index.IndexManager;
35  import org.crosswire.jsword.index.IndexManagerFactory;
36  import org.crosswire.jsword.index.IndexStatus;
37  import org.jdom.Document;
38  import org.jdom.Element;
39  
40  /**
41   * DefaultBookMetaData is an implementation of the of the BookMetaData
42   * interface. A less complete implementation design for inheritance is available
43   * in AbstractBookMetaData where the complexity is in the setup rather than the
44   * inheritance. DefaultBookMetaData is probably the preferred implementation.
45   * 
46   * @see gnu.lgpl.License for license details.<br>
47   *      The copyright to this program is held by it's authors.
48   * @author Joe Walker [joe at eireneh dot com]
49   */
50  public class DefaultBookMetaData extends AbstractBookMetaData {
51      /**
52       * Ctor with a properties from which to get values. A call to setBook() is
53       * still required after this ctor is called
54       */
55      public DefaultBookMetaData(BookDriver driver, Book book, Map<String, Object> prop) {
56          setDriver(driver);
57  
58          setProperties(prop);
59          setName((String) prop.get(BookMetaData.KEY_NAME));
60          setType((String) prop.get(BookMetaData.KEY_CATEGORY));
61          String lang = (String) prop.get(BookMetaData.KEY_XML_LANG);
62          setLanguage(new Language(lang));
63  
64          IndexManager imanager = IndexManagerFactory.getIndexManager();
65          if (imanager.isIndexed(book)) {
66              setIndexStatus(IndexStatus.DONE);
67          } else {
68              setIndexStatus(IndexStatus.UNDONE);
69          }
70      }
71  
72      /**
73       * Ctor with some default values. A call to setBook() is still required
74       * after this ctor is called
75       */
76      public DefaultBookMetaData(BookDriver driver, String name, BookCategory type) {
77          setDriver(driver);
78          setName(name);
79          setBookCategory(type);
80          setLanguage(new Language(null)); // Default language
81      }
82  
83      /*
84       * (non-Javadoc)
85       * 
86       * @see org.crosswire.jsword.book.BookMetaData#getType()
87       */
88      public BookCategory getBookCategory() {
89          return type;
90      }
91  
92      /*
93       * (non-Javadoc)
94       * 
95       * @see org.crosswire.jsword.book.BookMetaData#getName()
96       */
97      public String getName() {
98          return name;
99      }
100 
101     /*
102      * (non-Javadoc)
103      * 
104      * @see org.crosswire.jsword.book.BookMetaData#getInitials()
105      */
106     public String getInitials() {
107         return initials;
108     }
109 
110     /*
111      * (non-Javadoc)
112      * 
113      * @see org.crosswire.jsword.book.BookMetaData#isLeftToRight()
114      */
115     public boolean isLeftToRight() {
116         return getLanguage().isLeftToRight();
117     }
118 
119     /**
120      * See note on setName() for side effect on setInitials(). If a value of
121      * null is used then the initials are defaulted using the name
122      * 
123      * @see DefaultBookMetaData#setName(String)
124      * @param initials
125      *            The initials to set.
126      */
127     public void setInitials(String initials) {
128         if (initials == null) {
129             if (name == null) {
130                 this.initials = "";
131             } else {
132                 this.initials = StringUtil.getInitials(name);
133             }
134         } else {
135             this.initials = initials;
136         }
137 
138         putProperty(KEY_INITIALS, this.initials);
139     }
140 
141     /**
142      * Setting the name also sets some default initials, so if you wish to set
143      * some specific initials then it should be done after setting the name.
144      * 
145      * @see DefaultBookMetaData#setInitials(String)
146      * @param name
147      *            The name to set.
148      */
149     public void setName(String name) {
150         this.name = name;
151 
152         putProperty(KEY_NAME, this.name);
153 
154         setInitials(StringUtil.getInitials(name));
155     }
156 
157     /**
158      * @param aType
159      *            The type to set.
160      */
161     public void setBookCategory(BookCategory aType) {
162         BookCategory t = aType;
163         if (t == null) {
164             t = BookCategory.BIBLE;
165         }
166         type = t;
167 
168         putProperty(KEY_CATEGORY, type);
169     }
170 
171     /**
172      * @param typestr
173      *            The string version of the type to set.
174      */
175     public void setType(String typestr) {
176         BookCategory newType = null;
177         if (typestr != null) {
178             newType = BookCategory.fromString(typestr);
179         }
180 
181         setBookCategory(newType);
182     }
183 
184     /*
185      * (non-Javadoc)
186      * 
187      * @see org.crosswire.jsword.book.BookMetaData#toOSIS()
188      */
189     @Override
190     public Document toOSIS() {
191         OSISUtil.OSISFactory factory = OSISUtil.factory();
192         Element ele = factory.createTable();
193         addRow(ele, "Initials", getInitials());
194         addRow(ele, "Description", getName());
195         addRow(ele, "Key", getBookCategory().toString());
196         addRow(ele, "Language", getLanguage().getName());
197         return new Document(ele);
198     }
199 
200     private void addRow(Element table, String key, String value) {
201         if (value == null) {
202             return;
203         }
204 
205         OSISUtil.OSISFactory factory = OSISUtil.factory();
206 
207         Element rowEle = factory.createRow();
208 
209         Element nameEle = factory.createCell();
210         Element hiEle = factory.createHI();
211         hiEle.setAttribute(OSISUtil.OSIS_ATTR_TYPE, OSISUtil.HI_BOLD);
212         nameEle.addContent(hiEle);
213         Element valueElement = factory.createCell();
214         rowEle.addContent(nameEle);
215         rowEle.addContent(valueElement);
216 
217         // I18N(DMS): use name to lookup translation.
218         hiEle.addContent(key);
219 
220         String expandedValue = XMLUtil.escape(value);
221         valueElement.addContent(expandedValue);
222 
223         table.addContent(rowEle);
224     }
225 
226     private BookCategory type;
227     private String name;
228     private String initials;
229 }
230