source: main/trunk/greenstone3/CollectionGroups.java@ 31853

Last change on this file since 31853 was 31285, checked in by Georgiy Litvinov, 7 years ago

Java code for hierarchy view in cross collection search

File size: 15.5 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
33 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.BerryBasket.class.getName());
34
35 @Override
36 protected Element getServiceDescription(Document doc, String service, String lang, String subset) {
37 // TODO Auto-generated method stub
38 return null;
39 }
40
41 String[] _services = { GROUP_CONTENT, UNIQUE_COLLECTIONS };
42
43 public boolean configure(Element info, Element extra_info) {
44 if (!super.configure(info, extra_info)) {
45 return false;
46 }
47
48 logger.info("Configuring CollectionGroups...");
49 this.config_info = info;
50
51 for (int i = 0; i < _services.length; i++) {
52 Element service = this.desc_doc.createElement(GSXML.SERVICE_ELEM);
53 service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_GROUPINFO);
54 service.setAttribute(GSXML.NAME_ATT, _services[i]);
55 this.short_service_info.appendChild(service);
56 }
57 // Load group configuration from file
58 readGroupConfiguration();
59
60 return true;
61 }
62
63 protected Element processGroupCurrentContent(Element request) {
64
65 Document doc = XMLConverter.newDOM();
66 UserContext userContext = new UserContext(request);
67
68 NodeList collList;
69 NodeList groupList;
70 int collIndex = 0;
71 int grpIndex = 0;
72 boolean hierarchy = true;
73
74 // Prepare basic response
75 Element result = GSXML.createBasicResponse(doc, GSXML.SERVICE_TYPE_GROUPINFO);
76 Element result_collection_list = doc.createElement(GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER);
77 result.appendChild(result_collection_list);
78 Element result_group_list = doc.createElement(GSXML.GROUP_ELEM + GSXML.LIST_MODIFIER);
79 result.appendChild(result_group_list);
80
81 // Get param list from request
82 Element paramList = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
83 // Set default group path (main page)
84 String groupPath = "";
85 // If param list not null and group param exists extract value and
86 // override groupPath variable
87 if (paramList != null) {
88 Element paramGroup = GSXML.getNamedElement(paramList, GSXML.PARAM_ELEM, GSXML.NAME_ATT, GSXML.GROUP_ELEM);
89 if (paramGroup != null) {
90 groupPath = paramGroup.getAttribute(GSXML.VALUE_ATT);
91 }
92 Element paramHierarchy = GSXML.getNamedElement(paramList, GSXML.PARAM_ELEM, GSXML.NAME_ATT, GSXML.HIERARCHY_ELEM);
93 if (paramHierarchy != null){
94 hierarchy = true;
95 }
96 }
97 //Remove leading, ending / and dupliclated /
98 groupPath = groupPath.replaceAll("(/+)", "/");
99 groupPath = groupPath.replaceAll("(^/+)|(/+$)", "");
100
101 Element mrCollectionList = getMRCollectionList(userContext);
102 if (mrCollectionList == null){
103 return result;
104 }
105 //Get current groups and collections
106 Element currentContent = getCurrentContent(groupPath);
107 if (currentContent != null){
108 currentContent = (Element) doc.importNode(currentContent, true);
109 }
110
111 //Get ungrouped collection list
112 Element ungroupedCollectionsList = getUngroupedCollections(mrCollectionList);
113
114 if (currentContent != null){
115 if (hierarchy){
116 collList = currentContent.getElementsByTagName(GSXML.COLLECTION_ELEM);
117 groupList = currentContent.getElementsByTagName(GSXML.GROUP_ELEM);
118 } else {
119 collList = GSXML.getChildrenByTagName(currentContent, GSXML.COLLECTION_ELEM);
120 groupList = GSXML.getChildrenByTagName(currentContent, GSXML.GROUP_ELEM);
121 }
122 //Check collection list for existence
123 int collListLenght = collList.getLength();
124 for (collIndex = 0; collIndex < collListLenght; collIndex++) {
125 Element currentCollection = (Element) collList.item(collIndex);
126 String collection_name = currentCollection.getAttribute(GSXML.NAME_ATT);
127 Element checkedCollection = GSXML.getNamedElement(mrCollectionList, GSXML.COLLECTION_ELEM,GSXML.NAME_ATT, collection_name);
128 if (checkedCollection != null) {
129 //Set position value
130 if (!hierarchy){
131 int position = GSXML.getNodeIndex(currentCollection);
132 checkedCollection.setAttribute(GSXML.POSITION_ATT, Integer.toString(position));
133 }
134 // Add collection to response
135 result_collection_list.appendChild(doc.importNode(checkedCollection, true));
136 } else {
137 //remove collection from currentContent
138 currentCollection.getParentNode().removeChild(currentCollection);
139 collIndex--;
140 collListLenght--;
141 }
142 }
143 //check group
144 int groupListLenght = groupList.getLength();
145 for (grpIndex = 0; grpIndex < groupListLenght; grpIndex++) {
146 Element currentGroup = (Element) groupList.item(grpIndex);
147 String currentGroupName = currentGroup.getAttribute(GSXML.NAME_ATT);
148 Element groupDescription = getGroupDescription(currentGroupName);
149 if (groupDescription != null) {
150 //Set position value
151 if (!hierarchy){
152 int position = GSXML.getNodeIndex(currentGroup);
153 groupDescription.setAttribute(GSXML.POSITION_ATT, Integer.toString(position));
154 }
155 result_group_list.appendChild(doc.importNode(groupDescription, true));
156 } else {
157 //remove group from currentContent
158 currentGroup.getParentNode().removeChild(currentGroup);
159 grpIndex--;
160 groupListLenght--;
161 }
162 }
163 logger.error("Group list lenght " + groupListLenght+ " result_group_list is " + GSXML.elementToString(result_group_list, true));
164
165 }
166 //Add ungrouped collections if groupPath /+ or "" or null
167 if (groupPath.isEmpty()) {
168
169 //Add each ungrouped collection to the collection list in loop
170 NodeList ungroupedCollectionNodes = GSXML.getChildrenByTagName(ungroupedCollectionsList, GSXML.COLLECTION_ATT);
171 if (ungroupedCollectionNodes != null) {
172 for (int k = 0; k < ungroupedCollectionNodes.getLength(); k++) {
173 Element ungroupedCollection = (Element) doc.importNode(ungroupedCollectionNodes.item(k), true);
174 if (!hierarchy){
175 ungroupedCollection.setAttribute(GSXML.POSITION_ATT, String.valueOf(grpIndex + collIndex++));
176 }
177 result_collection_list.appendChild(ungroupedCollection);
178 if (hierarchy){
179
180 currentContent.appendChild(doc.importNode(ungroupedCollectionNodes.item(k), true));
181 }
182 }
183 }
184
185 } else {
186 Element pathInfo = getPathInfo(groupPath);
187 if (currentContent != null){
188 result.appendChild(doc.importNode(pathInfo, true));
189 }
190 }
191 if (hierarchy){
192 result.appendChild(currentContent);
193 }
194 logger.error("currentContent is " + GSXML.elementToString(currentContent, true));
195 return result;
196 }
197
198 protected Element processUniqueCollections(Element request) {
199 Document doc = XMLConverter.newDOM();
200 UserContext userContext = new UserContext(request);
201 // Prepare basic response
202 Element result = GSXML.createBasicResponse(doc, GSXML.SERVICE_TYPE_GROUPINFO);
203 Element resultCollections = doc.createElement(GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER);
204 result.appendChild(resultCollections);
205 Element mrCollectionList = getMRCollectionList(userContext);
206 //Collections from message router check
207 if (mrCollectionList == null){
208 logger.error("mrCollectionList is null!");
209 return result;
210 }
211 //paramList check
212 Element paramList = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
213 if (paramList == null) {
214 logger.error("UniqueCollections request had no paramList.");
215 return result;
216 }
217 //Add collections from request
218 Set<String> uniq_colls = new HashSet<String>();
219 Element collParam = GSXML.getNamedElement(paramList, GSXML.PARAM_ELEM, GSXML.NAME_ATT, GSXML.COLLECTION_ELEM);
220 if (collParam != null){
221 String colls = GSXML.getValue(collParam);
222 if (!colls.isEmpty())
223 {
224 String[] _colls = colls.split(",");
225 for (int i=0;i < _colls.length;i++){
226 uniq_colls.add(_colls[i]);
227 }
228 }
229 }
230 //groupParam check
231 Element groupParam = GSXML.getNamedElement(paramList, GSXML.PARAM_ELEM, GSXML.NAME_ATT, GSXML.GROUP_ELEM);
232 if (groupParam == null) {
233 logger.error("UniqueCollections request had no groupParam.");
234 return result;
235 }
236 //Add collections from groups
237 String[] groups = null;
238 groups = GSXML.getValue(groupParam).split(",");
239 for (int i = 0; i < groups.length; i++) {
240 Element groupContent = getCurrentContent(groups[i]);
241 //If group exists
242 if (groupContent != null) {
243 NodeList collectionNodes = GSXML.getChildrenByTagName(groupContent, GSXML.COLLECTION_ELEM);
244 for (int j = 0; j < collectionNodes.getLength(); j++) {
245 String collName = ((Element) collectionNodes.item(j)).getAttribute(GSXML.NAME_ATT);
246 uniq_colls.add(collName);
247 }
248 }
249
250 }
251 //Fill result collectionList
252 for (Iterator<String> iterator = uniq_colls.iterator(); iterator.hasNext();) {
253 String collectionName = (String) iterator.next();
254 Element checkedCollection = GSXML.getNamedElement(mrCollectionList, GSXML.COLLECTION_ELEM,GSXML.NAME_ATT, collectionName);
255 if (checkedCollection != null){
256 resultCollections.appendChild(doc.importNode(checkedCollection, true));
257 }
258 }
259 return result;
260
261 }
262
263 private Element getCurrentContent(String path) {
264
265 if (hierarchy == null || groupDesc == null) {
266 return null;
267 }
268
269 Document doc = XMLConverter.newDOM();
270
271 if (path == null) {
272 path = "";
273 }
274
275 path = path.replaceAll("(/+)", "/");
276 path = path.replaceAll("(^/+)|(/+$)", "");
277
278 String[] pathSteps = path.split("/");
279
280
281 Element currentView = (Element) hierarchy.cloneNode(true);
282 // Get the current view
283 for (int i = 0; i < pathSteps.length; i++) {
284 if (!pathSteps[i].isEmpty()) {
285 currentView = GSXML.getNamedElement(currentView, GSXML.GROUP_ELEM, GSXML.NAME_ATT, pathSteps[i]);
286 if (currentView == null){
287 break;
288 }
289 }
290 }
291 if (currentView == null || !currentView.hasChildNodes()) {
292 // Return to the main page
293 return null;
294 }
295 return currentView;
296 }
297
298 private void readGroupConfiguration() {
299
300 File configFile = new File(GSFile.groupConfigFile(site_home));
301 //
302 if (!configFile.exists()) {
303 logger.info("Groups config file " + configFile.getPath() + " does not exist.");
304 return;
305 }
306 // Try to read and catch exception if it fails
307 Document doc = XMLConverter.getDOM(configFile);
308 Element content = doc.getDocumentElement();
309
310 // XPath to find empty text nodes.
311 try {
312 XPathFactory xpathFactory = XPathFactory.newInstance();
313 XPathExpression xpathExp = xpathFactory.newXPath().compile("//text()[normalize-space(.) = '']");
314 NodeList emptyTextNodes = (NodeList) xpathExp.evaluate(doc, XPathConstants.NODESET);
315 for (int i = 0; i < emptyTextNodes.getLength(); i++) {
316 Node emptyTextNode = emptyTextNodes.item(i);
317 emptyTextNode.getParentNode().removeChild(emptyTextNode);
318 }
319
320 } catch (XPathExpressionException e) {
321 logger.error("Error occurred while trying to remove emtpy nodes from groupConfig.xml");
322 e.printStackTrace();
323 }
324
325 hierarchy = (Element) GSXML.getChildByTagName(content, GSXML.HIERARCHY_ELEM);
326 groupDesc = (Element) GSXML.getChildByTagName(content, GSXML.GROUP_DESC_ELEM);
327 }
328
329 private Element getGroupDescription(String name) {
330 if (groupDesc != null) {
331 Element description = (Element) GSXML.getNamedElement(groupDesc, GSXML.GROUP_ELEM, GSXML.NAME_ATT, name);
332 if (description != null) {
333 return description;
334 }
335 logger.error("GroupDescription is not defined. Check your groupConfig.xml");
336 }
337
338 logger.error("No group descriptions found. Check your groupConfig.xml");
339 return null;
340 }
341
342 private Element getUngroupedCollections(Element mr_collection_list) {
343
344 if (groupDesc == null || hierarchy == null) {
345 logger.error("No group descriptions in groupConfig.xml. Check your groupConfig.xml");
346 //return mr_collection_list
347 return mr_collection_list;
348 }
349 Document doc = XMLConverter.newDOM();
350 // Create Set
351 Set<String> hierarchy_unique_collections = new HashSet<String>();
352 // Element hierarchyCollections = doc.createElement("coll_list");
353 // Get collection nodes
354
355 NodeList hierarchy_all_collection_list = hierarchy.getElementsByTagName(GSXML.COLLECTION_ELEM);
356 // Save hierarchy collection names to Hashset
357 for (int i = 0; i < hierarchy_all_collection_list.getLength(); i++) {
358 Element collection_element = (Element) hierarchy_all_collection_list.item(i);
359 hierarchy_unique_collections.add(collection_element.getAttribute(GSXML.NAME_ATT));
360 }
361 // Save available by message router collection names to Hashset
362 Set<String> mr_collections = new HashSet<String>();
363 NodeList mr_coll_list = mr_collection_list.getElementsByTagName(GSXML.COLLECTION_ELEM);
364
365 for (int i = 0; i < mr_coll_list.getLength(); i++) {
366 Element collection_element = (Element) mr_coll_list.item(i);
367 mr_collections.add(collection_element.getAttribute(GSXML.NAME_ATT));
368 }
369 //Save collections available by message router and not existed in hierarchy to ungrouped collections set
370 Set<String> ungrouped_collections = new HashSet<String>();
371 for (String string : mr_collections) {
372 if (!hierarchy_unique_collections.contains(string)){
373 ungrouped_collections.add(string);
374 }
375 }
376 //Output
377 Element result = doc.createElement(GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER);
378 for (String name : ungrouped_collections) {
379 Element collection = doc.createElement(GSXML.COLLECTION_ELEM);
380 collection.setAttribute(GSXML.NAME_ATT, name);
381 result.appendChild(collection);
382 }
383 return result;
384
385 }
386 private Element getPathInfo(String path) {
387
388 if (hierarchy == null || groupDesc == null) {
389 return null;
390 }
391
392 Document doc = XMLConverter.newDOM();
393
394 if (path == null) {
395 path = "";
396 }
397 String[] pathSteps = path.split("/");
398
399 Element pathInfo = doc.createElement(GSXML.PATH_ELEM + GSXML.LIST_MODIFIER);
400
401 String currentPath = "";
402 for (int i = 0; i < pathSteps.length; i++) {
403 if (!pathSteps[i].isEmpty()) {
404 currentPath += "/" + pathSteps[i];
405 Element pathStepDescription = getGroupDescription(pathSteps[i]);
406 if (pathStepDescription != null){
407 pathStepDescription.setAttribute(GSXML.POSITION_ATT, String.valueOf(i));
408 pathStepDescription.setAttribute(GSXML.PATH_ATT, currentPath);
409 pathInfo.appendChild(doc.importNode(pathStepDescription, true));
410 }
411 }
412 }
413
414 return pathInfo;
415 }
416 private Element getMRCollectionList(UserContext userContext){
417 Document doc = XMLConverter.newDOM();
418 // Get the message router info
419 Element mr_info_message = doc.createElement(GSXML.MESSAGE_ELEM);
420 Element mr_request = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_DESCRIBE, "", userContext);
421 mr_info_message.appendChild(mr_request);
422 Element mr_info_response_message = (Element) this.router.process(mr_info_message);
423 if (mr_info_response_message == null) {
424 logger.error(" couldn't query the message router!");
425 return null;
426 }
427 Element mr_info_response = (Element) GSXML.getChildByTagName(mr_info_response_message, GSXML.RESPONSE_ELEM);
428 if (mr_info_response == null) {
429 logger.error("Message router response is null!");
430 return null;
431 }
432
433 Element mr_collection_list = (Element) GSXML.getChildByTagName(mr_info_response, GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER);
434
435 return mr_collection_list;
436 }
437}
Note: See TracBrowser for help on using the repository browser.