source: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GDBMWrapper.java@ 31665

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

GS3 source code now updated to use SafeProcess instead of Process (calling Runtime.exec() directly). The use of SafeProcess in RunTarget and BrowserLauncher has been tested on Linux. GDBMWrapper, MapRetrieve and admin/guiext's Command.java are not tested. For GDBMWrapper, because it's in a bit of code that works with txtgz databases. MapRetrive.java and Command.java are untested because I don't know how to test them.

  • Property svn:keywords set to Author Date Id Revision
File size: 9.4 KB
Line 
1/*
2 * GDBMWrapper.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 au.com.pharos.gdbm.GdbmFile;
22import au.com.pharos.packing.*;
23import au.com.pharos.gdbm.GdbmException;
24
25import org.apache.log4j.Logger;
26
27import java.io.UnsupportedEncodingException;
28import java.io.File;
29import java.util.ArrayList;
30
31import org.greenstone.util.SafeProcess;
32
33/**
34 * java wrapper class for gdbm - uses Java-GDBM written by Martin Pool replaces
35 * gdbmclass in the old version
36 */
37
38public class GDBMWrapper implements FlatDatabaseWrapper
39{
40
41 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.util.GDBMWrapper.class.getName());
42
43 static
44 {
45 /** Register this Wrapper with the DBHelper */
46 DBHelper.registerDBTypeExt("gdbm",".gdb");
47 }
48
49 /*
50 * GdbmFile modes: READER - read access, many readers may share the database
51 * WRITER - read/write access, exclusive access WRCREAT - read/write access,
52 * create db if doesn't exist NEWDB - read/write access, db should be
53 * replaced if exists
54 */
55
56 protected GdbmFile db_ = null;
57
58 /**
59 * open the database filename, with mode mode - uses the constants above, eg
60 * GdbmFile.WRITER
61 */
62 public boolean openDatabase(String filename, int mode)
63 {
64 // need to convert mode to GdbmFile mode
65 if (mode == READ)
66 {
67 mode = GdbmFile.READER;
68 }
69 else if (mode == WRITE)
70 {
71 mode = GdbmFile.WRITER;
72 }
73 else
74 {
75 logger.error("invalid mode, " + mode + ", opening db for reading only");
76 mode = GdbmFile.READER;
77 }
78 try
79 {
80 if (db_ != null)
81 {
82 db_.close();
83 }
84
85 // The java version of the C++ code in common-src/src/lib/gdbmclass.cpp
86 if (mode == GdbmFile.READER)
87 {
88 // Looking to read in the database
89 // we now use gdb extension. Check for ldb/bdb in case of legacy collection
90 // if not (first time) then generate using txt2db
91 if (!new File(filename).exists())
92 {
93 logger.warn("Database file " + filename + " does not exist. Looking for ldb/bdb version");
94 int extension = filename.lastIndexOf('.');
95 String filename_head = filename.substring(0, extension);
96 filename = filename_head + ".ldb";
97 if (!new File(filename).exists())
98 {
99 filename = filename_head + ".bdb";
100
101 if (!new File(filename).exists())
102 {
103 logger.warn("ldb/bdb version of database file " + filename + " does not exist. Looking for txtgz version of db file.");
104 // put the filename back to gdb
105 filename = filename_head + ".gdb";
106 // need to generate architecture native GDBM file using txt2db
107
108 // replace sought after gdbm filename ext with ".txt.gz"
109
110 String txtgzFilename = filename_head + ".txt.gz";
111 if (new File(txtgzFilename).exists())
112 {
113 // Test to make sure Perl is on the path
114 // On Linux, the output of the test goes to STDOUT so redirect it to STDERR
115 String cmdTest = "perl -v 2>&1";
116 //String cmdTest = "echo %PATH%";
117
118 //int returnValue = Processing.runProcess(cmdTest);
119
120 // replace Processing.java with SafeProcess.java
121 // so retain the same behaviour (logging)
122 SafeProcess process = new SafeProcess(cmdTest);
123 logger.error("executing command "+cmdTest);
124 int returnValue = process.runProcess();
125 // do something with the messages
126 logger.error("err>"+process.getStdError());
127 logger.error("out>"+process.getStdOutput());
128 process = null;
129
130 if (returnValue != 0)
131 {
132 logger.error("Tried to find Perl. Return exit value of running " + cmdTest + ": " + returnValue + ", (expected this to be 0)");
133 logger.error("Check that Perl is set in your PATH environment variable.");
134 //log.error("At present, PATH=" + System.getenv("PATH"));
135 }
136
137 String cmd = "perl -S txtgz-to-gdbm.pl \"" + txtgzFilename + "\" \"" + filename + "\"";
138 //returnValue = Processing.runProcess(cmd);
139
140 // replace Processing.java with SafeProcess.java
141 // so retain the same behaviour (logging)
142 process = new SafeProcess(cmd);
143 logger.error("executing command "+cmd);
144 returnValue = process.runProcess();
145 // do something with the messages
146 logger.error("err>"+process.getStdError());
147 logger.error("out>"+process.getStdOutput());
148 process = null;
149
150 // For some reason, launching this command with gsdl_system() still returns 1
151 // even when it returns 0 when run from the command-line. We can check whether
152 // we succeeded by looking at whether the output database file was created.
153 if (returnValue != 0)
154 {
155 logger.warn("Warning, non-zero return value on running command \"" + cmd + "\": " + returnValue);
156 if (!new File(filename).exists())
157 {
158 logger.error("Tried to run command \"" + cmd + "\", but it failed");
159 }
160 }
161 }
162 }
163 }
164
165 }
166 }
167
168 db_ = new GdbmFile(filename, mode);
169 }
170 catch (GdbmException e)
171 { // the database wasn't opened or created
172 logger.error("couldn't open database " + filename);
173 return false;
174 }
175 db_.setKeyPacking(new StringPacking());
176 db_.setValuePacking(new StringPacking());
177 return true;
178 }
179
180 /** close the database associated with this wrapper */
181 public void closeDatabase()
182 {
183 try
184 {
185 if (db_ != null)
186 {
187 db_.close();
188 db_ = null;
189 if (System.getProperty("os.name").startsWith("Windows"))
190 {
191 //Hack: force Windows to let go of the gdb file
192 System.gc();
193 }
194 }
195 }
196 catch (GdbmException e)
197 {
198 // should never get here - close never actually throws an exception
199 logger.error("error on close()");
200 }
201 }
202
203 public String getValue(String key)
204 {
205 if (db_ == null)
206 {
207 return null;
208 }
209 String s_info = null;
210 try
211 {
212 try
213 {
214 // The key is UTF8: do db lookup using the UTF8 version of key
215 if (db_.exists(key.getBytes("UTF-8")))
216 {
217 s_info = (String) db_.fetch(key.getBytes("UTF-8"));
218 }
219 }
220 catch (UnsupportedEncodingException e)
221 {
222 logger.warn("utf8 key for " + key + " unrecognised. Retrying with default encoding.");
223 // retry db lookup using default encoding of key instead of UTF8
224 s_info = (String) db_.fetch(key);
225 }
226 }
227 catch (GdbmException e)
228 {
229 logger.error("couldn't get record");
230 return null;
231 }
232 if (s_info == null)
233 {
234 // record not present
235 logger.error("key " + key + " not present in db");
236 return null;
237 }
238 return s_info;
239 }
240
241 /**
242 * sets the given key to the given value in the database
243 */
244 public boolean setValue(String key, String value)
245 {
246 if (db_ == null || !db_.isWritable())
247 {
248 logger.error("GDBM database is either null or not writable");
249 return false;
250 }
251
252 try
253 {
254 db_.store(key, value);
255 }
256 catch (GdbmException ex)
257 {
258 logger.error("Error storing " + key + " = " + value + " in GDBM database");
259 logger.error("Error message is: " + ex.getMessage());
260 return false;
261 }
262 return true;
263 }
264
265 /**
266 * deletes the entry for given key
267 */
268 public boolean deleteKey(String key)
269 {
270 if (db_ == null)
271 {
272 logger.error("GDBM database is null");
273 return false;
274 }
275
276 try
277 {
278 db_.delete(key);
279 }
280 catch (GdbmException ex)
281 {
282 logger.error("Error deleting key " + key + " from the database");
283 logger.error("Error message is: " + ex.getMessage());
284 return false;
285 }
286
287 return true;
288 }
289
290 /** Returns all the keys of the database as Strings */
291 public ArrayList<String> getAllEntryKeys() {
292
293 ArrayList<String> keys = new ArrayList<String>();
294
295 try {
296 java.util.Enumeration e = db_.keys();
297 while (e.hasMoreElements()) {
298
299 Object key = e.nextElement();
300 keys.add((String)key);
301
302 }
303 } catch (Exception e) {
304 logger.error("Exception encountered when trying to GDBMWrapper.getAllEntries():" + e);
305 }
306
307 return keys;
308 }
309
310
311 /**
312 * returns a string of key-value entries that can be printed for debugging
313 * purposes.
314 */
315 public String displayAllEntries()
316 {
317 StringBuffer output = new StringBuffer();
318 try
319 {
320 java.util.Enumeration e = db_.keys();
321 while (e.hasMoreElements())
322 {
323 Object key = e.nextElement();
324 Object value = db_.fetch(key);
325
326 output.append("key href: ");
327 output.append((String) key);
328 output.append("\tvalue ID: ");
329 output.append((String) value);
330 output.append("\n");
331 //logger.warn("key: " + key + "\tvalue: " + value);
332
333 String urlkey = java.net.URLEncoder.encode((String) key, "UTF8");
334 output.append("URL encoded key: " + urlkey);
335 //logger.warn("URL encoded key: " + urlkey);
336 }
337 }
338 catch (UnsupportedEncodingException e)
339 {
340 logger.warn("Trouble converting key to UTF-8.");
341 }
342 catch (Exception e)
343 {
344 logger.warn("Exception encountered when trying to displayAllEntries():" + e);
345 }
346 return output.toString();
347 }
348}
Note: See TracBrowser for help on using the repository browser.