source: greenstone3/branches/customizingGreenstone3/src/java/org/greenstone/gsdl3/util/SimpleCollectionDatabase.java@ 15787

Last change on this file since 15787 was 15787, checked in by oranfry, 16 years ago

updating from trunk: brought in trunk changes from r15191 to r15785

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.