source: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/action/DepositorAction.java@ 36107

Last change on this file since 36107 was 36107, checked in by kjdon, 2 years ago

greenstone.org now https

  • Property svn:executable set to *
File size: 16.8 KB
RevLine 
[27617]1package org.greenstone.gsdl3.action;
2
[27719]3import java.io.BufferedWriter;
[27617]4import java.io.File;
5import java.io.FileWriter;
6import java.io.Serializable;
[27806]7import java.lang.reflect.Type;
[27617]8import java.util.ArrayList;
9import java.util.HashMap;
10import java.util.Iterator;
[27806]11import java.util.List;
12import java.util.Map;
[27617]13
14import javax.xml.parsers.DocumentBuilderFactory;
15import javax.xml.transform.Transformer;
16import javax.xml.transform.TransformerFactory;
17import javax.xml.transform.dom.DOMSource;
18import javax.xml.transform.stream.StreamResult;
19
[27719]20import org.apache.commons.io.FileUtils;
[27617]21import org.greenstone.gsdl3.util.DerbyWrapper;
22import org.greenstone.gsdl3.util.GSConstants;
[32448]23import org.greenstone.gsdl3.util.GSParams;
[27617]24import org.greenstone.gsdl3.util.GSXML;
25import org.greenstone.gsdl3.util.GSXSLT;
26import org.greenstone.gsdl3.util.UserContext;
[33699]27import org.greenstone.gsdl3.util.XMLConverter;
[27617]28import org.greenstone.util.GlobalProperties;
29import org.w3c.dom.Document;
30import org.w3c.dom.Element;
31import org.w3c.dom.Node;
[33733]32import org.w3c.dom.NodeList;
[27617]33
[27806]34import com.google.gson.Gson;
35import com.google.gson.reflect.TypeToken;
36
[27617]37public class DepositorAction extends Action
38{
39 //Sub actions
[27806]40 private final String DE_RETRIEVE_WIZARD = "getwizard";
41 private final String DE_DEPOSIT_FILE = "depositfile";
[27908]42 private final String DE_CLEAR_CACHE = "clearcache";
[27806]43 private final String DE_CLEAR_DATABASE = "cleardatabase";
[27617]44
[32448]45 // cgi args
46 private final String DE_PAGE_ARG = "dePage";
47 private final String CURRENT_PAGE_ARG = "currentPage";
48 private final String FILE_TO_ADD_ARG = "fileToAdd";
49
[27617]50 public Node process(Node message)
51 {
52 Element request = (Element) GSXML.getChildByTagName(message, GSXML.REQUEST_ELEM);
[28382]53 Document doc = request.getOwnerDocument();
[33699]54
55 UserContext uc = new UserContext((Element) request);
[28382]56
57 Element responseMessage = doc.createElement(GSXML.MESSAGE_ELEM);
58 Element response = GSXML.createBasicResponse(doc, this.getClass().getSimpleName());
[27617]59 responseMessage.appendChild(response);
60
[33699]61 addSiteMetadata(response, uc);
62 addInterfaceOptions(response);
63
64 String currentUsername = uc.getUsername();
65
66 // logger.debug("username="+username+", groups = "+groups);
67 if (currentUsername == null || currentUsername.equals(""))
68 {
69
70 // TODO if user is not logged in, push to login page
71 request.setAttribute("subaction", "");
72 GSXML.addError(response, "You need to be logged in to use the depositor");
73 return responseMessage;
74 }
75
[27617]76 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
77 HashMap<String, Serializable> params = GSXML.extractParams(param_list, false);
78
[32448]79 String collection = (String) params.get(GSParams.COLLECTION);
[27617]80
[33699]81 if (collection !=null && !collection.equals("")) {
[33733]82 if (!userHasCollectionEditPermission(collection, uc)) {
[33699]83 // we need to reset back to empty subaction here
84 request.setAttribute("subaction", "");
85 GSXML.addError(response, "You are not in the right group to access this collection. Please log in as a different user.");
[33733]86 return responseMessage;
[33699]87
88 }
89 }
[27617]90 int pageNum = -1;
[27719]91 boolean pageNumParseFail = false;
[27617]92 try
93 {
[32448]94 pageNum = Integer.parseInt(((String) params.get(DE_PAGE_ARG)));
[27617]95 }
96 catch (Exception ex)
97 {
[27719]98 pageNumParseFail = true;
[27617]99 }
100
[27719]101 int prevPageNum = -1;
102 boolean prevPageNumFail = false;
103 try
104 {
[32448]105 prevPageNum = Integer.parseInt((String) params.get(CURRENT_PAGE_ARG));
[27719]106 }
107 catch (Exception ex)
108 {
109 prevPageNumFail = true;
110 }
111
[28202]112 DerbyWrapper database = new DerbyWrapper(GlobalProperties.getGSDL3Home() + File.separatorChar + "etc" + File.separatorChar + "usersDB");
[27719]113 if (pageNumParseFail)
[27617]114 {
115 try
116 {
117 pageNum = Integer.parseInt(database.getUserData(currentUsername, "DE___" + collection + "___CACHED_PAGE"));
118 }
119 catch (Exception ex)
120 {
121 pageNum = 1;
122 }
123 }
124
[27806]125 int highestVisitedPage = -1;
126 String result = "";
127 int counter = 1;
128 while (result != null)
129 {
130 result = database.getUserData(currentUsername, "DE___" + collection + "___" + counter + "___VISITED_PAGE");
131 if (result != null)
132 {
133 counter++;
134 }
135 }
136 highestVisitedPage = counter - 1;
137 if (highestVisitedPage == 0)
138 {
139 highestVisitedPage = 1;
140 }
141
142 if (pageNum > highestVisitedPage + 1)
143 {
144 pageNum = highestVisitedPage + 1;
145 }
146
147 database.addUserData(currentUsername, "DE___" + collection + "___" + pageNum + "___VISITED_PAGE", "VISITED");
148
[27617]149 String subaction = ((Element) request).getAttribute(GSXML.SUBACTION_ATT);
[27806]150 if (subaction.toLowerCase().equals(DE_RETRIEVE_WIZARD))
[27617]151 {
152 //Save given metadata
153 StringBuilder saveString = new StringBuilder("[");
154 Iterator<String> paramIter = params.keySet().iterator();
155 while (paramIter.hasNext())
156 {
157 String paramName = paramIter.next();
[32448]158 if (paramName.startsWith(GSParams.MD_PREFIX))
[27617]159 {
160 Object paramValue = params.get(paramName);
161
162 if (paramValue instanceof String)
163 {
164 saveString.append("{name:\"" + paramName + "\", value:\"" + (String) paramValue + "\"},");
165 }
166 else if (paramValue instanceof HashMap)
167 {
168 HashMap<String, String> subMap = (HashMap<String, String>) paramValue;
169 Iterator<String> subKeyIter = subMap.keySet().iterator();
170 while (subKeyIter.hasNext())
171 {
172 String subName = subKeyIter.next();
173 saveString.append("{name:\"" + paramName + "." + subName + "\", value:\"" + subMap.get(subName) + "\"},");
174 }
175 }
176 }
177 }
178 if (saveString.length() > 2)
179 {
180 saveString.deleteCharAt(saveString.length() - 1);
181 saveString.append("]");
182
[27719]183 if (!prevPageNumFail)
184 {
185 database.addUserData(currentUsername, "DE___" + collection + "___" + prevPageNum + "___CACHED_VALUES", saveString.toString());
186 }
[27617]187 }
188
189 //Construct the xsl
190 Document compiledDepositorFile = null;
191 try
192 {
193 compiledDepositorFile = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
194 }
195 catch (Exception ex)
196 {
197 ex.printStackTrace();
198 }
199 Document depositorBaseFile = GSXSLT.mergedXSLTDocumentCascade("depositor/depositor.xsl", (String) this.config_params.get(GSConstants.SITE_NAME), collection, (String) this.config_params.get(GSConstants.INTERFACE_NAME), (ArrayList<String>) this.config_params.get(GSConstants.BASE_INTERFACES), false);
200
201 Element numOfPagesElement = GSXML.getNamedElement(depositorBaseFile.getDocumentElement(), "xsl:variable", "name", "numOfPages");
202 int numberOfPages = Integer.parseInt(numOfPagesElement.getTextContent());
203
204 compiledDepositorFile.appendChild(compiledDepositorFile.importNode(depositorBaseFile.getDocumentElement(), true));
205
206 ArrayList<Document> pageDocs = new ArrayList<Document>();
207 ArrayList<String> pageNames = new ArrayList<String>();
208 for (int i = 1; i <= numberOfPages; i++)
209 {
210 Document page = GSXSLT.mergedXSLTDocumentCascade("depositor/de_page" + i + ".xsl", (String) this.config_params.get(GSConstants.SITE_NAME), collection, (String) this.config_params.get(GSConstants.INTERFACE_NAME), (ArrayList<String>) this.config_params.get(GSConstants.BASE_INTERFACES), false);
211 pageDocs.add(page);
212
213 Element pageTitleElem = (Element) GSXML.getNamedElement(page.getDocumentElement(), "xsl:variable", "name", "title");
214 pageNames.add(pageTitleElem.getTextContent());
215
216 Element wizardPageElem = (Element) GSXML.getNamedElement(page.getDocumentElement(), "xsl:template", "name", "wizardPage");
217 wizardPageElem.setAttribute("name", "wizardPage" + i);
218 compiledDepositorFile.getDocumentElement().appendChild(compiledDepositorFile.importNode(wizardPageElem, true));
219 }
220
221 //Create the wizard bar
222 Element wizardBarTemplate = GSXML.getNamedElement(compiledDepositorFile.getDocumentElement(), "xsl:template", "name", "wizardBar");
223 Element wizardBar = compiledDepositorFile.createElement("ul");
224 wizardBar.setAttribute("id", "wizardBar");
225 wizardBarTemplate.appendChild(wizardBar);
226
227 for (int i = 0; i < pageNames.size(); i++)
228 {
229 String pageName = pageNames.get(i);
230 Element pageLi = compiledDepositorFile.createElement("li");
231 if (pageNum == i + 1)
232 {
233 pageLi.setAttribute("class", "wizardStepLink ui-state-active ui-corner-all");
234 }
[27806]235 else if (i + 1 > highestVisitedPage + 1 && i + 1 > pageNum + 1)
236 {
237 pageLi.setAttribute("class", "wizardStepLink ui-state-disabled ui-corner-all");
238 }
[27617]239 else
240 {
241 pageLi.setAttribute("class", "wizardStepLink ui-state-default ui-corner-all");
242 }
243 Element link = compiledDepositorFile.createElement("a");
244 pageLi.appendChild(link);
245
246 link.setAttribute(GSXML.HREF_ATT, "javascript:;");
247 link.setAttribute("page", "" + (i + 1));
248 link.appendChild(compiledDepositorFile.createTextNode(pageName));
249 wizardBar.appendChild(pageLi);
250 }
251
252 //Add a call-template call to the appropriate page in the xsl
253 Element mainDePageElem = GSXML.getNamedElement(compiledDepositorFile.getDocumentElement(), "xsl:template", "match", "/page");
254 Element wizardContainer = GSXML.getNamedElement(mainDePageElem, "div", "id", "wizardContainer");
255 Element formContainer = GSXML.getNamedElement(wizardContainer, "form", "name", "depositorform");
256 Element callToPage = compiledDepositorFile.createElement("xsl:call-template");
257 callToPage.setAttribute("name", "wizardPage" + pageNum);
258 formContainer.appendChild(callToPage);
259
[28382]260 Element cachedValueElement = doc.createElement("cachedValues");
[27617]261 response.appendChild(cachedValueElement);
262 try
263 {
264 for (int i = pageNum; i > 0; i--)
265 {
[28382]266 Element page = doc.createElement("pageCache");
[27719]267 page.setAttribute("pageNum", "" + i);
[27617]268 String cachedValues = database.getUserData(currentUsername, "DE___" + collection + "___" + i + "___CACHED_VALUES");
[27719]269 if (cachedValues != null)
270 {
[28382]271 page.appendChild(doc.createTextNode(cachedValues));
[27719]272 cachedValueElement.appendChild(page);
273 }
[27617]274 }
275 }
276 catch (Exception ex)
277 {
278 ex.printStackTrace();
279 }
280
281 try
282 {
283 Transformer transformer = TransformerFactory.newInstance().newTransformer();
284
285 File newFileDir = new File(GlobalProperties.getGSDL3Home() + File.separator + "sites" + File.separator + this.config_params.get(GSConstants.SITE_NAME) + File.separator + "collect" + File.separator + collection + File.separator + "transform" + File.separator + "depositor");
286 newFileDir.mkdirs();
287
288 File newFile = new File(newFileDir, File.separator + "compiledDepositor.xsl");
289
290 //initialize StreamResult with File object to save to file
291 StreamResult sresult = new StreamResult(new FileWriter(newFile));
292 DOMSource source = new DOMSource(compiledDepositorFile);
293 transformer.transform(source, sresult);
294 }
295 catch (Exception ex)
296 {
297 ex.printStackTrace();
298 }
299 database.closeDatabase();
300 }
[27806]301 else if (subaction.toLowerCase().equals(DE_DEPOSIT_FILE))
[27719]302 {
[32448]303 String fileToAdd = (String) params.get(FILE_TO_ADD_ARG);
[27719]304 File tempFile = new File(GlobalProperties.getGSDL3Home() + File.separator + "tmp" + File.separator + fileToAdd);
305 if (tempFile.exists())
306 {
307 File newFileLocationDir = new File(GlobalProperties.getGSDL3Home() + File.separator + "sites" + File.separator + this.config_params.get(GSConstants.SITE_NAME) + File.separator + "collect" + File.separator + collection + File.separator + "import" + File.separator + fileToAdd);
308 if (!newFileLocationDir.exists())
309 {
310 newFileLocationDir.mkdir();
311 }
312 File newFileLocation = new File(newFileLocationDir, fileToAdd);
[27617]313
[27719]314 try
315 {
316 FileUtils.copyFile(tempFile, newFileLocation);
317 }
318 catch (Exception ex)
319 {
320 ex.printStackTrace();
[28964]321 GSXML.addError(responseMessage, "Failed to copy the deposited file into the collection.");
[27719]322 return responseMessage;
323 }
324
[27806]325 HashMap<String, String> metadataMap = new HashMap<String, String>();
326 for (int i = pageNum; i > 0; i--)
[27719]327 {
[27806]328 String cachedValues = database.getUserData(currentUsername, "DE___" + collection + "___" + i + "___CACHED_VALUES");
329 if (cachedValues != null)
[27719]330 {
[27806]331 Type type = new TypeToken<List<Map<String, String>>>()
332 {
333 }.getType();
[27719]334
[27806]335 Gson gson = new Gson();
336 List<Map<String, String>> metadataList = gson.fromJson(cachedValues, type);
337 for (Map<String, String> metadata : metadataList)
[27719]338 {
[27806]339 metadataMap.put(metadata.get("name"), metadata.get("value"));
[27719]340 }
341 }
342 }
343
[36107]344 String xmlString = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><!DOCTYPE DirectoryMetadata SYSTEM \"https://greenstone.org/dtd/DirectoryMetadata/1.0/DirectoryMetadata.dtd\"><DirectoryMetadata><FileSet>";
[27806]345 xmlString += "<FileName>.*</FileName><Description>";
346 for (String key : metadataMap.keySet())
347 {
348 xmlString += "<Metadata name=\"" + key.substring("MD___".length()) + "\" mode=\"accumulate\">" + metadataMap.get(key) + "</Metadata>";
349 }
350 xmlString += "</Description></FileSet></DirectoryMetadata>";
351
[27719]352 File metadataFile = new File(GlobalProperties.getGSDL3Home() + File.separator + "sites" + File.separator + this.config_params.get(GSConstants.SITE_NAME) + File.separator + "collect" + File.separator + collection + File.separator + "import" + File.separator + fileToAdd + File.separator + "metadata.xml");
353
354 try
355 {
356 BufferedWriter bw = new BufferedWriter(new FileWriter(metadataFile));
357 bw.write(xmlString);
358 bw.close();
359 }
360 catch (Exception ex)
361 {
362 ex.printStackTrace();
363 }
364
[28382]365 Element buildMessage = doc.createElement(GSXML.MESSAGE_ELEM);
366 Element buildRequest = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_PROCESS, "ImportCollection", uc);
[27719]367 buildMessage.appendChild(buildRequest);
368
[28382]369 Element paramListElem = doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
[27719]370 buildRequest.appendChild(paramListElem);
371
[28382]372 Element collectionParam = doc.createElement(GSXML.PARAM_ELEM);
[27719]373 paramListElem.appendChild(collectionParam);
374 collectionParam.setAttribute(GSXML.NAME_ATT, GSXML.COLLECTION_ATT);
375 collectionParam.setAttribute(GSXML.VALUE_ATT, collection);
376
[28382]377 Element documentsParam = doc.createElement(GSXML.PARAM_ELEM);
[27719]378 paramListElem.appendChild(documentsParam);
379 documentsParam.setAttribute(GSXML.NAME_ATT, "documents");
380 documentsParam.setAttribute(GSXML.VALUE_ATT, fileToAdd);
381
382 Element buildResponseMessage = (Element) this.mr.process(buildMessage);
383
[28382]384 response.appendChild(doc.importNode(buildResponseMessage, true));
[27719]385 }
386 }
[27908]387 else if (subaction.toLowerCase().equals(DE_CLEAR_CACHE))
388 {
389 database.clearUserDataWithPrefix(currentUsername, "DE___");
390 }
[27806]391 else if (subaction.toLowerCase().equals(DE_CLEAR_DATABASE))
392 {
393 database.clearUserData();
[28202]394 database.clearTrackerData();
[27806]395 }
[27719]396 else
397 {
[28382]398 Element depositorPage = doc.createElement("depositorPage");
[27719]399 response.appendChild(depositorPage);
400
[33733]401 Element collList = getCollectionsInSiteForUser(uc);
[28382]402 depositorPage.appendChild(doc.importNode(collList, true));
[27719]403 }
404
[27617]405 return responseMessage;
406 }
407
[33733]408
409 public Element getCollectionsInSiteForUser(UserContext uc)
410 {
411 Document doc = XMLConverter.newDOM();
412 Element message = doc.createElement(GSXML.MESSAGE_ELEM);
413 Element request = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_DESCRIBE, "", new UserContext());
414 message.appendChild(request);
415 Element responseMessage = (Element) this.mr.process(message);
416
417 Element response = (Element) GSXML.getChildByTagName(responseMessage, GSXML.RESPONSE_ELEM);
418 Element collectionList = (Element) GSXML.getChildByTagName(response, GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER);
419
420 Element validCollectionList = doc.createElement(GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER);
[27617]421
[33733]422 NodeList collections = GSXML.getChildrenByTagName(collectionList, GSXML.COLLECTION_ELEM);
423 for (int i = 0; i < collections.getLength(); i++) {
424 String coll_name = ((Element)collections.item(i)).getAttribute(GSXML.NAME_ATT);
425 if (userHasCollectionEditPermission(coll_name, uc)) {
426 // only add to the new list if the user has edit permission
427 validCollectionList.appendChild(doc.importNode(collections.item(i), true));
428
429 }
[27617]430 }
[33733]431
432 return validCollectionList;
433 }
[33699]434
435 // collection must be non-null and non-empty
[33733]436 protected boolean userHasCollectionEditPermission(String collection, UserContext user_context) {
[33699]437
438 for (String group : user_context.getGroups()) {
439 // administrator always has permission
440 if (group.equals("administrator")) {
441 return true;
442 }
443 // all-collections-editor can edit any collection
444
445 if (group.equals("all-collections-editor")) {
446 return true;
447 }
448 if (group.equals(collection+"-collection-editor")) {
449 return true;
450 }
451 }
452
453 // haven't found a group with edit permissions
454 return false;
455
456 }
[32448]457}
Note: See TracBrowser for help on using the repository browser.