Changeset 15325 for greenstone3


Ignore:
Timestamp:
2008-05-01T13:57:15+12:00 (16 years ago)
Author:
kjdon
Message:

added support for JDBM (or other) in place of GDBM: new interface - FlatDatabaseWrapper. Has basic functions for opening a database and getting the value for a key. GDBMWrapper and JDBMWrapper both inplement this. (JDBMWrapper waiting for code from Steve). GDBMWrapper much simpler now as no greenstone specific stuff is included. SimpleCollectionDatabase is the class that services use now to access their databases. This will create a new wrapper based on database type. Then getting DBInfo, convertinng between oid and docnums etc is all handled by this class.

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  
    55import au.com.pharos.gdbm.GdbmException;
    66
    7 import org.apache.log4j.*;
     7import org.apache.log4j.Logger;
    88
    99/** java wrapper class for gdbm - uses Java-GDBM written by Martin Pool
     
    1111 */
    1212
    13 public class GDBMWrapper {
     13public class GDBMWrapper
     14  implements FlatDatabaseWrapper {
    1415
    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 
    3425
    3526    protected GdbmFile db_=null;
    3627
    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;
    5239    }
     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  }
    5367
    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;
    6571    }
     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  }
    6686
    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  }
    88103
    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     }
    299104}
Note: See TracChangeset for help on using the changeset viewer.