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

Last change on this file since 28202 was 28202, checked in by sjm84, 11 years ago

Some major changes to DerbyWrapper to try and make it more reliable and consistent

  • Property svn:executable set to *
File size: 14.4 KB
Line 
1package org.greenstone.gsdl3.action;
2
3import java.io.BufferedWriter;
4import java.io.File;
5import java.io.FileWriter;
6import java.io.Serializable;
7import java.lang.reflect.Type;
8import java.util.ArrayList;
9import java.util.HashMap;
10import java.util.Iterator;
11import java.util.List;
12import java.util.Map;
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
20import org.apache.commons.io.FileUtils;
21import org.greenstone.gsdl3.util.DerbyWrapper;
22import org.greenstone.gsdl3.util.GSConstants;
23import org.greenstone.gsdl3.util.GSXML;
24import org.greenstone.gsdl3.util.GSXSLT;
25import org.greenstone.gsdl3.util.UserContext;
26import org.greenstone.util.GlobalProperties;
27import org.w3c.dom.Document;
28import org.w3c.dom.Element;
29import org.w3c.dom.Node;
30
31import com.google.gson.Gson;
32import com.google.gson.reflect.TypeToken;
33
34public class DepositorAction extends Action
35{
36 //Sub actions
37 private final String DE_RETRIEVE_WIZARD = "getwizard";
38 private final String DE_DEPOSIT_FILE = "depositfile";
39 private final String DE_CLEAR_CACHE = "clearcache";
40 private final String DE_CLEAR_DATABASE = "cleardatabase";
41
42 public Node process(Node message)
43 {
44 Element request = (Element) GSXML.getChildByTagName(message, GSXML.REQUEST_ELEM);
45
46 UserContext uc = new UserContext((Element) request);
47 String currentUsername = uc.getUsername();
48
49 Element responseMessage = this.doc.createElement(GSXML.MESSAGE_ELEM);
50 Element response = GSXML.createBasicResponse(this.doc, this.getClass().getSimpleName());
51 responseMessage.appendChild(response);
52
53 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
54 HashMap<String, Serializable> params = GSXML.extractParams(param_list, false);
55
56 String collection = (String) params.get("c");
57
58 int pageNum = -1;
59 boolean pageNumParseFail = false;
60 try
61 {
62 pageNum = Integer.parseInt(((String) params.get("dePage")));
63 }
64 catch (Exception ex)
65 {
66 pageNumParseFail = true;
67 }
68
69 int prevPageNum = -1;
70 boolean prevPageNumFail = false;
71 try
72 {
73 prevPageNum = Integer.parseInt((String) params.get("currentPage"));
74 }
75 catch (Exception ex)
76 {
77 prevPageNumFail = true;
78 }
79
80 DerbyWrapper database = new DerbyWrapper(GlobalProperties.getGSDL3Home() + File.separatorChar + "etc" + File.separatorChar + "usersDB");
81 if (pageNumParseFail)
82 {
83 try
84 {
85 pageNum = Integer.parseInt(database.getUserData(currentUsername, "DE___" + collection + "___CACHED_PAGE"));
86 }
87 catch (Exception ex)
88 {
89 pageNum = 1;
90 }
91 }
92
93 int highestVisitedPage = -1;
94 String result = "";
95 int counter = 1;
96 while (result != null)
97 {
98 result = database.getUserData(currentUsername, "DE___" + collection + "___" + counter + "___VISITED_PAGE");
99 if (result != null)
100 {
101 counter++;
102 }
103 }
104 highestVisitedPage = counter - 1;
105 if (highestVisitedPage == 0)
106 {
107 highestVisitedPage = 1;
108 }
109
110 if (pageNum > highestVisitedPage + 1)
111 {
112 pageNum = highestVisitedPage + 1;
113 }
114
115 database.addUserData(currentUsername, "DE___" + collection + "___" + pageNum + "___VISITED_PAGE", "VISITED");
116
117 String subaction = ((Element) request).getAttribute(GSXML.SUBACTION_ATT);
118 if (subaction.toLowerCase().equals(DE_RETRIEVE_WIZARD))
119 {
120 //Save given metadata
121 StringBuilder saveString = new StringBuilder("[");
122 Iterator<String> paramIter = params.keySet().iterator();
123 while (paramIter.hasNext())
124 {
125 String paramName = paramIter.next();
126 if (paramName.startsWith("md___"))
127 {
128 Object paramValue = params.get(paramName);
129
130 if (paramValue instanceof String)
131 {
132 saveString.append("{name:\"" + paramName + "\", value:\"" + (String) paramValue + "\"},");
133 }
134 else if (paramValue instanceof HashMap)
135 {
136 HashMap<String, String> subMap = (HashMap<String, String>) paramValue;
137 Iterator<String> subKeyIter = subMap.keySet().iterator();
138 while (subKeyIter.hasNext())
139 {
140 String subName = subKeyIter.next();
141 saveString.append("{name:\"" + paramName + "." + subName + "\", value:\"" + subMap.get(subName) + "\"},");
142 }
143 }
144 }
145 }
146 if (saveString.length() > 2)
147 {
148 saveString.deleteCharAt(saveString.length() - 1);
149 saveString.append("]");
150
151 if (!prevPageNumFail)
152 {
153 database.addUserData(currentUsername, "DE___" + collection + "___" + prevPageNum + "___CACHED_VALUES", saveString.toString());
154 }
155 }
156
157 //Construct the xsl
158 Document compiledDepositorFile = null;
159 try
160 {
161 compiledDepositorFile = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
162 }
163 catch (Exception ex)
164 {
165 ex.printStackTrace();
166 }
167 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);
168
169 Element numOfPagesElement = GSXML.getNamedElement(depositorBaseFile.getDocumentElement(), "xsl:variable", "name", "numOfPages");
170 int numberOfPages = Integer.parseInt(numOfPagesElement.getTextContent());
171
172 compiledDepositorFile.appendChild(compiledDepositorFile.importNode(depositorBaseFile.getDocumentElement(), true));
173
174 ArrayList<Document> pageDocs = new ArrayList<Document>();
175 ArrayList<String> pageNames = new ArrayList<String>();
176 for (int i = 1; i <= numberOfPages; i++)
177 {
178 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);
179 pageDocs.add(page);
180
181 Element pageTitleElem = (Element) GSXML.getNamedElement(page.getDocumentElement(), "xsl:variable", "name", "title");
182 pageNames.add(pageTitleElem.getTextContent());
183
184 Element wizardPageElem = (Element) GSXML.getNamedElement(page.getDocumentElement(), "xsl:template", "name", "wizardPage");
185 wizardPageElem.setAttribute("name", "wizardPage" + i);
186 compiledDepositorFile.getDocumentElement().appendChild(compiledDepositorFile.importNode(wizardPageElem, true));
187 }
188
189 //Create the wizard bar
190 Element wizardBarTemplate = GSXML.getNamedElement(compiledDepositorFile.getDocumentElement(), "xsl:template", "name", "wizardBar");
191 Element wizardBar = compiledDepositorFile.createElement("ul");
192 wizardBar.setAttribute("id", "wizardBar");
193 wizardBarTemplate.appendChild(wizardBar);
194
195 for (int i = 0; i < pageNames.size(); i++)
196 {
197 String pageName = pageNames.get(i);
198 Element pageLi = compiledDepositorFile.createElement("li");
199 if (pageNum == i + 1)
200 {
201 pageLi.setAttribute("class", "wizardStepLink ui-state-active ui-corner-all");
202 }
203 else if (i + 1 > highestVisitedPage + 1 && i + 1 > pageNum + 1)
204 {
205 pageLi.setAttribute("class", "wizardStepLink ui-state-disabled ui-corner-all");
206 }
207 else
208 {
209 pageLi.setAttribute("class", "wizardStepLink ui-state-default ui-corner-all");
210 }
211 Element link = compiledDepositorFile.createElement("a");
212 pageLi.appendChild(link);
213
214 link.setAttribute(GSXML.HREF_ATT, "javascript:;");
215 link.setAttribute("page", "" + (i + 1));
216 link.appendChild(compiledDepositorFile.createTextNode(pageName));
217 wizardBar.appendChild(pageLi);
218 }
219
220 //Add a call-template call to the appropriate page in the xsl
221 Element mainDePageElem = GSXML.getNamedElement(compiledDepositorFile.getDocumentElement(), "xsl:template", "match", "/page");
222 Element wizardContainer = GSXML.getNamedElement(mainDePageElem, "div", "id", "wizardContainer");
223 Element formContainer = GSXML.getNamedElement(wizardContainer, "form", "name", "depositorform");
224 Element callToPage = compiledDepositorFile.createElement("xsl:call-template");
225 callToPage.setAttribute("name", "wizardPage" + pageNum);
226 formContainer.appendChild(callToPage);
227
228 Element cachedValueElement = this.doc.createElement("cachedValues");
229 response.appendChild(cachedValueElement);
230 try
231 {
232 for (int i = pageNum; i > 0; i--)
233 {
234 Element page = this.doc.createElement("pageCache");
235 page.setAttribute("pageNum", "" + i);
236 String cachedValues = database.getUserData(currentUsername, "DE___" + collection + "___" + i + "___CACHED_VALUES");
237 if (cachedValues != null)
238 {
239 page.appendChild(this.doc.createTextNode(cachedValues));
240 cachedValueElement.appendChild(page);
241 }
242 }
243 }
244 catch (Exception ex)
245 {
246 ex.printStackTrace();
247 }
248
249 try
250 {
251 Transformer transformer = TransformerFactory.newInstance().newTransformer();
252
253 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");
254 newFileDir.mkdirs();
255
256 File newFile = new File(newFileDir, File.separator + "compiledDepositor.xsl");
257
258 //initialize StreamResult with File object to save to file
259 StreamResult sresult = new StreamResult(new FileWriter(newFile));
260 DOMSource source = new DOMSource(compiledDepositorFile);
261 transformer.transform(source, sresult);
262 }
263 catch (Exception ex)
264 {
265 ex.printStackTrace();
266 }
267 database.closeDatabase();
268 }
269 else if (subaction.toLowerCase().equals(DE_DEPOSIT_FILE))
270 {
271 String fileToAdd = (String) params.get("fileToAdd");
272 File tempFile = new File(GlobalProperties.getGSDL3Home() + File.separator + "tmp" + File.separator + fileToAdd);
273 if (tempFile.exists())
274 {
275 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);
276 if (!newFileLocationDir.exists())
277 {
278 newFileLocationDir.mkdir();
279 }
280 File newFileLocation = new File(newFileLocationDir, fileToAdd);
281
282 try
283 {
284 FileUtils.copyFile(tempFile, newFileLocation);
285 }
286 catch (Exception ex)
287 {
288 ex.printStackTrace();
289 GSXML.addError(this.doc, responseMessage, "Failed to copy the deposited file into the collection.");
290 return responseMessage;
291 }
292
293 HashMap<String, String> metadataMap = new HashMap<String, String>();
294 for (int i = pageNum; i > 0; i--)
295 {
296 String cachedValues = database.getUserData(currentUsername, "DE___" + collection + "___" + i + "___CACHED_VALUES");
297 if (cachedValues != null)
298 {
299 Type type = new TypeToken<List<Map<String, String>>>()
300 {
301 }.getType();
302
303 Gson gson = new Gson();
304 List<Map<String, String>> metadataList = gson.fromJson(cachedValues, type);
305 for (Map<String, String> metadata : metadataList)
306 {
307 metadataMap.put(metadata.get("name"), metadata.get("value"));
308 }
309 }
310 }
311
312 String xmlString = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><!DOCTYPE DirectoryMetadata SYSTEM \"http://greenstone.org/dtd/DirectoryMetadata/1.0/DirectoryMetadata.dtd\"><DirectoryMetadata><FileSet>";
313 xmlString += "<FileName>.*</FileName><Description>";
314 for (String key : metadataMap.keySet())
315 {
316 xmlString += "<Metadata name=\"" + key.substring("MD___".length()) + "\" mode=\"accumulate\">" + metadataMap.get(key) + "</Metadata>";
317 }
318 xmlString += "</Description></FileSet></DirectoryMetadata>";
319
320 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");
321
322 try
323 {
324 BufferedWriter bw = new BufferedWriter(new FileWriter(metadataFile));
325 bw.write(xmlString);
326 bw.close();
327 }
328 catch (Exception ex)
329 {
330 ex.printStackTrace();
331 }
332
333 Element buildMessage = this.doc.createElement(GSXML.MESSAGE_ELEM);
334 Element buildRequest = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, "ImportCollection", uc);
335 buildMessage.appendChild(buildRequest);
336
337 Element paramListElem = this.doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
338 buildRequest.appendChild(paramListElem);
339
340 Element collectionParam = this.doc.createElement(GSXML.PARAM_ELEM);
341 paramListElem.appendChild(collectionParam);
342 collectionParam.setAttribute(GSXML.NAME_ATT, GSXML.COLLECTION_ATT);
343 collectionParam.setAttribute(GSXML.VALUE_ATT, collection);
344
345 Element documentsParam = this.doc.createElement(GSXML.PARAM_ELEM);
346 paramListElem.appendChild(documentsParam);
347 documentsParam.setAttribute(GSXML.NAME_ATT, "documents");
348 documentsParam.setAttribute(GSXML.VALUE_ATT, fileToAdd);
349
350 Element buildResponseMessage = (Element) this.mr.process(buildMessage);
351
352 response.appendChild(this.doc.importNode(buildResponseMessage, true));
353 }
354 }
355 else if (subaction.toLowerCase().equals(DE_CLEAR_CACHE))
356 {
357 database.clearUserDataWithPrefix(currentUsername, "DE___");
358 }
359 else if (subaction.toLowerCase().equals(DE_CLEAR_DATABASE))
360 {
361 database.clearUserData();
362 database.clearTrackerData();
363 }
364 else
365 {
366 Element depositorPage = this.doc.createElement("depositorPage");
367 response.appendChild(depositorPage);
368
369 Element collList = getCollectionsInSite();
370 depositorPage.appendChild(this.doc.importNode(collList, true));
371 }
372
373 return responseMessage;
374 }
375
376 public Element getCollectionsInSite()
377 {
378 Element message = this.doc.createElement(GSXML.MESSAGE_ELEM);
379 Element request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_DESCRIBE, "", new UserContext());
380 message.appendChild(request);
381 Element responseMessage = (Element) this.mr.process(message);
382
383 Element response = (Element) GSXML.getChildByTagName(responseMessage, GSXML.RESPONSE_ELEM);
384 Element collectionList = (Element) GSXML.getChildByTagName(response, GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER);
385
386 return collectionList;
387 }
388}
Note: See TracBrowser for help on using the repository browser.