ingo@1970: package de.intevation.flys.wsplgen;
ingo@1970: 
christian@4573: import de.intevation.artifacts.CallContext;
christian@4573: import de.intevation.flys.artifacts.model.map.WSPLGENJob;
christian@4573: 
ingo@3302: import java.io.File;
ingo@1970: import java.io.IOException;
ingo@1970: import java.util.concurrent.Callable;
ingo@1970: 
ingo@1970: import org.apache.log4j.Logger;
ingo@1970: 
ingo@1970: 
ingo@1970: /**
ingo@1970:  * A Callable that is used to start and observe an external Process for WSPLGEN.
ingo@1970:  *
ingo@1970:  * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
ingo@1970:  */
ingo@1970: public class WSPLGENCallable implements Callable {
ingo@1970: 
ingo@1970:     public static final String WSPLGEN_PARAMETER_FILE =
ingo@1970:         "wsplgen.par";
ingo@1970: 
ingo@1970:     public static final String WSPLGEN_BIN_PATH =
ingo@1970:         System.getProperty("wsplgen.bin.path");
ingo@1970: 
ingo@1970: 
ingo@1970:     private Logger logger = Logger.getLogger(WSPLGENCallable.class);
ingo@1970: 
ingo@1970:     private Process process;
ingo@1970: 
ingo@1970:     protected Scheduler scheduler;
ingo@1970: 
ingo@1970:     protected WSPLGENJob job;
ingo@1970: 
ingo@1970:     protected JobObserver     logObserver;
ingo@1970:     protected ProblemObserver errorObserver;
ingo@1970: 
ingo@1970: 
ingo@1970:     public WSPLGENCallable(Scheduler scheduler, WSPLGENJob job) {
ingo@1970:         this.scheduler     = scheduler;
ingo@1970:         this.job           = job;
ingo@1970:         this.logObserver   = new JobObserver(job);
ingo@1970:         this.errorObserver = new ProblemObserver(job);
ingo@1970:     }
ingo@1970: 
ingo@1970: 
ingo@1970:     @Override
ingo@1970:     public WSPLGENJob call() {
ingo@1970:         File dir       = job.getWorkingDir();
ingo@1970:         File parameter = new File(dir, WSPLGEN_PARAMETER_FILE);
ingo@1970: 
ingo@1970:         String[] args = new String[] {
ingo@1970:             WSPLGEN_BIN_PATH,
ingo@1970:             "-PAR=\"" + parameter.getAbsolutePath() + "\""
ingo@1970:         };
ingo@1970: 
ingo@1970:         execute(args, dir);
ingo@1970: 
ingo@1970:         return job;
ingo@1970:     }
ingo@1970: 
ingo@1970: 
ingo@1970:     protected void execute(String[] args, File dir) {
ingo@1970:         logger.info("Start JobExecutor for artifact: " + dir.getName());
ingo@1970: 
ingo@1970:         try {
ingo@1970:             synchronized (this) {
ingo@1970:                 process = Runtime.getRuntime().exec(args, null, dir);
ingo@1970: 
ingo@1970:                 logObserver.setInputStream(process.getInputStream());
ingo@1970:                 errorObserver.setInputStream(process.getErrorStream());
ingo@1970: 
ingo@1970:                 logObserver.start();
ingo@1970:                 errorObserver.start();
ingo@1970: 
ingo@1970:                 try {
ingo@1970:                     process.waitFor();
ingo@1970:                 }
ingo@1970:                 catch (InterruptedException ie) {
ingo@1970:                     logger.warn("WSPLGEN job interrupted: " + ie.getMessage());
ingo@1970:                 }
ingo@1970: 
ingo@1970:                 try {
ingo@1970:                     logObserver.join();
ingo@1970:                     errorObserver.join();
ingo@1970:                 }
ingo@1970:                 catch (InterruptedException iee) { /* do nothing */ }
ingo@1970: 
ingo@1970:                 logger.info("WSPLGEN exit value: " + process.exitValue());
ingo@1970:                 logger.info(
ingo@1970:                     "WSPLGEN throw " +
ingo@1970:                     errorObserver.numErrors() + " errors.");
ingo@1970:                 logger.info(
ingo@1970:                     "WSPLGEN throw " +
ingo@1970:                     errorObserver.numWarnings() + " warnings.");
ingo@1970: 
ingo@1970:                 if (process.exitValue() < 2 && errorObserver.numErrors() == 0) {
ingo@1970:                     FacetCreator fc = job.getFacetCreator();
ingo@1970:                     fc.createWSPLGENFacet();
ingo@1970:                     fc.finish();
ingo@1970:                 }
ingo@1970: 
ingo@1970:                 job.getCallContext().afterBackground(CallContext.STORE);
ingo@1970: 
ingo@1970:                 scheduler.removeJob(getJob().getArtifact().identifier());
ingo@1970: 
ingo@1970:                 return;
ingo@1970:             }
ingo@1970:         }
ingo@1970:         catch (SecurityException se) {
ingo@1970:             logger.error(se);
ingo@1970:         }
ingo@1970:         catch (IOException ioe) {
ingo@1970:             logger.error(ioe);
ingo@1970:         }
ingo@1970:         catch (NullPointerException npe) {
ingo@1970:             logger.error(npe, npe);
ingo@1970:         }
ingo@1970:         catch (IndexOutOfBoundsException ioobe) {
ingo@1970:             logger.error(ioobe, ioobe);
ingo@1970:         }
ingo@1970:     }
ingo@1970: 
ingo@1970: 
ingo@1970:     public void cancelWSPLGEN() {
ingo@1970:         if (process != null) {
ingo@1970:             logger.debug("Cancel running WSPLGEN process.");
ingo@1970:             process.destroy();
ingo@1970:         }
ingo@1970:     }
ingo@1970: 
ingo@1970: 
ingo@1970:     public WSPLGENJob getJob() {
ingo@1970:         return job;
ingo@1970:     }
ingo@1970: }
ingo@1970: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :