source: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/GS2Construct.java@ 29318

Last change on this file since 29318 was 28966, checked in by kjdon, 10 years ago

Lots of changes. Mainly to do with removing this.doc from everywhere. Document is not thread safe. Now we tend to create a new Document everytime we are starting a new page/message etc. in service this.desc_doc is available as teh document to create service info stuff. But it should only be used for this and not for other messages. newDOM is now static for XMLConverter. method param changes for some GSXML methods.

  • Property svn:keywords set to Author Date Id Revision
File size: 27.4 KB
Line 
1/*
2 * GS2Construct.java
3 * Copyright (C) 2002 New Zealand Digital Library, http://www.nzdl.org
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19package org.greenstone.gsdl3.service;
20
21import java.io.BufferedWriter;
22import java.io.File;
23import java.io.FileWriter;
24import java.io.Serializable;
25import java.util.Collections;
26import java.util.HashMap;
27import java.util.Map;
28
29import org.apache.log4j.Logger;
30import org.greenstone.gsdl3.build.GS2PerlConstructor;
31import org.greenstone.gsdl3.build.GS2PerlListener;
32import org.greenstone.gsdl3.util.GSFile;
33import org.greenstone.gsdl3.util.GSParams;
34import org.greenstone.gsdl3.util.GSPath;
35import org.greenstone.gsdl3.util.GSStatus;
36import org.greenstone.gsdl3.util.GSXML;
37import org.greenstone.gsdl3.util.UserContext;
38import org.greenstone.gsdl3.util.XMLConverter;
39
40import org.w3c.dom.Document;
41import org.w3c.dom.Element;
42import org.w3c.dom.Node;
43import org.w3c.dom.Text;
44
45/**
46 * A Services class for building collections provides a wrapper around the old
47 * perl scripts
48 *
49 * @author Katherine Don
50 */
51public class GS2Construct extends ServiceRack
52{
53
54 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.GS2Construct.class.getName());
55
56 // services offered
57 private static final String NEW_SERVICE = "NewCollection";
58 private static final String ADD_DOC_SERVICE = "AddDocument";
59 private static final String IMPORT_SERVICE = "ImportCollection";
60 private static final String BUILD_SERVICE = "BuildCollection";
61 private static final String ACTIVATE_SERVICE = "ActivateCollection";
62 private static final String BUILD_AND_ACTIVATE_SERVICE = "BuildAndActivateCollection";
63 private static final String DELETE_SERVICE = "DeleteCollection";
64 private static final String RELOAD_SERVICE = "ReloadCollection";
65
66 // params used
67 private static final String COL_PARAM = "collection";
68 private static final String NEW_COL_TITLE_PARAM = "collTitle";
69 private static final String NEW_COL_ABOUT_PARAM = "collAbout";
70 private static final String CREATOR_PARAM = "creator";
71 private static final String NEW_FILE_PARAM = "newfile";
72 private static final String PROCESS_ID_PARAM = GSParams.PROCESS_ID;
73 private static final String BUILDTYPE_PARAM = "buildType";
74 private static final String BUILDTYPE_MG = "mg";
75 private static final String BUILDTYPE_MGPP = "mgpp";
76
77 // the list of the collections - store between some method calls
78 private String[] collection_list = null;
79
80 // set of listeners for any construction commands
81 protected Map<String, GS2PerlListener> listeners = null;
82 protected HashMap<String, Boolean> collectionOperationMap = new HashMap<String, Boolean>();
83
84 public GS2Construct()
85 {
86 this.listeners = Collections.synchronizedMap(new HashMap<String, GS2PerlListener>());
87 }
88
89 /** returns a specific service description */
90 protected Element getServiceDescription(Document doc, String service, String lang, String subset)
91 {
92
93 Element description = doc.createElement(GSXML.SERVICE_ELEM);
94 description.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_PROCESS);
95 description.setAttribute(GSXML.NAME_ATT, service);
96 if (subset == null || subset.equals(GSXML.DISPLAY_TEXT_ELEM + GSXML.LIST_MODIFIER))
97 {
98 description.appendChild(GSXML.createDisplayTextElement(doc, GSXML.DISPLAY_TEXT_NAME, getTextString(service + ".name", lang)));
99 description.appendChild(GSXML.createDisplayTextElement(doc, GSXML.DISPLAY_TEXT_DESCRIPTION, getTextString(service + ".description", lang)));
100 description.appendChild(GSXML.createDisplayTextElement(doc, GSXML.DISPLAY_TEXT_SUBMIT, getTextString(service + ".submit", lang)));
101 }
102 if (subset == null || subset.equals(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER))
103 {
104 Element param_list = doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
105 description.appendChild(param_list);
106
107 if (service.equals(NEW_SERVICE))
108 {
109
110 Element param = GSXML.createParameterDescription(doc, NEW_COL_TITLE_PARAM, getTextString("param." + NEW_COL_TITLE_PARAM, lang), GSXML.PARAM_TYPE_STRING, null, null, null);
111 param_list.appendChild(param);
112 param = GSXML.createParameterDescription(doc, CREATOR_PARAM, getTextString("param." + CREATOR_PARAM, lang), GSXML.PARAM_TYPE_STRING, null, null, null);
113 param_list.appendChild(param);
114 param = GSXML.createParameterDescription(doc, NEW_COL_ABOUT_PARAM, getTextString("param." + NEW_COL_ABOUT_PARAM, lang), GSXML.PARAM_TYPE_TEXT, null, null, null);
115 param_list.appendChild(param);
116 String[] types = { BUILDTYPE_MGPP, BUILDTYPE_MG };
117 String[] type_texts = { getTextString("param." + BUILDTYPE_PARAM + "." + BUILDTYPE_MGPP, lang), getTextString("param." + BUILDTYPE_PARAM + "." + BUILDTYPE_MG, lang) };
118
119 param = GSXML.createParameterDescription(doc, BUILDTYPE_PARAM, getTextString("param." + BUILDTYPE_PARAM, lang), GSXML.PARAM_TYPE_ENUM_SINGLE, BUILDTYPE_MGPP, types, type_texts);
120 param_list.appendChild(param);
121 }
122 else if (service.equals(ACTIVATE_SERVICE) || service.equals(IMPORT_SERVICE) || service.equals(BUILD_SERVICE) || service.equals(RELOAD_SERVICE) || service.equals(DELETE_SERVICE))
123 {
124
125 this.collection_list = getCollectionList();
126 Element param = GSXML.createParameterDescription(doc, COL_PARAM, getTextString("param." + COL_PARAM, lang), GSXML.PARAM_TYPE_ENUM_SINGLE, null, this.collection_list, this.collection_list);
127 param_list.appendChild(param);
128 }
129 else
130 {
131 // invalid service name
132 return null;
133 }
134 }
135 return description;
136 }
137
138 // each service must have a method "process<New service name>"
139
140 protected Element processNewCollection(Element request)
141 {
142 return runCommand(request, GS2PerlConstructor.NEW);
143 }
144
145 /** TODO:implement this */
146 protected Element processAddDocument(Element request)
147 {
148 Document result_doc = XMLConverter.newDOM();
149 // decode the file name, add it to the import directory
150 String name = GSPath.getFirstLink(request.getAttribute(GSXML.TO_ATT));
151 Element response = result_doc.createElement(GSXML.RESPONSE_ELEM);
152 response.setAttribute(GSXML.FROM_ATT, name);
153 Element status = result_doc.createElement(GSXML.STATUS_ELEM);
154 response.appendChild(status);
155 //String lang = request.getAttribute(GSXML.LANG_ATT);
156 //String request_type = request.getAttribute(GSXML.TYPE_ATT);
157 Text t = result_doc.createTextNode("AddDocument: not implemented yet");
158 status.appendChild(t);
159 status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.ERROR));
160 return response;
161 }
162
163 protected Element processBuildAndActivateCollection(Element request)
164 {
165
166 waitUntilReady(request);
167 Element buildResponse = processBuildCollection(request);
168 if (buildResponse.getElementsByTagName(GSXML.ERROR_ELEM).getLength() > 0)
169 {
170 return buildResponse;
171 }
172
173 Element statusElem = (Element) buildResponse.getElementsByTagName(GSXML.STATUS_ELEM).item(0);
174 String id = statusElem.getAttribute("pid");
175
176 GS2PerlListener currentListener = this.listeners.get(id);
177 int statusCode = currentListener.getStatus();
178 while (!GSStatus.isCompleted(statusCode))
179 {
180 // wait for the process, and keep checking the status code
181 // there is probably a better way to do this.
182 try
183 {
184 Thread.currentThread().sleep(100);
185 }
186 catch (Exception e)
187 { // ignore
188 }
189 statusCode = currentListener.getStatus();
190 }
191
192 Element activateResponse = processActivateCollection(request);
193 signalReady(request);
194 return activateResponse;
195 }
196
197 protected Element processImportCollection(Element request)
198 {
199 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
200 HashMap<String, Serializable> params = GSXML.extractParams(param_list, false);
201
202 if (params == null)
203 {
204 return null;
205 }
206
207 //If we have been requested to only build certain documents then we need to create a manifest file
208 String documentsParam = (String) params.get("documents");
209 if (documentsParam != null && !documentsParam.equals(""))
210 {
211 String s = File.separator;
212 String manifestFolderPath = this.site_home + s + "collect" + s + params.get(COL_PARAM) + s + "manifests";
213 String manifestFilePath = manifestFolderPath + File.separator + "tempManifest.xml";
214
215 File manifestFolderFile = new File(manifestFolderPath);
216 if (!manifestFolderFile.exists())
217 {
218 manifestFolderFile.mkdirs();
219 }
220
221 File manifestFile = new File(manifestFilePath);
222 if (!manifestFile.exists())
223 {
224 try
225 {
226 manifestFile.createNewFile();
227 }
228 catch (Exception ex)
229 {
230 ex.printStackTrace();
231 return null; //Probably should return an actual error
232 }
233 }
234 String[] docList = documentsParam.split(",");
235
236 try
237 {
238 BufferedWriter bw = new BufferedWriter(new FileWriter(manifestFile));
239 bw.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
240 bw.write("<Manifest>\n");
241 bw.write(" <Index>\n");
242 for (int j = 0; j < docList.length; j++)
243 {
244 bw.write(" <Filename>" + docList[j] + "</Filename>\n");
245 }
246 bw.write(" </Index>\n");
247 bw.write("</Manifest>\n");
248 bw.close();
249 }
250 catch (Exception ex)
251 {
252 ex.printStackTrace();
253 return null; //Probably should return an actual error
254 }
255 }
256
257 return runCommand(request, GS2PerlConstructor.IMPORT);
258 }
259
260 protected Element processBuildCollection(Element request)
261 {
262 return runCommand(request, GS2PerlConstructor.BUILD);
263 }
264
265 protected Element processActivateCollection(Element request)
266 {
267 // this activates the collection on disk. but now we need to tell
268 // the MR about it. but we have to wait until the process is finished.
269 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
270 HashMap<String, Serializable> params = GSXML.extractParams(param_list, false);
271 String coll_name = (String) params.get(COL_PARAM);
272 String lang = request.getAttribute(GSXML.LANG_ATT);
273
274 Element response = runCommand(request, GS2PerlConstructor.ACTIVATE);
275 Element status = (Element) GSXML.getChildByTagName(response, GSXML.STATUS_ELEM);
276
277 String request_type = request.getAttribute(GSXML.TYPE_ATT);
278 if (request_type.equals(GSXML.REQUEST_TYPE_STATUS))
279 {
280 return response;
281 }
282
283 UserContext userContext = new UserContext(request);
284 systemRequest("delete", coll_name, null, userContext);
285
286 // check for finished
287 int status_code = Integer.parseInt(status.getAttribute(GSXML.STATUS_ERROR_CODE_ATT));
288 if (GSStatus.isCompleted(status_code) && GSStatus.isError(status_code))
289 {
290 // we shouldn't carry out the next bit, just return the response
291 return response;
292 }
293 String id = status.getAttribute(GSXML.STATUS_PROCESS_ID_ATT);
294 GS2PerlListener listener = this.listeners.get(id);
295 if (listener == null)
296 {
297 logger.error("somethings gone wrong, couldn't find the listener");
298 status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.ERROR));
299 return response;
300 }
301
302 while (!GSStatus.isCompleted(status_code))
303 {
304 // wait for the process, and keep checking the status code
305 // there is probably a better way to do this.
306 try
307 {
308 Thread.currentThread().sleep(100);
309 }
310 catch (Exception e)
311 { // ignore
312 }
313 status_code = listener.getStatus();
314 }
315
316 // add the rest of the messages to the status node
317 Text t = status.getOwnerDocument().createTextNode("\n" + listener.getUpdate());
318 status.appendChild(t);
319 status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(listener.getStatus()));
320 if (GSStatus.isError(status_code))
321 {
322 return response; // without doing the next bit
323 }
324
325 t = status.getOwnerDocument().createTextNode("\n");
326 status.appendChild(t);
327 // once have got here, we assume
328 // the first bit proceeded successfully, now reload the collection
329 systemRequest("reload", coll_name, status, userContext); // this will append more messages to the status, and overwrite the error code att
330 return response;
331
332 }
333
334 protected Element processDeleteCollection(Element request)
335 {
336 Document result_doc = XMLConverter.newDOM();
337 // the response to send back
338 String name = GSPath.getFirstLink(request.getAttribute(GSXML.TO_ATT));
339 Element response = result_doc.createElement(GSXML.RESPONSE_ELEM);
340 response.setAttribute(GSXML.FROM_ATT, name);
341 Element status = result_doc.createElement(GSXML.STATUS_ELEM);
342 response.appendChild(status);
343 Text t = null; // the text node for the error/success message
344 String lang = request.getAttribute(GSXML.LANG_ATT);
345 String request_type = request.getAttribute(GSXML.TYPE_ATT);
346
347 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
348 HashMap<String, Serializable> params = GSXML.extractParams(param_list, false);
349
350 boolean get_status_only = false;
351 if (request_type.equals(GSXML.REQUEST_TYPE_STATUS))
352 {
353 get_status_only = true;
354 }
355 if (get_status_only)
356 {
357 // at the moment, delete is synchronous. but it may take ages so should do the command in another thread maybe? in which case we will want to ask for status
358 logger.error("had a status request for delete - this shouldn't happen!!");
359 //t = result_doc.createTextNode("");
360 //status.appendChild(t);
361 status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.ERROR));
362 return response;
363 }
364 String coll_name = (String) params.get(COL_PARAM);
365 String[] args = { coll_name };
366 File coll_dir = new File(GSFile.collectionBaseDir(this.site_home, coll_name));
367 // check that the coll is there in the first place
368 if (!coll_dir.exists())
369 {
370 t = result_doc.createTextNode(getTextString("delete.exists_error", lang, args));
371 status.appendChild(t);
372 status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.ERROR));
373 return response;
374 }
375
376 // try to delete the directory
377 if (!GSFile.deleteFile(coll_dir))
378 {
379 t = result_doc.createTextNode(getTextString("delete.delete_error", lang, args));
380 status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.ERROR));
381 status.appendChild(t);
382 return response;
383 }
384
385 UserContext userContext = new UserContext(request);
386
387 systemRequest("delete", coll_name, status, userContext);
388 return response;
389 }
390
391 protected Element processReloadCollection(Element request)
392 {
393 Document result_doc = XMLConverter.newDOM();
394 // the response to send back
395 String name = GSPath.getFirstLink(request.getAttribute(GSXML.TO_ATT));
396 Element response = result_doc.createElement(GSXML.RESPONSE_ELEM);
397 response.setAttribute(GSXML.FROM_ATT, name);
398 Element status = result_doc.createElement(GSXML.STATUS_ELEM);
399 response.appendChild(status);
400 Text t = null; // the text node for the error/success message
401
402 String lang = request.getAttribute(GSXML.LANG_ATT);
403 String request_type = request.getAttribute(GSXML.TYPE_ATT);
404
405 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
406 HashMap<String, Serializable> params = GSXML.extractParams(param_list, false);
407
408 boolean get_status_only = false;
409 if (request_type.equals(GSXML.REQUEST_TYPE_STATUS))
410 {
411 get_status_only = true;
412 }
413 if (get_status_only)
414 {
415 // reload is synchronous - this makes no sense
416 logger.error("had a status request for reload - this shouldn't happen!!");
417 //t = result_doc.createTextNode("");
418 //status.appendChild(t);
419 status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.ERROR));
420 return response;
421 }
422
423 String coll_name = (String) params.get(COL_PARAM);
424
425 UserContext userContext = new UserContext(request);
426
427 systemRequest("reload", coll_name, status, userContext);
428 return response;
429
430 }
431
432 /**
433 * send a configure request to the message router action name should be
434 * "delete" or "reload" response will be put into the status element
435 */
436 protected void systemRequest(String operation, String coll_name, Element status, UserContext userContext)
437 {
438 // send the request to the MR
439 Document doc = XMLConverter.newDOM();
440 Element message = doc.createElement(GSXML.MESSAGE_ELEM);
441 Element request = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_SYSTEM, "", userContext);
442 message.appendChild(request);
443 Element command = doc.createElement(GSXML.SYSTEM_ELEM);
444 request.appendChild(command);
445 command.setAttribute(GSXML.SYSTEM_MODULE_TYPE_ATT, GSXML.COLLECTION_ELEM);
446 command.setAttribute(GSXML.SYSTEM_MODULE_NAME_ATT, coll_name);
447
448 if (operation.equals("delete"))
449 {
450 command.setAttribute(GSXML.TYPE_ATT, GSXML.SYSTEM_TYPE_DEACTIVATE);
451 }
452 else if (operation.equals("reload"))
453 {
454 command.setAttribute(GSXML.TYPE_ATT, GSXML.SYSTEM_TYPE_ACTIVATE);
455 }
456 else
457 {
458 logger.error("invalid action name passed to systemRequest:" + operation);
459 return;
460 }
461 request.appendChild(command);
462 Node response = this.router.process(message); // at the moment, get no info in response so ignore it
463 Text t;
464 String[] args = { coll_name };
465
466 if (status != null)
467 {
468 if (response == null)
469 {
470 t = status.getOwnerDocument().createTextNode(getTextString(operation + ".configure_error", userContext.getLanguage(), args));
471 status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.ERROR));
472 status.appendChild(t);
473 return;
474 }
475
476 // if we got here, we have succeeded!
477 t = status.getOwnerDocument().createTextNode(getTextString(operation + ".success", userContext.getLanguage(), args));
478 status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.SUCCESS));
479 status.appendChild(t);
480 }
481 }
482
483 /**
484 * configure the service module for now, all services have type=build - need
485 * to think about this
486 */
487 public boolean configure(Element info, Element extra_info)
488 {
489 if (!super.configure(info, extra_info))
490 {
491 return false;
492 }
493
494 logger.info("configuring GS2Construct");
495
496 Element e = null;
497 // hard code in the services for now
498
499 // set up short_service_info_ - for now just has name and type
500
501 e = this.desc_doc.createElement(GSXML.SERVICE_ELEM);
502 e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_PROCESS);
503 e.setAttribute(GSXML.NAME_ATT, NEW_SERVICE);
504 this.short_service_info.appendChild(e);
505
506 e = this.desc_doc.createElement(GSXML.SERVICE_ELEM);
507 e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_PROCESS);
508 e.setAttribute(GSXML.NAME_ATT, IMPORT_SERVICE);
509 this.short_service_info.appendChild(e);
510
511 e = this.desc_doc.createElement(GSXML.SERVICE_ELEM);
512 e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_PROCESS);
513 e.setAttribute(GSXML.NAME_ATT, BUILD_SERVICE);
514 this.short_service_info.appendChild(e);
515
516 e = this.desc_doc.createElement(GSXML.SERVICE_ELEM);
517 e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_PROCESS);
518 e.setAttribute(GSXML.NAME_ATT, ACTIVATE_SERVICE);
519 this.short_service_info.appendChild(e);
520
521 e = this.desc_doc.createElement(GSXML.SERVICE_ELEM);
522 e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_PROCESS);
523 e.setAttribute(GSXML.NAME_ATT, BUILD_AND_ACTIVATE_SERVICE);
524 this.short_service_info.appendChild(e);
525
526 e = this.desc_doc.createElement(GSXML.SERVICE_ELEM);
527 e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_PROCESS);
528 e.setAttribute(GSXML.NAME_ATT, DELETE_SERVICE);
529 this.short_service_info.appendChild(e);
530
531 e = this.desc_doc.createElement(GSXML.SERVICE_ELEM);
532 e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_PROCESS);
533 e.setAttribute(GSXML.NAME_ATT, RELOAD_SERVICE);
534 this.short_service_info.appendChild(e);
535
536 //e = this.desc_doc.createElement(GSXML.SERVICE_ELEM);
537 //e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_PROCESS);
538 //e.setAttribute(GSXML.NAME_ATT, ADD_DOC_SERVICE);
539 //this.short_service_info.appendChild(e);
540
541 return true;
542 }
543
544 /** returns a response element */
545 protected Element runCommand(Element request, int type)
546 {
547 Document result_doc = XMLConverter.newDOM();
548 // the response to send back
549 String name = GSPath.getFirstLink(request.getAttribute(GSXML.TO_ATT));
550 Element response = result_doc.createElement(GSXML.RESPONSE_ELEM);
551 response.setAttribute(GSXML.FROM_ATT, name);
552 Element status = result_doc.createElement(GSXML.STATUS_ELEM);
553 response.appendChild(status);
554
555 String lang = request.getAttribute(GSXML.LANG_ATT);
556 String request_type = request.getAttribute(GSXML.TYPE_ATT);
557
558 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
559 HashMap<String, Serializable> params = GSXML.extractParams(param_list, false);
560
561 boolean get_status_only = false;
562 if (request_type.equals(GSXML.REQUEST_TYPE_STATUS))
563 {
564 get_status_only = true;
565 }
566
567 // just check for status messages if that's all that's required
568 if (get_status_only)
569 {
570 String id = (String) params.get(PROCESS_ID_PARAM);
571 status.setAttribute(GSXML.STATUS_PROCESS_ID_ATT, id);
572 GS2PerlListener listener = this.listeners.get(id);
573 if (listener == null)
574 {
575 Text t = result_doc.createTextNode(getTextString("general.process_id_error", lang));
576 status.appendChild(t);
577 status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.ERROR));
578 }
579 else
580 {
581 Text t = result_doc.createTextNode(listener.getUpdate());
582 status.appendChild(t);
583 status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(listener.getStatus()));
584 // check that we actually should be removing the listener here
585 if (listener.isFinished())
586 { // remove this listener - its job is done
587 this.listeners.remove(id); // not working
588 }
589 }
590 return response;
591
592 }
593
594 // do teh actual command
595 String coll_name = null;
596 if (type == GS2PerlConstructor.NEW)
597 {
598 String coll_title = (String) params.get(NEW_COL_TITLE_PARAM);
599 coll_name = createNewCollName(coll_title);
600 }
601 else
602 {
603 coll_name = (String) params.get(COL_PARAM);
604 }
605
606 // makes a paramList of the relevant params
607 Element other_params = extractOtherParams(params, type);
608
609 //create the constructor to do the work
610 GS2PerlConstructor constructor = new GS2PerlConstructor("perl_build");
611 if (!constructor.configure())
612 {
613 Text t = result_doc.createTextNode(getTextString("general.configure_constructor_error", lang));
614 status.appendChild(t);
615 status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.ERROR));
616 return response;
617 }
618
619 constructor.setSiteHome(this.site_home);
620 constructor.setCollectionName(coll_name);
621 constructor.setActionType(type);
622 constructor.setProcessParams(other_params);
623 if (type == GS2PerlConstructor.IMPORT)
624 {
625 constructor.setManifestFile(this.site_home + File.separator + "collect" + File.separator + params.get(COL_PARAM) + File.separator + "manifests" + File.separator + "tempManifest.xml");
626 }
627
628 GS2PerlListener listener = new GS2PerlListener();
629 constructor.addListener(listener);
630 constructor.start();
631
632 String id = newID();
633 this.listeners.put(id, listener);
634
635 status.setAttribute(GSXML.STATUS_PROCESS_ID_ATT, id);
636 status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.ACCEPTED));
637 Text t = result_doc.createTextNode(getTextString("general.process_start", lang));
638 status.appendChild(t);
639 return response;
640 }
641
642 //************************
643 // some helper functions
644 //************************
645
646 /** parse the collect directory and return a list of collection names */
647 protected String[] getCollectionList()
648 {
649
650 File collectDir = new File(GSFile.collectDir(this.site_home));
651 if (!collectDir.exists())
652 {
653 logger.error("couldn't find collect dir: " + collectDir.toString());
654 return null;
655 }
656 logger.info("GS2Construct: reading thru directory " + collectDir.getPath() + " to find collections.");
657 File[] contents = collectDir.listFiles();
658 int num_colls = 0;
659 for (int i = 0; i < contents.length; i++)
660 {
661 if (contents[i].isDirectory() && !contents[i].getName().startsWith("CVS"))
662 {
663 num_colls++;
664 }
665 }
666
667 String[] names = new String[num_colls];
668
669 for (int i = 0, j = 0; i < contents.length; i++)
670 {
671 if (contents[i].isDirectory())
672 {
673 String colName = contents[i].getName();
674 if (!colName.startsWith("CVS"))
675 {
676 names[j] = colName;
677 j++;
678 }
679
680 }
681 }
682
683 return names;
684
685 }
686
687 /** ids used for process id */
688 private int current_id = 0;
689
690 private String newID()
691 {
692 current_id++;
693 return Integer.toString(current_id);
694 }
695
696 /** creates a new short name from the collection title */
697 protected String createNewCollName(String coll_title)
698 {
699
700 String base_name = null;
701 // take the first 6 letters
702 if (coll_title.length() < 6)
703 {
704 base_name = coll_title;
705 }
706 else
707 {
708 base_name = coll_title.substring(0, 6);
709 }
710 File coll_dir = new File(GSFile.collectionBaseDir(this.site_home, base_name));
711 if (!coll_dir.exists())
712 { // this name is ok - not used yet
713 return base_name;
714 }
715
716 // now we have to make a new name until we get a good one
717 // try name1, name2 name3 etc
718 int i = 0;
719 while (coll_dir.exists())
720 {
721 i++;
722 coll_dir = new File(GSFile.collectionBaseDir(this.site_home, base_name + Integer.toString(i)));
723 }
724 return base_name + Integer.toString(i);
725
726 }
727
728 /**
729 * takes the params from the request (in the HashMap) and extracts any that
730 * need to be passed to the constructor and puts them into a paramList
731 * element
732 */
733 protected Element extractOtherParams(HashMap<String, Serializable> params, int type)
734 {
735 Document doc = XMLConverter.newDOM();
736 Element param_list = doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
737 if (type == GS2PerlConstructor.NEW)
738 {
739 Element param = doc.createElement(GSXML.PARAM_ELEM);
740 param.setAttribute(GSXML.NAME_ATT, "creator");
741 param.setAttribute(GSXML.VALUE_ATT, (String) params.get(CREATOR_PARAM));
742
743 param_list.appendChild(param);
744 param = doc.createElement(GSXML.PARAM_ELEM);
745 param.setAttribute(GSXML.NAME_ATT, "about");
746 param.setAttribute(GSXML.VALUE_ATT, (String) params.get(NEW_COL_ABOUT_PARAM));
747 param_list.appendChild(param);
748 param = doc.createElement(GSXML.PARAM_ELEM);
749 param.setAttribute(GSXML.NAME_ATT, "title");
750 param.setAttribute(GSXML.VALUE_ATT, (String) params.get(NEW_COL_TITLE_PARAM));
751 param_list.appendChild(param);
752 param = doc.createElement(GSXML.PARAM_ELEM);
753 param.setAttribute(GSXML.NAME_ATT, "buildtype");
754 param.setAttribute(GSXML.VALUE_ATT, (String) params.get(BUILDTYPE_PARAM));
755 param_list.appendChild(param);
756 return param_list;
757 }
758
759 // other ones dont have params yet
760 return null;
761 }
762
763 protected void waitUntilReady(Element request)
764 {
765 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
766 HashMap<String, Serializable> params = GSXML.extractParams(param_list, false);
767
768 String collection = (String) params.get(COL_PARAM);
769
770 if (checkCollectionIsNotBusy(collection))
771 {
772 return;
773 }
774
775 while (collectionOperationMap.get(collection) != null)
776 {
777 try
778 {
779 Thread.currentThread().sleep(1000);
780 }
781 catch (Exception ex)
782 {
783 ex.printStackTrace();
784 }
785 }
786 }
787
788 protected void signalReady(Element request)
789 {
790 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
791 HashMap<String, Serializable> params = GSXML.extractParams(param_list, false);
792
793 String collection = (String) params.get(COL_PARAM);
794
795 collectionOperationMap.remove(collection);
796 }
797
798 protected synchronized boolean checkCollectionIsNotBusy(String collection)
799 {
800 if (collectionOperationMap.get(collection) == null)
801 {
802 collectionOperationMap.put(collection, true);
803 return true;
804 }
805 return false;
806 }
807}
Note: See TracBrowser for help on using the repository browser.