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

Last change on this file since 27135 was 27135, checked in by ak19, 11 years ago

Shifting instructions for svn updating gs2build/common-src/cgi-bin scripts for moving into gs3/web/WEB-INF/cgi to its own target and making sure it gets called at the same time as it did before (previously in prepare-gli and svnupdate-gli targets, now called alongside those targets). Now metadata-server.pl in cgi-bin is also svn-updated.

  • Property svn:keywords set to Author Date Id Revision
File size: 27.1 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 org.greenstone.gsdl3.util.*;
22import org.greenstone.gsdl3.build.*;
23import org.greenstone.util.GlobalProperties;
24
25import org.w3c.dom.Document;
26import org.w3c.dom.Node;
27import org.w3c.dom.Text;
28import org.w3c.dom.Element;
29import org.w3c.dom.NodeList;
30
31import java.util.Collections;
32import java.util.HashMap;
33import java.util.Map;
34import java.util.List;
35import java.util.ArrayList;
36import java.io.BufferedWriter;
37import java.io.File;
38import java.io.FileWriter;
39import java.io.Serializable;
40import java.lang.Thread.State;
41import java.util.Locale;
42
43import java.util.Timer;
44import java.util.TimerTask;
45
46import org.apache.log4j.*;
47
48/**
49 * A Services class for building collections provides a wrapper around the old
50 * perl scripts
51 *
52 * @author Katherine Don
53 * @version $Revision: 27135 $
54 */
55public class GS2Construct extends ServiceRack
56{
57
58 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.GS2Construct.class.getName());
59
60 // services offered
61 private static final String NEW_SERVICE = "NewCollection";
62 private static final String ADD_DOC_SERVICE = "AddDocument";
63 private static final String IMPORT_SERVICE = "ImportCollection";
64 private static final String BUILD_SERVICE = "BuildCollection";
65 private static final String ACTIVATE_SERVICE = "ActivateCollection";
66 private static final String BUILD_AND_ACTIVATE_SERVICE = "BuildAndActivateCollection";
67 private static final String DELETE_SERVICE = "DeleteCollection";
68 private static final String RELOAD_SERVICE = "ReloadCollection";
69
70 // params used
71 private static final String COL_PARAM = "collection";
72 private static final String NEW_COL_TITLE_PARAM = "collTitle";
73 private static final String NEW_COL_ABOUT_PARAM = "collAbout";
74 private static final String CREATOR_PARAM = "creator";
75 private static final String NEW_FILE_PARAM = "newfile";
76 private static final String PROCESS_ID_PARAM = GSParams.PROCESS_ID;
77 private static final String BUILDTYPE_PARAM = "buildType";
78 private static final String BUILDTYPE_MG = "mg";
79 private static final String BUILDTYPE_MGPP = "mgpp";
80
81 // the list of the collections - store between some method calls
82 private String[] collection_list = null;
83
84 // set of listeners for any construction commands
85 protected Map<String, GS2PerlListener> listeners = null;
86 protected HashMap<String, Boolean> collectionOperationMap = new HashMap<String, Boolean>();
87
88 public GS2Construct()
89 {
90 this.listeners = Collections.synchronizedMap(new HashMap<String, GS2PerlListener>());
91 }
92
93 /** returns a specific service description */
94 protected Element getServiceDescription(String service, String lang, String subset)
95 {
96
97 Element description = this.doc.createElement(GSXML.SERVICE_ELEM);
98 description.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_PROCESS);
99 description.setAttribute(GSXML.NAME_ATT, service);
100 if (subset == null || subset.equals(GSXML.DISPLAY_TEXT_ELEM + GSXML.LIST_MODIFIER))
101 {
102 description.appendChild(GSXML.createDisplayTextElement(this.doc, GSXML.DISPLAY_TEXT_NAME, getTextString(service + ".name", lang)));
103 description.appendChild(GSXML.createDisplayTextElement(this.doc, GSXML.DISPLAY_TEXT_DESCRIPTION, getTextString(service + ".description", lang)));
104 description.appendChild(GSXML.createDisplayTextElement(this.doc, GSXML.DISPLAY_TEXT_SUBMIT, getTextString(service + ".submit", lang)));
105 }
106 if (subset == null || subset.equals(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER))
107 {
108 Element param_list = this.doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
109 description.appendChild(param_list);
110
111 if (service.equals(NEW_SERVICE))
112 {
113
114 Element param = GSXML.createParameterDescription(this.doc, NEW_COL_TITLE_PARAM, getTextString("param." + NEW_COL_TITLE_PARAM, lang), GSXML.PARAM_TYPE_STRING, null, null, null);
115 param_list.appendChild(param);
116 param = GSXML.createParameterDescription(this.doc, CREATOR_PARAM, getTextString("param." + CREATOR_PARAM, lang), GSXML.PARAM_TYPE_STRING, null, null, null);
117 param_list.appendChild(param);
118 param = GSXML.createParameterDescription(this.doc, NEW_COL_ABOUT_PARAM, getTextString("param." + NEW_COL_ABOUT_PARAM, lang), GSXML.PARAM_TYPE_TEXT, null, null, null);
119 param_list.appendChild(param);
120 String[] types = { BUILDTYPE_MGPP, BUILDTYPE_MG };
121 String[] type_texts = { getTextString("param." + BUILDTYPE_PARAM + "." + BUILDTYPE_MGPP, lang), getTextString("param." + BUILDTYPE_PARAM + "." + BUILDTYPE_MG, lang) };
122
123 param = GSXML.createParameterDescription(this.doc, BUILDTYPE_PARAM, getTextString("param." + BUILDTYPE_PARAM, lang), GSXML.PARAM_TYPE_ENUM_SINGLE, BUILDTYPE_MGPP, types, type_texts);
124 param_list.appendChild(param);
125 }
126 else if (service.equals(ACTIVATE_SERVICE) || service.equals(IMPORT_SERVICE) || service.equals(BUILD_SERVICE) || service.equals(RELOAD_SERVICE) || service.equals(DELETE_SERVICE))
127 {
128
129 this.collection_list = getCollectionList();
130 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);
131 param_list.appendChild(param);
132 }
133 else
134 {
135 // invalid service name
136 return null;
137 }
138 }
139 return description;
140 }
141
142 // each service must have a method "process<New service name>"
143
144 protected Element processNewCollection(Element request)
145 {
146 return runCommand(request, GS2PerlConstructor.NEW);
147 }
148
149 /** TODO:implement this */
150 protected Element processAddDocument(Element request)
151 {
152 // decode the file name, add it to the import directory
153 String name = GSPath.getFirstLink(request.getAttribute(GSXML.TO_ATT));
154 Element response = this.doc.createElement(GSXML.RESPONSE_ELEM);
155 response.setAttribute(GSXML.FROM_ATT, name);
156 Element status = this.doc.createElement(GSXML.STATUS_ELEM);
157 response.appendChild(status);
158 //String lang = request.getAttribute(GSXML.LANG_ATT);
159 //String request_type = request.getAttribute(GSXML.TYPE_ATT);
160 Text t = this.doc.createTextNode("AddDocument: not implemented yet");
161 status.appendChild(t);
162 status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.ERROR));
163 return response;
164 }
165
166 protected Element processBuildAndActivateCollection(Element request)
167 {
168
169 logger.error("**** GS2Construct Build and Activate: " + GSXML.elementToString(request, true));
170
171 waitUntilReady(request);
172 Element buildResponse = processBuildCollection(request);
173 if (buildResponse.getElementsByTagName(GSXML.ERROR_ELEM).getLength() > 0)
174 {
175 return buildResponse;
176 }
177
178 Element statusElem = (Element) buildResponse.getElementsByTagName(GSXML.STATUS_ELEM).item(0);
179 String id = statusElem.getAttribute("pid");
180
181 GS2PerlListener currentListener = this.listeners.get(id);
182 int statusCode = currentListener.getStatus();
183 while (!GSStatus.isCompleted(statusCode))
184 {
185 // wait for the process, and keep checking the status code
186 // there is probably a better way to do this.
187 try
188 {
189 Thread.currentThread().sleep(100);
190 }
191 catch (Exception e)
192 { // ignore
193 }
194 statusCode = currentListener.getStatus();
195 }
196
197 Element activateResponse = processActivateCollection(request);
198 signalReady(request);
199 return activateResponse;
200 }
201
202 protected Element processImportCollection(Element request)
203 {
204 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
205 HashMap<String, Serializable> params = GSXML.extractParams(param_list, false);
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 = this.doc.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 = this.doc.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
337 // the response to send back
338 String name = GSPath.getFirstLink(request.getAttribute(GSXML.TO_ATT));
339 Element response = this.doc.createElement(GSXML.RESPONSE_ELEM);
340 response.setAttribute(GSXML.FROM_ATT, name);
341 Element status = this.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 = this.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 = this.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 = this.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
394 // the response to send back
395 String name = GSPath.getFirstLink(request.getAttribute(GSXML.TO_ATT));
396 Element response = this.doc.createElement(GSXML.RESPONSE_ELEM);
397 response.setAttribute(GSXML.FROM_ATT, name);
398 Element status = this.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 = this.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 Element message = this.doc.createElement(GSXML.MESSAGE_ELEM);
440 Element request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_SYSTEM, "", userContext);
441 message.appendChild(request);
442 Element command = this.doc.createElement(GSXML.SYSTEM_ELEM);
443 request.appendChild(command);
444 command.setAttribute(GSXML.SYSTEM_MODULE_TYPE_ATT, GSXML.COLLECTION_ELEM);
445 command.setAttribute(GSXML.SYSTEM_MODULE_NAME_ATT, coll_name);
446
447 if (operation.equals("delete"))
448 {
449 command.setAttribute(GSXML.TYPE_ATT, GSXML.SYSTEM_TYPE_DEACTIVATE);
450 }
451 else if (operation.equals("reload"))
452 {
453 command.setAttribute(GSXML.TYPE_ATT, GSXML.SYSTEM_TYPE_ACTIVATE);
454 }
455 else
456 {
457 logger.error("invalid action name passed to systemRequest:" + operation);
458 return;
459 }
460 request.appendChild(command);
461 Node response = this.router.process(message); // at the moment, get no info in response so ignore it
462 Text t;
463 String[] args = { coll_name };
464
465 if (status != null)
466 {
467 if (response == null)
468 {
469 t = this.doc.createTextNode(getTextString(operation + ".configure_error", userContext.getLanguage(), args));
470 status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.ERROR));
471 status.appendChild(t);
472 return;
473 }
474
475 // if we got here, we have succeeded!
476 t = this.doc.createTextNode(getTextString(operation + ".success", userContext.getLanguage(), args));
477 status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.SUCCESS));
478 status.appendChild(t);
479 }
480 }
481
482 /**
483 * configure the service module for now, all services have type=build - need
484 * to think about this
485 */
486 public boolean configure(Element info, Element extra_info)
487 {
488 if (!super.configure(info, extra_info))
489 {
490 return false;
491 }
492
493 logger.info("configuring GS2Construct");
494
495 Element e = null;
496 // hard code in the services for now
497
498 // set up short_service_info_ - for now just has name and type
499
500 e = this.doc.createElement(GSXML.SERVICE_ELEM);
501 e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_PROCESS);
502 e.setAttribute(GSXML.NAME_ATT, NEW_SERVICE);
503 this.short_service_info.appendChild(e);
504
505 e = this.doc.createElement(GSXML.SERVICE_ELEM);
506 e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_PROCESS);
507 e.setAttribute(GSXML.NAME_ATT, IMPORT_SERVICE);
508 this.short_service_info.appendChild(e);
509
510 e = this.doc.createElement(GSXML.SERVICE_ELEM);
511 e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_PROCESS);
512 e.setAttribute(GSXML.NAME_ATT, BUILD_SERVICE);
513 this.short_service_info.appendChild(e);
514
515 e = this.doc.createElement(GSXML.SERVICE_ELEM);
516 e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_PROCESS);
517 e.setAttribute(GSXML.NAME_ATT, ACTIVATE_SERVICE);
518 this.short_service_info.appendChild(e);
519
520 e = this.doc.createElement(GSXML.SERVICE_ELEM);
521 e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_PROCESS);
522 e.setAttribute(GSXML.NAME_ATT, BUILD_AND_ACTIVATE_SERVICE);
523 this.short_service_info.appendChild(e);
524
525 e = this.doc.createElement(GSXML.SERVICE_ELEM);
526 e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_PROCESS);
527 e.setAttribute(GSXML.NAME_ATT, DELETE_SERVICE);
528 this.short_service_info.appendChild(e);
529
530 e = this.doc.createElement(GSXML.SERVICE_ELEM);
531 e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_PROCESS);
532 e.setAttribute(GSXML.NAME_ATT, RELOAD_SERVICE);
533 this.short_service_info.appendChild(e);
534
535 //e = this.doc.createElement(GSXML.SERVICE_ELEM);
536 //e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_PROCESS);
537 //e.setAttribute(GSXML.NAME_ATT, ADD_DOC_SERVICE);
538 //this.short_service_info.appendChild(e);
539
540 return true;
541 }
542
543 /** returns a response element */
544 protected Element runCommand(Element request, int type)
545 {
546 // the response to send back
547 String name = GSPath.getFirstLink(request.getAttribute(GSXML.TO_ATT));
548 Element response = this.doc.createElement(GSXML.RESPONSE_ELEM);
549 response.setAttribute(GSXML.FROM_ATT, name);
550 Element status = this.doc.createElement(GSXML.STATUS_ELEM);
551 response.appendChild(status);
552
553 String lang = request.getAttribute(GSXML.LANG_ATT);
554 String request_type = request.getAttribute(GSXML.TYPE_ATT);
555
556 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
557 HashMap<String, Serializable> params = GSXML.extractParams(param_list, false);
558
559 boolean get_status_only = false;
560 if (request_type.equals(GSXML.REQUEST_TYPE_STATUS))
561 {
562 get_status_only = true;
563 }
564
565 // just check for status messages if that's all that's required
566 if (get_status_only)
567 {
568 String id = (String) params.get(PROCESS_ID_PARAM);
569 status.setAttribute(GSXML.STATUS_PROCESS_ID_ATT, id);
570 GS2PerlListener listener = this.listeners.get(id);
571 if (listener == null)
572 {
573 Text t = this.doc.createTextNode(getTextString("general.process_id_error", lang));
574 status.appendChild(t);
575 status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.ERROR));
576 }
577 else
578 {
579 Text t = this.doc.createTextNode(listener.getUpdate());
580 status.appendChild(t);
581 status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(listener.getStatus()));
582 // check that we actually should be removing the listener here
583 if (listener.isFinished())
584 { // remove this listener - its job is done
585 this.listeners.remove(id); // not working
586 }
587 }
588 return response;
589
590 }
591
592 // do teh actual command
593 String coll_name = null;
594 if (type == GS2PerlConstructor.NEW)
595 {
596 String coll_title = (String) params.get(NEW_COL_TITLE_PARAM);
597 coll_name = createNewCollName(coll_title);
598 }
599 else
600 {
601 coll_name = (String) params.get(COL_PARAM);
602 }
603
604 // makes a paramList of the relevant params
605 Element other_params = extractOtherParams(params, type);
606
607 //create the constructor to do the work
608 GS2PerlConstructor constructor = new GS2PerlConstructor("perl_build");
609 if (!constructor.configure())
610 {
611 Text t = this.doc.createTextNode(getTextString("general.configure_constructor_error", lang));
612 status.appendChild(t);
613 status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.ERROR));
614 return response;
615 }
616
617 constructor.setSiteHome(this.site_home);
618 constructor.setCollectionName(coll_name);
619 constructor.setActionType(type);
620 constructor.setProcessParams(other_params);
621 if (type == GS2PerlConstructor.IMPORT)
622 {
623 constructor.setManifestFile(this.site_home + File.separator + "collect" + File.separator + params.get(COL_PARAM) + File.separator + "manifests" + File.separator + "tempManifest.xml");
624 }
625
626 GS2PerlListener listener = new GS2PerlListener();
627 constructor.addListener(listener);
628 constructor.start();
629
630 String id = newID();
631 this.listeners.put(id, listener);
632
633 status.setAttribute(GSXML.STATUS_PROCESS_ID_ATT, id);
634 status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.ACCEPTED));
635 Text t = this.doc.createTextNode(getTextString("general.process_start", lang));
636 status.appendChild(t);
637 return response;
638 }
639
640 //************************
641 // some helper functions
642 //************************
643
644 /** parse the collect directory and return a list of collection names */
645 protected String[] getCollectionList()
646 {
647
648 File collectDir = new File(GSFile.collectDir(this.site_home));
649 if (!collectDir.exists())
650 {
651 logger.error("couldn't find collect dir: " + collectDir.toString());
652 return null;
653 }
654 logger.info("GS2Construct: reading thru directory " + collectDir.getPath() + " to find collections.");
655 File[] contents = collectDir.listFiles();
656 int num_colls = 0;
657 for (int i = 0; i < contents.length; i++)
658 {
659 if (contents[i].isDirectory() && !contents[i].getName().startsWith("CVS"))
660 {
661 num_colls++;
662 }
663 }
664
665 String[] names = new String[num_colls];
666
667 for (int i = 0, j = 0; i < contents.length; i++)
668 {
669 if (contents[i].isDirectory())
670 {
671 String colName = contents[i].getName();
672 if (!colName.startsWith("CVS"))
673 {
674 names[j] = colName;
675 j++;
676 }
677
678 }
679 }
680
681 return names;
682
683 }
684
685 /** ids used for process id */
686 private int current_id = 0;
687
688 private String newID()
689 {
690 current_id++;
691 return Integer.toString(current_id);
692 }
693
694 /** creates a new short name from the collection title */
695 protected String createNewCollName(String coll_title)
696 {
697
698 String base_name = null;
699 // take the first 6 letters
700 if (coll_title.length() < 6)
701 {
702 base_name = coll_title;
703 }
704 else
705 {
706 base_name = coll_title.substring(0, 6);
707 }
708 File coll_dir = new File(GSFile.collectionBaseDir(this.site_home, base_name));
709 if (!coll_dir.exists())
710 { // this name is ok - not used yet
711 return base_name;
712 }
713
714 // now we have to make a new name until we get a good one
715 // try name1, name2 name3 etc
716 int i = 0;
717 while (coll_dir.exists())
718 {
719 i++;
720 coll_dir = new File(GSFile.collectionBaseDir(this.site_home, base_name + Integer.toString(i)));
721 }
722 return base_name + Integer.toString(i);
723
724 }
725
726 /**
727 * takes the params from the request (in the HashMap) and extracts any that
728 * need to be passed to the constructor and puts them into a paramList
729 * element
730 */
731 protected Element extractOtherParams(HashMap<String, Serializable> params, int type)
732 {
733
734 Element param_list = this.doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
735 if (type == GS2PerlConstructor.NEW)
736 {
737 Element param = this.doc.createElement(GSXML.PARAM_ELEM);
738 param.setAttribute(GSXML.NAME_ATT, "creator");
739 param.setAttribute(GSXML.VALUE_ATT, (String) params.get(CREATOR_PARAM));
740
741 param_list.appendChild(param);
742 param = this.doc.createElement(GSXML.PARAM_ELEM);
743 param.setAttribute(GSXML.NAME_ATT, "about");
744 param.setAttribute(GSXML.VALUE_ATT, (String) params.get(NEW_COL_ABOUT_PARAM));
745 param_list.appendChild(param);
746 param = this.doc.createElement(GSXML.PARAM_ELEM);
747 param.setAttribute(GSXML.NAME_ATT, "title");
748 param.setAttribute(GSXML.VALUE_ATT, (String) params.get(NEW_COL_TITLE_PARAM));
749 param_list.appendChild(param);
750 param = this.doc.createElement(GSXML.PARAM_ELEM);
751 param.setAttribute(GSXML.NAME_ATT, "buildtype");
752 param.setAttribute(GSXML.VALUE_ATT, (String) params.get(BUILDTYPE_PARAM));
753 param_list.appendChild(param);
754 return param_list;
755 }
756
757 // other ones dont have params yet
758 return null;
759 }
760
761 protected void waitUntilReady(Element request)
762 {
763 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
764 HashMap<String, Serializable> params = GSXML.extractParams(param_list, false);
765
766 String collection = (String)params.get(COL_PARAM);
767
768 if (checkCollectionIsNotBusy(collection))
769 {
770 return;
771 }
772
773 while (collectionOperationMap.get(collection) != null)
774 {
775 try
776 {
777 Thread.currentThread().sleep(1000);
778 }
779 catch (Exception ex)
780 {
781 ex.printStackTrace();
782 }
783 }
784 }
785
786 protected void signalReady(Element request)
787 {
788 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
789 HashMap<String, Serializable> params = GSXML.extractParams(param_list, false);
790
791 String collection = (String)params.get(COL_PARAM);
792
793 collectionOperationMap.remove(collection);
794 }
795
796 protected synchronized boolean checkCollectionIsNotBusy(String collection)
797 {
798 if (collectionOperationMap.get(collection) == null)
799 {
800 collectionOperationMap.put(collection, true);
801 return true;
802 }
803 return false;
804 }
805}
Note: See TracBrowser for help on using the repository browser.