1 16 package org.outerj.daisy.doctaskrunner.serverimpl; 17 18 import org.outerj.daisy.doctaskrunner.TaskSpecification; 19 import org.outerj.daisy.doctaskrunner.DocumentSelection; 20 import org.outerj.daisy.doctaskrunner.DocumentExecutionState; 21 import org.outerj.daisy.doctaskrunner.TaskState; 22 import org.outerj.daisy.repository.VariantKey; 23 import org.outerj.daisy.repository.Repository; 24 import org.mozilla.javascript.Context; 25 import org.mozilla.javascript.Scriptable; 26 import org.mozilla.javascript.Script; 27 import org.mozilla.javascript.ScriptableObject; 28 29 import java.io.StringWriter ; 30 import java.io.Writer ; 31 import java.io.PrintWriter ; 32 import java.util.Arrays ; 33 34 import EDU.oswego.cs.dl.util.concurrent.Sync; 35 36 public class TaskRunner implements Runnable { 37 private DocumentSelection documentSelection; 38 private TaskSpecification taskSpecification; 39 private TaskContext taskContext; 40 private Repository repository; 41 42 public TaskRunner(DocumentSelection documentSelection, TaskSpecification taskSpecification, 43 TaskContext taskContext, Repository repository) { 44 this.documentSelection = documentSelection; 45 this.taskSpecification = taskSpecification; 46 this.taskContext = taskContext; 47 this.repository = repository; 48 } 49 50 public void run() { 51 try { 52 boolean hasErrors = false; 53 Context cx = Context.enter(); 54 try { 55 if (!"javascript".equalsIgnoreCase(taskSpecification.getScriptLanguage())) 56 throw new Exception ("Unsupported script language: \"" + taskSpecification.getScriptLanguage() + "\"."); 57 58 taskContext.setTaskState(TaskState.RUNNING, "Collecting documents to process", null); 59 VariantKey[] variantKeys = documentSelection.getKeys(repository); 60 Arrays.sort(variantKeys); 61 taskContext.initDocumentResults(variantKeys); 62 63 cx.setOptimizationLevel(-1); 64 taskContext.setProgress("Compiling script"); 65 Script script; 66 try { 67 script = cx.compileString(taskSpecification.getScript(), "", 1, null); 68 } catch (Exception e) { 69 String details = createExceptionDescription(e); 70 taskContext.setTaskState(TaskState.INTERRUPTED_BY_ERROR, "", details); 71 return; 72 } 73 74 Sync executionLock = taskContext.getExecutionLock(); 75 int currentPercentage = 0; 76 taskContext.setProgress(formatProgress(0)); 77 for (int i = 0; i < variantKeys.length; i++) { 78 if (taskContext.isInterrupted()) { 79 taskContext.setTaskState(TaskState.INTERRUPTED_BY_USER, formatProgress(currentPercentage), null); 80 return; 81 } 82 83 Scriptable scope = cx.initStandardObjects(); 85 86 Object wrappedRepository = Context.javaToJS(repository, scope); 88 ScriptableObject.putProperty(scope, "repository", wrappedRepository); 89 Object wrappedKey = Context.javaToJS(variantKeys[i], scope); 90 ScriptableObject.putProperty(scope, "variantKey", wrappedKey); 91 92 Exception exception = null; 94 executionLock.acquire(); 95 try { 96 script.exec(cx, scope); 97 } catch (Exception e) { 98 exception = e; 99 } finally { 100 executionLock.release(); 101 } 102 103 if (exception != null) { 105 String details = createExceptionDescription(exception); 106 taskContext.setDocumentResult(variantKeys[i], DocumentExecutionState.ERROR, details); 107 } else { 108 taskContext.setDocumentResult(variantKeys[i], DocumentExecutionState.DONE, null); 109 } 110 111 if (exception != null && taskSpecification.stopOnFirstError()) { 112 taskContext.setTaskState(TaskState.INTERRUPTED_BY_ERROR, formatProgress(currentPercentage), ""); 113 return; 114 } else if (exception != null) { 115 hasErrors = true; 116 } 117 118 int percentage = (int)(((double)(i+1) / (double)variantKeys.length) * 100); 120 if (percentage != currentPercentage) { 121 currentPercentage = percentage; 122 taskContext.setProgress(formatProgress(currentPercentage)); 123 } 124 } 125 } catch (Throwable e) { 126 String details = createExceptionDescription(e); 127 taskContext.setTaskState(TaskState.INTERRUPTED_BY_ERROR, "", details); 128 return; 129 } finally { 130 Context.exit(); 131 } 132 133 taskContext.setTaskState(hasErrors ? TaskState.FINISHED_WITH_ERRORS : TaskState.FINISHED, "", null); 134 } finally { 135 taskContext.cleanup(); 136 } 137 } 138 139 private String formatProgress(int percentage) { 140 return percentage + "%"; 141 } 142 143 private String createExceptionDescription(Throwable throwable) { 144 Writer writer = new StringWriter (); 145 throwable.printStackTrace(new PrintWriter (writer)); 146 return writer.toString(); 147 } 148 } 149 | Popular Tags |