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

Last change on this file since 31915 was 31915, checked in by ak19, 7 years ago

Dr Bainbridge thought about it and decided that the correct solution is that, since a collection will always have an oai-inf db from now on, the earliest datestamp of a collection should not fall back to either buildconfig's earliestdatestamp field or else buildconfig's lastmodified. However, the latter are used as the publishing date by the RSS service, and so still stored as Collection.java's earliestDatestamp. Now OAICollection has a new additional field, earliestOAIDatestamp which contains the earliest timestamp in oai-inf db. The OAIReceptionist now determines the earliestDatestamp of the entire OAIRepository solely based on the earliestOAIDatestamp values across all OAICollections, also with no fallbacks on Collections' earliestDatestamp or lastModified fields.

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