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

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

A minor error check

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