source: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/AbstractGS2DocumentRetrieve.java@ 26090

Last change on this file since 26090 was 26090, checked in by kjdon, 12 years ago

java getMetadata only concerned with metadata name and relation info (parent, root etc). position, separator done with xslt. all values for a particular metadata are always returned. ancestors returned in descending order. even if all metadata is specified, we still need to go through the list of metadata names. all will return all for the current node but there may be eg parent_Title in the list which also needs to be returned.

  • Property svn:keywords set to Author Date Id Revision
File size: 9.4 KB
Line 
1/*
2 * AbstractGS2DocumentRetrieve.java
3 * Copyright (C) 2002 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.service;
20
21// Greenstone classes
22import org.greenstone.gsdl3.core.GSException;
23import org.greenstone.gsdl3.util.BasicDocumentDatabase;
24import org.greenstone.gsdl3.util.GSXML;
25import org.greenstone.gsdl3.util.GSFile;
26import org.greenstone.gsdl3.util.OID;
27import org.greenstone.gsdl3.util.MacroResolver;
28import org.greenstone.gsdl3.util.GS2MacroResolver;
29import org.greenstone.gsdl3.util.GSConstants;
30import org.greenstone.gsdl3.util.SimpleCollectionDatabase;
31import org.greenstone.gsdl3.util.DBInfo;
32// XML classes
33import org.w3c.dom.Document;
34import org.w3c.dom.Element;
35import org.w3c.dom.NodeList;
36
37// General Java classes
38import java.io.File;
39import java.util.StringTokenizer;
40import java.util.Vector;
41import java.util.Set;
42import java.util.Iterator;
43import java.util.ArrayList;
44
45import org.apache.log4j.*;
46
47// Apache Commons
48import org.apache.commons.lang3.*;
49
50/**
51 * Implements the generic retrieval and classifier services for GS2 collections.
52 *
53 * @author Katherine Don
54 * @author Michael Dewsnip
55 */
56
57public abstract class AbstractGS2DocumentRetrieve extends AbstractDocumentRetrieve
58{
59
60 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.AbstractGS2DocumentRetrieve.class.getName());
61
62 // protected static final String EXTLINK_PARAM = "ext"; here or in base??
63 protected String index_stem = null;
64
65 protected SimpleCollectionDatabase coll_db = null;
66 BasicDocumentDatabase gs_doc_db = null;
67 /** constructor */
68 protected AbstractGS2DocumentRetrieve()
69 {
70 this.macro_resolver = new GS2MacroResolver();
71 }
72
73 public void cleanUp()
74 {
75 super.cleanUp();
76 this.coll_db.closeDatabase();
77 this.gs_doc_db.cleanUp();
78 }
79
80 /** configure this service */
81 public boolean configure(Element info, Element extra_info)
82 {
83 if (!super.configure(info, extra_info))
84 {
85 return false;
86 }
87
88 logger.info("Configuring AbstractGS2DocumentRetrieve...");
89 //this.config_info = info;
90
91 // the index stem is either specified in the config file or is the collection name
92 Element index_stem_elem = (Element) GSXML.getChildByTagName(info, GSXML.INDEX_STEM_ELEM);
93 if (index_stem_elem != null)
94 {
95 this.index_stem = index_stem_elem.getAttribute(GSXML.NAME_ATT);
96 }
97 if (this.index_stem == null || this.index_stem.equals(""))
98 {
99 logger.error("AbstractGS2DocumentRetrieve.configure(): indexStem element not found, stem will default to collection name");
100 this.index_stem = this.cluster_name;
101 }
102
103 // find out what kind of database we have
104 Element database_type_elem = (Element) GSXML.getChildByTagName(info, GSXML.DATABASE_TYPE_ELEM);
105 String database_type = null;
106 if (database_type_elem != null)
107 {
108 database_type = database_type_elem.getAttribute(GSXML.NAME_ATT);
109 }
110 if (database_type == null || database_type.equals(""))
111 {
112 database_type = "gdbm"; // the default
113 }
114 coll_db = new SimpleCollectionDatabase(database_type);
115 if (!coll_db.databaseOK())
116 {
117 logger.error("Couldn't create the collection database of type " + database_type);
118 return false;
119 }
120
121 // Open database for querying
122 String coll_db_file = GSFile.collectionDatabaseFile(this.site_home, this.cluster_name, this.index_stem, database_type);
123 if (!this.coll_db.openDatabase(coll_db_file, SimpleCollectionDatabase.READ))
124 {
125 logger.error("Could not open collection database!");
126 return false;
127 }
128
129 gs_doc_db = new BasicDocumentDatabase(this.doc, database_type, this.site_home, this.cluster_name, this.index_stem);
130 if (!gs_doc_db.isValid())
131 {
132 logger.error("Failed to open Document Database.");
133 return false;
134 }
135 this.gs_doc = gs_doc_db;
136
137 // we need to set the database for our GS2 macro resolver
138 GS2MacroResolver gs2_macro_resolver = (GS2MacroResolver) this.macro_resolver;
139 gs2_macro_resolver.setDB(this.coll_db);
140
141 return true;
142 }
143
144 /** if id ends in .fc, .pc etc, then translate it to the correct id */
145 protected String translateId(String node_id)
146 {
147 return OID.translateOID(this.coll_db, node_id); //return this.coll_db.translateOID(node_id);
148 }
149
150 /**
151 * if an id is not a greenstone id (an external id) then translate it to a
152 * greenstone one
153 */
154 protected String translateExternalId(String node_id)
155 {
156 return this.coll_db.externalId2OID(node_id);
157 }
158
159 /**
160 * returns the id of the root node of the document containing node node_id.
161 * . may be the same as node_id
162 */
163 protected String getRootId(String node_id)
164 {
165 return this.gs_doc.getRootId(node_id);
166 }
167
168
169
170 /**
171 * get the metadata for the classifier node node_id returns a metadataList
172 * element: <metadataList><metadata
173 * name="xxx">value</metadata></metadataList>
174 */
175 protected Element getMetadataList(String node_id, boolean all_metadata, ArrayList<String> metadata_names) throws GSException
176 {
177 Element metadata_list = this.doc.createElement(GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
178 DBInfo info = this.coll_db.getInfo(node_id);
179 if (info == null)
180 {
181 return null;
182 }
183 String lang = "en"; // why do we need this??
184 if (all_metadata) // this will get all metadata for current node
185 {
186 // return everything out of the database
187 Set<String> keys = info.getKeys();
188 Iterator<String> it = keys.iterator();
189 while (it.hasNext())
190 {
191 String key = it.next();
192 //String value = info.getInfo(key);
193 Vector<String> values = info.getMultiInfo(key);
194 for (int i = 0; i < values.size(); i++)
195 {
196 GSXML.addMetadata(this.doc, metadata_list, key, this.macro_resolver.resolve(values.elementAt(i), lang, MacroResolver.SCOPE_META, node_id));
197 }
198 }
199
200 }
201 // now we go through the list of names. If we have specified
202 // all_metadata, then here we only get the ones like
203 // parent_Title, that are not the current node.
204 for (int i = 0; i < metadata_names.size(); i++)
205 {
206 String meta_name = metadata_names.get(i);
207
208 if (!all_metadata || meta_name.indexOf(GSConstants.META_RELATION_SEP)!=-1) {
209 Vector <String> values = getMetadata(node_id, info, meta_name, lang);
210 if (values != null) {
211 for (int j = 0; j < values.size(); j++)
212 {
213 // some of these may be parent/ancestor. does resolve need a different id???
214 GSXML.addMetadata(this.doc, metadata_list, meta_name, this.macro_resolver.resolve(values.elementAt(j), lang, MacroResolver.SCOPE_META, node_id));
215 }
216 }
217 }
218 }
219
220 return metadata_list;
221 }
222
223 protected Vector<String> getMetadata(String node_id, DBInfo info, String metadata, String lang) {
224
225 DBInfo current_info = info;
226
227 int index = metadata.indexOf(GSConstants.META_RELATION_SEP);
228 if (index == -1) {
229 // metadata is for this node
230 Vector<String> values = info.getMultiInfo(metadata);
231 return values;
232 }
233 // we need to get metadata for one or more different nodes
234 String relation = metadata.substring(0, index);
235 String relation_id="";
236 metadata = metadata.substring(index + 1);
237 if (relation.equals("parent") || relation.equals("ancestors")) {
238 relation_id = OID.getParent(node_id);
239 if (relation_id.equals(node_id)) {
240 return null;
241 }
242 } else if (relation.equals("root")) {
243 relation_id = OID.getTop(node_id);
244 }
245
246 DBInfo relation_info;
247 if (relation_id.equals(node_id)) {
248 relation_info = info;
249 } else {
250 relation_info = this.coll_db.getInfo(relation_id);
251 }
252 if (relation_info == null)
253 {
254 return null;
255 }
256
257 Vector<String> values = relation_info.getMultiInfo(metadata);
258 // do resolving
259 if (!relation.equals("ancestors")){
260 return values;
261 }
262
263 // ancestors: go up the chain
264
265 String current_id = relation_id;
266 relation_id = OID.getParent(current_id);
267 while (!relation_id.equals(current_id))
268 {
269 relation_info = this.coll_db.getInfo(relation_id);
270 if (relation_info == null)
271 return values;
272
273 Vector<String> more_values = relation_info.getMultiInfo(metadata);
274 if (more_values != null)
275 {
276 values.addAll(0, more_values);
277 }
278
279
280 current_id = relation_id;
281 relation_id = OID.getParent(current_id);
282 }
283 return values; // for now
284 }
285
286 protected int getNumChildren(String node_id)
287 {
288 return this.gs_doc.getNumChildren(node_id);
289 }
290
291
292 /**
293 * returns the content of a node should return a nodeContent element:
294 * <nodeContent>text content or other elements</nodeContent>
295 */
296 abstract protected Element getNodeContent(String doc_id, String lang) throws GSException;
297
298
299 /**
300 * needs to get info from collection database - if the calling code gets it
301 * already it may pay to pass it in instead
302 */
303 protected String resolveTextMacros(String doc_content, String doc_id, String lang)
304 {
305 // resolve any collection specific macros
306 doc_content = macro_resolver.resolve(doc_content, lang, MacroResolver.SCOPE_TEXT, doc_id);
307 return doc_content;
308 }
309
310
311
312}
Note: See TracBrowser for help on using the repository browser.