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

Last change on this file since 25727 was 25727, checked in by kjdon, 12 years ago

getting rid of my email address

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