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

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

Fixing nullpointer exception thrown when there is no collection groups configuration file (when there are no collectiongroups).

File size: 10.8 KB
Line 
1package org.greenstone.gsdl3.service;
2
3import java.io.File;
4import org.apache.log4j.Logger;
5import org.greenstone.gsdl3.util.GSFile;
6import org.greenstone.gsdl3.util.GSXML;
7import org.greenstone.gsdl3.util.UserContext;
8import org.greenstone.gsdl3.util.XMLConverter;
9import org.w3c.dom.Document;
10import org.w3c.dom.Element;
11import org.w3c.dom.Node;
12import org.w3c.dom.NodeList;
13import java.util.Set;
14
15import javax.xml.xpath.XPathConstants;
16import javax.xml.xpath.XPathExpression;
17import javax.xml.xpath.XPathExpressionException;
18import javax.xml.xpath.XPathFactory;
19
20import java.util.HashSet;
21
22public class CollectionGroups extends ServiceRack {
23
24 private Element hierarchy = null;
25 private Element groupDesc = null;
26
27 private static final String GROUP_CONTENT = "GroupCurrentContent";
28
29 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.BerryBasket.class.getName());
30
31 @Override
32 protected Element getServiceDescription(Document doc, String service, String lang, String subset) {
33 // TODO Auto-generated method stub
34 return null;
35 }
36
37 String[] _services = { GROUP_CONTENT };
38
39 public boolean configure(Element info, Element extra_info) {
40 if (!super.configure(info, extra_info)) {
41 return false;
42 }
43
44 logger.info("Configuring CollectionGroups...");
45 this.config_info = info;
46
47 for (int i = 0; i < _services.length; i++) {
48 Element service = this.desc_doc.createElement(GSXML.SERVICE_ELEM);
49 service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_GROUPINFO);
50 service.setAttribute(GSXML.NAME_ATT, _services[i]);
51 this.short_service_info.appendChild(service);
52 }
53 // Load group configuration from file
54 readGroupConfiguration();
55
56 return true;
57 }
58
59 protected Element processGroupCurrentContent(Element request) {
60
61 Document doc = XMLConverter.newDOM();
62
63 UserContext userContext = new UserContext(request);
64
65 // Get param list from request
66 Element paramList = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
67 // Set default group path (main page)
68 String groupPath = "";
69 // If param list not null and group param exists extract value and
70 // override groupPath variable
71 if (paramList != null) {
72 Element paramGroup = GSXML.getNamedElement(paramList, GSXML.PARAM_ELEM, GSXML.NAME_ATT, GSXML.GROUP_ELEM);
73 if (paramGroup != null) {
74 groupPath = paramGroup.getAttribute(GSXML.VALUE_ATT);
75 }
76 }
77 //Remove leading, ending / and dupliclated /
78 groupPath = groupPath.replaceAll("(/+)", "/");
79 groupPath = groupPath.replaceAll("(^/+)|(/+$)", "");
80
81 // Get the message router info
82 Element mr_info_message = doc.createElement(GSXML.MESSAGE_ELEM);
83 Element mr_request = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_DESCRIBE, "", userContext);
84 mr_info_message.appendChild(mr_request);
85 Element mr_info_response_message = (Element) this.router.process(mr_info_message);
86 if (mr_info_response_message == null) {
87 logger.error(" couldn't query the message router!");
88 return null;
89 }
90 Element mr_info_response = (Element) GSXML.getChildByTagName(mr_info_response_message, GSXML.RESPONSE_ELEM);
91 if (mr_info_response == null) {
92 logger.error("couldn't query the message router!");
93 return null;
94 }
95
96 Element mr_collection_list = (Element) GSXML.getChildByTagName(mr_info_response,
97 GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER);
98 //Get current groups and collections
99 Element groupContent = getCurrentContent(groupPath);
100
101 //Get ungrouped collection list
102 Element ungroupedCollections = getUngroupedCollections(mr_collection_list);
103
104 // Prepare basic response
105 Element result = GSXML.createBasicResponse(doc, GSXML.SERVICE_TYPE_GROUPINFO);
106
107 // If groupContent is empty return empty collection list
108 if (groupContent == null) {
109 // If config file is broken
110 if (hierarchy == null || groupDesc == null) {
111 //Get ungrouped collection list
112 result.appendChild(doc.importNode(ungroupedCollections, true));
113 } else {
114 //If config is ok, but in this group no any collection or group
115 result.appendChild(doc.createElement(GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER));
116 }
117 return result;
118 }
119 NodeList currentContent = groupContent.getChildNodes();
120 if (currentContent != null && currentContent.getLength() > 0) {
121 // Create CollectionList element in response
122 Element result_collection_list = doc.createElement(GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER);
123 result.appendChild(result_collection_list);
124 Element result_group_list = doc.createElement(GSXML.GROUP_ELEM + GSXML.LIST_MODIFIER);
125 result.appendChild(result_group_list);
126 // Iterate over collections from current view
127 // i represents current position in groupConfig.xml
128 int i;
129 for (i=0; i < currentContent.getLength(); i++) {
130 //logger.warn("NODE CuR Content" + GSXML.xmlNodeToString(currentContent.item(i)));
131
132 if (currentContent.item(i).getNodeName() == GSXML.COLLECTION_ELEM) {
133
134 Element collection = (Element) currentContent.item(i);
135 String collection_name = collection.getAttribute(GSXML.NAME_ATT);
136 // Check whether collection from current view exists in message router response
137 Element checkedCollection = GSXML.getNamedElement(mr_collection_list, GSXML.COLLECTION_ELEM,GSXML.NAME_ATT, collection_name);
138 if (checkedCollection != null) {
139 //Set position value
140 checkedCollection.setAttribute(GSXML.POSITION_ATT, String.valueOf(i));
141 // Add collection to response
142 result_collection_list.appendChild(doc.importNode(checkedCollection, true));
143 }
144
145 //Iterate over groups in current view
146 } else if (currentContent.item(i).getNodeName() == GSXML.GROUP_ELEM) {
147 Element currentGroup = (Element) currentContent.item(i);
148 String currentGroupName = currentGroup.getAttribute(GSXML.NAME_ATT);
149 //Get group description
150 Element group = getGroupDescription(currentGroupName);
151 //Set position value
152 if (group != null) {
153 group.setAttribute(GSXML.POSITION_ATT, String.valueOf(i));
154 result_group_list.appendChild(doc.importNode(group, true));
155 }
156
157 }
158
159 }
160 //Add ungrouped collections if groupPath /+ or "" or null
161 if (groupPath.isEmpty()) {
162
163
164 //Add each ungrouped collection to the collection list in loop
165 NodeList ungroupedCollectionNodes = GSXML.getChildrenByTagName(ungroupedCollections, GSXML.COLLECTION_ATT);
166 if (ungroupedCollectionNodes != null) {
167 for (int j = 0; j < ungroupedCollectionNodes.getLength(); j++) {
168 //logger.warn("UNGROUPED COLL ELEM" + GSXML.xmlNodeToString(ungroupedCollections).intern());
169 Element ungroupedCollection = (Element) doc.importNode(ungroupedCollectionNodes.item(j), true);
170 ungroupedCollection.setAttribute(GSXML.POSITION_ATT, String.valueOf(i++));
171 result_collection_list.appendChild(ungroupedCollection);
172 }
173 }
174
175 }
176
177
178
179 }
180
181 return result;
182 }
183
184 private Element getCurrentContent(String path) {
185
186 if (hierarchy == null || groupDesc == null) {
187 return null;
188 }
189
190 Document doc = XMLConverter.newDOM();
191
192 if (path == null) {
193 path = "";
194 }
195 String[] pathSteps = path.split("/");
196
197
198 Element currentView = (Element) hierarchy.cloneNode(true);
199 // Get the current view
200 for (int i = 0; i < pathSteps.length; i++) {
201 if (!pathSteps[i].isEmpty()) {
202 currentView = GSXML.getNamedElement(currentView, GSXML.GROUP_ELEM, GSXML.NAME_ATT, pathSteps[i]);
203 }
204 }
205 if (currentView == null || !currentView.hasChildNodes()) {
206 // Return to the main page
207 return null;
208 }
209 return currentView;
210 }
211
212 private void readGroupConfiguration() {
213
214 File configFile = new File(GSFile.groupConfigFile(site_home));
215 //
216 if (!configFile.exists()) {
217 logger.info("Groups config file " + configFile.getPath() + " does not exist.");
218 return;
219 }
220 // Try to read and catch exception if it fails
221 Document doc = XMLConverter.getDOM(configFile);
222 Element content = doc.getDocumentElement();
223
224 // XPath to find empty text nodes.
225 try {
226 XPathFactory xpathFactory = XPathFactory.newInstance();
227 XPathExpression xpathExp = xpathFactory.newXPath().compile("//text()[normalize-space(.) = '']");
228 NodeList emptyTextNodes = (NodeList) xpathExp.evaluate(doc, XPathConstants.NODESET);
229 for (int i = 0; i < emptyTextNodes.getLength(); i++) {
230 Node emptyTextNode = emptyTextNodes.item(i);
231 emptyTextNode.getParentNode().removeChild(emptyTextNode);
232 }
233
234 } catch (XPathExpressionException e) {
235 logger.error("Error occurred while trying to remove emtpy nodes from groupConfig.xml");
236 e.printStackTrace();
237 }
238
239 hierarchy = (Element) GSXML.getChildByTagName(content, GSXML.HIERARCHY_ELEM);
240 groupDesc = (Element) GSXML.getChildByTagName(content, GSXML.GROUP_DESC_ELEM);
241 }
242
243 private Element getGroupDescription(String name) {
244 if (groupDesc != null) {
245 Element description = (Element) GSXML.getNamedElement(groupDesc, GSXML.GROUP_ELEM, GSXML.NAME_ATT, name);
246 if (description != null) {
247 return description;
248 }
249 logger.error("GroupDescription is not defined. Check your groupConfig.xml");
250 }
251
252 logger.error("No group descriptions found. Check your groupConfig.xml");
253 return null;
254 }
255
256 private Element getUngroupedCollections(Element mr_collection_list) {
257
258 if (groupDesc == null || hierarchy == null) {
259 logger.error("No group descriptions in groupConfig.xml. Check your groupConfig.xml");
260 //return mr_collection_list
261 return mr_collection_list;
262 }
263 Document doc = XMLConverter.newDOM();
264 // Create Set
265 Set<String> hierarchy_unique_collections = new HashSet<String>();
266 // Element hierarchyCollections = doc.createElement("coll_list");
267 // Get collection nodes
268
269 NodeList hierarchy_all_collection_list = hierarchy.getElementsByTagName(GSXML.COLLECTION_ELEM);
270 // Save hierarchy collection names to Hashset
271 for (int i = 0; i < hierarchy_all_collection_list.getLength(); i++) {
272 Element collection_element = (Element) hierarchy_all_collection_list.item(i);
273 hierarchy_unique_collections.add(collection_element.getAttribute(GSXML.NAME_ATT));
274 }
275 // Save available by message router collection names to Hashset
276 Set<String> mr_collections = new HashSet<String>();
277 NodeList mr_coll_list = mr_collection_list.getElementsByTagName(GSXML.COLLECTION_ELEM);
278
279 for (int i = 0; i < mr_coll_list.getLength(); i++) {
280 Element collection_element = (Element) mr_coll_list.item(i);
281 mr_collections.add(collection_element.getAttribute(GSXML.NAME_ATT));
282 }
283 //Save collections available by message router and not existed in hierarchy to ungrouped collections set
284 Set<String> ungrouped_collections = new HashSet<String>();
285 for (String string : mr_collections) {
286 if (!hierarchy_unique_collections.contains(string)){
287 ungrouped_collections.add(string);
288 }
289 }
290 //Output
291 Element result = doc.createElement(GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER);
292 for (String name : ungrouped_collections) {
293 Element collection = doc.createElement(GSXML.COLLECTION_ELEM);
294 collection.setAttribute(GSXML.NAME_ATT, name);
295 result.appendChild(collection);
296 }
297 return result;
298
299 }
300
301}
Note: See TracBrowser for help on using the repository browser.