Changeset 15325
- Timestamp:
- 2008-05-01T13:57:15+12:00 (16 years ago)
- Location:
- greenstone3/trunk/src/java/org/greenstone/gsdl3/util
- Files:
-
- 3 added
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
greenstone3/trunk/src/java/org/greenstone/gsdl3/util/GDBMWrapper.java
r15010 r15325 5 5 import au.com.pharos.gdbm.GdbmException; 6 6 7 import org.apache.log4j. *;7 import org.apache.log4j.Logger; 8 8 9 9 /** java wrapper class for gdbm - uses Java-GDBM written by Martin Pool … … 11 11 */ 12 12 13 public class GDBMWrapper { 13 public class GDBMWrapper 14 implements FlatDatabaseWrapper { 14 15 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; 16 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.util.GDBMWrapper.class.getName()); 17 18 /* GdbmFile modes: 19 READER - read access, many readers may share the database 20 WRITER - read/write access, exclusive access 21 WRCREAT - read/write access, create db if doesn't exist 22 NEWDB - read/write access, db should be replaced if exists 23 */ 24 34 25 35 26 protected GdbmFile db_=null; 36 27 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; 28 /** open the database filename, with mode mode - uses the constants 29 above, eg GdbmFile.WRITER */ 30 public boolean openDatabase(String filename, int mode) { 31 // need to convert mode to GdbmFile mode 32 if (mode == READ) { 33 mode = GdbmFile.READER; 34 } else if (mode == WRITE) { 35 mode = GdbmFile.WRITER; 36 } else { 37 logger.error ("invalid mode, "+mode+ ", opening db for reading only"); 38 mode = GdbmFile.READER; 52 39 } 40 41 try { 42 if (db_!=null) { 43 db_.close(); 44 } 45 db_ = new GdbmFile(filename, mode); 46 } catch ( GdbmException e) { // the database wasn't opened or created 47 logger.error("couldn't open database "+filename); 48 return false; 49 } 50 db_.setKeyPacking(new StringPacking()); 51 db_.setValuePacking(new StringPacking()); 52 return true; 53 } 54 55 /** close the database associated with this wrapper */ 56 public void closeDatabase() { 57 try { 58 if (db_ != null) { 59 db_.close(); 60 db_ = null; 61 } 62 } catch (GdbmException e) { 63 // should never get here - close never actually throws an exception 64 logger.error("error on close()"); 65 } 66 } 53 67 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 } 68 public String getValue(String key) { 69 if (db_==null) { 70 return null; 65 71 } 72 String s_info; 73 try { 74 s_info = (String)db_.fetch(key); 75 } catch (GdbmException e) { 76 logger.error("couldn't get record"); 77 return null; 78 } 79 if (s_info==null) { 80 // record not present 81 logger.error("key "+key+" not present in db"); 82 return null; 83 } 84 return s_info; 85 } 66 86 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(); 87 /** sets the key value as info 88 * TODO - not implemented yet */ 89 public boolean setValue (String key, String value) { 90 if (db_==null) { 91 return false; 92 } 93 return false; 94 } 95 /** deletes the entry for key 96 * TODO - not implemented yet */ 97 public boolean deleteKey(String key) { 98 if (db_==null) { 99 return false; 100 } 101 return false; 102 } 88 103 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 key111 * 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 info119 * 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 key127 * 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 document175 * a suffix is expected to be present so test before using176 */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 translate188 // we process inner ones first189 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 child200 String node_id = translateOID(top+".fc");201 if (!node_id.equals(top)) {202 return node_id;203 }204 // try next sibling205 node_id = translateOID(top+".ns");206 if (!node_id.equals(top)) {207 return node_id;208 }209 // otherwise we keep trying parents sibling210 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 original221 }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 parent226 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 top240 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 top251 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 wrong263 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 104 }
Note:
See TracChangeset
for help on using the changeset viewer.