Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
ConfigEntryTable |
|
| 1.3333333333333333;1.333 |
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 | * © CrossWire Bible Society, 2005 - 2016 | |
18 | * | |
19 | */ | |
20 | package org.crosswire.jsword.book.sword; | |
21 | ||
22 | /** | |
23 | * A utility class for loading the entries in a Sword book's conf file. Since | |
24 | * the conf files are manually maintained, there can be all sorts of errors in | |
25 | * them. This class does robust checking and reporting. | |
26 | * <p/> | |
27 | * <p/> | |
28 | * Config file format. See also: <a href= | |
29 | * "http://sword.sourceforge.net/cgi-bin/twiki/view/Swordapi/ConfFileLayout"> | |
30 | * http://sword.sourceforge.net/cgi-bin/twiki/view/Swordapi/ConfFileLayout</a> | |
31 | * <p/> | |
32 | * <p/> | |
33 | * The contents of the About field are in rtf. | |
34 | * <p/> | |
35 | * \ is used as a continuation line. | |
36 | * | |
37 | * @author Mark Goodwin | |
38 | * @author Joe Walker | |
39 | * @author Jacky Cheung | |
40 | * @author DM Smith | |
41 | * @see gnu.lgpl.License The GNU Lesser General Public License for details.<br> | |
42 | * The copyright to this program is held by its authors. | |
43 | */ | |
44 | public final class ConfigEntryTable { | |
45 | ||
46 | /** | |
47 | * Create an empty Sword config for the named book. | |
48 | * | |
49 | * @param bookName the name of the book | |
50 | * @param isRootConfig true to indicate a root configuration | |
51 | */ | |
52 | public ConfigEntryTable(String bookName, boolean isRootConfig) { | |
53 | 0 | this(bookName, isRootConfig, null); |
54 | 0 | } |
55 | ||
56 | /** | |
57 | * Sometimes, we're creating the config off another config, and so need to ensure the initials match exactly. | |
58 | * | |
59 | * @param bookName the name of the book | |
60 | * @param isRootConfig true to indicate a root configuration | |
61 | * @param initials the set of initials used to identify this module. This could be different to the bookName (which may be lowercase) | |
62 | */ | |
63 | 0 | public ConfigEntryTable(String bookName, boolean isRootConfig, String initials) { |
64 | 0 | this.initials = initials == null ? bookName : initials; |
65 | 0 | } |
66 | ||
67 | /** | |
68 | * Build's a SWORD conf file as a string. The result is not identical to the | |
69 | * original, cleaning up problems in the original and re-arranging the | |
70 | * entries into a predictable order. | |
71 | * | |
72 | * @return the well-formed conf. | |
73 | */ | |
74 | public String toConf() { | |
75 | 0 | StringBuilder buf = new StringBuilder(); |
76 | 0 | buf.append('['); |
77 | 0 | buf.append(initials); |
78 | 0 | buf.append("]\n"); |
79 | /* | |
80 | toConf(buf, BASIC_INFO); | |
81 | toConf(buf, SYSTEM_INFO); | |
82 | toConf(buf, HIDDEN); | |
83 | toConf(buf, FEATURE_INFO); | |
84 | toConf(buf, LANG_INFO); | |
85 | toConf(buf, COPYRIGHT_INFO); | |
86 | toConf(buf, extra); | |
87 | */ | |
88 | 0 | return buf.toString(); |
89 | } | |
90 | ||
91 | /* | |
92 | protected void report() { | |
93 | Iterator<String> kIter = config.keySet().iterator(); | |
94 | while (kIter.hasNext()) { | |
95 | String key = kIter.next(); | |
96 | Iterator<String> vIter = config.getValues(key).iterator(); | |
97 | while (vIter.hasNext()) { | |
98 | String value = vIter.next(); | |
99 | ||
100 | // Only CIPHER_KEYS that are empty are not ignored | |
101 | if (value.length() == 0 && !SwordBookMetaData.KEY_CIPHER_KEY.equalsIgnoreCase(key)) { | |
102 | log.warn("Ignoring empty entry in [{}]{}=", initials, key); | |
103 | continue; | |
104 | } | |
105 | ||
106 | // Create a configEntry so that the name is normalized. | |
107 | ConfigEntry configEntry = new ConfigEntry(initials, key); | |
108 | ConfigEntryType type = configEntry.getType(); | |
109 | ConfigEntry e = null; // table.get(type); | |
110 | ||
111 | if (e == null) { | |
112 | if (type == null) { | |
113 | log.warn("Extra entry in [{}]{}", initials, configEntry.getName()); | |
114 | // extra.put(key, configEntry); | |
115 | } else if (type.isSynthetic()) { | |
116 | log.warn("Ignoring unexpected entry in [{}]{}", initials, configEntry.getName()); | |
117 | } else { | |
118 | // table.put(type, configEntry); | |
119 | } | |
120 | } else { | |
121 | configEntry = e; | |
122 | } | |
123 | // History is a special case it is of the form History_x.x | |
124 | // The config entry is History without the x.x. | |
125 | // We want to put x.x at the beginning of the string | |
126 | if (ConfigEntryType.HISTORY.equals(type)) { | |
127 | int pos = key.indexOf('_'); | |
128 | value = key.substring(pos + 1) + ' ' + value; | |
129 | } | |
130 | ||
131 | configEntry.addValue(value); | |
132 | ||
133 | // Filter known types of entries | |
134 | if (type != null) { | |
135 | value = type.filter(value); | |
136 | ||
137 | // Report on fields that shouldn't have RTF but do | |
138 | if (!type.allowsRTF() && RTF_PATTERN.matcher(value).find()) { | |
139 | log.info("Unexpected RTF for [{}]{} = {}", initials, key, value); | |
140 | } | |
141 | ||
142 | if (type.mayRepeat()) { | |
143 | if (!type.isAllowed(value)) { | |
144 | log.info("Unknown config value for [{}]{} = {}", initials, key, value); | |
145 | } | |
146 | } else { | |
147 | if (value != null) { | |
148 | log.info("Ignoring unexpected additional entry for [{}]{} = {}", initials, key, value); | |
149 | } else { | |
150 | if (!type.isAllowed(value)) { | |
151 | log.info("Unknown config value for [{}]{} = {}", initials, key, value); | |
152 | } | |
153 | } | |
154 | } | |
155 | } | |
156 | } | |
157 | } | |
158 | } | |
159 | */ | |
160 | ||
161 | /** | |
162 | * Build an ordered map so that it displays in a consistent order. | |
163 | */ | |
164 | /* | |
165 | private void toConf(StringBuilder buf, ConfigEntryType[] category) { | |
166 | for (int i = 0; i < category.length; i++) { | |
167 | ||
168 | String entry = table.get(category[i]); | |
169 | ||
170 | if (entry != null && !category[i].isSynthetic()) { | |
171 | String text = entry.toConf(); | |
172 | if (text != null && text.length() > 0) { | |
173 | buf.append(entry.toConf()); | |
174 | } | |
175 | } | |
176 | } | |
177 | } | |
178 | */ | |
179 | /** | |
180 | * Build an ordered map so that it displays in a consistent order. | |
181 | */ | |
182 | /* | |
183 | private void toConf(StringBuilder buf, Map<String, ConfigEntry> map) { | |
184 | for (Map.Entry<String, ConfigEntry> mapEntry : map.entrySet()) { | |
185 | ConfigEntry entry = mapEntry.getValue(); | |
186 | String text = entry.toConf(); | |
187 | if (text != null && text.length() > 0) { | |
188 | buf.append(text); | |
189 | } | |
190 | } | |
191 | } | |
192 | */ | |
193 | ||
194 | /** | |
195 | * The set of initials identifying this book | |
196 | */ | |
197 | private String initials; | |
198 | ||
199 | /** | |
200 | * A pattern of allowable RTF in a SWORD conf. These are: \pard, \pae, \par, \qc \b, \i and embedded Unicode | |
201 | */ | |
202 | // private static final Pattern RTF_PATTERN = Pattern.compile("\\\\pard|\\\\pa[er]|\\\\qc|\\\\[bi]|\\\\u-?[0-9]{4,6}+"); | |
203 | ||
204 | } |