Changeset 15325 for greenstone3

Show
Ignore:
Timestamp:
01.05.2008 13:57:15 (12 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 modified

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}