source: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/OAIPMH.java@ 21782

Last change on this file since 21782 was 21782, checked in by kjdon, 14 years ago

slightly modified where info comes from in config files. service rack now in collectionConfig, indexstem and infodbtype from metadata in buildConfig

File size: 28.1 KB
Line 
1/*
2 * OAIPMH.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.GSXML;
24import org.greenstone.gsdl3.util.OAIXML;
25import org.greenstone.gsdl3.util.OID;
26import org.greenstone.gsdl3.util.GSFile;
27import org.greenstone.gsdl3.util.XMLConverter;
28
29import org.greenstone.gsdl3.util.SimpleCollectionDatabase;
30import org.greenstone.gsdl3.util.DBInfo;
31// XML classes
32import org.w3c.dom.Document;
33import org.w3c.dom.Element;
34import org.w3c.dom.NodeList;
35
36// General Java classes
37import java.io.File;
38import java.util.StringTokenizer;
39import java.util.Vector;
40import java.util.Set;
41import java.util.Iterator;
42import java.util.ArrayList;
43import java.util.Date;
44import java.util.HashMap;
45import java.util.Map.Entry;
46
47import org.apache.log4j.Logger;
48
49/** Implements the oai metadata retrieval service for GS3 collections.
50 * Dig into each collection's database and retrieve the metadata
51 *
52 * @author <a href="mailto:[email protected]">Xiao</a>
53 */
54
55public class OAIPMH extends ServiceRack {
56
57 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.OAIPMH.class.getName());
58
59 protected SimpleCollectionDatabase coll_db = null;
60
61 protected String site_name = "";
62 protected String coll_name = "";
63
64 /** constructor */
65 public OAIPMH() {
66
67 }
68
69 public void cleanUp() {
70 super.cleanUp();//??
71 this.coll_db.closeDatabase();
72 }
73 /** configure this service
74 info is the OAIPMH service rack from collectionConfig.xml, and
75 extra_info is buildConfig.xml */
76 public boolean configure(Element info, Element extra_info) {
77 if (!super.configure(info, extra_info)){
78 logger.info("Configuring ServiceRack.java returns false.");
79 return false;
80 }
81
82 //get the names from ServiceRack.java
83 this.site_name = this.router.getSiteName();
84 this.coll_name = this.cluster_name;
85
86 logger.info("Configuring OAIPMH...");
87
88 this.config_info = info;
89
90 // the index stem is either specified in the buildConfig.xml file (extra_info) or uses the collection name
91 Element metadata_list = (Element) GSXML.getChildByTagName(extra_info, GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
92 String index_stem = "";
93 String infodb_type = "";
94 if (metadata_list != null) {
95
96 Element index_stem_elem = (Element) GSXML.getNamedElement(metadata_list, GSXML.METADATA_ELEM, GSXML.NAME_ATT, "indexStem");
97
98 if (index_stem_elem != null) {
99 index_stem = GSXML.getNodeText(index_stem_elem);
100 }
101
102 Element infodb_type_elem = (Element) GSXML.getNamedElement(metadata_list, GSXML.METADATA_ELEM, GSXML.NAME_ATT, "infodbType");
103 if (infodb_type_elem != null) {
104 infodb_type = GSXML.getNodeText(infodb_type_elem);
105 }
106
107 }
108
109 if (index_stem == null || index_stem.equals("")) {
110 index_stem = this.cluster_name;
111 }
112 if (infodb_type == null || infodb_type.equals("")) {
113 infodb_type = "gdbm"; // the default
114 }
115
116 coll_db = new SimpleCollectionDatabase(infodb_type);
117 if (coll_db == null) {
118 logger.error("Couldn't create the collection database of type "+infodb_type);
119 return false;
120 }
121
122 // Open database for querying
123 String coll_db_file = GSFile.collectionDatabaseFile(this.site_home, this.cluster_name, index_stem, infodb_type);
124 if (!this.coll_db.openDatabase(coll_db_file, SimpleCollectionDatabase.READ)) {
125 logger.error("Could not open collection database!");
126 return false;
127 }
128
129 // the short_service_info is used by the message router to find the method names,
130 //so we just use the doc variable in class ServiceRack to create the xml; but
131 // in each method we will use OAIXML to create the response xml
132 // set up short_service_info_ - just the name
133
134 Element identify = this.doc.createElement(OAIXML.SERVICE);
135
136 identify.setAttribute(OAIXML.NAME, OAIXML.IDENTIFY);
137 identify.setAttribute(GSXML.TYPE_ATT, "oai");
138 this.short_service_info.appendChild(identify);
139
140 Element list_records = this.doc.createElement(OAIXML.SERVICE);
141 list_records.setAttribute(OAIXML.NAME, OAIXML.LIST_RECORDS);
142 list_records.setAttribute(GSXML.TYPE_ATT, "oai");
143 this.short_service_info.appendChild(list_records);
144
145 Element list_identifiers = this.doc.createElement(OAIXML.SERVICE);
146 list_identifiers.setAttribute(OAIXML.NAME, OAIXML.LIST_IDENTIFIERS);
147 list_identifiers.setAttribute(GSXML.TYPE_ATT, "oai");
148 this.short_service_info.appendChild(list_identifiers);
149
150 Element list_sets = this.doc.createElement(OAIXML.SERVICE);
151 list_sets.setAttribute(OAIXML.NAME, OAIXML.LIST_SETS);
152 list_sets.setAttribute(GSXML.TYPE_ATT, "oai");
153 this.short_service_info.appendChild(list_sets);
154
155 Element list_metadata_formats = this.doc.createElement(OAIXML.SERVICE);
156 list_metadata_formats.setAttribute(OAIXML.NAME, OAIXML.LIST_METADATA_FORMATS);
157 list_metadata_formats.setAttribute(GSXML.TYPE_ATT, "oai");
158 this.short_service_info.appendChild(list_metadata_formats);
159
160 Element get_record = this.doc.createElement(OAIXML.SERVICE);
161 get_record.setAttribute(OAIXML.NAME, OAIXML.GET_RECORD);
162 get_record.setAttribute(GSXML.TYPE_ATT, "oai");
163 this.short_service_info.appendChild(get_record);
164
165 return true;
166 }
167 /** returns a specific service description */
168 public Element getServiceDescription(String service_id, String lang, String subset) {
169
170 if (service_id.equals(OAIXML.IDENTIFY)) {
171 Element identify = this.doc.createElement(OAIXML.SERVICE);
172 identify.setAttribute(OAIXML.NAME, OAIXML.IDENTIFY);
173 identify.setAttribute(GSXML.TYPE_ATT, "oai");
174 return identify;
175 }
176 if (service_id.equals(OAIXML.LIST_RECORDS)) {
177 Element list_records = this.doc.createElement(OAIXML.SERVICE);
178 list_records.setAttribute(OAIXML.NAME, OAIXML.LIST_RECORDS);
179 list_records.setAttribute(GSXML.TYPE_ATT, "oai");
180 return list_records;
181 }
182
183 if (service_id.equals(OAIXML.LIST_IDENTIFIERS)) {
184 Element list_identifiers = this.doc.createElement(OAIXML.SERVICE);
185 list_identifiers.setAttribute(OAIXML.NAME, OAIXML.LIST_IDENTIFIERS);
186 list_identifiers.setAttribute(GSXML.TYPE_ATT, "oai");
187 return list_identifiers;
188 }
189 if (service_id.equals(OAIXML.LIST_SETS)) {
190 Element list_sets = this.doc.createElement(OAIXML.SERVICE);
191 list_sets.setAttribute(OAIXML.NAME, OAIXML.LIST_SETS);
192 list_sets.setAttribute(GSXML.TYPE_ATT, "oai");
193 return list_sets;
194 }
195 if (service_id.equals(OAIXML.LIST_METADATA_FORMATS)) {
196 Element list_metadata_formats = this.doc.createElement(OAIXML.SERVICE);
197 list_metadata_formats.setAttribute(OAIXML.NAME, OAIXML.LIST_METADATA_FORMATS);
198 list_metadata_formats.setAttribute(GSXML.TYPE_ATT, "oai");
199 return list_metadata_formats;
200 }
201
202 if (service_id.equals(OAIXML.GET_RECORD)) {
203 Element get_record = this.doc.createElement(OAIXML.SERVICE);
204 get_record.setAttribute(OAIXML.NAME, OAIXML.GET_RECORD);
205 get_record.setAttribute(GSXML.TYPE_ATT, "oai");
206 return get_record;
207 }
208
209 return null;
210 }
211 /** return the metadata information about this set of the repository */
212 protected Element processIdentify(Element req) {
213 return null;
214 }
215 /** return the metadata information */
216 protected Element processListSets(Element req) {
217 //This method is never called unless each set in the returned message contain a
218 //'description' element so that we need to ask each collection for their info
219 return null;
220 }
221 /** return the metadata information */
222 protected Element processGetRecord(Element req) {
223 /** arguments:
224 identifier: required
225 metadataPrefix: required
226 * Exceptions: badArgument; cannotDisseminateFormat; idDoesNotExist
227 */
228 NodeList params = GSXML.getChildrenByTagName(req, OAIXML.PARAM);
229 HashMap param_map = OAIXML.getParamMap(params);
230
231 String prefix = (String)param_map.get(OAIXML.METADATA_PREFIX);
232 if (prefix == null || prefix.equals("")) {
233 //Just a double-check
234 logger.error("the value of metadataPrefix att is not present in the request.");
235 return OAIXML.getResponse(OAIXML.createErrorElement(OAIXML.CANNOT_DISSEMINATE_FORMAT, ""));
236 }
237
238 Element metadata_format = getMetadataFormatElement(prefix);
239 if(metadata_format == null) {
240 logger.error("metadata prefix is not supported.");
241 return OAIXML.getResponse(OAIXML.createErrorElement(OAIXML.CANNOT_DISSEMINATE_FORMAT, ""));
242 }
243
244 String oid = (String)param_map.get(OAIXML.OID);
245
246 //get a DBInfo object of the identifier; if this identifier is not present in the database,
247 // null is returned.
248 DBInfo info = this.coll_db.getInfo(oid);
249 if (info == null) {
250 logger.error("OID: " + oid + " is not present in the database.");
251 return OAIXML.getResponse(OAIXML.createErrorElement(OAIXML.ID_DOES_NOT_EXIST, ""));
252 }
253
254 ArrayList keys = new ArrayList(info.getKeys());
255 String lastmodified = "";
256 if(keys.contains(OAIXML.LASTMODIFIED)) {
257 lastmodified = info.getInfo(OAIXML.LASTMODIFIED);
258 }
259 lastmodified = OAIXML.getTime(Long.parseLong(lastmodified));
260
261 Element get_record = OAIXML.createElement(OAIXML.GET_RECORD);
262 Element record = OAIXML.createElement(OAIXML.RECORD);
263 //compose the header element
264 record.appendChild(createHeaderElement(oid, lastmodified));
265 //compose the metadata element
266 record.appendChild(createMetadataElement(prefix, info, metadata_format));
267 get_record.appendChild(record);
268 return OAIXML.getResponse(get_record);
269 }
270 /** return a list of identifiers */
271 protected Element processListIdentifiers(Element req) {
272 /** arguments:
273 metadataPrefix: required
274 * from: optional
275 * until: optional
276 * set: optional
277 * resumptionToken: exclusive and optional (ignored as it has been handled by OAIReceptionist)
278 * Exceptions: badArgument; cannotDisseminateFormat; idDoesNotExist
279 */
280 NodeList params = GSXML.getChildrenByTagName(req, OAIXML.PARAM);
281
282 if(params.getLength() == 0) {
283 logger.error("must at least have the metadataPrefix parameter, can't be none");
284 return OAIXML.getResponse(OAIXML.createErrorElement(OAIXML.BAD_ARGUMENT, ""));
285 }
286
287 HashMap param_map = OAIXML.getParamMap(params);
288
289 String prefix = "";
290 Date from_date = null;
291 Date until_date = null;
292
293 if(param_map.containsKey(OAIXML.METADATA_PREFIX) == false) {
294 //Just a double-check
295 logger.error("A param element containing the metadataPrefix is not present.");
296 return OAIXML.getResponse(OAIXML.createErrorElement(OAIXML.CANNOT_DISSEMINATE_FORMAT, ""));
297 }
298 prefix = (String)param_map.get(OAIXML.METADATA_PREFIX);
299 if (prefix == null || prefix.equals("")) {
300 //Just a double-check
301 logger.error("the value of metadataPrefix att is not present in the request.");
302 return OAIXML.getResponse(OAIXML.createErrorElement(OAIXML.CANNOT_DISSEMINATE_FORMAT, ""));
303 }
304
305 if(param_map.containsKey(OAIXML.FROM)) {
306 String from = (String)param_map.get(OAIXML.FROM);
307 from_date = OAIXML.getDate(from);
308 }
309 if(param_map.containsKey(OAIXML.UNTIL)) {
310 String until = (String)param_map.get(OAIXML.UNTIL);
311 until_date = OAIXML.getDate(until);
312 }
313
314 Element metadata_format = getMetadataFormatElement(prefix);
315 if(metadata_format == null) {
316 logger.error("metadata prefix is not supported.");
317 return OAIXML.getResponse(OAIXML.createErrorElement(OAIXML.CANNOT_DISSEMINATE_FORMAT, ""));
318 }
319 ArrayList oid_list = getChildrenIds(OAIXML.BROWSELIST);
320 if (oid_list == null) {
321 logger.error("No matched records found in collection: browselist is empty");
322 return OAIXML.getResponse(OAIXML.createErrorElement(OAIXML.NO_RECORDS_MATCH, ""));
323 }
324 // all validation is done
325 Element list_identifiers = OAIXML.createElement(OAIXML.LIST_IDENTIFIERS);
326 for(int i=0; i<oid_list.size(); i++) {
327 String oid = (String)oid_list.get(i);
328 DBInfo info = this.coll_db.getInfo(oid);
329 if (info == null) {
330 logger.error("Database does not contains information about oid: " +oid);
331 continue;
332 }
333 ArrayList keys = new ArrayList(info.getKeys());
334 String lastmodified = "";
335 if(keys.contains(OAIXML.LASTMODIFIED)) {
336 lastmodified = info.getInfo(OAIXML.LASTMODIFIED);
337 }
338 lastmodified = OAIXML.getTime(Long.parseLong(lastmodified));
339
340 Date this_date = OAIXML.getDate(lastmodified);
341 if (from_date != null) {
342 if(this_date.before(from_date)) {
343 continue;
344 }
345 }
346 if (until_date != null) {
347 if (this_date.after(until_date)) {
348 continue;
349 }
350 }
351 //compose the header element and append it
352 list_identifiers.appendChild(createHeaderElement(oid, lastmodified));
353 }//end of for(int i=0; i<oid_list.size(); i++) of doing thru each record
354
355 return OAIXML.getResponse(list_identifiers);
356 }
357 /** return a list of records */
358 protected Element processListRecords(Element req) {
359 /** the request sent here may contain optional 'from', 'untill', 'metadataPrefix',
360 * and 'resumptionToken' params. see doListSets() in OAIReceptionist.
361 * if the request contains 'resumptionToken' then it should have been handled by the
362 * OAIReceptionist. Therefore, the request sent here must not contain 'resumptionToken'
363 * argument but a 'metadataPrefix' param. The OAIReceptionist makes sure of this.
364 */
365 NodeList params = GSXML.getChildrenByTagName(req, OAIXML.PARAM);
366
367 if(params.getLength() == 0) {
368 logger.error("must at least have the metadataPrefix parameter, can't be none");
369 return OAIXML.getResponse(OAIXML.createErrorElement(OAIXML.BAD_ARGUMENT, ""));
370 }
371
372 HashMap param_map = OAIXML.getParamMap(params);
373
374 String prefix = "";
375 Date from_date = null;
376 Date until_date = null;
377
378 if(param_map.containsKey(OAIXML.METADATA_PREFIX) == false) {
379 //Just a double-check
380 logger.error("A param element containing the metadataPrefix is not present.");
381 return OAIXML.getResponse(OAIXML.createErrorElement(OAIXML.CANNOT_DISSEMINATE_FORMAT, ""));
382 }
383 prefix = (String)param_map.get(OAIXML.METADATA_PREFIX);
384 if (prefix == null || prefix.equals("")) {
385 //Just a double-check
386 logger.error("the value of metadataPrefix att is not present in the request.");
387 return OAIXML.getResponse(OAIXML.createErrorElement(OAIXML.CANNOT_DISSEMINATE_FORMAT, ""));
388 }
389
390 if(param_map.containsKey(OAIXML.FROM)) {
391 String from = (String)param_map.get(OAIXML.FROM);
392 from_date = OAIXML.getDate(from);
393 }
394 if(param_map.containsKey(OAIXML.UNTIL)) {
395 String until = (String)param_map.get(OAIXML.UNTIL);
396 until_date = OAIXML.getDate(until);
397 }
398 Element metadata_format = getMetadataFormatElement(prefix);
399 if(metadata_format == null) {
400 logger.error("metadata prefix is not supported.");
401 return OAIXML.getResponse(OAIXML.createErrorElement(OAIXML.CANNOT_DISSEMINATE_FORMAT, ""));
402 }
403
404 //get a list of identifiers (it contains a list of strings)
405 ArrayList oid_list = getChildrenIds(OAIXML.BROWSELIST);
406 if (oid_list == null) {
407 logger.error("No matched records found in collection: browselist is empty");
408 return OAIXML.getResponse(OAIXML.createErrorElement(OAIXML.NO_RECORDS_MATCH, ""));
409 }
410 // all validation is done
411 Element list_records = OAIXML.createElement(OAIXML.LIST_RECORDS);
412 for(int i=0; i<oid_list.size(); i++) {
413 String oid = (String)oid_list.get(i);
414 DBInfo info = this.coll_db.getInfo(oid);
415 if (info == null) {
416 logger.error("Database does not contains information about oid: " +oid);
417 continue;
418 }
419 ArrayList keys = new ArrayList(info.getKeys());
420 String lastmodified = "";
421 if(keys.contains(OAIXML.LASTMODIFIED)) {
422 lastmodified = info.getInfo(OAIXML.LASTMODIFIED);
423 }
424 lastmodified = OAIXML.getTime(Long.parseLong(lastmodified));
425
426 Date this_date = OAIXML.getDate(lastmodified);
427 if (from_date != null) {
428 if(this_date.before(from_date)) {
429 continue;
430 }
431 }
432 if (until_date != null) {
433 if (this_date.after(until_date)) {
434 continue;
435 }
436 }
437
438 Element record = OAIXML.createElement(OAIXML.RECORD);
439 list_records.appendChild(record);
440 //compose the header element
441 record.appendChild(createHeaderElement(oid, lastmodified));
442 //compose the metadata element
443 record.appendChild(createMetadataElement(prefix, info, metadata_format));
444
445 }//end of for(int i=0; i<oid_list.size(); i++) of doing thru each record
446
447 return OAIXML.getResponse(list_records);
448 }
449
450 /** get the metadataFormat element from the collectionConfig.xml containing the specified metadata prefix.
451 * return null if not found.
452 */
453 private Element getMetadataFormatElement(String prefix) {
454 Element list_meta_format = (Element)GSXML.getChildByTagName(this.config_info, OAIXML.LIST_METADATA_FORMATS);
455 Element metadata_format = GSXML.getNamedElement(list_meta_format, OAIXML.METADATA_FORMAT, OAIXML.METADATA_PREFIX, prefix);
456 return metadata_format;
457 }
458 /** create the metadata element used when processing ListRecords/GetRecord requests
459 */
460 private Element createMetadataElement(String prefix, DBInfo info, Element metadata_format) {
461 //the prefix string is in the form: oai_dc, for example.
462 String prfx_str = "";
463 //the metadata namespace used to retrieve metadata in the repository
464 //For example, if the prefix is like 'oai_ex' then we used 'ex' to get the metadata
465 //Normally we would use 'dc' to find metadata.
466 String meta_ns = "";
467 if(prefix.equals(OAIXML.OAI_DC)) {
468 if(OAIXML.oai_version.equals(OAIXML.OAI_VERSION2)) {
469 prfx_str = prefix + ":" + OAIXML.DC;
470 } else {
471 prfx_str = OAIXML.DC;//oai version 1
472 }
473 meta_ns = OAIXML.DC;
474 } else {
475 prfx_str = prefix.substring(prefix.indexOf("_") + 1);
476 meta_ns = prfx_str;
477 }
478 //create the <metadata> element
479 //OAIXML.oai_version is read from OAIConfig.xml and its default value is "2.0"
480 Element prfx_str_elem = OAIXML.getMetadataPrefixElement(prfx_str, OAIXML.oai_version);
481 String[] metadata_names = getMetadataNames(metadata_format);
482 HashMap meta_map = getInfoByNames(info, metadata_names);
483 ArrayList meta_list = new ArrayList(meta_map.entrySet());
484 for (int j=0; j<meta_list.size(); j++) {
485 Entry men = (Entry)meta_list.get(j);
486 String meta_name = (String)men.getKey();
487 String meta_value = (String)men.getValue();
488 Element e = OAIXML.createElement(meta_name);
489 GSXML.setNodeText(e, meta_value);
490 prfx_str_elem.appendChild(e);
491 }
492 Element metadata = OAIXML.createElement(OAIXML.METADATA);
493 metadata.appendChild(prfx_str_elem);
494 return metadata;
495 }
496 /** create a header element used when processing requests like ListRecords/GetRecord/ListIdentifiers
497 */
498 private Element createHeaderElement(String oid, String lastmodified) {
499 Element header = OAIXML.createElement(OAIXML.HEADER);
500 Element identifier = OAIXML.createElement(OAIXML.IDENTIFIER);
501 GSXML.setNodeText(identifier, site_name + ":" + coll_name + ":" + oid);
502 header.appendChild(identifier);
503 Element set_spec = OAIXML.createElement(OAIXML.SET_SPEC);
504 GSXML.setNodeText(set_spec, site_name + ":" + coll_name);
505 header.appendChild(set_spec);
506 Element datestamp = OAIXML.createElement(OAIXML.DATESTAMP);
507 GSXML.setNodeText(datestamp, lastmodified);
508 header.appendChild(datestamp);
509 return header;
510 }
511 /** return the metadata information */
512 protected Element processListMetadataFormats(Element req) {
513 // the request sent here must contain an OID. see doListMetadataFormats() in OAIReceptionist
514 Element param = GSXML.getNamedElement(req, OAIXML.PARAM, OAIXML.NAME, OAIXML.OID);
515 if (param == null) {
516 logger.error("An element containing the OID attribute not is present.");
517 return OAIXML.getResponse(OAIXML.createErrorElement(OAIXML.ID_DOES_NOT_EXIST, ""));
518 }
519 String oid = param.getAttribute(OAIXML.VALUE);
520 if (oid == null || oid.equals("")) {
521 logger.error("No OID is present in the request.");
522 return OAIXML.getResponse(OAIXML.createErrorElement(OAIXML.ID_DOES_NOT_EXIST, ""));
523 }
524 ArrayList oid_list = getChildrenIds(OAIXML.BROWSELIST);
525 if (oid_list == null || oid_list.contains(oid) == false) {
526 logger.error("OID: " + oid + " is not present in the database.");
527 Element e= OAIXML.getResponse(OAIXML.createErrorElement(OAIXML.ID_DOES_NOT_EXIST, ""));
528// logger.error((new XMLConverter()).getPrettyString (e));
529 return e;
530 }
531
532 DBInfo info = null;
533 info = this.coll_db.getInfo(oid);
534 if (info == null) { //just double check
535 return OAIXML.getResponse(OAIXML.createErrorElement(OAIXML.OAI_SERVICE_UNAVAILABLE, ""));
536 }
537
538 NodeList meta_list = getMetadataFormatList();
539 if (meta_list == null || meta_list.getLength() == 0) {
540 logger.error("No metadata format is present in collectionConfig.xml");
541 return OAIXML.getResponse(OAIXML.createErrorElement(OAIXML.NO_METADATA_FORMATS, ""));
542 }
543
544 Element list_metadata_formats = OAIXML.createElement(OAIXML.LIST_METADATA_FORMATS);
545 boolean has_meta_format = false;
546
547 for (int i=0; i<meta_list.getLength(); i++) {
548 Element metadata_format = (Element)meta_list.item(i);
549 String[] metadata_names = getMetadataNames(metadata_format);
550 if (containsMetadata(info, metadata_names) == true) {
551 has_meta_format = true;
552 Element meta_fmt = OAIXML.createElement(OAIXML.METADATA_FORMAT);
553 OAIXML.copyElement(meta_fmt, metadata_format, OAIXML.METADATA_PREFIX);
554 OAIXML.copyElement(meta_fmt, metadata_format, OAIXML.METADATA_NAMESPACE);
555 OAIXML.copyElement(meta_fmt, metadata_format, OAIXML.SCHEMA);
556 list_metadata_formats.appendChild(meta_fmt);
557 }
558 }//end of for loop
559 if (has_meta_format == false) {
560 logger.error("Specified metadata names are not contained in the database.");
561 return OAIXML.getResponse(OAIXML.createErrorElement(OAIXML.NO_METADATA_FORMATS, ""));
562 } else {
563 return OAIXML.getResponse(list_metadata_formats);
564 }
565 }
566
567 /** return the ListMetadataFormats element in collectionConfig.xml
568 * Currently, it will only contain one metadata format: oai_dc
569 */
570 protected NodeList getMetadataFormatList() {
571 Element list_meta_formats = (Element)GSXML.getChildByTagName(this.config_info, OAIXML.LIST_METADATA_FORMATS);
572 return GSXML.getChildrenByTagName(list_meta_formats, OAIXML.METADATA_FORMAT);
573 }
574 /** @param metadata_format - the metadataFormat element in collectionConfig.xml
575 */
576 protected String[] getMetadataNames(Element metadata_format) {
577 String[] names = null;
578
579 //read the mappingList element
580 Element mapping_list = (Element)GSXML.getChildByTagName(metadata_format, OAIXML.MAPPING_LIST);
581 if (mapping_list == null) {
582 logger.info("No metadata mappings are provided in collectionConfig.xml. Use the standard Dublin Core names.");
583 names = OAIXML.getGlobalMetadataMapping(metadata_format.getAttribute(OAIXML.METADATA_PREFIX));
584
585 return (names != null)? names : OAIXML.getDublinCoreNames();
586 }
587 NodeList mappings = GSXML.getChildrenByTagName(mapping_list, OAIXML.MAPPING);
588 int size = mappings.getLength();
589 if (size == 0) {
590 logger.info("No metadata mappings are provided in collectionConfig.xml. \n Return standard DC names.");
591 // read the standard Dublin Core metadata names
592 return OAIXML.getDublinCoreNames();
593 }
594 names = new String[size];
595 for (int i=0; i<size; i++) {
596 names[i] = GSXML.getNodeText((Element)mappings.item(i)).trim();
597 }
598 return names;
599 }
600
601 /** returns a list of the child ids in order, null if no children */
602 protected ArrayList getChildrenIds(String node_id) {
603 DBInfo info = this.coll_db.getInfo(node_id);
604 if (info == null) {
605 return null;
606 }
607
608 String contains = info.getInfo("contains");
609 if (contains.equals("")) {
610 return null;
611 }
612 ArrayList children = new ArrayList();
613 StringTokenizer st = new StringTokenizer(contains, ";");
614 while (st.hasMoreTokens()) {
615 String child_id = st.nextToken().replaceAll("\"", node_id);
616 children.add(child_id);
617 }
618 return children;
619 }
620 /**method to check whether any of the 'metadata_names' is contained in the 'info'.
621 * The name may be in the form: <name>,<mapped name>, in which the mapped name is
622 * optional. The mapped name is looked up in the DBInfo; if not present, use the first
623 * name which is mendatory.
624 */
625 protected boolean containsMetadata(DBInfo info, String[] metadata_names) {
626 if (metadata_names == null) return false;
627 logger.info("checking metadata names in db.");
628 for(int i=0; i<metadata_names.length; i++) {
629 int index = metadata_names[i].indexOf(",");
630 String meta_name = (index == -1) ? metadata_names[i] :
631 metadata_names[i].substring(index + 1);
632
633 if(info.getInfo(meta_name).equals("") == false) {
634 return true;
635 }
636 }
637 return false;
638 }
639 /** @param keys - contains a list of keys in string format.
640 * Here is a typical record in the collection database, 'keys' contains the values in <...>:
641 *----------------------------------------------------------------------
642[HASH01a84acb0f1aad2380493b3a]
643<doctype>doc
644<hastxt>1
645<Language>en
646<Encoding>windows_1252
647<Plugin>HTMLPlug
648<FileSize>205093
649<Source>wb34te.htm
650<hascover>1
651<dls.Organization>World Bank
652<dls.Title>Development in practice: Toward Gender Equality (wb34te)
653<dls.Language>English
654<dls.AZList>A-B-C-D-E-F-G-H-I-J-K-L-M-N-O-P-Q-R-S-T-U-V-W-X-Y-Z
655<dls.Subject>Women, gender and development, women's organizations
656<dls.Keyword>achieve gender equality
657<URL>http://wb34te/wb34te.htm
658<Title>Development in practice: Toward Gender Equality
659<lastmodified>1178245194
660<assocfilepath>HASH01a8.dir
661<memberof>CL3
662<archivedir>HASH01a8.dir
663<thistype>VList
664<childtype>VList
665<contains>".1;".2;".3;".4;".5;".6;".7;".8;".9
666<docnum>349
667----------------------------------------------------------------------
668 */
669 public String[] getMetadata(DBInfo info, String names) {
670 String[] name_value = new String[2];
671 ArrayList keys = new ArrayList(info.getKeys());
672 for (int i=0; i<keys.size(); i++) {
673 String key = (String)keys.get(i);
674 String first_name = "";
675 String second_name = "";
676 int index = names.indexOf(",");
677 if(index != -1) {
678 first_name = names.substring(0, index);
679 second_name = names.substring(index + 1);
680 } else {
681 first_name = second_name = names;
682 }
683 if(key.equals(second_name)) {
684 String meta_value = info.getInfo(key);
685 name_value[0] = first_name;
686 name_value[1] = meta_value;
687 return name_value;
688 }
689 }
690 return null;
691 }
692 protected HashMap getInfoByNames(DBInfo info, String[] metadata_names) {
693 HashMap map = new HashMap();
694 boolean empty_map = true;
695
696 for(int i=0; i<metadata_names.length; i++) {
697 String[] name_value = getMetadata(info, metadata_names[i]);
698 if(name_value != null) {
699 map.put(name_value[0], name_value[1]);
700 empty_map = false;
701 }
702 }
703 return (empty_map == true) ? null : map;
704 }
705}
706
707
Note: See TracBrowser for help on using the repository browser.