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

Last change on this file since 32453 was 30731, checked in by kjdon, 8 years ago

if we are setting text, then we just remove the NoText metadata if its there, in case we are adding text where there wasn't any before. Leaving NoText=1 may mean the text doesn't get displayed (depending on the format statement)

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