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

Last change on this file since 29318 was 28966, checked in by kjdon, 10 years ago

Lots of changes. Mainly to do with removing this.doc from everywhere. Document is not thread safe. Now we tend to create a new Document everytime we are starting a new page/message etc. in service this.desc_doc is available as teh document to create service info stuff. But it should only be used for this and not for other messages. newDOM is now static for XMLConverter. method param changes for some GSXML methods.

  • Property svn:keywords set to Author Date Id Revision
File size: 9.5 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(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 // set the class loader in case we have collection specific properties files
141 gs2_macro_resolver.setClassLoader(this.class_loader);
142 return true;
143 }
144
145 /** if id ends in .fc, .pc etc, then translate it to the correct id */
146 protected String translateId(String node_id)
147 {
148 return OID.translateOID(this.coll_db, node_id); //return this.coll_db.translateOID(node_id);
149 }
150
151 /**
152 * if an id is not a greenstone id (an external id) then translate it to a
153 * greenstone one
154 */
155 protected String translateExternalId(String node_id)
156 {
157 return this.coll_db.externalId2OID(node_id);
158 }
159
160 /**
161 * returns the id of the root node of the document containing node node_id.
162 * . may be the same as node_id
163 */
164 protected String getRootId(String node_id)
165 {
166 return this.gs_doc.getRootId(node_id);
167 }
168
169
170
171 /**
172 * get the metadata for the classifier node node_id returns a metadataList
173 * element: <metadataList><metadata
174 * name="xxx">value</metadata></metadataList>
175 */
176 protected Element getMetadataList(Document doc, String node_id, boolean all_metadata, ArrayList<String> metadata_names, String lang) throws GSException
177 {
178 Element metadata_list = doc.createElement(GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
179 DBInfo info = this.coll_db.getInfo(node_id);
180 if (info == null)
181 {
182 return null;
183 }
184
185 if (all_metadata) // this will get all metadata for current node
186 {
187 // return everything out of the database
188 Set<String> keys = info.getKeys();
189 Iterator<String> it = keys.iterator();
190 while (it.hasNext())
191 {
192 String key = it.next();
193 //String value = info.getInfo(key);
194 Vector<String> values = info.getMultiInfo(key);
195 for (int i = 0; i < values.size(); i++)
196 {
197 GSXML.addMetadata(metadata_list, key, this.macro_resolver.resolve(values.elementAt(i), lang, MacroResolver.SCOPE_META, node_id));
198 }
199 }
200
201 }
202 // now we go through the list of names. If we have specified
203 // all_metadata, then here we only get the ones like
204 // parent_Title, that are not the current node.
205 for (int i = 0; i < metadata_names.size(); i++)
206 {
207 String meta_name = metadata_names.get(i);
208
209 if (!all_metadata || meta_name.indexOf(GSConstants.META_RELATION_SEP)!=-1) {
210 Vector <String> values = getMetadata(node_id, info, meta_name, lang);
211 if (values != null) {
212 for (int j = 0; j < values.size(); j++)
213 {
214 // some of these may be parent/ancestor. does resolve need a different id???
215 GSXML.addMetadata(metadata_list, meta_name, this.macro_resolver.resolve(values.elementAt(j), lang, MacroResolver.SCOPE_META, node_id));
216 }
217 }
218 }
219 }
220
221 return metadata_list;
222 }
223
224 protected Vector<String> getMetadata(String node_id, DBInfo info, String metadata, String lang) {
225
226 DBInfo current_info = info;
227
228 int index = metadata.indexOf(GSConstants.META_RELATION_SEP);
229 if (index == -1) {
230 // metadata is for this node
231 Vector<String> values = info.getMultiInfo(metadata);
232 return values;
233 }
234 // we need to get metadata for one or more different nodes
235 String relation = metadata.substring(0, index);
236 String relation_id="";
237 metadata = metadata.substring(index + 1);
238 if (relation.equals("parent") || relation.equals("ancestors")) {
239 relation_id = OID.getParent(node_id);
240 if (relation_id.equals(node_id)) {
241 return null;
242 }
243 } else if (relation.equals("root")) {
244 relation_id = OID.getTop(node_id);
245 }
246
247 DBInfo relation_info;
248 if (relation_id.equals(node_id)) {
249 relation_info = info;
250 } else {
251 relation_info = this.coll_db.getInfo(relation_id);
252 }
253 if (relation_info == null)
254 {
255 return null;
256 }
257
258 Vector<String> values = relation_info.getMultiInfo(metadata);
259 // do resolving
260 if (!relation.equals("ancestors")){
261 return values;
262 }
263
264 // ancestors: go up the chain
265
266 String current_id = relation_id;
267 relation_id = OID.getParent(current_id);
268 while (!relation_id.equals(current_id))
269 {
270 relation_info = this.coll_db.getInfo(relation_id);
271 if (relation_info == null)
272 return values;
273
274 Vector<String> more_values = relation_info.getMultiInfo(metadata);
275 if (more_values != null)
276 {
277 values.addAll(0, more_values);
278 }
279
280
281 current_id = relation_id;
282 relation_id = OID.getParent(current_id);
283 }
284 return values; // for now
285 }
286
287 protected int getNumChildren(String node_id)
288 {
289 return this.gs_doc.getNumChildren(node_id);
290 }
291
292
293 /**
294 * returns the content of a node should return a nodeContent element:
295 * <nodeContent>text content or other elements</nodeContent>
296 */
297 abstract protected Element getNodeContent(Document doc, String doc_id, String lang) throws GSException;
298
299
300 /**
301 * needs to get info from collection database - if the calling code gets it
302 * already it may pay to pass it in instead
303 */
304 protected String resolveTextMacros(String doc_content, String doc_id, String lang)
305 {
306 // resolve any collection specific macros
307 doc_content = macro_resolver.resolve(doc_content, lang, MacroResolver.SCOPE_TEXT, doc_id);
308 return doc_content;
309 }
310
311
312
313}
Note: See TracBrowser for help on using the repository browser.