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

Last change on this file since 26446 was 26446, checked in by kjdon, 11 years ago

trying to tidy up the collection classes. Move some general stuff to servicecluster and reuse the code a bit more

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