source: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/SimpleCollectionDatabase.java@ 30263

Last change on this file since 30263 was 30263, checked in by jmt12, 9 years ago

Added an extra catch to report exceptions *other* than ClassNotFoundException when trying to dynamically load database wrapper class. Extended one other exception to show actual exception error message to aid in debugging certain errors only thrown when loading database wrappers outside the gsdl3.jar

File size: 8.0 KB
Line 
1/*
2 * SimpleCollectionDatabase.java
3 * Copyright (C) 2008 New Zealand Digital Library, http://www.nzdl.org
4 *
5 * This program 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 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program 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 this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19package org.greenstone.gsdl3.util;
20
21import java.util.Iterator;
22import java.util.Set;
23import java.util.Vector;
24
25import org.apache.log4j.*;
26
27import org.apache.commons.lang3.StringUtils;
28
29public class SimpleCollectionDatabase implements OID.OIDTranslatable
30{
31
32 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.util.SimpleCollectionDatabase.class.getName());
33
34 /* just read access, many readers can share a database */
35 public final static int READ = FlatDatabaseWrapper.READ;
36 /* read/write, exclusive access */
37 public final static int WRITE = FlatDatabaseWrapper.WRITE;
38
39 protected FlatDatabaseWrapper coll_db = null;
40
41 public SimpleCollectionDatabase(String db_type)
42 {
43 if (db_type.toLowerCase().endsWith("server")) {
44 db_type = db_type.substring(0, db_type.length() - 6);
45 }
46
47 // Access databaseWrapper through reflection (forName) so code
48 // can be more dynamic as to the database backends that are
49 // supported for this installation of Greenstone
50
51 String dbwrap_name = db_type.toUpperCase() + "Wrapper";
52 Class dbwrap_class = null;
53
54 try
55 {
56 String full_dbwrap_name = "org.greenstone.gsdl3.util." + dbwrap_name;
57 dbwrap_class = Class.forName(full_dbwrap_name);
58 }
59 catch (ClassNotFoundException e)
60 {
61 try
62 {
63 //try the dbwrap_name alone in case the package name is
64 //already specified
65 dbwrap_class = Class.forName(dbwrap_name);
66 }
67 catch (ClassNotFoundException ae)
68 {
69 logger.error("Couldn't create SimpleCollectionDatabase of type " + db_type);
70 logger.info(ae.getMessage());
71 }
72 }
73 catch (Exception ae) {
74 logger.error("Couldn't create SimpleCollectionDatabase of type " + db_type);
75 logger.info(ae.getMessage());
76 }
77
78 try
79 {
80 this.coll_db = (FlatDatabaseWrapper) dbwrap_class.newInstance();
81 }
82 catch (Exception e)
83 {
84 logger.error("Failed to call the constructor " + dbwrap_name + "()");
85 logger.info(e.getMessage());
86 }
87
88 }
89
90 public boolean databaseOK()
91 {
92 // Previously failed to open database
93 // Most likely cause is that this installation of Greenstone3 has not
94 // been compiled with support for this database type
95 return coll_db != null;
96 }
97
98 /**
99 * open the database filename, with mode mode - uses the FlatDatabaseWrapper
100 * modes
101 */
102 public boolean openDatabase(String filename, int mode)
103 {
104 return this.coll_db.openDatabase(filename, mode);
105 }
106
107 /** close the database */
108 public void closeDatabase()
109 {
110 this.coll_db.closeDatabase();
111 }
112
113 /**
114 * Returns a DBInfo structure of the key-value pairs associated with a
115 * particular main key in the database
116 */
117 public DBInfo getInfo(String main_key)
118 {
119 //logger.warn("All the entries of the db are:");
120 //this.coll_db.displayAllEntries();
121
122 if (this.coll_db == null)
123 {
124 // Most likely cause is that this installation of Greenstone3 has not
125 // been compiled with support for this database type
126 return null;
127 }
128
129 String key_info = this.coll_db.getValue(main_key);
130 if (key_info == null || key_info.equals(""))
131 {
132 return null;
133 }
134
135 DBInfo info = new DBInfo();
136 // add in the Identifier field // hack for OAI. useful for other things? or not???
137 info.addInfo("Identifier", main_key);
138 String[] lines = StringUtils.split(key_info, "\n");
139 String key;
140 String value;
141 for (int i = 0; i < lines.length; i++)
142 {
143 //logger.debug("line:" + lines[i]);
144 int a = lines[i].indexOf('<');
145 int b = lines[i].indexOf('>');
146 if (a == -1 || b == -1)
147 {
148 logger.error("bad format in db");
149 }
150 else
151 {
152 key = lines[i].substring(a + 1, b);
153 value = lines[i].substring(b + 1);
154 //logger.debug("key=" + key + ", val=" + value);
155 info.addInfo(key, value);
156 }
157 }
158
159 return info;
160 }
161
162 public boolean setInfo(String mainKey, DBInfo info)
163 {
164 StringBuilder valueToAdd = new StringBuilder();
165 Iterator<String> i = info.getKeys().iterator();
166 while (i.hasNext())
167 {
168 String currentKey = i.next();
169 Vector<String> currentValues = (Vector<String>)info.getMultiInfo(currentKey);
170
171 if(currentValues.size() == 0)
172 {
173 valueToAdd.append("<" + currentKey + ">\n");
174 continue;
175 }
176
177 for(int j = 0; j < currentValues.size(); j++)
178 {
179 valueToAdd.append("<" + currentKey + ">" + currentValues.get(j) + "\n");
180 }
181 }
182
183 //Remove the final \n
184 if (valueToAdd.length() > 0)
185 {
186 valueToAdd.delete(valueToAdd.length() - 1, valueToAdd.length());
187 }
188
189 return this.coll_db.setValue(mainKey, valueToAdd.toString());
190 }
191
192 public String getValue(String key)
193 {
194 return this.coll_db.getValue(key);
195 }
196
197 public boolean setValue(String key, String value)
198 {
199 return this.coll_db.setValue(key, value);
200 }
201
202 public boolean deleteKey(String key)
203 {
204 return this.coll_db.deleteKey(key);
205 }
206
207 /** converts a greenstone OID to internal docnum */
208 public String OID2Docnum(String OID)
209 {
210 DBInfo info = getInfo(OID);
211 if (info != null)
212 {
213 return info.getInfo("docnum");
214 }
215 return null;
216 }
217
218 /**
219 * converts a greenstone OID to an internal docnum, returning a Long -
220 * convenience method
221 */
222 public long OID2DocnumLong(String OID)
223 {
224 DBInfo info = getInfo(OID);
225 if (info != null)
226 {
227 long real_num = Long.parseLong(info.getInfo("docnum"));
228 return real_num;
229 }
230 return -1;
231 }
232
233 /** converts a docnum to greenstone OID */
234 public String docnum2OID(String docnum)
235 {
236 DBInfo info = getInfo(docnum);
237 if (info != null)
238 {
239 String oid = info.getInfo("section");
240 return oid;
241 }
242 else
243 {
244 return null;
245 }
246 }
247
248 /**
249 * converts a docnum to greenstone OID - convenience method
250 */
251 public String docnum2OID(long docnum)
252 {
253 return docnum2OID(Long.toString(docnum));
254 }
255
256 /** converts an external id to greenstone OID */
257 public String externalId2OID(String extid)
258 {
259 DBInfo info = getInfo(extid);
260 if (info != null)
261 {
262 String oid = info.getInfo("section");
263 return oid;
264 }
265 return null;
266 }
267
268 /**
269 * After OID.translateOID() is through, this method processes OID further to
270 * translate relative oids into proper oids: .pr (parent), .rt (root) .fc
271 * (first child), .lc (last child), .ns (next sibling), .ps (previous
272 * sibling) .np (next page), .pp (previous page) : links sections in the
273 * order that you'd read the document a suffix is expected to be present so
274 * test before using
275 */
276 public String processOID(String doc_id, String top, String suff, int sibling_num)
277 {
278 DBInfo info = getInfo(doc_id);
279 if (info == null)
280 {
281 logger.info("info is null!!");
282 return top;
283 }
284
285 String contains = info.getInfo("contains");
286 if (contains.equals(""))
287 {
288 // something is wrong
289 return top;
290 }
291 contains = StringUtils.replace(contains, "\"", doc_id);
292 String[] children = StringUtils.split(contains, ";");
293 if (suff.equals("fc"))
294 {
295 return children[0];
296 }
297 else if (suff.equals("lc"))
298 {
299 return children[children.length - 1];
300 }
301 else
302 {
303 if (suff.equals("ss"))
304 {
305 return children[sibling_num - 1];
306 }
307 // find the position that we are at.
308 int i = 0;
309 while (i < children.length)
310 {
311 if (children[i].equals(top))
312 {
313 break;
314 }
315 i++;
316 }
317
318 if (suff.equals("ns"))
319 {
320 if (i == children.length - 1)
321 {
322 return children[i];
323 }
324 return children[i + 1];
325 }
326 else if (suff.equals("ps"))
327 {
328 if (i == 0)
329 {
330 return children[i];
331 }
332 return children[i - 1];
333 }
334 }
335
336 return top;
337 }
338}
Note: See TracBrowser for help on using the repository browser.