source: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/collection/Collection.java@ 25974

Last change on this file since 25974 was 25974, checked in by sjm84, 12 years ago

Set the global format from the collection config file

  • Property svn:keywords set to Author Date Id Revision
File size: 28.0 KB
Line 
1/*
2 * Collection.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.collection;
20
21import java.io.BufferedReader;
22import java.io.BufferedWriter;
23import java.io.File;
24import java.io.FileReader;
25import java.io.FileWriter;
26import java.io.IOException;
27import java.io.PrintWriter;
28import java.io.StringWriter;
29import java.util.ArrayList;
30import java.util.HashMap;
31
32import org.apache.commons.lang3.StringUtils;
33import org.apache.log4j.Logger;
34import org.greenstone.gsdl3.core.ModuleInterface;
35import org.greenstone.gsdl3.util.GSFile;
36import org.greenstone.gsdl3.util.GSXML;
37import org.greenstone.gsdl3.util.OAIXML;
38import org.greenstone.gsdl3.util.UserContext;
39import org.greenstone.gsdl3.util.XMLTransformer;
40import org.w3c.dom.Document;
41import org.w3c.dom.Element;
42import org.w3c.dom.Node;
43import org.w3c.dom.NodeList;
44
45/**
46 * Represents a collection in Greenstone. A collection is an extension of a
47 * ServiceCluster - it has local data that the services use.
48 *
49 * @author Katherine Don
50 * @see ModuleInterface
51 */
52public class Collection extends ServiceCluster
53{
54
55 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.collection.Collection.class.getName());
56
57 /** is this collection being tidied */
58 protected boolean useBook = false;
59 /** is this collection public or private */
60 protected boolean is_public = true;
61
62 /** does this collection provide the OAI service */
63 protected boolean has_oai = true;
64 /** time when this collection was built */
65 protected long lastmodified = 0;
66 /** earliestDatestamp of this collection. Necessary for OAI */
67 protected long earliestDatestamp = 0;
68
69 /** Stores the default accessibility of guest users */
70 protected boolean _publicAccess = true;
71 /** Stores the scope of any security rules (either collection or document) */
72 protected boolean _securityScopeCollection = true;
73
74 protected HashMap<String, ArrayList<Element>> _documentSets = new HashMap<String, ArrayList<Element>>();
75 protected ArrayList<HashMap<String, ArrayList<String>>> _securityExceptions = new ArrayList<HashMap<String, ArrayList<String>>>();
76
77 /**
78 * An element containing the serviceRackList element of buildConfig.xml,
79 * used to determine whether it contains the OAIPMH serviceRack
80 */
81 //protected Element service_rack_list = null;
82
83 protected XMLTransformer transformer = null;
84
85 /** same as setClusterName */
86 public void setCollectionName(String name)
87 {
88 setClusterName(name);
89 }
90
91 public Collection()
92 {
93 super();
94 this.description = this.doc.createElement(GSXML.COLLECTION_ELEM);
95 }
96
97 /**
98 * Configures the collection.
99 *
100 * gsdlHome and collectionName must be set before configure is called.
101 *
102 * the file buildcfg.xml is located in gsdlHome/collect/collectionName
103 * collection metadata is obtained, and services loaded.
104 *
105 * @return true/false on success/fail
106 */
107 public boolean configure()
108 {
109 if (this.site_home == null || this.cluster_name == null)
110 {
111 logger.error("Collection: site_home and collection_name must be set before configure called!");
112 return false;
113 }
114
115 Element coll_config_xml = loadCollConfigFile();
116 Element build_config_xml = loadBuildConfigFile();
117
118 if (coll_config_xml == null || build_config_xml == null)
119 {
120 return false;
121 }
122
123 // get the collection type attribute
124 Element search = (Element) GSXML.getChildByTagName(coll_config_xml, GSXML.SEARCH_ELEM);
125 if (search != null)
126 {
127 col_type = search.getAttribute(GSXML.TYPE_ATT);
128 }
129
130 Element browse = (Element) GSXML.getChildByTagName(coll_config_xml, GSXML.INFODB_ELEM);
131 if (browse != null)
132 {
133 db_type = browse.getAttribute(GSXML.TYPE_ATT);
134 }
135 else
136 {
137 db_type = "gdbm"; //Default database type
138 }
139
140 _globalFormat = (Element) GSXML.getChildByTagName(coll_config_xml, GSXML.FORMAT_ELEM);
141
142 // process the metadata and display items
143 findAndLoadInfo(coll_config_xml, build_config_xml);
144
145 loadSecurityInformation(coll_config_xml);
146
147 // now do the services
148 configureServiceRacks(coll_config_xml, build_config_xml);
149
150 return true;
151
152 }
153
154 public boolean useBook()
155 {
156 return useBook;
157 }
158
159 public boolean isPublic()
160 {
161 return is_public;
162 }
163
164 // Not used anymore by the OAIReceptionist to find out the earliest datestamp
165 // amongst all oai collections in the repository. May be useful generally.
166 public long getLastmodified()
167 {
168 return lastmodified;
169 }
170
171 //used by the OAIReceptionist to find out the earliest datestamp amongst all oai collections in the repository
172 public long getEarliestDatestamp()
173 {
174 return earliestDatestamp;
175 }
176
177 /**
178 * whether the service_map in ServiceCluster.java contains the service
179 * 'OAIPMH' 11/06/2007 xiao
180 */
181 public boolean hasOAI()
182 {
183 return has_oai;
184 }
185
186 /**
187 * load in the collection config file into a DOM Element
188 */
189 protected Element loadCollConfigFile()
190 {
191
192 File coll_config_file = new File(GSFile.collectionConfigFile(this.site_home, this.cluster_name));
193
194 if (!coll_config_file.exists())
195 {
196 logger.error("Collection: couldn't configure collection: " + this.cluster_name + ", " + coll_config_file + " does not exist");
197 return null;
198 }
199 // get the xml for both files
200 Document coll_config_doc = this.converter.getDOM(coll_config_file, CONFIG_ENCODING);
201 Element coll_config_elem = null;
202 if (coll_config_doc != null)
203 {
204 coll_config_elem = coll_config_doc.getDocumentElement();
205 }
206 return coll_config_elem;
207
208 }
209
210 /**
211 * load in the collection build config file into a DOM Element
212 */
213 protected Element loadBuildConfigFile()
214 {
215 File build_config_file = new File(GSFile.collectionBuildConfigFile(this.site_home, this.cluster_name));
216 if (!build_config_file.exists())
217 {
218 logger.error("Collection: couldn't configure collection: " + this.cluster_name + ", " + build_config_file + " does not exist");
219 return null;
220 }
221 Document build_config_doc = this.converter.getDOM(build_config_file, CONFIG_ENCODING);
222 Element build_config_elem = null;
223 if (build_config_doc != null)
224 {
225 build_config_elem = build_config_doc.getDocumentElement();
226 }
227
228 lastmodified = build_config_file.lastModified();
229
230 return build_config_elem;
231 }
232
233 /**
234 * find the metadata and display elems from the two config files and add it
235 * to the appropriate lists
236 */
237 protected boolean findAndLoadInfo(Element coll_config_xml, Element build_config_xml)
238 {
239 Element meta_list = (Element) GSXML.getChildByTagName(coll_config_xml, GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
240 addMetadata(meta_list);
241 meta_list = (Element) GSXML.getChildByTagName(build_config_xml, GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
242 addMetadata(meta_list);
243
244 meta_list = this.doc.createElement(GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
245 GSXML.addMetadata(this.doc, meta_list, "httpPath", this.site_http_address + "/collect/" + this.cluster_name);
246 addMetadata(meta_list);
247
248 // display stuff
249 Element display_list = (Element) GSXML.getChildByTagName(coll_config_xml, GSXML.DISPLAY_TEXT_ELEM + GSXML.LIST_MODIFIER);
250 if (display_list != null)
251 {
252 resolveMacros(display_list);
253 addDisplayItems(display_list);
254 }
255
256 //check whether the html are tidy or not
257 Element import_list = (Element) GSXML.getChildByTagName(coll_config_xml, GSXML.IMPORT_ELEM);
258 if (import_list != null)
259 {
260 Element plugin_list = (Element) GSXML.getChildByTagName(import_list, GSXML.PLUGIN_ELEM + GSXML.LIST_MODIFIER);
261 addPlugins(plugin_list);
262 if (plugin_list != null)
263 {
264 Element plugin_elem = (Element) GSXML.getNamedElement(plugin_list, GSXML.PLUGIN_ELEM, GSXML.NAME_ATT, "HTMLPlugin");
265 if (plugin_elem != null)
266 {
267 //get the option
268 Element option_elem = (Element) GSXML.getNamedElement(plugin_elem, GSXML.PARAM_OPTION_ELEM, GSXML.NAME_ATT, "-use_realistic_book");
269 if (option_elem != null)
270 {
271 useBook = true;
272 }
273 }
274 }
275 }
276 meta_list = this.doc.createElement(GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
277 if (useBook == true)
278 GSXML.addMetadata(this.doc, meta_list, "tidyoption", "tidy");
279 else
280 GSXML.addMetadata(this.doc, meta_list, "tidyoption", "untidy");
281 addMetadata(meta_list);
282
283 // check whether we are public or not
284 if (this.metadata_list != null)
285 {
286 Element meta_elem = (Element) GSXML.getNamedElement(this.metadata_list, GSXML.METADATA_ELEM, GSXML.NAME_ATT, "public");
287 if (meta_elem != null)
288 {
289 String value = GSXML.getValue(meta_elem).toLowerCase().trim();
290 if (value.equals("false"))
291 {
292 is_public = false;
293 }
294 }
295 }
296 return true;
297 }
298
299 protected void loadSecurityInformation(Element coll_config_xml)
300 {
301 Element securityBlock = (Element) GSXML.getChildByTagName(coll_config_xml, GSXML.SECURITY_ELEM);
302
303 if (securityBlock == null)
304 {
305 return;
306 }
307
308 String scope = securityBlock.getAttribute(GSXML.SCOPE_ATT);
309 String defaultAccess = securityBlock.getAttribute(GSXML.DEFAULT_ACCESS_ATT);
310
311 if (defaultAccess.toLowerCase().equals("public"))
312 {
313 _publicAccess = true;
314 }
315 else if (defaultAccess.toLowerCase().equals("private"))
316 {
317 _publicAccess = false;
318 }
319 else
320 {
321 logger.warn("Default access for collection " + this.cluster_name + " is neither public or private, assuming public");
322 }
323
324 if (scope.toLowerCase().equals("collection"))
325 {
326 _securityScopeCollection = true;
327 }
328 else if (scope.toLowerCase().equals("documents") || scope.toLowerCase().equals("document"))
329 {
330 _securityScopeCollection = false;
331 }
332 else
333 {
334 logger.warn("Security scope is neither collection or document, assuming collection");
335 }
336
337 NodeList exceptions = GSXML.getChildrenByTagName(securityBlock, GSXML.EXCEPTION_ELEM);
338
339 if (exceptions.getLength() > 0)
340 {
341 if (!_securityScopeCollection)
342 {
343 NodeList documentSetElems = GSXML.getChildrenByTagName(securityBlock, GSXML.DOCUMENT_SET_ELEM);
344 for (int i = 0; i < documentSetElems.getLength(); i++)
345 {
346 Element documentSet = (Element) documentSetElems.item(i);
347 String setName = documentSet.getAttribute(GSXML.NAME_ATT);
348 NodeList matchStatements = GSXML.getChildrenByTagName(documentSet, GSXML.MATCH_ELEM);
349 ArrayList<Element> matchStatementList = new ArrayList<Element>();
350 for (int j = 0; j < matchStatements.getLength(); j++)
351 {
352 matchStatementList.add((Element) matchStatements.item(j));
353 }
354 _documentSets.put(setName, matchStatementList);
355 }
356 }
357
358 for (int i = 0; i < exceptions.getLength(); i++)
359 {
360 HashMap<String, ArrayList<String>> securityException = new HashMap<String, ArrayList<String>>();
361 ArrayList<String> exceptionGroups = new ArrayList<String>();
362 ArrayList<String> exceptionSets = new ArrayList<String>();
363
364 Element exception = (Element) exceptions.item(i);
365 NodeList groups = GSXML.getChildrenByTagName(exception, GSXML.GROUP_ELEM);
366 for (int j = 0; j < groups.getLength(); j++)
367 {
368 Element group = (Element) groups.item(j);
369 String groupName = group.getAttribute(GSXML.NAME_ATT);
370 exceptionGroups.add(groupName);
371 }
372 NodeList docSets = GSXML.getChildrenByTagName(exception, GSXML.DOCUMENT_SET_ELEM);
373 for (int j = 0; j < docSets.getLength(); j++)
374 {
375 Element docSet = (Element) docSets.item(j);
376 String docSetName = docSet.getAttribute(GSXML.NAME_ATT);
377 exceptionSets.add(docSetName);
378 }
379
380 securityException.put("groups", exceptionGroups);
381 securityException.put("sets", exceptionSets);
382 _securityExceptions.add(securityException);
383 }
384 }
385 }
386
387 protected boolean configureServiceRacks(Element coll_config_xml, Element build_config_xml)
388 {
389 clearServices();
390 Element service_list = (Element) GSXML.getChildByTagName(build_config_xml, GSXML.SERVICE_CLASS_ELEM + GSXML.LIST_MODIFIER);
391 configureServiceRackList(service_list, coll_config_xml);
392
393 // collection Config may also contain manually added service racks
394 service_list = (Element) GSXML.getChildByTagName(coll_config_xml, GSXML.SERVICE_CLASS_ELEM + GSXML.LIST_MODIFIER);
395 if (service_list != null)
396 {
397 configureServiceRackList(service_list, build_config_xml);
398
399 // Check for oai
400 Element oai_service_rack = GSXML.getNamedElement(service_list, GSXML.SERVICE_CLASS_ELEM, OAIXML.NAME, OAIXML.OAIPMH);
401 if (oai_service_rack == null)
402 {
403 has_oai = false;
404 logger.info("No oai for collection: " + this.cluster_name);
405
406 }
407 else
408 {
409 has_oai = true;
410
411 // extract earliestDatestamp from the buildconfig.xml for OAI
412 Element metadata_list = (Element) GSXML.getChildByTagName(build_config_xml, GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
413
414 if (metadata_list != null)
415 {
416 NodeList children = metadata_list.getElementsByTagName(GSXML.METADATA_ELEM);
417 // can't do getChildNodes(), because whitespace, such as newlines, creates Text nodes
418 for (int i = 0; i < children.getLength(); i++)
419 {
420 Element metadata = (Element) children.item(i);
421 if (metadata.getAttribute(GSXML.NAME_ATT).equals(OAIXML.EARLIEST_DATESTAMP))
422 {
423 String earliestDatestampStr = GSXML.getValue(metadata);
424 if (!earliestDatestampStr.equals(""))
425 {
426 earliestDatestamp = Long.parseLong(earliestDatestampStr);
427 }
428 break; // found a metadata element with name=earliestDatestamp in buildconfig
429 }
430 }
431 }
432
433 // If at the end of this, there is no value for earliestDatestamp, print out a warning
434 logger.warn("No earliestDatestamp in buildConfig.xml for collection: " + this.cluster_name + ". Defaulting to 0.");
435
436 }
437 }
438 else
439 { // no list of services (no ServiceRackList), so no oai_service_rack either
440 // explicitly set has_oai to false here, since it's initialised to true by default
441 has_oai = false;
442 }
443 return true;
444 }
445
446 protected boolean resolveMacros(Element display_list)
447 {
448 if (display_list == null)
449 return false;
450 NodeList displaynodes = display_list.getElementsByTagName(GSXML.DISPLAY_TEXT_ELEM);
451 if (displaynodes.getLength() > 0)
452 {
453 String http_site = this.site_http_address;
454 String http_collection = this.site_http_address + "/collect/" + this.cluster_name;
455 for (int k = 0; k < displaynodes.getLength(); k++)
456 {
457 Element d = (Element) displaynodes.item(k);
458 String text = GSXML.getNodeText(d);
459 text = StringUtils.replace(text, "_httpsite_", http_site);
460 text = StringUtils.replace(text, "_httpcollection_", http_collection);
461 GSXML.setNodeText(d, text);
462 }
463 }
464 return true;
465 }
466
467 /**
468 * do a configure on only part of the collection
469 */
470 protected boolean configureSubset(String subset)
471 {
472
473 // need the coll config files
474 Element coll_config_elem = loadCollConfigFile();
475 Element build_config_elem = loadBuildConfigFile();
476 if (coll_config_elem == null || build_config_elem == null)
477 {
478 // wont be able to do any of the requests
479 return false;
480 }
481
482 if (subset.equals(GSXML.SERVICE_ELEM + GSXML.LIST_MODIFIER))
483 {
484 return configureServiceRacks(coll_config_elem, build_config_elem);
485 }
486
487 if (subset.equals(GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER) || subset.equals(GSXML.DISPLAY_TEXT_ELEM + GSXML.LIST_MODIFIER) || subset.equals(GSXML.PLUGIN_ELEM + GSXML.LIST_MODIFIER))
488 {
489 return findAndLoadInfo(coll_config_elem, build_config_elem);
490
491 }
492
493 logger.error("Collection: cant process system request, configure " + subset);
494 return false;
495 }
496
497 /**
498 * handles requests made to the ServiceCluster itself
499 *
500 * @param req
501 * - the request Element- <request>
502 * @return the result Element - should be <response>
503 */
504 protected Element processMessage(Element request)
505 {
506
507 Element response = this.doc.createElement(GSXML.RESPONSE_ELEM);
508 response.setAttribute(GSXML.FROM_ATT, this.cluster_name);
509 String type = request.getAttribute(GSXML.TYPE_ATT);
510 String lang = request.getAttribute(GSXML.LANG_ATT);
511 response.setAttribute(GSXML.TYPE_ATT, type);
512
513 if (type.equals(GSXML.REQUEST_TYPE_FORMAT_STRING))
514 {
515 String subaction = request.getAttribute("subaction");
516 String service = request.getAttribute("service");
517
518 String classifier = null;
519 if (service.equals("ClassifierBrowse"))
520 {
521 classifier = request.getAttribute("classifier");
522 }
523
524 // check for version file
525 String directory = new File(GSFile.collectionConfigFile(this.site_home, this.cluster_name)).getParent() + File.separator;
526
527 String version_filename = "";
528 if (service.equals("ClassifierBrowse"))
529 version_filename = directory + "browse_" + classifier + "_format_statement_version.txt";
530 else
531 version_filename = directory + "query_format_statement_version.txt";
532
533 File version_file = new File(version_filename);
534
535 if (subaction.equals("update"))
536 {
537 Element format_element = (Element) GSXML.getChildByTagName(request, GSXML.FORMAT_STRING_ELEM);
538 //String format_string = GSXML.getNodeText(format_element);
539 Element format_statement = (Element) format_element.getFirstChild();
540
541 String version_number = "1";
542 BufferedWriter writer;
543
544 try
545 {
546
547 if (version_file.exists())
548 {
549 // Read version
550 BufferedReader reader = new BufferedReader(new FileReader(version_filename));
551 version_number = reader.readLine();
552 int aInt = Integer.parseInt(version_number) + 1;
553 version_number = Integer.toString(aInt);
554 reader.close();
555 }
556 else
557 {
558 // Create
559 version_file.createNewFile();
560 writer = new BufferedWriter(new FileWriter(version_filename));
561 writer.write(version_number);
562 writer.close();
563 }
564
565 // Write version file
566 String format_statement_filename = "";
567
568 if (service.equals("ClassifierBrowse"))
569 format_statement_filename = directory + "browse_" + classifier + "_format_statement_v" + version_number + ".txt";
570 else
571 format_statement_filename = directory + "query_format_statement_v" + version_number + ".txt";
572
573 // Write format statement
574 String format_string = this.converter.getString(format_statement); //GSXML.xmlNodeToString(format_statement);
575 writer = new BufferedWriter(new FileWriter(format_statement_filename));
576 writer.write(format_string);
577 writer.close();
578
579 // Update version number
580 writer = new BufferedWriter(new FileWriter(version_filename));
581 writer.write(version_number);
582 writer.close();
583
584 }
585 catch (IOException e)
586 {
587 logger.error("IO Exception " + e);
588 }
589 }
590
591 if (subaction.equals("saveDocument"))
592 {
593 Element format_element = (Element) GSXML.getChildByTagName(request, GSXML.FORMAT_STRING_ELEM);
594 //String format_string = GSXML.getNodeText(format_element);
595 // Get display tag
596 Element display_format = (Element) format_element.getFirstChild();
597
598 String collection_config = directory + "collectionConfig.xml";
599 Document config = this.converter.getDOM(new File(collection_config), "UTF-8");
600
601 Node current_node = GSXML.getChildByTagName(config, "CollectionConfig");
602
603 // Get display child
604 if (GSXML.getChildByTagName(current_node, "display") == null)
605 {
606 // well then create a format tag
607 Element display_tag = config.createElement("display");
608 current_node = (Node) current_node.appendChild(display_tag);
609 }
610 else
611 {
612 current_node = GSXML.getChildByTagName(current_node, "display");
613 }
614
615 if (GSXML.getChildByTagName(current_node, "format") == null)
616 {
617 // well then create a format tag
618 Element format_tag = config.createElement("format");
619 current_node.appendChild(format_tag);
620 }
621
622 current_node.replaceChild(config.importNode(display_format, true), GSXML.getChildByTagName(current_node, "format"));
623
624 String new_config = this.converter.getString(config);
625
626 new_config = StringUtils.replace(new_config, "&lt;", "<");
627 new_config = StringUtils.replace(new_config, "&gt;", ">");
628 new_config = StringUtils.replace(new_config, "&quot;", "\"");
629
630 try
631 {
632 // Write to file (not original! for now)
633 BufferedWriter writer = new BufferedWriter(new FileWriter(collection_config + ".new"));
634 writer.write(new_config);
635 writer.close();
636 }
637 catch (IOException e)
638 {
639 logger.error("IO Exception " + e);
640 }
641 }
642
643 if (subaction.equals("save"))
644 {
645 Element format_element = (Element) GSXML.getChildByTagName(request, GSXML.FORMAT_STRING_ELEM);
646 Element format_statement = (Element) format_element.getFirstChild();
647
648 try
649 {
650 // open collectionConfig.xml and read in to w3 Document
651 String collection_config = directory + "collectionConfig.xml";
652 Document config = this.converter.getDOM(new File(collection_config), "UTF-8");
653
654 //String tag_name = "";
655 int k;
656 int index;
657 Element elem;
658 // Try importing entire tree to this.doc so we can add and remove children at ease
659 //Node current_node = this.doc.importNode(GSXML.getChildByTagName(config, "CollectionConfig"),true);
660 Node current_node = GSXML.getChildByTagName(config, "CollectionConfig");
661 NodeList current_node_list;
662
663 if (service.equals("ClassifierBrowse"))
664 {
665 //tag_name = "browse";
666 // if CLX then need to look in <classifier> X then <format>
667 // default is <browse><format>
668
669 current_node = GSXML.getChildByTagName(current_node, "browse");
670
671 // find CLX
672 if (classifier != null)
673 {
674 current_node_list = GSXML.getChildrenByTagName(current_node, "classifier");
675 index = Integer.parseInt(classifier.substring(2)) - 1;
676
677 // index should be given by X-1
678 current_node = current_node_list.item(index);
679 // what if classifier does not have a format tag?
680 if (GSXML.getChildByTagName(current_node, "format") == null)
681 {
682 // well then create a format tag
683 Element format_tag = config.createElement("format");
684 current_node.appendChild(format_tag);
685 }
686 }
687 else
688 {
689 // To support all classifiers, set classifier to null? There is the chance here that the format tag does not exist
690 if (GSXML.getChildByTagName(current_node, "format") == null)
691 {
692 // well then create a format tag
693 Element format_tag = config.createElement("format");
694 current_node.appendChild(format_tag);
695 }
696 }
697 }
698 else if (service.equals("AllClassifierBrowse"))
699 {
700 current_node = GSXML.getChildByTagName(current_node, "browse");
701 if (GSXML.getChildByTagName(current_node, "format") == null)
702 {
703 // well then create a format tag
704 Element format_tag = config.createElement("format");
705 current_node.appendChild(format_tag);
706 }
707 }
708 else
709 {
710 // look in <format> with no attributes
711 current_node_list = GSXML.getChildrenByTagName(current_node, "search");
712 for (k = 0; k < current_node_list.getLength(); k++)
713 {
714 current_node = current_node_list.item(k);
715 // if current_node has no attributes then break
716 elem = (Element) current_node;
717 if (elem.hasAttribute("name") == false)
718 break;
719 }
720 }
721
722 current_node.replaceChild(config.importNode(format_statement, true), GSXML.getChildByTagName(current_node, "format"));
723
724 // Now convert config document to string for writing to file
725 String new_config = this.converter.getString(config);
726
727 new_config = StringUtils.replace(new_config, "&lt;", "<");
728 new_config = StringUtils.replace(new_config, "&gt;", ">");
729 new_config = StringUtils.replace(new_config, "&quot;", "\"");
730
731 // Write to file (not original! for now)
732 BufferedWriter writer = new BufferedWriter(new FileWriter(collection_config + ".new"));
733 writer.write(new_config);
734 writer.close();
735
736 }
737 catch (Exception ex)
738 {
739 logger.error("There was an exception " + ex);
740
741 StringWriter sw = new StringWriter();
742 PrintWriter pw = new PrintWriter(sw, true);
743 ex.printStackTrace(pw);
744 pw.flush();
745 sw.flush();
746 logger.error(sw.toString());
747 }
748
749 }
750 }
751 else if (type.equals(GSXML.REQUEST_TYPE_SECURITY))
752 {
753 String oid = request.getAttribute("oid");
754 if (oid.contains("."))
755 {
756 oid = oid.substring(0, oid.indexOf("."));
757 }
758
759 ArrayList<String> groups = getPermittedGroups(oid);
760
761 Element groupList = this.doc.createElement(GSXML.GROUP_ELEM + GSXML.LIST_MODIFIER);
762 response.appendChild(groupList);
763
764 for (String groupName : groups)
765 {
766 Element group = this.doc.createElement(GSXML.GROUP_ELEM);
767 groupList.appendChild(group);
768 group.setAttribute(GSXML.NAME_ATT, groupName);
769 }
770 }
771 else
772 { // unknown type
773 return super.processMessage(request);
774
775 }
776 return response;
777 }
778
779 protected ArrayList<String> getPermittedGroups(String oid)
780 {
781 ArrayList<String> groups = new ArrayList<String>();
782
783 if (_securityScopeCollection)
784 {
785 if (_publicAccess)
786 {
787 groups.add("");
788 }
789 else
790 {
791 for (HashMap<String, ArrayList<String>> exception : _securityExceptions)
792 {
793 for (String group : exception.get("groups"))
794 {
795 groups.add(group);
796 }
797 }
798 }
799 }
800 else
801 {
802 if (oid != null && !oid.equals(""))
803 {
804 boolean inSet = false;
805 for (HashMap<String, ArrayList<String>> exception : _securityExceptions)
806 {
807 for (String setName : exception.get("sets"))
808 {
809 if (documentIsInSet(oid, setName))
810 {
811 inSet = true;
812 for (String group : exception.get("groups"))
813 {
814 groups.add(group);
815 }
816 }
817 }
818 }
819
820 if (!inSet && _publicAccess)
821 {
822 groups.add("");
823 }
824 }
825 else
826 {
827 groups.add("");
828 }
829 }
830
831 return groups;
832 }
833
834 protected boolean documentIsInSet(String oid, String setName)
835 {
836 ArrayList<Element> matchStatements = _documentSets.get(setName);
837 if (matchStatements == null || matchStatements.size() == 0)
838 {
839 return false;
840 }
841
842 for (Element currentMatchStatement : matchStatements)
843 {
844 String fieldName = currentMatchStatement.getAttribute(GSXML.FIELD_ATT);
845 if (fieldName == null || fieldName.equals(""))
846 {
847 fieldName = "oid";
848 }
849
850 String type = currentMatchStatement.getAttribute(GSXML.TYPE_ATT);
851 if (type == null || type.equals(""))
852 {
853 type = "match";
854 }
855
856 String fieldValue = "";
857 if (!fieldName.equals("oid"))
858 {
859 fieldValue = getFieldValue(oid, fieldName);
860 if (fieldValue == null)
861 {
862 return false;
863 }
864 }
865 else
866 {
867 fieldValue = oid;
868 }
869
870 String matchValue = GSXML.getNodeText(currentMatchStatement);
871 if (type.equals("match"))
872 {
873 if (matchValue.equals(fieldValue))
874 {
875 return true;
876 }
877 }
878 else if (type.equals("regex"))
879 {
880 if (fieldValue.matches(matchValue))
881 {
882 return true;
883 }
884 }
885 else
886 {
887 logger.warn("Unknown type of match specified in security block of collection " + this.cluster_name + ".");
888 }
889 }
890
891 return false;
892 }
893
894 protected String getFieldValue(String oid, String fieldName)
895 {
896 Element metadataMessage = this.doc.createElement(GSXML.MESSAGE_ELEM);
897 Element metadataRequest = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, this.cluster_name + "/DocumentMetadataRetrieve", new UserContext());
898 metadataMessage.appendChild(metadataRequest);
899
900 Element paramList = this.doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
901 metadataRequest.appendChild(paramList);
902
903 Element param = this.doc.createElement(GSXML.PARAM_ELEM);
904 paramList.appendChild(param);
905
906 param.setAttribute(GSXML.NAME_ATT, "metadata");
907 param.setAttribute(GSXML.VALUE_ATT, fieldName);
908
909 Element docList = this.doc.createElement(GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER);
910 metadataRequest.appendChild(docList);
911
912 Element doc = this.doc.createElement(GSXML.DOC_NODE_ELEM);
913 docList.appendChild(doc);
914
915 doc.setAttribute(GSXML.NODE_ID_ATT, oid);
916
917 Element response = (Element) this.router.process(metadataMessage);
918 NodeList metadataElems = response.getElementsByTagName(GSXML.METADATA_ELEM);
919
920 if (metadataElems.getLength() > 0)
921 {
922 Element metadata = (Element) metadataElems.item(0);
923 return GSXML.getNodeText(metadata);
924 }
925
926 return null;
927 }
928}
Note: See TracBrowser for help on using the repository browser.