source: greenstone3/trunk/src/java/org/greenstone/gsdl3/util/SimpleCollectionDatabase.java@ 15325

Last change on this file since 15325 was 15325, checked in by kjdon, 16 years ago

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.

File size: 7.4 KB
Line 
1/*
2 * SimpleCollectionDatabase.java
3 * Copyright (C) 2008 New Zealand Digital Library, http://www.nzdl.org
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19package org.greenstone.gsdl3.util;
20
21import org.apache.log4j.*;
22
23public class SimpleCollectionDatabase {
24
25 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.util.SimpleCollectionDatabase.class.getName());
26
27 /* just read access, many readers can share a database */
28 public final static int READ = FlatDatabaseWrapper.READ;
29 /* read/write, exclusive access */
30 public final static int WRITE = FlatDatabaseWrapper.WRITE;
31
32 protected FlatDatabaseWrapper coll_db = null;
33
34 public SimpleCollectionDatabase(String db_type) {
35 if (db_type.equalsIgnoreCase("gdbm")) {
36 this.coll_db = new GDBMWrapper();
37 }
38 else if (db_type.equalsIgnoreCase("jdbm")) {
39 this.coll_db = new JDBMWrapper();
40 }
41 else {
42 logger.error("Couldn't create SimpleCollectionDatabase of type "+db_type);
43 }
44 }
45
46 /** open the database filename, with mode mode - uses the FlatDatabaseWrapper modes */
47 public boolean openDatabase(String filename, int mode){
48 return this.coll_db.openDatabase(filename, mode);
49 }
50
51 /** close the database */
52 public void closeDatabase() {
53 this.coll_db.closeDatabase();
54 }
55
56 /** Returns a DBInfo structure of the key-value pairs associated with a
57 particular main key in the database */
58 public DBInfo getInfo(String main_key) {
59 String key_info = this.coll_db.getValue(main_key);
60 if (key_info == null || key_info.equals("")) {
61 return null;
62 }
63
64 DBInfo info = new DBInfo();
65
66 String [] lines = key_info.split("\n");
67 String key;
68 String value;
69 for (int i=0; i<lines.length; i++) {
70 logger.debug("line:"+lines[i]);
71 int a = lines[i].indexOf('<');
72 int b= lines[i].indexOf('>');
73 if (a==-1 || b==-1) {
74 logger.error("bad format in db");
75 }
76 else {
77 key=lines[i].substring(a+1, b);
78 value=lines[i].substring(b+1);
79 logger.debug("key="+key+", val="+value);
80 info.addInfo(key, value);
81
82 }
83 }
84 return info;
85
86 }
87
88 /** converts a greenstone OID to internal docnum */
89 public String OID2Docnum(String OID) {
90 DBInfo info = getInfo(OID);
91 if (info != null) {
92 return info.getInfo("docnum");
93 }
94 return null;
95 }
96
97 /** converts a greenstone OID to an internal docnum, returning a Long
98 - convenience method*/
99 public long OID2DocnumLong(String OID) {
100 DBInfo info = getInfo(OID);
101 if (info != null) {
102 long real_num = Long.parseLong(info.getInfo("docnum"));
103 return real_num;
104 }
105 return -1;
106 }
107
108
109 /** converts a docnum to greenstone OID */
110 public String docnum2OID(String docnum) {
111 DBInfo info = getInfo(docnum);
112 if (info!=null){
113 String oid = info.getInfo("section");
114 return oid;
115 } else{
116 return null;
117 }
118 }
119
120 /** converts a docnum to greenstone OID
121 - convenience method */
122 public String docnum2OID(long docnum) {
123 return docnum2OID(Long.toString(docnum));
124 }
125
126 /** converts an external id to greenstone OID */
127 public String externalId2OID(String extid) {
128 DBInfo info = getInfo(extid);
129 if (info != null) {
130 String oid = info.getInfo("section");
131 return oid;
132 }
133 return null;
134 }
135
136 /** translates relative oids into proper oids:
137 * .pr (parent), .rt (root) .fc (first child), .lc (last child),
138 * .ns (next sibling), .ps (previous sibling)
139 * .np (next page), .pp (previous page) : links sections in the order that you'd read the document
140 * a suffix is expected to be present so test before using
141 */
142 public String translateOID(String oid) {
143
144 int p = oid.lastIndexOf('.');
145 if (p != oid.length()-3) {
146 logger.info("translateoid error: '.' is not the third to last char!!");
147 return oid;
148 }
149
150 String top = oid.substring(0, p);
151 String suff = oid.substring(p+1);
152 // just in case we have multiple extensions, we must translate
153 // we process inner ones first
154 if (OID.needsTranslating(top)) {
155 top = translateOID(top);
156 }
157 if (suff.equals("pr")) {
158 return OID.getParent(top);
159 }
160 if (suff.equals("rt")) {
161 return OID.getTop(top);
162 }
163 if (suff.equals("np")) {
164 // try first child
165 String node_id = translateOID(top+".fc");
166 if (!node_id.equals(top)) {
167 return node_id;
168 }
169 // try next sibling
170 node_id = translateOID(top+".ns");
171 if (!node_id.equals(top)) {
172 return node_id;
173 }
174 // otherwise we keep trying parents sibling
175 String child_id = top;
176 String parent_id = OID.getParent(child_id);
177 while(!parent_id.equals(child_id)) {
178 node_id = translateOID(parent_id+".ns");
179 if (!node_id.equals(parent_id)) {
180 return node_id;
181 }
182 child_id = parent_id;
183 parent_id = OID.getParent(child_id);
184 }
185 return top; // we couldn't get a next page, so just return the original
186 }
187 if (suff.equals("pp")) {
188 String prev_sib = translateOID(top+".ps");
189 if (prev_sib.equals(top)) {
190 // no previous sibling, so return the parent
191 return OID.getParent(top);
192 }
193 // there is a previous sibling, so its either this section, or the last child of the last child..
194 String last_child = translateOID(prev_sib+".lc");
195 while (!last_child.equals(prev_sib)) {
196 prev_sib = last_child;
197 last_child = translateOID(prev_sib+".lc");
198 }
199 return last_child;
200 }
201
202 int sibling_num = 0;
203 if (suff.equals("ss")) {
204 // we have to remove the sib num before we get top
205 p = top.lastIndexOf('.');
206 sibling_num = Integer.parseInt(top.substring(p+1));
207 top = top.substring(0, p);
208 }
209
210 // need to get info out of collection db -
211 String doc_id = top;
212 if (suff.endsWith("s")) {
213 doc_id = OID.getParent(top);
214 if (doc_id.equals(top)) {
215 // i.e. we are already at the top
216 return top;
217 }
218 }
219 DBInfo info = getInfo(doc_id);
220 if (info==null) {
221 logger.info("info is null!!");
222 return top;
223 }
224
225 String contains = info.getInfo("contains");
226 if (contains.equals("")) {
227 // something is wrong
228 return top;
229 }
230 contains = contains.replaceAll("\"", doc_id);
231 String [] children = contains.split(";");
232 if (suff.equals("fc")) {
233 return children[0];
234 } else if (suff.equals("lc")) {
235 return children[children.length-1];
236 } else {
237 if (suff.equals("ss")) {
238 return children[sibling_num-1];
239 }
240 // find the position that we are at.
241 int i=0;
242 while (i<children.length) {
243 if (children[i].equals(top)) {
244 break;
245 }
246 i++;
247 }
248
249 if (suff.equals("ns")) {
250 if (i==children.length-1) {
251 return children[i];
252 }
253 return children[i+1];
254 } else if (suff.equals("ps")) {
255 if (i==0) {
256 return children[i];
257 }
258 return children[i-1];
259 }
260 }
261
262 return top;
263 }
264}
Note: See TracBrowser for help on using the repository browser.