source: trunk/gsdl3/src/java/org/greenstone/gsdl3/util/GDBMWrapper.java@ 13270

Last change on this file since 13270 was 13270, checked in by shaoqun, 17 years ago

replace Category class which is deprecated with Logger class

  • Property svn:keywords set to Author Date Id Revision
File size: 7.8 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 /** cloase 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 String oid = info.getInfo("section");
155 return oid;
156 }
157
158 /** converts an external id to greenstone OID */
159 public String externalId2OID(String extid) {
160 DBInfo info = getInfo(extid);
161 if (info != null) {
162 String oid = info.getInfo("section");
163 return oid;
164 }
165 return null;
166 }
167 /** translates relative oids into proper oids:
168 * .pr (parent), .rt (root) .fc (first child), .lc (last child),
169 * .ns (next sibling), .ps (previous sibling)
170 * .np (next page), .pp (previous page) : links sections in the order that you'd read the document
171 * a suffix is expected to be present so test before using
172 */
173 public String translateOID(String oid) {
174
175 int p = oid.lastIndexOf('.');
176 if (p != oid.length()-3) {
177 logger.info("translateoid error: '.' is not the third to last char!!");
178 return oid;
179 }
180
181 String top = oid.substring(0, p);
182 String suff = oid.substring(p+1);
183 // just in case we have multiple extensions, we must translate
184 // we process inner ones first
185 if (OID.needsTranslating(top)) {
186 top = translateOID(top);
187 }
188 if (suff.equals("pr")) {
189 return OID.getParent(top);
190 }
191 if (suff.equals("rt")) {
192 return OID.getTop(top);
193 }
194 if (suff.equals("np")) {
195 // try first child
196 String node_id = translateOID(top+".fc");
197 if (!node_id.equals(top)) {
198 return node_id;
199 }
200 // try next sibling
201 node_id = translateOID(top+".ns");
202 if (!node_id.equals(top)) {
203 return node_id;
204 }
205 // otherwise we keep trying parents sibling
206 String child_id = top;
207 String parent_id = OID.getParent(child_id);
208 while(!parent_id.equals(child_id)) {
209 node_id = translateOID(parent_id+".ns");
210 if (!node_id.equals(parent_id)) {
211 return node_id;
212 }
213 child_id = parent_id;
214 parent_id = OID.getParent(child_id);
215 }
216 return top; // we couldn't get a next page, so just return the original
217 }
218 if (suff.equals("pp")) {
219 String prev_sib = translateOID(top+".ps");
220 if (prev_sib.equals(top)) {
221 // no previous sibling, so return the parent
222 return OID.getParent(top);
223 }
224 // there is a previous sibling, so its either this section, or the last child of the last child..
225 String last_child = translateOID(prev_sib+".lc");
226 while (!last_child.equals(prev_sib)) {
227 prev_sib = last_child;
228 last_child = translateOID(prev_sib+".lc");
229 }
230 return last_child;
231 }
232
233 int sibling_num = 0;
234 if (suff.equals("ss")) {
235 // we have to remove the sib num before we get top
236 p = top.lastIndexOf('.');
237 sibling_num = Integer.parseInt(top.substring(p+1));
238 top = top.substring(0, p);
239 }
240
241 // need to get info out of gdbm db -
242 String doc_id = top;
243 if (suff.endsWith("s")) {
244 doc_id = OID.getParent(top);
245 if (doc_id.equals(top)) {
246 // i.e. we are already at the top
247 return top;
248 }
249 }
250 DBInfo info = getInfo(doc_id);
251 if (info==null) {
252 logger.info("info is null!!");
253 return top;
254 }
255
256 String contains = info.getInfo("contains");
257 if (contains.equals("")) {
258 // something is wrong
259 return top;
260 }
261 contains = contains.replaceAll("\"", doc_id);
262 String [] children = contains.split(";");
263 if (suff.equals("fc")) {
264 return children[0];
265 } else if (suff.equals("lc")) {
266 return children[children.length-1];
267 } else {
268 if (suff.equals("ss")) {
269 return children[sibling_num-1];
270 }
271 // find the position that we are at.
272 int i=0;
273 while (i<children.length) {
274 if (children[i].equals(top)) {
275 break;
276 }
277 i++;
278 }
279
280 if (suff.equals("ns")) {
281 if (i==children.length-1) {
282 return children[i];
283 }
284 return children[i+1];
285 } else if (suff.equals("ps")) {
286 if (i==0) {
287 return children[i];
288 }
289 return children[i-1];
290 }
291 }
292
293 return top;
294 }
295}
Note: See TracBrowser for help on using the repository browser.