function run($array) { $zipFile = $array[0]; if (count($array) !== 2) { throw new InvalidArgumentException("This must receive 2 parameters in the array exactly."); } $launcher = new \asm\core\JavaLauncher(); $pluginResults = ""; $response = null; $error = $launcher->launch(Filesystem::combinePaths(CheckerRunner::$xmlCheckRoot, "/files/plugins/XML XQuery/XQueryPlugin.jar"), array($zipFile, $array[1]), $responseString); if (!$error) { if (isset($responseString)) { try { $response = \asm\plugin\PluginResponse::fromXmlString($responseString); } catch (Exception $ex) { $response = \asm\plugin\PluginResponse::createError('Internal error. Plugin did not supply valid response XML and this error occured: ' . $ex->getMessage() . '. Plugin instead supplied this response string: ' . $responseString); } } } else { $response = \asm\plugin\PluginResponse::createError('Plugin cannot be launched (' . $error . ').'); } return $response; }
/** * Launches plugin and updates database with results. * @param string $pluginType one of 'php', 'java', or 'exe' * @param string $pluginFile plugin file path * @param string $inputFile input file path * @param boolean $isTest is this a plugin test or a submission? true if plugin test * @param int $rowId ID of row to be updated * @param array $arguments plugin arguments * @return bool true if no error occurred */ public static function launchPlugin($pluginType, $pluginFile, $inputFile, $isTest, $rowId, $arguments = array()) { try { $response = null; if (!is_file($pluginFile) || !is_file($inputFile)) { $error = "plugin file and/or input file don't exist"; } else { array_unshift($arguments, $inputFile); $cwd = getcwd(); chdir(dirname($pluginFile)); switch ($pluginType) { case 'php': $launcher = new PhpLauncher(); ob_start(); $error = $launcher->launch($pluginFile, $arguments, $response); ob_end_clean(); break; case 'java': $launcher = new JavaLauncher(); $error = $launcher->launch($pluginFile, $arguments, $responseString); break; case 'exe': $launcher = new ExeLauncher(); $error = $launcher->launch($pluginFile, $arguments, $responseString); break; default: $error = "unsupported plugin type '{$pluginType}'"; } chdir($cwd); } if (!$error) { if (isset($responseString)) { try { $response = PluginResponse::fromXmlString($responseString); } catch (Exception $ex) { $response = PluginResponse::createError('Internal error. Plugin did not supply valid response XML and this error occurred: ' . $ex->getMessage() . '. Plugin instead supplied this response string: ' . $responseString); } } } else { $response = PluginResponse::createError('Plugin cannot be launched (' . $error . ').'); } $outputFile = $response->getOutput(); if ($outputFile) { $outputFolder = Config::get('paths', 'output'); $newFile = $outputFolder . date('Y-m-d_H-i-s_') . StringUtils::randomString(10) . '.zip'; if (rename($outputFile, $newFile)) { $outputFile = $newFile; } else { $outputFile = 'tmp-file-rename-failed'; } } /** * @var $pluginTest \PluginTest * @var $submission \Submission * @var $previousSubmissions \Submission[] */ if ($isTest) { $pluginTest = Repositories::findEntity(Repositories::PluginTest, $rowId); $pluginTest->setStatus(\PluginTest::STATUS_COMPLETED); $pluginTest->setSuccess($response->getFulfillment()); $pluginTest->setInfo($response->getDetails()); $pluginTest->setOutput($outputFile); Repositories::persistAndFlush($pluginTest); } else { $submission = Repositories::findEntity(Repositories::Submission, $rowId); // There is a sort of a race condition in here. // It is, in theory, possible, that there will be two submissions with the "latest" status after all is done // This should not happen in practice, though, and even if it does, it will have negligible negative effects. $previousSubmissions = Repositories::makeDqlQuery("SELECT s FROM \\Submission s WHERE s.user = :sameUser AND s.assignment = :sameAssignment AND s.status != 'graded' AND s.status != 'deleted'")->setParameter('sameUser', $submission->getUser()->getId())->setParameter('sameAssignment', $submission->getAssignment()->getId())->getResult(); foreach ($previousSubmissions as $previousSubmission) { $previousSubmission->setStatus(\Submission::STATUS_NORMAL); Repositories::getEntityManager()->persist($previousSubmission); } $submission->setStatus(\Submission::STATUS_LATEST); $submission->setInfo($response->getDetails()); $submission->setSuccess($response->getFulfillment()); $submission->setOutputfile($outputFile); Repositories::getEntityManager()->persist($submission); Repositories::flushAll(); } return !$error; } catch (Exception $exception) { $errorInformation = "Internal error. Plugin launcher or plugin failed with an internal error. Exception information: " . $exception->getMessage() . " in " . $exception->getFile() . " at " . $exception->getLine(); if ($isTest) { $pluginTest = Repositories::findEntity(Repositories::PluginTest, $rowId); $pluginTest->setStatus(\PluginTest::STATUS_COMPLETED); $pluginTest->setSuccess(0); $pluginTest->setInfo($errorInformation); Repositories::persistAndFlush($pluginTest); } else { $submission = Repositories::findEntity(Repositories::Submission, $rowId); $submission->setStatus(\Submission::STATUS_NORMAL); $submission->setInfo($errorInformation); Repositories::persistAndFlush($submission); } return false; } }