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

Last change on this file since 30516 was 30516, checked in by Georgiy Litvinov, 8 years ago

Moved to incremental rebuild in webeditor

  • Property svn:executable set to *
File size: 17.0 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. Somebody already using this database!");
490 }
491 String old_value = coll_db.getValue(oid);
492 String new_value = old_value.replace("<index-status>B", "<index-status>" + mark);
493 // Close database for reading
494 coll_db.closeDatabase();
495 if (!coll_db.openDatabase(coll_db_file, SimpleCollectionDatabase.WRITE))
496 {
497 logger.error("Could not open collection archives database. Somebody already using this database!");
498 }
499 coll_db.setValue(oid, new_value);
500 coll_db.closeDatabase();
501
502 }
503}
Note: See TracBrowser for help on using the repository browser.