source: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/DocumentMaker.java@ 30617

Last change on this file since 30617 was 30617, checked in by ak19, 8 years ago

Bugfix to oversight: web document editor didn't reindex on removing metadata, only on setting it. This is because there wasn't corresponding Service on Java side to handle removing metadata. Now the Java code has a ModifyMetdata service and this is connected to both the set- and remove-metadata functions in the javascript. For now, the javascript metadataserver calls have been made synchronous by setting the async ajax-jquery property to false. Need to test whether the code still works asynchronous as before.

  • Property svn:executable set to *
File size: 17.1 KB
Line 
1/*
2 * DocumentMaker.java
3 * The Document Maker service that can be used to create/modify custom
4 * documents in Greenstone collection
5 *
6 * Copyright (C) 2005 New Zealand Digital Library, http://www.nzdl.org
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22package org.greenstone.gsdl3.service;
23
24import java.io.BufferedReader;
25import java.io.InputStreamReader;
26import java.io.OutputStream;
27import java.io.Serializable;
28import java.lang.reflect.Type;
29import java.util.ArrayList;
30import java.util.HashMap;
31import java.util.Iterator;
32import java.util.List;
33import java.util.Map;
34import java.util.Set;
35
36import org.apache.log4j.*;
37
38import org.greenstone.gsdl3.util.UserContext;
39import org.greenstone.gsdl3.util.SimpleCollectionDatabase;
40
41
42import org.greenstone.gsdl3.util.GSDocumentModel;
43import org.greenstone.gsdl3.util.GSFile;
44import org.greenstone.gsdl3.util.GSPath;
45import org.greenstone.gsdl3.util.GSXML;
46import org.greenstone.gsdl3.util.UserContext;
47import org.greenstone.gsdl3.util.XMLConverter;
48
49import org.w3c.dom.Document;
50import org.w3c.dom.Element;
51import org.w3c.dom.NodeList;
52
53import com.google.gson.Gson;
54import com.google.gson.reflect.TypeToken;
55
56public class DocumentMaker extends ServiceRack
57{
58 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.ArchiveIO.class.getName());
59
60 GSDocumentModel _GSDM = null;
61
62 /****************************************************
63 * The list of services the Document Maker supports *
64 ***************************************************/
65 //Document/section services
66 protected static final String DOCUMENT_CREATE = "DocumentCreate";
67 protected static final String DOCUMENT_DELETE = "DocumentDelete";
68 protected static final String DOCUMENT_DUPLICATE = "DocumentDuplicate";
69 protected static final String DOCUMENT_MOVE = "DocumentMove";
70 protected static final String DOCUMENT_MERGE = "DocumentMerge";
71 protected static final String DOCUMENT_SPLIT = "DocumentSplit";
72 protected static final String DOCUMENT_GET_INFORMATION = "DocumentGetInformation";
73
74 //Other services
75 protected static final String DOCUMENT_EXECUTE_TRANSACTION = "DocumentExecuteTransaction";
76 /***************************************************/
77
78 String[] services = { DOCUMENT_CREATE, DOCUMENT_DELETE, DOCUMENT_DUPLICATE, DOCUMENT_GET_INFORMATION, DOCUMENT_MOVE, DOCUMENT_MERGE, DOCUMENT_SPLIT, DOCUMENT_EXECUTE_TRANSACTION };
79
80 /** configure this service */
81 public boolean configure(Element info, Element extra_info)
82 {
83 if (!super.configure(info, extra_info))
84 {
85 return false;
86 }
87
88 logger.info("Configuring DocumentMaker...");
89 this.config_info = info;
90
91 for (int i = 0; i < services.length; i++)
92 {
93 Element service = this.desc_doc.createElement(GSXML.SERVICE_ELEM);
94 service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
95 service.setAttribute(GSXML.NAME_ATT, services[i]);
96 this.short_service_info.appendChild(service);
97 }
98
99 _GSDM = new GSDocumentModel(this.site_home, this.router);
100
101 return true;
102 }
103
104 protected Element getServiceDescription(Document doc, String service_id, String lang, String subset)
105 {
106 for (int i = 0; i < services.length; i++)
107 {
108 if (service_id.equals(services[i]))
109 {
110 Element service_elem = doc.createElement(GSXML.SERVICE_ELEM);
111 service_elem.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
112 service_elem.setAttribute(GSXML.NAME_ATT, services[i]);
113 return service_elem;
114 }
115 }
116
117 return null;
118 }
119
120 /************
121 * Services *
122 ***********/
123
124 protected Element processDocumentCreate(Element request)
125 {
126 Document result_doc = XMLConverter.newDOM();
127 Element result = GSXML.createBasicResponse(result_doc, DOCUMENT_CREATE);
128
129 if (request == null)
130 {
131 GSXML.addError(result, DOCUMENT_CREATE + ": Request is null", GSXML.ERROR_TYPE_SYNTAX);
132 return result;
133 }
134
135 UserContext userContext = new UserContext(request);
136
137 //Get the list of documents to create
138 NodeList documents = request.getElementsByTagName(GSXML.DOCUMENT_ELEM);
139 for (int i = 0; i < documents.getLength(); i++)
140 {
141 //Get information about the current new document
142 Element currentDoc = (Element) documents.item(i);
143 String oid = currentDoc.getAttribute(GSXML.NODE_ID_ATT);
144 String collection = currentDoc.getAttribute(GSXML.COLLECTION_ATT);
145
146 _GSDM.documentCreate(oid, collection, userContext);
147 if (_GSDM.checkError(result, DOCUMENT_CREATE))
148 {
149 return result;
150 }
151 }
152
153 return result;
154 }
155
156 protected Element processDocumentDelete(Element request)
157 {
158 Document result_doc = XMLConverter.newDOM();
159 Element result = GSXML.createBasicResponse(result_doc, DOCUMENT_DELETE);
160
161 if (request == null)
162 {
163 GSXML.addError(result, DOCUMENT_DELETE + ": Request is null", GSXML.ERROR_TYPE_SYNTAX);
164 return result;
165 }
166
167 UserContext userContext = new UserContext(request);
168
169 //Get the list of documents to delete
170 NodeList documents = request.getElementsByTagName(GSXML.DOCUMENT_ELEM);
171 for (int i = 0; i < documents.getLength(); i++)
172 {
173 Element currentDoc = (Element) documents.item(i);
174 String oid = currentDoc.getAttribute(GSXML.NODE_ID_ATT);
175 String collection = currentDoc.getAttribute(GSXML.COLLECTION_ATT);
176
177 _GSDM.documentDelete(oid, collection, userContext);
178 if (_GSDM.checkError(result, DOCUMENT_DELETE))
179 {
180 return result;
181 }
182 }
183
184 return result;
185 }
186
187 protected Element processDocumentDuplicate(Element request)
188 {
189 Document result_doc = XMLConverter.newDOM();
190 Element result = GSXML.createBasicResponse(result_doc, DOCUMENT_DUPLICATE);
191
192 if (request == null)
193 {
194 GSXML.addError(result, DOCUMENT_DUPLICATE + ": Request is null", GSXML.ERROR_TYPE_SYNTAX);
195 return result;
196 }
197
198 UserContext userContext = new UserContext(request);
199
200 //Get the list of documents to duplicate
201 NodeList documents = request.getElementsByTagName(GSXML.DOCUMENT_ELEM);
202 for (int i = 0; i < documents.getLength(); i++)
203 {
204 Element currentDoc = (Element) documents.item(i);
205 String oid = currentDoc.getAttribute(GSXML.NODE_ID_ATT);
206 String collection = currentDoc.getAttribute(GSXML.COLLECTION_ATT);
207 String newOID = currentDoc.getAttribute("new" + GSXML.NODE_ID_ATT);
208 String newCollection = currentDoc.getAttribute("new" + GSXML.COLLECTION_ATT);
209 String operation = currentDoc.getAttribute("operation");
210
211 _GSDM.documentMoveOrDuplicate(oid, collection, newOID, newCollection, _GSDM.operationStringToInt(operation), false, userContext);
212 if (_GSDM.checkError(result, DOCUMENT_DUPLICATE))
213 {
214 return result;
215 }
216 }
217
218 return result;
219 }
220
221 protected Element processDocumentGetInformation(Element request)
222 {
223 Document result_doc = XMLConverter.newDOM();
224 Element result = GSXML.createBasicResponse(result_doc, DOCUMENT_GET_INFORMATION);
225
226 if (request == null)
227 {
228 GSXML.addError(result, DOCUMENT_GET_INFORMATION + ": Request is null", GSXML.ERROR_TYPE_SYNTAX);
229 return result;
230 }
231
232 UserContext userContext = new UserContext(request);
233
234 //Get the list of documents to duplicate
235 NodeList documents = request.getElementsByTagName(GSXML.DOCUMENT_ELEM);
236 for (int i = 0; i < documents.getLength(); i++)
237 {
238 Element currentDoc = (Element) documents.item(i);
239 String oid = currentDoc.getAttribute(GSXML.NODE_ID_ATT);
240 String collection = currentDoc.getAttribute(GSXML.COLLECTION_ATT);
241
242 NodeList requestedInfoList = currentDoc.getElementsByTagName("info"); //TODO: Replace info with a constant
243 String[] requestedInfo = new String[requestedInfoList.getLength()];
244
245 for (int j = 0; j < requestedInfoList.getLength(); j++)
246 {
247 requestedInfo[j] = ((Element) requestedInfoList.item(j)).getAttribute(GSXML.NAME_ATT);
248 }
249
250 _GSDM.documentGetInformation(oid, collection, requestedInfo, userContext);
251 if (_GSDM.checkError(result, DOCUMENT_GET_INFORMATION))
252 {
253 return result;
254 }
255 }
256
257 return result;
258 }
259
260 protected Element processDocumentMove(Element request)
261 {
262 Document result_doc = XMLConverter.newDOM();
263 Element result = GSXML.createBasicResponse(result_doc, DOCUMENT_MOVE);
264
265 if (request == null)
266 {
267 GSXML.addError(result, DOCUMENT_MOVE + ": Request is null", GSXML.ERROR_TYPE_SYNTAX);
268 return result;
269 }
270
271 UserContext userContext = new UserContext(request);
272
273 //Get the list of documents to duplicate
274 NodeList documents = request.getElementsByTagName(GSXML.DOCUMENT_ELEM);
275 for (int i = 0; i < documents.getLength(); i++)
276 {
277 Element currentDoc = (Element) documents.item(i);
278 String oid = currentDoc.getAttribute(GSXML.NODE_ID_ATT);
279 String collection = currentDoc.getAttribute(GSXML.COLLECTION_ATT);
280 String newOID = currentDoc.getAttribute("new" + GSXML.NODE_ID_ATT);
281 String newCollection = currentDoc.getAttribute("new" + GSXML.COLLECTION_ATT);
282 String operation = currentDoc.getAttribute("operation");
283
284 _GSDM.documentMoveOrDuplicate(oid, collection, newOID, newCollection, _GSDM.operationStringToInt(operation), true, userContext);
285 if (_GSDM.checkError(result, DOCUMENT_MOVE))
286 {
287 return result;
288 }
289 }
290 return result;
291 }
292
293 protected Element processDocumentMerge(Element request)
294 {
295 Document result_doc = XMLConverter.newDOM();
296 Element result = GSXML.createBasicResponse(result_doc, DOCUMENT_MERGE);
297
298 if (request == null)
299 {
300 GSXML.addError(result, DOCUMENT_MERGE + ": Request is null", GSXML.ERROR_TYPE_SYNTAX);
301 return result;
302 }
303
304 UserContext userContext = new UserContext(request);
305
306 //Get the list of documents to duplicate
307 NodeList documents = request.getElementsByTagName(GSXML.DOCUMENT_ELEM);
308 for (int i = 0; i < documents.getLength(); i++)
309 {
310 Element currentDoc = (Element) documents.item(i);
311 String oid = currentDoc.getAttribute(GSXML.NODE_ID_ATT);
312 String collection = currentDoc.getAttribute(GSXML.COLLECTION_ATT);
313 String mergeOID = currentDoc.getAttribute("merge" + GSXML.NODE_ID_ATT);
314
315 _GSDM.documentMerge(oid, collection, mergeOID, userContext);
316 if (_GSDM.checkError(result, DOCUMENT_MERGE))
317 {
318 return result;
319 }
320 }
321
322 return result;
323 }
324
325 protected Element processDocumentSplit(Element request)
326 {
327 Document result_doc = XMLConverter.newDOM();
328 Element result = GSXML.createBasicResponse(result_doc, DOCUMENT_SPLIT);
329
330 if (request == null)
331 {
332 GSXML.addError(result, DOCUMENT_SPLIT + ": Request is null", GSXML.ERROR_TYPE_SYNTAX);
333 return result;
334 }
335
336 UserContext userContext = new UserContext(request);
337
338 //Get the list of documents to duplicate
339 NodeList documents = request.getElementsByTagName(GSXML.DOCUMENT_ELEM);
340 for (int i = 0; i < documents.getLength(); i++)
341 {
342 Element currentDoc = (Element) documents.item(i);
343 String oid = currentDoc.getAttribute(GSXML.NODE_ID_ATT);
344 String collection = currentDoc.getAttribute(GSXML.COLLECTION_ATT);
345 String splitPoint = currentDoc.getAttribute("splitpoint");
346
347 int split;
348 try
349 {
350 split = Integer.parseInt(splitPoint);
351 }
352 catch (Exception ex)
353 {
354 GSXML.addError(result, DOCUMENT_SPLIT + ": The split point was not an integer", GSXML.ERROR_TYPE_SYNTAX);
355 return result;
356 }
357
358 _GSDM.documentSplit(oid, collection, split, userContext);
359 if (_GSDM.checkError(result, DOCUMENT_SPLIT))
360 {
361 return result;
362 }
363 }
364
365 return result;
366 }
367
368 protected Element processDocumentExecuteTransaction(Element request)
369 {
370 Document result_doc = XMLConverter.newDOM();
371 Element result = GSXML.createBasicResponse(result_doc, DOCUMENT_EXECUTE_TRANSACTION);
372
373 if (request == null)
374 {
375 GSXML.addError(result, DOCUMENT_EXECUTE_TRANSACTION + ": Request is null", GSXML.ERROR_TYPE_SYNTAX);
376 return result;
377 }
378
379 UserContext userContext = new UserContext(request);
380
381 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
382 if (param_list == null)
383 {
384 GSXML.addError(result, DOCUMENT_EXECUTE_TRANSACTION + ": Request has no parameter list", GSXML.ERROR_TYPE_SYNTAX);
385 return result;
386 }
387
388 HashMap<String, Serializable> params = GSXML.extractParams(param_list, false);
389 String transactionString = (String) params.get("transactions");
390 transactionString = transactionString.replace("%26", "&");
391
392 List<Map<String, String>> transactions = null;
393 try
394 {
395 Gson gson = new Gson();
396 Type type = new TypeToken<List<Map<String, String>>>()
397 {
398 }.getType();
399 transactions = gson.fromJson(transactionString, type);
400 }
401 catch (Exception ex)
402 {
403 ex.printStackTrace();
404 }
405
406 if (transactions != null && transactions.size() > 0)
407 {
408 for (int j = 0; j < transactions.size(); j++)
409 {
410 Map keyValueMap = transactions.get(j);
411 String operation = (String) keyValueMap.get("operation");
412 if (operation.equals("move") || operation.equals("duplicate"))
413 {
414 String origCollection = (String) keyValueMap.get("collection");
415 String origOID = (String) keyValueMap.get("oid");
416 String newCollection = (String) keyValueMap.get("newCollection");
417 String newOID = (String) keyValueMap.get("newOID");
418 String subOperation = (String) keyValueMap.get("subOperation");
419
420 _GSDM.documentMoveOrDuplicate(origOID, origCollection, newOID, newCollection, _GSDM.operationStringToInt(subOperation), operation.equals("move"), userContext);
421 }
422 else if (operation.equals("createDocument"))
423 {
424 String oid = (String) keyValueMap.get("oid");
425 String collection = (String) keyValueMap.get("collection");
426
427 _GSDM.documentCreate(oid, collection, userContext);
428 }
429 else if (operation.equals("create"))
430 {
431 String oid = (String) keyValueMap.get("oid");
432 String collection = (String) keyValueMap.get("collection");
433 String subOperation = (String) keyValueMap.get("subOperation");
434
435 //_GSDM.documentCreate(oid, collection, userContext); <--- Maybe go back to this
436 _GSDM.documentXMLSetSection(oid, collection, result_doc.createElement(GSXML.DOCXML_SECTION_ELEM), _GSDM.operationStringToInt(subOperation), userContext);
437 }
438 else if (operation.equals("delete"))
439 {
440 String oid = (String) keyValueMap.get("oid");
441 String collection = (String) keyValueMap.get("collection");
442
443 _GSDM.documentDelete(oid, collection, userContext);
444 }
445 else if (operation.equals("setText"))
446 {
447 String oid = (String) keyValueMap.get("oid");
448 String collection = (String) keyValueMap.get("collection");
449 String newContent = (String) keyValueMap.get("text");
450
451 _GSDM.documentXMLSetText(oid, collection, newContent, userContext);
452
453 markDocumentInFlatDatabase("R", collection, oid);
454
455 }
456
457 if (_GSDM.checkError(result, DOCUMENT_EXECUTE_TRANSACTION))
458 {
459 return result;
460 }
461 }
462 }
463 return result;
464
465 }
466 protected void markDocumentInFlatDatabase(String mark, String collection, String oid) {
467
468 Document msg_doc = XMLConverter.newDOM();
469 Element message = msg_doc.createElement(GSXML.MESSAGE_ELEM);
470 UserContext userContext = new UserContext();
471 Element query_request = GSXML.createBasicRequest(msg_doc, GSXML.REQUEST_TYPE_DESCRIBE , collection, userContext);
472 message.appendChild(query_request);
473 Element result = (Element) this.router.process(message);
474 Element resp_elem = (Element) GSXML.getChildByTagName(result, GSXML.RESPONSE_ELEM);
475 Element coll_elem = (Element) GSXML.getChildByTagName(resp_elem, GSXML.COLLECTION_ELEM);
476 String dbtype = coll_elem.getAttribute(GSXML.DB_TYPE_ATT);
477
478 SimpleCollectionDatabase coll_db = new SimpleCollectionDatabase(dbtype);
479 if (!coll_db.databaseOK())
480 {
481 logger.error("Couldn't create the collection database of type " + dbtype);
482 return;
483 }
484
485 // Open database for reading
486 String coll_db_file = GSFile.archivesDatabaseFile(this.site_home, collection, dbtype);
487 if (!coll_db.openDatabase(coll_db_file, SimpleCollectionDatabase.READ))
488 {
489 logger.error("Could not open collection archives database. Database doesn't exist or else somebody's already using it?");
490 return;
491 }
492 String old_value = coll_db.getValue(oid);
493 String new_value = old_value.replace("<index-status>B", "<index-status>" + mark);
494 // Close database for reading
495 coll_db.closeDatabase();
496 if (!coll_db.openDatabase(coll_db_file, SimpleCollectionDatabase.WRITE))
497 {
498 logger.error("Could not open collection archives database. Somebody already using this database!");
499 return;
500 }
501 coll_db.setValue(oid, new_value);
502 coll_db.closeDatabase();
503
504 }
505}
Note: See TracBrowser for help on using the repository browser.