source: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/CollectionGroups.java@ 31869

Last change on this file since 31869 was 31869, checked in by kjdon, 7 years ago

modified an error message

File size: 19.7 KB
Line 
1package org.greenstone.gsdl3.service;
2
3import java.io.File;
4
5import org.apache.log4j.Logger;
6import org.greenstone.gsdl3.util.GSFile;
7import org.greenstone.gsdl3.util.GSXML;
8import org.greenstone.gsdl3.util.UserContext;
9import org.greenstone.gsdl3.util.XMLConverter;
10import org.w3c.dom.Document;
11import org.w3c.dom.Element;
12import org.w3c.dom.Node;
13import org.w3c.dom.NodeList;
14
15import java.util.Set;
16
17import javax.xml.xpath.XPathConstants;
18import javax.xml.xpath.XPathExpression;
19import javax.xml.xpath.XPathExpressionException;
20import javax.xml.xpath.XPathFactory;
21
22import java.util.HashSet;
23import java.util.Iterator;
24
25public class CollectionGroups extends ServiceRack {
26
27 private Element hierarchy = null;
28 private Element groupDesc = null;
29
30 private static final String GROUP_CONTENT = "GroupCurrentContent";
31 private static final String UNIQUE_COLLECTIONS = "UniqueCollections";
32 private static final String COLLECTIONS_HIERARCHY = "CollectionsHierarchy";
33
34 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.BerryBasket.class.getName());
35
36 @Override
37 protected Element getServiceDescription(Document doc, String service, String lang, String subset) {
38 // TODO Auto-generated method stub
39 return null;
40 }
41
42 String[] _services = { GROUP_CONTENT, UNIQUE_COLLECTIONS, COLLECTIONS_HIERARCHY };
43
44 public boolean configure(Element info, Element extra_info) {
45 if (!super.configure(info, extra_info)) {
46 return false;
47 }
48
49 logger.info("Configuring CollectionGroups...");
50 this.config_info = info;
51
52 for (int i = 0; i < _services.length; i++) {
53 Element service = this.desc_doc.createElement(GSXML.SERVICE_ELEM);
54 service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_GROUPINFO);
55 service.setAttribute(GSXML.NAME_ATT, _services[i]);
56 this.short_service_info.appendChild(service);
57 }
58 // Load group configuration from file
59 return readGroupConfiguration();
60 }
61
62 protected Element processGroupCurrentContent(Element request) {
63
64 Document doc = XMLConverter.newDOM();
65 UserContext userContext = new UserContext(request);
66
67 // Prepare basic response
68 Element result = GSXML.createBasicResponse(doc, GSXML.SERVICE_TYPE_GROUPINFO);
69
70
71 // Get param list from request
72 Element paramList = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
73 // Set default group path (main page)
74 String groupPath = "";
75 // If param list not null and group param exists extract value and
76 // override groupPath variable
77 if (paramList != null) {
78 Element paramGroup = GSXML.getNamedElement(paramList, GSXML.PARAM_ELEM, GSXML.NAME_ATT, GSXML.GROUP_ELEM);
79 if (paramGroup != null) {
80 groupPath = paramGroup.getAttribute(GSXML.VALUE_ATT);
81 }
82 }
83 //Remove leading, ending / and dupliclated /
84 groupPath = groupPath.replaceAll("(/+)", "/");
85 groupPath = groupPath.replaceAll("(^/+)|(/+$)", "");
86
87 Element mrCollectionList = getAvailableCollectionList(userContext);
88 if (mrCollectionList == null){
89 result.appendChild(doc.createElement(GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER));
90 return result;
91 }
92 //Get current groups and collections
93 Element groupContent = getRawCurrentContent(groupPath);
94
95 //Get ungrouped collection list
96 Element ungroupedCollections = getUngroupedCollections(mrCollectionList);
97
98 // If groupContent is empty return empty collection list
99 if (groupContent == null) {
100 result.appendChild(doc.createElement(GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER));
101 return result;
102 }
103 NodeList currentContent = groupContent.getChildNodes();
104 if (currentContent != null && currentContent.getLength() > 0) {
105 // Create CollectionList element in response
106 Element result_collection_list = doc.createElement(GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER);
107 result.appendChild(result_collection_list);
108 Element result_group_list = doc.createElement(GSXML.GROUP_ELEM + GSXML.LIST_MODIFIER);
109 result.appendChild(result_group_list);
110 // Iterate over collections from current view
111 // i represents current position in groupConfig.xml
112 int i;
113 for (i=0; i < currentContent.getLength(); i++) {
114 //logger.warn("NODE CuR Content" + GSXML.xmlNodeToString(currentContent.item(i)));
115
116 if (currentContent.item(i).getNodeName() == GSXML.COLLECTION_ELEM) {
117
118 Element collection = (Element) currentContent.item(i);
119 String collection_name = collection.getAttribute(GSXML.NAME_ATT);
120 // Check whether collection from current view exists in message router response
121 Element checkedCollection = GSXML.getNamedElement(mrCollectionList, GSXML.COLLECTION_ELEM,GSXML.NAME_ATT, collection_name);
122 if (checkedCollection != null) {
123 //Set position value
124 checkedCollection.setAttribute(GSXML.POSITION_ATT, String.valueOf(i));
125 // Add collection to response
126 result_collection_list.appendChild(doc.importNode(checkedCollection, true));
127 }
128
129 //Iterate over groups in current view
130 } else if (currentContent.item(i).getNodeName() == GSXML.GROUP_ELEM) {
131 Element currentGroup = (Element) currentContent.item(i);
132 String currentGroupName = currentGroup.getAttribute(GSXML.NAME_ATT);
133 Element groupDescription = getGroupDescription(currentGroupName);
134
135 groupDescription.setAttribute(GSXML.POSITION_ATT, String.valueOf(i));
136 result_group_list.appendChild(doc.importNode(groupDescription, true));
137 }
138
139 }
140 //Add ungrouped collections if groupPath /+ or "" or null
141 if (groupPath.isEmpty()) {
142
143 //Add each ungrouped collection to the collection list in loop
144 NodeList ungroupedCollectionNodes = GSXML.getChildrenByTagName(ungroupedCollections, GSXML.COLLECTION_ATT);
145 if (ungroupedCollectionNodes != null) {
146 for (int j = 0; j < ungroupedCollectionNodes.getLength(); j++) {
147 //logger.warn("UNGROUPED COLL ELEM" + GSXML.xmlNodeToString(ungroupedCollections).intern());
148 Element ungroupedCollection = (Element) doc.importNode(ungroupedCollectionNodes.item(j), true);
149 ungroupedCollection.setAttribute(GSXML.POSITION_ATT, String.valueOf(i++));
150 result_collection_list.appendChild(ungroupedCollection);
151 }
152 }
153
154 } else {
155 Element groupDescription = getPathInfo(groupPath);
156 if (groupContent != null){
157 result.appendChild(doc.importNode(groupDescription, true));
158 }
159 }
160 }
161
162 return result;
163 }
164
165 protected Element processUniqueCollections(Element request) {
166 Document doc = XMLConverter.newDOM();
167 UserContext userContext = new UserContext(request);
168 // Prepare basic response
169 Element result = GSXML.createBasicResponse(doc, GSXML.SERVICE_TYPE_GROUPINFO);
170 Element resultCollections = doc.createElement(GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER);
171 result.appendChild(resultCollections);
172 Element mrCollectionList = getAvailableCollectionList(userContext);
173 //Collections from message router check
174 if (mrCollectionList == null){
175 logger.error("mrCollectionList is null!");
176 return result;
177 }
178 //paramList check
179 Element paramList = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
180 if (paramList == null) {
181 logger.error("UniqueCollections request had no paramList.");
182 return result;
183 }
184 //Add collections from request
185 Set<String> uniq_colls = new HashSet<String>();
186 Element collParam = GSXML.getNamedElement(paramList, GSXML.PARAM_ELEM, GSXML.NAME_ATT, GSXML.COLLECTION_ELEM);
187 if (collParam != null){
188 String colls = GSXML.getValue(collParam);
189 if (!colls.isEmpty())
190 {
191 String[] _colls = colls.split(",");
192 for (int i=0;i < _colls.length;i++){
193 uniq_colls.add(_colls[i]);
194 }
195 }
196 }
197 //groupParam check
198 Element groupParam = GSXML.getNamedElement(paramList, GSXML.PARAM_ELEM, GSXML.NAME_ATT, GSXML.GROUP_ELEM);
199 if (groupParam == null) {
200 logger.error("UniqueCollections request had no groupParam.");
201 return result;
202 }
203 //Add collections from groups
204 String[] groups = null;
205 groups = GSXML.getValue(groupParam).split(",");
206 for (int i = 0; i < groups.length; i++) {
207 Element groupContent = getRawCurrentContent(groups[i]);
208 //If group exists
209 if (groupContent != null) {
210 NodeList collectionNodes = GSXML.getChildrenByTagName(groupContent, GSXML.COLLECTION_ELEM);
211 for (int j = 0; j < collectionNodes.getLength(); j++) {
212 String collName = ((Element) collectionNodes.item(j)).getAttribute(GSXML.NAME_ATT);
213 uniq_colls.add(collName);
214 }
215 }
216
217 }
218 //Fill result collectionList
219 for (Iterator<String> iterator = uniq_colls.iterator(); iterator.hasNext();) {
220 String collectionName = (String) iterator.next();
221 Element checkedCollection = GSXML.getNamedElement(mrCollectionList, GSXML.COLLECTION_ELEM,GSXML.NAME_ATT, collectionName);
222 if (checkedCollection != null){
223 resultCollections.appendChild(doc.importNode(checkedCollection, true));
224 }
225 }
226 return result;
227
228 }
229
230 protected Element processCollectionsHierarchy(Element request){
231
232 Document doc = XMLConverter.newDOM();
233 UserContext userContext = new UserContext(request);
234 // Prepare basic response
235 Element result = GSXML.createBasicResponse(doc, GSXML.SERVICE_TYPE_GROUPINFO);
236 String currentPath = "";
237 Element currentContent = getRawCurrentContent(currentPath);
238 if (currentContent == null){
239 return result;
240 }
241 Element searchableCollectionList = getSearchableCollectionList(userContext);
242 if (searchableCollectionList == null){
243 return result;
244 }
245
246 //Get ungrouped collection list
247 sanitizeCurrentContent(currentContent, searchableCollectionList);
248 addGroupInfo(currentContent, currentPath);
249 addUngroupedCollections(currentContent, searchableCollectionList);
250 addAllOption(currentContent);
251 result.appendChild(doc.importNode(currentContent, true));
252 return result;
253 }
254
255 private void addAllOption(Element currentContent) {
256 if (currentContent == null){
257 return;
258 }
259 Document doc = currentContent.getOwnerDocument();
260 Element allOption = doc.createElement(GSXML.COLLECTION_ELEM);
261 allOption.setAttribute(GSXML.NAME_ATT, "all");
262 if (currentContent.hasChildNodes()){
263 currentContent.insertBefore(allOption,currentContent.getFirstChild());
264 } else
265 currentContent.appendChild(allOption);
266
267
268 }
269
270 private void addGroupInfo(Element currentContent, String groupPath) {
271 NodeList groups = GSXML.getChildrenByTagName(currentContent,GSXML.GROUP_ELEM);
272 for (int i=0;i<groups.getLength();i++){
273 Element group = (Element) groups.item(i);
274 String name = group.getAttribute(GSXML.NAME_ATT);
275 String newPath = groupPath + "/" + name;
276 group.setAttribute(GSXML.PATH_ATT, newPath);
277 Element groupDescription = getGroupDescription(name);
278 Element titleEl = (Element) GSXML.getChildByTagName(groupDescription, GSXML.TITLE_ELEM);
279 String title = titleEl.getTextContent();
280 group.setAttribute(GSXML.TITLE_ELEM, title );
281 addGroupInfo(group, newPath);
282 }
283
284 }
285
286 private Element getRawCurrentContent(String path) {
287
288 if (path == null) {
289 path = "";
290 }
291
292 Document doc = XMLConverter.newDOM();
293 path = path.replaceAll("(/+)", "/");
294 path = path.replaceAll("(^/+)|(/+$)", "");
295
296 String[] pathSteps = path.split("/");
297
298
299 Element currentContent = (Element) hierarchy.cloneNode(true);
300 // Get the current view
301 for (int i = 0; i < pathSteps.length; i++) {
302 if (!pathSteps[i].isEmpty()) {
303 currentContent = GSXML.getNamedElement(currentContent, GSXML.GROUP_ELEM, GSXML.NAME_ATT, pathSteps[i]);
304 if (currentContent == null){
305 break;
306 }
307 }
308 }
309 if (currentContent == null || !currentContent.hasChildNodes()) {
310 // Return to the main page
311 return null;
312 }
313 return currentContent;
314 }
315
316 private void sanitizeCurrentContent(Element currentContent, Element checkedCollectionList){
317 if (currentContent == null){
318 return;
319 }
320 NodeList nodes = currentContent.getElementsByTagName(GSXML.COLLECTION_ELEM);
321 for (int i = 0; i < nodes.getLength(); i++) {
322 Element element = (Element) nodes.item(i);
323 String name = element.getAttribute(GSXML.NAME_ATT);
324 Element checkedCollection = GSXML.getNamedElement(checkedCollectionList, GSXML.COLLECTION_ELEM, GSXML.NAME_ATT, name);
325 if (checkedCollection == null) {
326 element.getParentNode().removeChild(element);
327 i--;
328 }
329 }
330 }
331
332 private void addUngroupedCollections(Element currentContent, Element availableCollections){
333 if (currentContent == null){
334 return;
335 }
336 Document doc = currentContent.getOwnerDocument();
337 NodeList collectionList = availableCollections.getElementsByTagName(GSXML.COLLECTION_ELEM);
338 for (int i = 0; i < collectionList.getLength();i++){
339 Element collection = (Element) collectionList.item(i);
340 String name = collection.getAttribute(GSXML.NAME_ATT);
341 NodeList foundCollection = GSXML.getNamedElements(currentContent, GSXML.COLLECTION_ELEM, GSXML.NAME_ATT, name);
342 if (foundCollection.getLength() == 0){
343 Element ungroupedCollection = doc.createElement(GSXML.COLLECTION_ELEM);
344 ungroupedCollection.setAttribute(GSXML.NAME_ATT, name);
345 currentContent.appendChild(ungroupedCollection);
346 }
347 }
348
349 }
350
351 private boolean readGroupConfiguration() {
352
353 File configFile = new File(GSFile.groupConfigFile(site_home));
354 //
355 if (!configFile.exists()) {
356 logger.info("Groups config file " + configFile.getPath() + " does not exist.");
357 return false;
358 }
359 // Try to read and catch exception if it fails
360 Document doc = XMLConverter.getDOM(configFile);
361 Element content = doc.getDocumentElement();
362
363 // XPath to find empty text nodes.
364 try {
365 XPathFactory xpathFactory = XPathFactory.newInstance();
366 XPathExpression xpathExp = xpathFactory.newXPath().compile("//text()[normalize-space(.) = '']");
367 NodeList emptyTextNodes = (NodeList) xpathExp.evaluate(doc, XPathConstants.NODESET);
368 for (int i = 0; i < emptyTextNodes.getLength(); i++) {
369 Node emptyTextNode = emptyTextNodes.item(i);
370 emptyTextNode.getParentNode().removeChild(emptyTextNode);
371 }
372
373 } catch (XPathExpressionException e) {
374 logger.error("Error occurred while trying to remove emtpy nodes from groupConfig.xml");
375 e.printStackTrace();
376 return false;
377 }
378
379 hierarchy = (Element) GSXML.getChildByTagName(content, GSXML.HIERARCHY_ELEM);
380 groupDesc = (Element) GSXML.getChildByTagName(content, GSXML.GROUP_DESC_ELEM);
381 if (hierarchy == null || groupDesc == null){
382 logger.error("Error processing groups configuration. <groupConfig> should have both <hierarchy> and <groupDescriptions> elements. Check groupConfig.xml");
383 return false;
384 }
385 verifyGroupDescription();
386 return true;
387 }
388
389 private void verifyGroupDescription() {
390 Document doc = groupDesc.getOwnerDocument();
391 NodeList groups = hierarchy.getElementsByTagName(GSXML.GROUP_ELEM);
392 for (int i = 0; i < groups.getLength(); i++) {
393 Element group = (Element) groups.item(i);
394 String name = group.getAttribute(GSXML.NAME_ATT);
395 Element foundDescription = GSXML.getNamedElement(groupDesc, GSXML.GROUP_ELEM, GSXML.NAME_ATT, name);
396 if (foundDescription == null){
397 Element defaultDescription = doc.createElement(GSXML.GROUP_ELEM);
398 defaultDescription.setAttribute(GSXML.NAME_ATT, name);
399 Element groupTitle = doc.createElement(GSXML.TITLE_ELEM);
400 groupTitle.setTextContent(name);
401 defaultDescription.appendChild(groupTitle);
402 groupDesc.appendChild(defaultDescription);
403 }
404 }
405
406 }
407
408 private Element getGroupDescription(String name) {
409 Element description = (Element) GSXML.getNamedElement(groupDesc, GSXML.GROUP_ELEM, GSXML.NAME_ATT, name);
410 if (description == null) {
411 logger.error("GroupDescription is not defined. Check your groupConfig.xml");
412 }
413 return description;
414 }
415
416 private Element getUngroupedCollections(Element mr_collection_list) {
417
418 Document doc = XMLConverter.newDOM();
419 // Create Set
420 Set<String> hierarchy_unique_collections = new HashSet<String>();
421 // Element hierarchyCollections = doc.createElement("coll_list");
422 // Get collection nodes
423
424 NodeList hierarchy_all_collection_list = hierarchy.getElementsByTagName(GSXML.COLLECTION_ELEM);
425 // Save hierarchy collection names to Hashset
426 for (int i = 0; i < hierarchy_all_collection_list.getLength(); i++) {
427 Element collection_element = (Element) hierarchy_all_collection_list.item(i);
428 hierarchy_unique_collections.add(collection_element.getAttribute(GSXML.NAME_ATT));
429 }
430 // Save available by message router collection names to Hashset
431 Set<String> mr_collections = new HashSet<String>();
432 NodeList mr_coll_list = mr_collection_list.getElementsByTagName(GSXML.COLLECTION_ELEM);
433
434 for (int i = 0; i < mr_coll_list.getLength(); i++) {
435 Element collection_element = (Element) mr_coll_list.item(i);
436 mr_collections.add(collection_element.getAttribute(GSXML.NAME_ATT));
437 }
438 //Save collections available by message router and not existed in hierarchy to ungrouped collections set
439 Set<String> ungrouped_collections = new HashSet<String>();
440 for (String string : mr_collections) {
441 if (!hierarchy_unique_collections.contains(string)){
442 ungrouped_collections.add(string);
443 }
444 }
445 //Output
446 Element result = doc.createElement(GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER);
447 for (String name : ungrouped_collections) {
448 Element collection = doc.createElement(GSXML.COLLECTION_ELEM);
449 collection.setAttribute(GSXML.NAME_ATT, name);
450 result.appendChild(collection);
451 }
452 return result;
453
454 }
455 private Element getPathInfo(String path) {
456
457 Document doc = XMLConverter.newDOM();
458
459 if (path == null) {
460 path = "";
461 }
462 String[] pathSteps = path.split("/");
463
464 Element pathInfo = doc.createElement(GSXML.PATH_ELEM + GSXML.LIST_MODIFIER);
465
466 String currentPath = "";
467 for (int i = 0; i < pathSteps.length; i++) {
468 if (!pathSteps[i].isEmpty()) {
469 currentPath += "/" + pathSteps[i];
470 Element pathStepDescription = getGroupDescription(pathSteps[i]);
471 if (pathStepDescription != null){
472 pathStepDescription.setAttribute(GSXML.POSITION_ATT, String.valueOf(i));
473 pathStepDescription.setAttribute(GSXML.PATH_ATT, currentPath);
474 }
475 pathInfo.appendChild(doc.importNode(pathStepDescription, true));
476 }
477 }
478
479 return pathInfo;
480 }
481 private Element getAvailableCollectionList(UserContext userContext){
482 Document doc = XMLConverter.newDOM();
483 // Get the message router info
484 Element mr_info_message = doc.createElement(GSXML.MESSAGE_ELEM);
485 Element mr_request = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_DESCRIBE, "", userContext);
486 mr_info_message.appendChild(mr_request);
487 Element mr_info_response_message = (Element) this.router.process(mr_info_message);
488 if (mr_info_response_message == null) {
489 logger.error(" couldn't query the message router!");
490 return null;
491 }
492 Element mr_info_response = (Element) GSXML.getChildByTagName(mr_info_response_message, GSXML.RESPONSE_ELEM);
493 if (mr_info_response == null) {
494 logger.error("Message router response is null!");
495 return null;
496 }
497
498 Element mr_collection_list = (Element) GSXML.getChildByTagName(mr_info_response, GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER);
499
500 return mr_collection_list;
501 }
502 private Element getSearchableCollectionList(UserContext userContext){
503 Document doc = XMLConverter.newDOM();
504 Element collectionList = doc.createElement(GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER);
505 // Get the message router info
506 Element mr_info_message = doc.createElement(GSXML.MESSAGE_ELEM);
507 Element mr_request = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_DESCRIBE, "TextQuery" , userContext);
508 mr_info_message.appendChild(mr_request);
509 Element mr_info_response_message = (Element) this.router.process(mr_info_message);
510 if (mr_info_response_message == null) {
511 logger.error(" couldn't query the message router!");
512 return null;
513 }
514 NodeList options = mr_info_response_message.getElementsByTagName(GSXML.PARAM_OPTION_ELEM);
515 for (int i = 0; i < options.getLength(); i++) {
516 Element option = (Element) options.item(i);
517 String name = option.getAttribute(GSXML.NAME_ATT);
518 if (name.equals("all")){
519 continue;
520 }
521 Element collection = doc.createElement(GSXML.COLLECTION_ELEM);
522 collection.setAttribute(GSXML.NAME_ATT, name);
523 collectionList.appendChild(collection);
524 }
525 return collectionList;
526 }
527}
Note: See TracBrowser for help on using the repository browser.