source: greenstone3/branches/customizingGreenstone3/src/java/org/greenstone/gsdl3/util/GDBMWrapper.java@ 15191

Last change on this file since 15191 was 15191, checked in by dmn, 16 years ago

updating branch from trunk

  • Property svn:keywords set to Author Date Id Revision
File size: 7.9 KB
Line 
1package org.greenstone.gsdl3.util;
2
3import au.com.pharos.gdbm.GdbmFile;
4import au.com.pharos.packing.*;
5import au.com.pharos.gdbm.GdbmException;
6
7import org.apache.log4j.*;
8
9/** java wrapper class for gdbm - uses Java-GDBM written by Martin Pool
10 * replaces gdbmclass in the old version
11 */
12
13public class GDBMWrapper {
14
15 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.util.GDBMWrapper.class.getName());
16
17
18 // Values must match those from gdbm.h - uses the definitions from GdbmFile !
19 /** Indicates that the caller will just read the database. Many
20 * readers may share a database. */
21 public final static int READER = GdbmFile.READER;
22
23 /** The caller wants read/write access to an existing database and
24 * requires exclusive access. */
25 public final static int WRITER = GdbmFile.WRITER;
26
27 /** The caller wants exclusive read/write access, and the database
28 * should be created if it does not already exist. */
29 public final static int WRCREAT = GdbmFile.WRCREAT;
30
31 /** The caller wants exclusive read/write access, and the database
32 * should be replaced if it already exists. */
33 public final static int NEWDB = GdbmFile.NEWDB;
34
35 protected GdbmFile db_=null;
36
37 /** open the database filename, with mode mode - uses the constants
38 above, eg GdbmFile.WRITER */
39 public boolean openDatabase(String filename, int mode){
40 try {
41 if (db_!=null) {
42 db_.close();
43 }
44 db_ = new GdbmFile(filename, mode);
45 } catch ( GdbmException e) { // the database wasn't opened or created
46 logger.error("couldn't open database "+filename);
47 return false;
48 }
49 db_.setKeyPacking(new StringPacking());
50 db_.setValuePacking(new StringPacking());
51 return true;
52 }
53
54 /** close the database associated with this wrapper */
55 public void closeDatabase() {
56 try {
57 if (db_ != null) {
58 db_.close();
59 db_ = null;
60 }
61 } catch (GdbmException e) {
62 // should never get here - close never actually throws an exception
63 logger.error("error on close()");
64 }
65 }
66
67 /** returns a DBInfo object containing all the name-value pairs for
68 * main_key
69 * @see DBInfo
70 */
71 public DBInfo getInfo(String main_key) {
72 if (db_==null) {
73 return null;
74 }
75 String s_info;
76 try {
77 s_info = (String)db_.fetch(main_key);
78 } catch (GdbmException e) {
79 logger.error("couldn't get record");
80 return null;
81 }
82 if (s_info==null) {
83 // record not present
84 logger.error("key "+main_key+" not present in db");
85 return null;
86 }
87 DBInfo info = new DBInfo();
88
89 String [] lines = s_info.split("\n");
90 String key;
91 String value;
92 for (int i=0; i<lines.length; i++) {
93 logger.debug("line:"+lines[i]);
94 int a = lines[i].indexOf('<');
95 int b= lines[i].indexOf('>');
96 if (a==-1 || b==-1) {
97 logger.error("bad format in db");
98 }
99 else {
100 key=lines[i].substring(a+1, b);
101 value=lines[i].substring(b+1);
102 logger.debug("key="+key+", val="+value);
103 info.addInfo(key, value);
104
105 }
106 }
107 return info;
108 }
109
110 /** sets all the name-value pairs in info as the content for key key
111 * TODO - not implemented yet */
112 public boolean setInfo(String key, DBInfo info) {
113 if (db_==null) {
114 return false;
115 }
116 return true;
117 }
118 /** sets the key value as info
119 * TODO - not implemented yet */
120 public boolean setInfo (String key, String info) {
121 if (db_==null) {
122 return false;
123 }
124 return true;
125 }
126 /** deletes the entry for key
127 * TODO - not implemented yet */
128 public boolean deleteKey(String key) {
129 if (db_==null) {
130 return false;
131 }
132 return true;
133 }
134
135 // greenstone convenience methods - should these go into a separate class?
136 // yes I think so.
137 /** converts a greenstone OID to internal docnum */
138 public long OID2Docnum(String OID) {
139 DBInfo info = getInfo(OID);
140 if (info != null) {
141 long real_num = Long.parseLong(info.getInfo("docnum"));
142 return real_num;
143 }
144 return -1;
145 }
146 /** converts a docnum to greenstone OID */
147 public String docnum2OID(long docnum) {
148 return docnum2OID(Long.toString(docnum));
149 }
150
151 /** converts a docnum to greenstone OID */
152 public String docnum2OID(String docnum) {
153 DBInfo info = getInfo(docnum);
154 if (info!=null){
155 String oid = info.getInfo("section");
156 return oid;
157 }else{
158 return null;
159 }
160 }
161
162 /** converts an external id to greenstone OID */
163 public String externalId2OID(String extid) {
164 DBInfo info = getInfo(extid);
165 if (info != null) {
166 String oid = info.getInfo("section");
167 return oid;
168 }
169 return null;
170 }
171 /** translates relative oids into proper oids:
172 * .pr (parent), .rt (root) .fc (first child), .lc (last child),
173 * .ns (next sibling), .ps (previous sibling)
174 * .np (next page), .pp (previous page) : links sections in the order that you'd read the document
175 * a suffix is expected to be present so test before using
176 */
177 public String translateOID(String oid) {
178
179 int p = oid.lastIndexOf('.');
180 if (p != oid.length()-3) {
181 logger.info("translateoid error: '.' is not the third to last char!!");
182 return oid;
183 }
184
185 String top = oid.substring(0, p);
186 String suff = oid.substring(p+1);
187 // just in case we have multiple extensions, we must translate
188 // we process inner ones first
189 if (OID.needsTranslating(top)) {
190 top = translateOID(top);
191 }
192 if (suff.equals("pr")) {
193 return OID.getParent(top);
194 }
195 if (suff.equals("rt")) {
196 return OID.getTop(top);
197 }
198 if (suff.equals("np")) {
199 // try first child
200 String node_id = translateOID(top+".fc");
201 if (!node_id.equals(top)) {
202 return node_id;
203 }
204 // try next sibling
205 node_id = translateOID(top+".ns");
206 if (!node_id.equals(top)) {
207 return node_id;
208 }
209 // otherwise we keep trying parents sibling
210 String child_id = top;
211 String parent_id = OID.getParent(child_id);
212 while(!parent_id.equals(child_id)) {
213 node_id = translateOID(parent_id+".ns");
214 if (!node_id.equals(parent_id)) {
215 return node_id;
216 }
217 child_id = parent_id;
218 parent_id = OID.getParent(child_id);
219 }
220 return top; // we couldn't get a next page, so just return the original
221 }
222 if (suff.equals("pp")) {
223 String prev_sib = translateOID(top+".ps");
224 if (prev_sib.equals(top)) {
225 // no previous sibling, so return the parent
226 return OID.getParent(top);
227 }
228 // there is a previous sibling, so its either this section, or the last child of the last child..
229 String last_child = translateOID(prev_sib+".lc");
230 while (!last_child.equals(prev_sib)) {
231 prev_sib = last_child;
232 last_child = translateOID(prev_sib+".lc");
233 }
234 return last_child;
235 }
236
237 int sibling_num = 0;
238 if (suff.equals("ss")) {
239 // we have to remove the sib num before we get top
240 p = top.lastIndexOf('.');
241 sibling_num = Integer.parseInt(top.substring(p+1));
242 top = top.substring(0, p);
243 }
244
245 // need to get info out of gdbm db -
246 String doc_id = top;
247 if (suff.endsWith("s")) {
248 doc_id = OID.getParent(top);
249 if (doc_id.equals(top)) {
250 // i.e. we are already at the top
251 return top;
252 }
253 }
254 DBInfo info = getInfo(doc_id);
255 if (info==null) {
256 logger.info("info is null!!");
257 return top;
258 }
259
260 String contains = info.getInfo("contains");
261 if (contains.equals("")) {
262 // something is wrong
263 return top;
264 }
265 contains = contains.replaceAll("\"", doc_id);
266 String [] children = contains.split(";");
267 if (suff.equals("fc")) {
268 return children[0];
269 } else if (suff.equals("lc")) {
270 return children[children.length-1];
271 } else {
272 if (suff.equals("ss")) {
273 return children[sibling_num-1];
274 }
275 // find the position that we are at.
276 int i=0;
277 while (i<children.length) {
278 if (children[i].equals(top)) {
279 break;
280 }
281 i++;
282 }
283
284 if (suff.equals("ns")) {
285 if (i==children.length-1) {
286 return children[i];
287 }
288 return children[i+1];
289 } else if (suff.equals("ps")) {
290 if (i==0) {
291 return children[i];
292 }
293 return children[i-1];
294 }
295 }
296
297 return top;
298 }
299}
Note: See TracBrowser for help on using the repository browser.