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

Last change on this file since 31230 was 31230, checked in by ak19, 7 years ago

Commit for GS3 server side part of OAI deletion police implementation. Still to implement the GS2 server side part. The earlier commits implemented the PERL side, the oai-inf db implementation. I think I've now got the GS3 server side working, but have yet to try validating against the OAI validator. (I need to test that on a machine that is publicly accessible).

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