summaryrefslogtreecommitdiffstats
path: root/idrop-web/grails-app
diff options
context:
space:
mode:
authorBartosz Bosak <bbosak@man.poznan.pl>2013-11-18 13:26:33 (GMT)
committer Bartosz Bosak <bbosak@man.poznan.pl>2013-11-18 13:26:33 (GMT)
commita6dabdba1fd650b849ee6ead4ffc000662ed7a14 (patch)
treeb2482c909cf9e508c9ebe296cfdd5b6032731c14 /idrop-web/grails-app
parent47428502f9feaf1b3a898f50061e7e9bc92c8c1f (diff)
parent9300b5f96fdc3989d232051a68e765d376200cf3 (diff)
downloadQCG-Data-a6dabdba1fd650b849ee6ead4ffc000662ed7a14.zip
QCG-Data-a6dabdba1fd650b849ee6ead4ffc000662ed7a14.tar.gz
QCG-Data-a6dabdba1fd650b849ee6ead4ffc000662ed7a14.tar.bz2
Merge of Mike changesidrop-black
Diffstat (limited to 'idrop-web/grails-app')
-rwxr-xr-xidrop-web/grails-app/conf/BuildConfig.groovy14
-rwxr-xr-xidrop-web/grails-app/conf/Config.groovy2
-rwxr-xr-xidrop-web/grails-app/conf/spring/resources.groovy6
-rwxr-xr-xidrop-web/grails-app/controllers/org/irods/mydrop/controller/BrowseController.groovy19
-rwxr-xr-xidrop-web/grails-app/controllers/org/irods/mydrop/controller/FileController.groovy2
-rwxr-xr-xidrop-web/grails-app/controllers/org/irods/mydrop/controller/HomeController.groovy4
-rw-r--r--idrop-web/grails-app/controllers/org/irods/mydrop/controller/RuleController.groovy437
-rwxr-xr-xidrop-web/grails-app/i18n/messages.properties21
-rw-r--r--idrop-web/grails-app/services/org/irods/mydrop/service/RuleProcessingService.groovy85
-rw-r--r--idrop-web/grails-app/views/browse/dataObjectInfo.gsp17
-rwxr-xr-xidrop-web/grails-app/views/browse/index.gsp2
-rwxr-xr-xidrop-web/grails-app/views/common/_topbar.gsp1
-rwxr-xr-xidrop-web/grails-app/views/home/link.gsp1
-rw-r--r--idrop-web/grails-app/views/rule/_ruleDelayExecQueueDetails.gsp61
-rw-r--r--idrop-web/grails-app/views/rule/_ruleDetails.gsp95
-rw-r--r--idrop-web/grails-app/views/rule/addParameterDialog.gsp154
-rw-r--r--idrop-web/grails-app/views/rule/delayExecQueue.gsp39
-rw-r--r--idrop-web/grails-app/views/rule/index.gsp229
-rw-r--r--idrop-web/grails-app/views/rule/ruleErrorResult.gsp23
-rw-r--r--idrop-web/grails-app/views/rule/ruleResult.gsp41
20 files changed, 1237 insertions, 16 deletions
diff --git a/idrop-web/grails-app/conf/BuildConfig.groovy b/idrop-web/grails-app/conf/BuildConfig.groovy
index bfa180a..4faa39c 100755
--- a/idrop-web/grails-app/conf/BuildConfig.groovy
+++ b/idrop-web/grails-app/conf/BuildConfig.groovy
@@ -28,11 +28,15 @@ grails.project.dependency.resolution = {
test 'org.mockito:mockito-all:1.8.1'
compile 'commons-io:commons-io:2.1'
provided 'junit:junit:4.8.1'
- compile ('org.irods.jargon:jargon-core:3.3.1-SNAPSHOT') { excludes ([group:'org.jglobus'])}
- compile ('org.irods.jargon:jargon-data-utils:3.3.1-SNAPSHOT') { excludes ([group:'org.jglobus'])}
- compile ('org.irods.jargon:jargon-ticket:3.3.1-SNAPSHOT') { excludes ([group:'org.jglobus'])}
- compile ('org.irods.jargon:jargon-user-profile:3.3.1-SNAPSHOT') { excludes ([group:'org.jglobus'])}
- compile ('org.irods.jargon:jargon-user-tagging:3.3.1-SNAPSHOT') { excludes ([group:'org.jglobus'])}
+ compile ('org.irods.jargon:jargon-core:3.3.3-SNAPSHOT') { excludes ([group:'org.jglobus'])}
+ compile ('org.irods.jargon:jargon-data-utils:3.3.3-SNAPSHOT') { excludes ([group:'org.jglobus'])}
+ compile ('org.irods.jargon:jargon-ticket:3.3.3-SNAPSHOT') { excludes ([group:'org.jglobus'])}
+ compile ('org.irods.jargon:jargon-user-profile:3.3.3-SNAPSHOT') { excludes ([group:'org.jglobus'])}
+ compile ('org.irods.jargon:jargon-user-tagging:3.3.3-SNAPSHOT') { excludes ([group:'org.jglobus'])}
+ compile ('org.irods.jargon:jargon-workflow:3.3.3-SNAPSHOT') { excludes ([group:'org.jglobus'])}
+ compile ('org.irods.jargon:jargon-ruleservice:3.3.3-SNAPSHOT') { excludes ([group:'org.jglobus'])}
+
+
provided 'javax.servlet:servlet-api:2.5'
compile 'org.jsoup:jsoup:0.2.2'
diff --git a/idrop-web/grails-app/conf/Config.groovy b/idrop-web/grails-app/conf/Config.groovy
index 9b743cc..50d0426 100755
--- a/idrop-web/grails-app/conf/Config.groovy
+++ b/idrop-web/grails-app/conf/Config.groovy
@@ -48,7 +48,7 @@ environments {
idrop.config.idrop.lite.use.applet.dir=false
*/
-idrop.config.idrop.lite.applet.jar="idrop-lite-2.0.1-SNAPSHOT-jar-with-dependencies.jar"
+idrop.config.idrop.lite.applet.jar="idrop-lite-b964-SNAPSHOT-jar-with-dependencies.jar"
idrop.config.idrop.lite.codebase="http://iren-web.renci.org/idrop-snapshot"
idrop.config.idrop.lite.use.applet.dir=false
diff --git a/idrop-web/grails-app/conf/spring/resources.groovy b/idrop-web/grails-app/conf/spring/resources.groovy
index 0e15cc8..d7f25e6 100755
--- a/idrop-web/grails-app/conf/spring/resources.groovy
+++ b/idrop-web/grails-app/conf/spring/resources.groovy
@@ -7,6 +7,8 @@ beans = {
sharingService(org.irods.mydrop.service.SharingService) { irodsAccessObjectFactory = ref("irodsAccessObjectFactory") }
+ ruleProcessingService(org.irods.mydrop.service.RuleProcessingService) { irodsAccessObjectFactory = ref("irodsAccessObjectFactory") }
+
browseController(org.irods.mydrop.controller.BrowseController) {
irodsAccessObjectFactory = ref("irodsAccessObjectFactory")
@@ -48,6 +50,10 @@ beans = {
homeController(org.irods.mydrop.controller.HomeController) {
irodsAccessObjectFactory = ref("irodsAccessObjectFactory")
}
+
+ ruleController(org.irods.mydrop.controller.RuleController) {
+ irodsAccessObjectFactory = ref("irodsAccessObjectFactory")
+ }
shoppingCartController(org.irods.mydrop.controller.ShoppingCartController) {
diff --git a/idrop-web/grails-app/controllers/org/irods/mydrop/controller/BrowseController.groovy b/idrop-web/grails-app/controllers/org/irods/mydrop/controller/BrowseController.groovy
index 1fee905..235a682 100755
--- a/idrop-web/grails-app/controllers/org/irods/mydrop/controller/BrowseController.groovy
+++ b/idrop-web/grails-app/controllers/org/irods/mydrop/controller/BrowseController.groovy
@@ -14,12 +14,14 @@ import org.irods.jargon.datautils.image.MediaHandlingUtils
import org.irods.jargon.datautils.pagination.PagingActions
import org.irods.jargon.datautils.pagination.PagingAnalyser
import org.irods.jargon.datautils.sharing.*
+import org.irods.jargon.ruleservice.composition.Rule
import org.irods.jargon.ticket.TicketDistributionContext
import org.irods.jargon.usertagging.domain.IRODSStarredFileOrCollection
import org.irods.jargon.usertagging.tags.FreeTaggingService
import org.irods.jargon.usertagging.tags.IRODSTaggingService
import org.irods.jargon.usertagging.tags.TaggingServiceFactory
import org.irods.mydrop.config.ViewState
+import org.irods.mydrop.service.RuleProcessingService
import org.irods.mydrop.service.StarringService
import org.irods.mydrop.service.ViewStateService
@@ -34,6 +36,7 @@ class BrowseController {
TaggingServiceFactory taggingServiceFactory
StarringService starringService
ViewStateService viewStateService
+ RuleProcessingService ruleProcessingService
IRODSAccount irodsAccount
def grailsApplication
@@ -769,9 +772,21 @@ class BrowseController {
if (commentTag) {
comment = commentTag.getTagData()
}
-
+
+
+ Rule rule = null
+ if (ruleProcessingService.isRule(absPath)) {
+ log.info("is a .r file, see if a rule")
+ try {
+
+ rule = ruleProcessingService.loadRuleFromIrodsFile(irodsAccount, absPath)
+ } catch (JargonException je) {
+ log.error("exception attempting to load rule, do not show tab")
+ }
+ }
+
mav.view = "dataObjectInfo"
- mav.model = [dataObject:retObj,tags:freeTags,comment:comment,getThumbnail:getThumbnail,renderMedia:renderMedia,isDataObject:isDataObject,irodsStarredFileOrCollection:irodsStarredFileOrCollection,showLite:collectionAndDataObjectListAndSearchAO.getIRODSServerProperties().isTheIrodsServerAtLeastAtTheGivenReleaseVersion("rods3.0")]
+ mav.model = [dataObject:retObj,tags:freeTags,comment:comment,getThumbnail:getThumbnail,renderMedia:renderMedia,isDataObject:isDataObject,irodsStarredFileOrCollection:irodsStarredFileOrCollection,showLite:collectionAndDataObjectListAndSearchAO.getIRODSServerProperties().isTheIrodsServerAtLeastAtTheGivenReleaseVersion("rods3.0"), rule:rule]
return mav
} else {
log.info("getting free tags for collection")
diff --git a/idrop-web/grails-app/controllers/org/irods/mydrop/controller/FileController.groovy b/idrop-web/grails-app/controllers/org/irods/mydrop/controller/FileController.groovy
index 971b89e..714c505 100755
--- a/idrop-web/grails-app/controllers/org/irods/mydrop/controller/FileController.groovy
+++ b/idrop-web/grails-app/controllers/org/irods/mydrop/controller/FileController.groovy
@@ -236,7 +236,7 @@ class FileController {
IRODSFile targetFile = irodsFileFactory.instanceIRODSFile(absPath)
try {
- targetFile.delete()
+ targetFile.deleteWithForceOption()
log.info("file deleted")
render(view:"deleteResult", model:[absPath:targetFile.parent])
} catch (CatNoAccessException e) {
diff --git a/idrop-web/grails-app/controllers/org/irods/mydrop/controller/HomeController.groovy b/idrop-web/grails-app/controllers/org/irods/mydrop/controller/HomeController.groovy
index e5f0337..171f05c 100755
--- a/idrop-web/grails-app/controllers/org/irods/mydrop/controller/HomeController.groovy
+++ b/idrop-web/grails-app/controllers/org/irods/mydrop/controller/HomeController.groovy
@@ -59,6 +59,10 @@ class HomeController {
// TODO: refactor, add check to see if on same grid, in which case the account should not be changed
String mungedIRODSURI = irodsURIString.replaceAll(" ", "&&space&&")
URI irodsURI = new URI(mungedIRODSURI)
+
+ log.info("irodsURI ${irodsURI}")
+
+
String filePath = irodsURI.getPath()
log.info("irodsFilePath:${filePath}")
filePath = filePath.replaceAll("&&space&&", " ")
diff --git a/idrop-web/grails-app/controllers/org/irods/mydrop/controller/RuleController.groovy b/idrop-web/grails-app/controllers/org/irods/mydrop/controller/RuleController.groovy
new file mode 100644
index 0000000..49c502c
--- /dev/null
+++ b/idrop-web/grails-app/controllers/org/irods/mydrop/controller/RuleController.groovy
@@ -0,0 +1,437 @@
+package org.irods.mydrop.controller
+
+import org.irods.jargon.core.connection.IRODSAccount
+import org.irods.jargon.core.exception.JargonException
+import org.irods.jargon.core.pub.IRODSAccessObjectFactory
+import org.irods.jargon.core.pub.RuleProcessingAO
+import org.irods.jargon.core.pub.domain.DelayedRuleExecution
+import org.irods.jargon.core.rule.IRODSRuleExecResult
+import org.irods.jargon.ruleservice.composition.Rule
+import org.irods.jargon.ruleservice.formatting.HtmlLogTableFormatter
+import org.irods.mydrop.service.RuleProcessingService
+
+
+class RuleController {
+
+ IRODSAccessObjectFactory irodsAccessObjectFactory
+ IRODSAccount irodsAccount
+ RuleProcessingService ruleProcessingService
+ def grailsApplication
+
+ /**
+ * Interceptor grabs IRODSAccount from the SecurityContextHolder
+ */
+ def beforeInterceptor = [action:this.&auth]
+
+ def auth() {
+ if(!session["SPRING_SECURITY_CONTEXT"]) {
+ redirect(controller:"login", action:"login")
+ return false
+ }
+ irodsAccount = session["SPRING_SECURITY_CONTEXT"]
+ }
+
+ def afterInterceptor = {
+ log.debug("closing the session")
+ irodsAccessObjectFactory.closeSession()
+ }
+
+ /**
+ * List the contents of the delayed execution queue
+ * @return
+ */
+ def delayExecQueue() {
+ log.info("delayExecQueue()")
+ List<DelayedRuleExecution> rules = ruleProcessingService.listDelayedRuleExecutions(irodsAccount, 0)
+ render(view:"delayExecQueue", model:[rules:rules])
+ }
+
+
+ def deleteDelayExecQueue = {
+ log.info("deleteDelayExecQueue")
+
+ log.info("params: ${params}")
+
+ def rulesToDelete = params['selectDetail']
+
+ // if nothing selected, just jump out and return a message
+ if (!rulesToDelete) {
+ log.info("no rules to delete")
+ List<DelayedRuleExecution> rules = ruleProcessingService.listDelayedRuleExecutions(irodsAccount, 0)
+ render(view:"_ruleDelayExecQueueDetails", model:[rules:rules])
+ }
+
+ log.info("rulesToDelete: ${rulesToDelete}")
+
+
+ RuleProcessingAO ruleAO = irodsAccessObjectFactory.getRuleProcessingAO(irodsAccount)
+
+ if (!rulesToDelete) {
+ log.info("nothing to delete")
+ } else if (rulesToDelete instanceof Object[]) {
+ log.debug "is array"
+ rulesToDelete.each{
+ log.info "ruleToDelete: ${it}"
+ def idVal = parseRuleId(it)
+ if (idVal != -1) {
+ log.info("deleting id:${idVal}")
+ ruleAO.purgeRuleFromDelayedExecQueue(idVal)
+ }
+ }
+ } else {
+ log.debug "not array"
+ log.info "deleting: ${rulesToDelete}..."
+ def idVal = parseRuleId(rulesToDelete)
+ if (idVal != -1) {
+ log.info("deleting id:${idVal}")
+ ruleAO.purgeRuleFromDelayedExecQueue(idVal)
+ }
+
+ }
+
+ List<DelayedRuleExecution> rules = ruleProcessingService.listDelayedRuleExecutions(irodsAccount, 0)
+
+ render(view:"_ruleDelayExecQueueDetails", model:[rules:rules])
+
+ }
+
+ private int parseRuleId(String ruleId) {
+ if (!ruleId) {
+ throw new IllegalArgumentException("null ruleId")
+ }
+
+ int idx = ruleId.indexOf("select-");
+ if (idx == -1) {
+ return -1
+ }
+
+
+ return Integer.valueOf(ruleId.substring(7))
+
+ }
+
+
+ def updateRule() {
+ log.info("update rule")
+ log.info("params:${params}")
+
+ def absPath = params['ruleAbsPath']
+ if (absPath == null) {
+ log.error "no ruleAbsPath in request "
+ def message = message(code:"error.no.path.provided")
+ response.sendError(500,message)
+ }
+
+ def ruleBody = params['ruleBody']
+ if (!ruleBody) {
+ log.error "no ruleBody in request "
+ def message = message(code:"error.no.rule.body")
+ response.sendError(500,message)
+ }
+
+ List<String> inputParams = new ArrayList<String>()
+ List<String> inputParamValues = new ArrayList<String>()
+ List<String> outputParams = new ArrayList<String>()
+
+ def parmKey = params['inputParamName']
+ def parmValue = params['inputParamValue']
+
+ if (parmKey) {
+
+ if (parmKey instanceof Object[]) {
+ inputParams = parmKey
+ } else {
+ inputParams.add(parmKey)
+ }
+
+ if (!parmValue) {
+ log.error "no param values for param keys in request "
+ def message = message(code:"error.invalid.request")
+ response.sendError(500,message)
+ }
+
+ if (parmValue instanceof Object[]) {
+ inputParamValues = parmValue
+ } else {
+ inputParamValues.add(parmValue)
+ }
+ }
+
+ parmKey = params['outputParamName']
+
+ if (parmKey) {
+
+ if (parmKey instanceof Object[]) {
+ outputParams = parmKey
+ } else {
+ outputParams.add(parmKey)
+ }
+ }
+
+
+ List<String> concatParams = new ArrayList<String>()
+ for (int i = 0; i < inputParams.size(); i++) {
+ concatParams.add(inputParams[i] + "=" + inputParamValues[i])
+ }
+
+ Rule rule = ruleProcessingService.storeRule(irodsAccount, absPath, ruleBody, concatParams, outputParams)
+ log.info("rule stored:${rule}")
+ render(view:"_ruleDetails", model:[absPath:absPath, rule:rule])
+ }
+
+ def addRuleInputParameterDialog() {
+ log.info("addRuleInputParameterDialog()")
+ log.info("params:${params}")
+
+ def absPath = params['ruleAbsPath']
+ if (!absPath) {
+ log.error "no ruleAbsPath in request "
+ def message = message(code:"error.no.path.provided")
+ response.sendError(500,message)
+ }
+
+ render(view:"addParameterDialog", model:[absPath:absPath, isInputParameter:true])
+ }
+
+ def addRuleOutputParameterDialog() {
+ log.info("addRuleOutputParameterDialog()")
+ log.info("params:${params}")
+
+ def absPath = params['ruleAbsPath']
+ if (!absPath) {
+ log.error "no ruleAbsPath in request "
+ def message = message(code:"error.no.path.provided")
+ response.sendError(500,message)
+ }
+
+ render(view:"addParameterDialog", model:[absPath:absPath, isInputParameter:false])
+ }
+
+ def deleteRuleInputParameter() {
+ log.info("deleteRuleInputParameter()")
+ log.info("params:${params}")
+
+ def absPath = params['ruleAbsPath']
+ if (!absPath) {
+ log.error "no ruleAbsPath in request "
+ def message = message(code:"error.no.path.provided")
+ response.sendError(500,message)
+ }
+
+
+ def parmKey = params['inputParamName']
+ if (!parmKey) {
+ log.error "no parmkey in request "
+ def message = message(code:"error.invalid.request")
+ response.sendError(500,message)
+ }
+
+ Rule rule = ruleProcessingService.deleteInputParam(irodsAccount, absPath, parmKey)
+ log.info("rule stored:${rule}")
+ render(view:"_ruleDetails", model:[absPath:absPath, rule:rule])
+ }
+
+ def deleteRuleOutputParameter() {
+ log.info("deleteRuleOutputParameter()")
+ log.info("params:${params}")
+
+ def absPath = params['ruleAbsPath']
+ if (!absPath) {
+ log.error "no ruleAbsPath in request "
+ def message = message(code:"error.no.path.provided")
+ response.sendError(500,message)
+ }
+
+
+ def parmKey = params['outputParamName']
+ if (!parmKey) {
+ log.error "no parmkey in request "
+ def message = message(code:"error.invalid.request")
+ response.sendError(500,message)
+ }
+
+ Rule rule = ruleProcessingService.deleteOutputParam(irodsAccount, absPath, parmKey)
+ log.info("rule stored:${rule}")
+ render(view:"_ruleDetails", model:[absPath:absPath, rule:rule])
+ }
+
+ def reloadRule() {
+
+ log.info("reloadRule()")
+
+ def absPath = params['absPath']
+ if (absPath == null) {
+ log.error "no absPath in request "
+ def message = message(code:"error.no.path.provided")
+ response.sendError(500,message)
+ }
+
+ try {
+ def rule = ruleProcessingService.loadRuleFromIrodsFile(irodsAccount, absPath)
+ log.info("found rule:${rule}")
+ render(view:"_ruleDetails", model:[absPath:absPath, rule:rule])
+ } catch (JargonException je) {
+ log.error("unable to load rule", je)
+ def message = message(code:"error.unable.to.load.rule")
+ response.sendError(500,message)
+ }
+ }
+
+
+
+ def index() {
+
+ log.info("index()")
+
+ def absPath = params['absPath']
+ if (absPath == null) {
+ log.error "no absPath in request "
+ def message = message(code:"error.no.path.provided")
+ response.sendError(500,message)
+ }
+
+ try {
+ def rule = ruleProcessingService.loadRuleFromIrodsFile(irodsAccount, absPath)
+ log.info("found rule:${rule}")
+ render(view:"index", model:[absPath:absPath, rule:rule])
+ } catch (JargonException je) {
+ log.error("unable to load rule", je)
+ def message = message(code:"error.unable.to.load.rule")
+ response.sendError(500,message)
+ }
+ }
+
+
+ def runRule() {
+ log.info("runRule()")
+ log.info("params:${params}")
+
+ def absPath = params['ruleAbsPath']
+ if (absPath == null) {
+ log.error "no ruleAbsPath in request "
+ def message = message(code:"error.no.path.provided")
+ response.sendError(500,message)
+ }
+
+ def ruleBody = params['ruleBody']
+ if (!ruleBody) {
+ log.error "no ruleBody in request "
+ def message = message(code:"error.no.rule.body")
+ response.sendError(500,message)
+ }
+
+ List<String> inputParams = new ArrayList<String>()
+ List<String> inputParamValues = new ArrayList<String>()
+ List<String> outputParams = new ArrayList<String>()
+
+ def parmKey = params['inputParamName']
+ def parmValue = params['inputParamValue']
+
+ if (parmKey) {
+
+ if (parmKey instanceof Object[]) {
+ inputParams = parmKey
+ } else {
+ inputParams.add(parmKey)
+ }
+
+ if (!parmValue) {
+ log.error "no param values for param keys in request "
+ def message = message(code:"error.invalid.request")
+ response.sendError(500,message)
+ }
+
+ if (parmValue instanceof Object[]) {
+ inputParamValues = parmValue
+ } else {
+ inputParamValues.add(parmValue)
+ }
+ }
+
+ parmKey = params['outputParamName']
+
+ if (parmKey) {
+
+ if (parmKey instanceof Object[]) {
+ outputParams = parmKey
+ } else {
+ outputParams.add(parmKey)
+ }
+ }
+
+ List<String> concatParams = new ArrayList<String>()
+ for (int i = 0; i < inputParams.size(); i++) {
+ concatParams.add(inputParams[i] + "=" + inputParamValues[i])
+ }
+
+ try {
+ IRODSRuleExecResult ruleResult = ruleProcessingService.executeRule(irodsAccount, ruleBody, concatParams, outputParams)
+ log.info("rule result:${ruleResult}")
+ def execOut = HtmlLogTableFormatter.formatAsBootstrap2Table(ruleResult.ruleExecOut, "Std Out")
+ def errorOut = HtmlLogTableFormatter.formatAsBootstrap2Table(ruleResult.ruleExecErr, "Error Out")
+ render(view:"ruleResult", model:[ruleResult:ruleResult, execOut:execOut, errorOut:errorOut])
+ } catch (JargonException je) {
+ def message = HtmlLogTableFormatter.formatAsBootstrap2Table(je.message, "Error")
+ def stackTrace = HtmlLogTableFormatter.formatStackTraceAsBootstrap2Table(je)
+ render(view:"ruleErrorResult", model:[message:message,stackTrace:stackTrace])
+ }
+ }
+
+
+ def submitAddOutputParameterDialog() {
+ log.info("submitAddOutputParameterDialog")
+ log.info("params:${params}")
+
+ def absPath = params['ruleAbsPath']
+ if (absPath == null) {
+ log.error "no ruleAbsPath in request "
+ def message = message(code:"error.no.path.provided")
+ response.sendError(500,message)
+ }
+
+ def parmKey = params['addParameterName']
+
+ if (!parmKey) {
+ log.error "no param key in request "
+ def message = message(code:"error.no.param.key")
+ response.sendError(500,message)
+ }
+
+
+ Rule rule = ruleProcessingService.addRuleOutputParam(irodsAccount, absPath, parmKey)
+ log.info("rule stored:${rule}")
+ render(view:"_ruleDetails", model:[absPath:absPath, rule:rule])
+ }
+
+ def submitAddInputParameterDialog() {
+ log.info("submitAddInputParameterDialog")
+ log.info("params:${params}")
+
+ def absPath = params['ruleAbsPath']
+ if (absPath == null) {
+ log.error "no ruleAbsPath in request "
+ def message = message(code:"error.no.path.provided")
+ response.sendError(500,message)
+ }
+
+ def parmKey = params['addParameterName']
+ def parmValue = params['addParameterValue']
+
+ if (!parmKey) {
+ log.error "no param key in request "
+ def message = message(code:"error.no.param.key")
+ response.sendError(500,message)
+ }
+
+ if (!parmValue) {
+ log.error "no param values for param value in request "
+ def message = message(code:"error.no.param.value")
+ response.sendError(500,message)
+ }
+
+
+ Rule rule = ruleProcessingService.addRuleInputParam(irodsAccount, absPath, parmKey, parmValue)
+ log.info("rule stored:${rule}")
+ render(view:"_ruleDetails", model:[absPath:absPath, rule:rule])
+ }
+}
diff --git a/idrop-web/grails-app/i18n/messages.properties b/idrop-web/grails-app/i18n/messages.properties
index 6d60c26..1ba19c7 100755
--- a/idrop-web/grails-app/i18n/messages.properties
+++ b/idrop-web/grails-app/i18n/messages.properties
@@ -3,6 +3,9 @@ text.account=Account
text.actions=Actions
text.add.metadata=Add Metadata
text.add.all.to.cart=Add all selected items to the cart
+text.add.input.parm=Add input parameter
+text.add.output.parm=Add output parameter
+text.add.parameter=Add parameter
text.add.share=Add a share
text.add.to.cart=Add to Cart
text.address=Address
@@ -40,10 +43,10 @@ text.email=Email
text.file=File
text.file.name=File Name
text.first.name=First Name
-text.forward=Page Forward
text.find.path.in.tree=Open the path in the tree
text.folders.shared.with.me=Folders shared with me
text.folders.shared.by.me=Folders shared by me
+text.frequency=Frequency
text.gallery=Gallery
text.grant=Grant public access
text.guest.login=Use a guest login
@@ -52,8 +55,10 @@ text.home=Home
text.host=Host
text.id=ID
text.info=Info
+text.input.parameters=Input Parameters
text.idrop.lite=Idrop Lite
text.irods.uri=iRODS URI
+text.last.exec.time=Last Exec Time
text.last.name=Last Name
text.length=Size
text.login=Login
@@ -64,8 +69,11 @@ text.name=Name
text.new.folder=New Folder
text.object.path=Object Path
text.optional=(Optional)
+text.output.parameters=Output Parameters
text.owner=Owner
text.owner.zone=Owner Zone
+text.parameter.name=Parameter Name
+text.parameter.value=Parameter Value
text.parent=Parent Collection
text.path=Path
text.password=Password
@@ -84,6 +92,9 @@ text.replication.status=Replication Status
text.rename=Rename
text.resource=Resource
text.resource.group=Resource Group
+text.rule=Rule
+text.rule.body=Rule Body
+text.run.rule=Run Rule
text.search=Search
text.set.as.root=Set this as the root of the tree
text.set.default.resource=Set default resource
@@ -125,7 +136,6 @@ text.ticket.file.limit=Write File Limit
text.ticket.url=Ticket URL
text.ticket.url.landing=Show landing page
text.title=Title
-text.tags=Tags
text.timestamp=Timestamp
text.type=Type
text.tools=Tools
@@ -143,7 +153,6 @@ text.nickname=Nick Name
text.value=Value
text.view=View
text.zone=Zone
-text.new.folder=New Folder
# page headings
@@ -179,12 +188,17 @@ browse.page.prompt=Select a directory or file to see info and actions
# messages
error.confirm.password.missing=Confirmation password is null or blank
error.nothing.selected=Nothing was selected for the action
+error.invalid.request=Invalid Request
+error.in.rule.execution=An error occurred in processing the rule
error.no.access.permission=No access permission
error.no.action=No action found
error.no.audit.access=This user does not have permission to view audit data
error.no.data.found=No data found
+error.no.rule.body=No rule body was entered
error.no.share.name=No share name was provided, please enter a share name
error.no.ticket.found=No ticket was found
+error.no.param.key=No key entered for parameter
+error.no.param.value=No value entered for parameter
error.data.error=Invalid data entered
error.unable.to.find.acl=Unable to find ACL data
error.no.description.provided=No description provided
@@ -220,7 +234,6 @@ message.error.in.upload=An error occurred in uploading this file. If the proble
message.login=Please enter your credentials to log into iRODS
message.password.updated=The password was successfully updated
message.resource.updated=Default storage resource updated successfully
-message.update.successful=Update successful
message.no.access=You do not have access rights to perform that operation
message.no.starred=No starred files or folders to display
message.cannot.create.profile=A profile cannot be created for this user, this may be a mis-configuration
diff --git a/idrop-web/grails-app/services/org/irods/mydrop/service/RuleProcessingService.groovy b/idrop-web/grails-app/services/org/irods/mydrop/service/RuleProcessingService.groovy
new file mode 100644
index 0000000..44d74a4
--- /dev/null
+++ b/idrop-web/grails-app/services/org/irods/mydrop/service/RuleProcessingService.groovy
@@ -0,0 +1,85 @@
+package org.irods.mydrop.service
+
+import org.irods.jargon.core.connection.IRODSAccount
+import org.irods.jargon.core.pub.IRODSAccessObjectFactory
+import org.irods.jargon.core.pub.RuleProcessingAO
+import org.irods.jargon.core.utils.LocalFileUtils
+import org.irods.jargon.core.utils.MiscIRODSUtils
+import org.irods.jargon.ruleservice.composition.RuleCompositionService
+import org.irods.jargon.ruleservice.composition.RuleCompositionServiceImpl
+
+
+class RuleProcessingService {
+
+ static transactional = false
+ IRODSAccessObjectFactory irodsAccessObjectFactory
+
+ def loadRuleFromIrodsFile(IRODSAccount irodsAccount, String rulePath) {
+
+ RuleCompositionService ruleService = new RuleCompositionServiceImpl(irodsAccessObjectFactory, irodsAccount)
+ log.info("attempting to retrieve rule for ${rulePath}")
+
+ return ruleService.loadRuleFromIrods(rulePath)
+ }
+
+ def storeRule(IRODSAccount irodsAccount, String rulePath, String ruleBody, List<String> inputParameters, List<String> outputParameters) {
+
+ log.info("storeRule")
+ RuleCompositionService ruleService = new RuleCompositionServiceImpl(irodsAccessObjectFactory, irodsAccount)
+ return ruleService.storeRuleFromParts(rulePath, ruleBody, inputParameters, outputParameters)
+ }
+
+ def executeRule(IRODSAccount irodsAccount, String ruleBody, List<String> inputParameters, List<String> outputParameters) {
+
+ log.info("executeRule")
+ RuleCompositionService ruleService = new RuleCompositionServiceImpl(irodsAccessObjectFactory, irodsAccount)
+ return ruleService.executeRuleFromParts(ruleBody, inputParameters, outputParameters)
+ }
+
+ def isRule(String rulePath) {
+ if (!rulePath) {
+ return false
+ }
+
+ def fileName = MiscIRODSUtils.getLastPathComponentForGiveAbsolutePath(rulePath)
+ def fileExtension = LocalFileUtils.getFileExtension(fileName)
+ log.info("extension is:${fileExtension}")
+
+ if (fileExtension && fileExtension == ".r") {
+ return true
+ } else {
+ return false
+ }
+ }
+
+ def deleteOutputParam(IRODSAccount irodsAccount, String absPath, String parameter) {
+ log.info("deleteOutputParam")
+ RuleCompositionService ruleService = new RuleCompositionServiceImpl(irodsAccessObjectFactory, irodsAccount)
+ return ruleService.deleteOutputParameterFromRule(absPath, parameter)
+ }
+
+
+ def deleteInputParam(IRODSAccount irodsAccount, String absPath, String parameter) {
+ log.info("deleteInputParam")
+ RuleCompositionService ruleService = new RuleCompositionServiceImpl(irodsAccessObjectFactory, irodsAccount)
+ return ruleService.deleteInputParameterFromRule(absPath, parameter)
+ }
+
+ def addRuleInputParam(IRODSAccount irodsAccount, String absPath, String parameterName, String parameterValue) {
+ log.info("addInputParam")
+ RuleCompositionService ruleService = new RuleCompositionServiceImpl(irodsAccessObjectFactory, irodsAccount)
+ return ruleService.addInputParameterToRule(absPath, parameterName, parameterValue)
+ }
+
+ def addRuleOutputParam(IRODSAccount irodsAccount, String absPath, String parameterName) {
+ log.info("addOutputParam")
+ RuleCompositionService ruleService = new RuleCompositionServiceImpl(irodsAccessObjectFactory, irodsAccount)
+ return ruleService.addOutputParameterToRule(absPath, parameterName)
+ }
+
+ def listDelayedRuleExecutions(IRODSAccount irodsAccount, int offset) {
+ log.info("listDelayedRuleExecutions()")
+ RuleProcessingAO ruleProcessingAO = irodsAccessObjectFactory.getRuleProcessingAO(irodsAccount)
+ return ruleProcessingAO.listAllDelayedRuleExecutions(offset)
+ }
+}
diff --git a/idrop-web/grails-app/views/browse/dataObjectInfo.gsp b/idrop-web/grails-app/views/browse/dataObjectInfo.gsp
index e37c7c7..4105810 100644
--- a/idrop-web/grails-app/views/browse/dataObjectInfo.gsp
+++ b/idrop-web/grails-app/views/browse/dataObjectInfo.gsp
@@ -25,8 +25,6 @@
</h3>
</div>
-
-
<ul class="nav nav-tabs" id="infoTabs">
<li class="active"><a href="#info" id="infoTab"><g:message
code="text.info" /></a></li>
@@ -41,6 +39,11 @@
</g:if>
<li><a href="#audit" id="auditTab"><g:message
code="text.audit" /></a></li>
+ <g:if
+ test="${rule}">
+ <li><a href="#rule" id="ruleTab"><g:message
+ code="text.rule" /></a></li>
+ </g:if>
</ul>
<div class="tab-content">
@@ -246,6 +249,12 @@
<div class="tab-pane" id="audit">
<div id="infoAccordionAuditInner"></div>
</div>
+ <g:if
+ test="${rule}">
+ <div class="tab-pane" id="rule">
+ <div id="infoAccordionRuleInner"></div>
+ </div>
+ </g:if>
</div>
</div>
@@ -285,6 +294,10 @@
showAuditView(selectedPath, "#infoAccordionAuditInner");
});
+ $('#ruleTab').on('shown', function(e) {
+ showRuleView(selectedPath, "#infoAccordionRuleInner");
+ });
+
});
function callUpdateTags() {
diff --git a/idrop-web/grails-app/views/browse/index.gsp b/idrop-web/grails-app/views/browse/index.gsp
index ec5ac6b..ab16a69 100755
--- a/idrop-web/grails-app/views/browse/index.gsp
+++ b/idrop-web/grails-app/views/browse/index.gsp
@@ -8,7 +8,7 @@
<g:hiddenField name="mode" id="mode" value="${mode}"/>
<g:hiddenField name="viewStateBrowseOptionVal" id="viewStateBrowseOptionVal" value="${viewState.browseView}"/>
<g:hiddenField name="presetPath" id="presetPath" value="${viewState.rootPath}"/>
- <g:hiddenField id="viewStateSelectedPath" name="viewStateSelectedPath" value="${viewState.selectedPath}"/>
+ <g:hiddenField id="viewStateSelectedPath" name="viewStateSelectedPath" value="${absPath}"/>
<g:render template="/browse/browseTabContent" />
</div>
diff --git a/idrop-web/grails-app/views/common/_topbar.gsp b/idrop-web/grails-app/views/common/_topbar.gsp
index fee43d3..2edf9ce 100755
--- a/idrop-web/grails-app/views/common/_topbar.gsp
+++ b/idrop-web/grails-app/views/common/_topbar.gsp
@@ -29,6 +29,7 @@
<g:message code="text.tools" /><b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="${grailsApplication.config.idrop.config.idrop.jnlp}" id="idropDesktop")>iDrop Desktop</a></li>
+ <li id="topbarRule" class="topbarItem"><g:link controller="rule" action="delayExecQueue">User Rules</g:link></li>
</ul>
</li>
diff --git a/idrop-web/grails-app/views/home/link.gsp b/idrop-web/grails-app/views/home/link.gsp
index d8bfef5..a7e1531 100755
--- a/idrop-web/grails-app/views/home/link.gsp
+++ b/idrop-web/grails-app/views/home/link.gsp
@@ -17,6 +17,7 @@
return false;
}
baseAbsPath = escape(baseAbsPath);
+ //alert(baseAbsPath);
window.location.href = context + "/browse/index?mode=path&absPath=" + baseAbsPath;
});
</script> \ No newline at end of file
diff --git a/idrop-web/grails-app/views/rule/_ruleDelayExecQueueDetails.gsp b/idrop-web/grails-app/views/rule/_ruleDelayExecQueueDetails.gsp
new file mode 100644
index 0000000..9e9afa9
--- /dev/null
+++ b/idrop-web/grails-app/views/rule/_ruleDelayExecQueueDetails.gsp
@@ -0,0 +1,61 @@
+ <form id="delayExecForm" name="delayExecForm">
+
+<table id="delayExecQueueTable" class="table table-striped table-hover"
+ cellspacing="0" cellpadding="0" border="0">
+ <thead>
+ <tr>
+ <th>
+ <div class="btn-group">
+ <a class="btn dropdown-toggle" data-toggle="dropdown" href="#">Action<span
+ class="caret"></span></a>
+ <ul class="dropdown-menu">
+ <li id="menuDeleteDetails"><a href="#deleteAllDetails"
+ onclick="deleteRulesBulkAction()"><g:message code="text.delete.all" /></a></li>
+ <!-- dropdown menu links -->
+ </ul>
+ </div>
+
+ </th>
+ <th><g:message code="text.name" /></th>
+ <th><g:message code="text.user" /></th>
+ <th><g:message code="text.last.exec.time" /></th>
+ <th><g:message code="text.frequency" /></th>
+
+ </tr>
+ </thead>
+ <tbody>
+ <g:each in="${rules}" var="rule">
+
+ <tr id="rule-${rule.id}">
+
+ <td><g:checkBox name="selectDetail"
+ value="select-${rule.id}" checked="false" />
+ </td>
+ <td>
+ ${rule.name}
+ </td>
+ <td>
+ ${rule.userName}
+ </td>
+ <td>
+ ${rule.lastExecTime}
+ </td>
+ <td>
+ ${rule.frequency}
+ </td>
+ </tr>
+ </g:each>
+
+ </tbody>
+
+ <tfoot>
+ <tr>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ </tr>
+ </tfoot>
+ </table>
+ </form> \ No newline at end of file
diff --git a/idrop-web/grails-app/views/rule/_ruleDetails.gsp b/idrop-web/grails-app/views/rule/_ruleDetails.gsp
new file mode 100644
index 0000000..96c526d
--- /dev/null
+++ b/idrop-web/grails-app/views/rule/_ruleDetails.gsp
@@ -0,0 +1,95 @@
+
+<g:if test="${flash.error}">
+ <script>
+ $(function() { setErrorMessage("${flash.error}"); });
+ </script>
+ </g:if>
+
+ <g:if test="${flash.message}">
+ <script>
+ $(function() { setMessage("${flash.message}");});
+ </script>
+ </g:if>
+
+
+<div id="addParamDialogDiv">
+<!-- area for hanging dialogs -->
+</div>
+
+<g:form name="ruleDetailsForm" id="ruleDetailsForm">
+ <fieldset>
+ <label></label>
+ <g:textArea id="ruleBody" name="ruleBody" value="${rule.ruleBody}" rows="80" cols="100"/>
+
+ <g:hiddenField name="ruleAbsPath" value="${absPath}" id="ruleAbsPath"/>
+
+ <table class="table alert alert-info">
+ <caption><g:message code="text.input.parameters"/></caption>
+
+ <g:each in="${rule.inputParameters}">
+
+ <tr>
+ <g:hiddenField name="inputParamName" value="${it.uniqueName}" id="inputParamName"/>
+ <td>${it.uniqueName}</td>
+ <td><g:textField name="inputParamValue" id="inputParamValue" value="${it.getStringValue()}" size="80"/></td>
+ <td><i class='icon-remove' onclick='deleteInputParam(${"\"" + it.uniqueName + "\""})'></i></td>
+ </tr>
+
+ </g:each>
+ </table>
+ <div id="inputParamsToolbar" >
+ <button type="button" id="addInputParameterButton"
+ value="addInputParameter"
+ onclick="callAddInputParameter()">
+ <i class="icon-plus"></i><g:message code="text.add.input.parm" />
+ </button>
+ </div>
+
+
+ <br/>
+ <table class="table alert alert-info">
+ <caption><g:message code="text.output.parameters"/></caption>
+
+ <g:each in="${rule.outputParameters}">
+ <tr>
+ <g:hiddenField name="outputParamName" value="${it.uniqueName}" id="outputParamName"/>
+ <td>${it.uniqueName}</td>
+ <td><i class='icon-remove' onclick='deleteOutputParam(${"\"" + it.uniqueName + "\""})'></i></td>
+ </tr>
+
+ </g:each>
+
+ </table>
+ <div id="outputParamsToolbar" >
+ <button type="button" id="addOutputParameterButton"
+ value="addOutputParameter"
+ onclick="callAddOutputParameter()">
+ <i class="icon-plus"></i><g:message code="text.add.output.parm" />
+ </button>
+ </div>
+
+ </fieldset>
+</g:form>
+<script type="text/javascript">
+
+var editor = null;
+$(function() {
+ /* var myCodeMirror = CodeMirror.fromTextArea(document.getElementById('ruleBody'),{
+ mode: 'clike',
+ lineNumbers: true,
+ theme: "blackboard"
+ }); */
+
+ var uiOptions = { path : 'js/', searchMode: 'popup' }
+ var codeMirrorOptions = {
+ mode: 'text/x-rule',
+ lineNumbers: true,
+ theme: "eclipse"
+ }
+
+ //then create the editor
+ editor = new CodeMirrorUI(document.getElementById('ruleBody'),uiOptions,codeMirrorOptions);
+
+});
+</script>
+ \ No newline at end of file
diff --git a/idrop-web/grails-app/views/rule/addParameterDialog.gsp b/idrop-web/grails-app/views/rule/addParameterDialog.gsp
new file mode 100644
index 0000000..f891c31
--- /dev/null
+++ b/idrop-web/grails-app/views/rule/addParameterDialog.gsp
@@ -0,0 +1,154 @@
+<div id="addParameterDialog">
+
+ <div class="modal-header">
+ <h3>
+ <g:message code="text.add.parameter" />
+ </h3>
+ </div>
+
+ <div class="modal-body">
+ <label for="addParameterName"><g:message
+ code="text.parameter.name" />:<g:textField name="addParameterName"
+ id="addParameterName" /></label>
+ <g:hiddenField name="newParameterAbsPath" id="newParameterAbsPath"
+ value="${absPath }" />
+ <g:if test="${isInputParameter}">
+ <label for="addParameterValue"><g:message
+ code="text.parameter.value" />:<g:textField
+ name="addParameterValue" id="addParameterValue" /></label>
+ </g:if>
+ <g:hiddenField name="isInputParameter" id="isInputParameter"
+ value="${isInputParameter}" />
+
+
+ </div>
+
+ <div class="modal-footer">
+ <g:if test="${isInputParameter}">
+ <button type="button" id="updateNewParameterButton" value="update"
+ onclick="submitAddInputParameterDialog()")>
+ <g:message code="default.button.update.label" />
+ </button>
+ </g:if>
+ <g:else>
+ <button type="button" id="updateNewParameterButton" value="update"
+ onclick="submitAddOutputParameterDialog()")>
+ <g:message code="default.button.update.label" />
+ </button>
+ </g:else>
+ <button type="button" id="cancelAddButton" value="cancelAdd"
+ onclick="closeAddParameterDialog()")>
+ <g:message code="text.cancel" />
+ </button>
+ </div>
+
+</div>
+
+<script>
+ $(function() {
+ $("#addParameterDialog").dialog({
+ "modal" : true,
+ "width" : "500px"
+ });
+ });
+
+ function submitAddInputParameterDialog() {
+
+ var absPath = $("#newParameterAbsPath").val();
+ if (absPath == null || absPath == "") {
+ setErrorMessage("no absPath for rule");
+ return false;
+ }
+
+ var inputParamKey = $("#addParameterName").val();
+ if (inputParamKey == null || inputParamKey == "") {
+ setErrorMessage("no input parameter key for rule");
+ return false;
+ }
+
+ var inputParamValue = $("#addParameterValue").val();
+ if (inputParamValue == null || inputParamValue == "") {
+ setErrorMessage("no input parameter value for rule");
+ return false;
+ }
+
+ var params = {
+ ruleAbsPath : absPath,
+ addParameterName : inputParamKey,
+ addParameterValue : inputParamValue
+ }
+ var url = "/rule/submitAddInputParameterDialog";
+
+ showBlockingPanel();
+
+ var jqxhr = $.post(context + url, params, "html")
+ .success(
+ function(returnedData, status, xhr) {
+ var continueReq = checkForSessionTimeout(
+ returnedData, xhr);
+ if (!continueReq) {
+ unblockPanel();
+ return false;
+ }
+ $("#ruleDetailDiv").html(returnedData);
+
+ $("#addParameterDialog").dialog("close");
+ $("#addParameterDialog").html("");
+ unblockPanel();
+
+ }).error(function(xhr, status, error) {
+ unblockPanel();
+
+ setErrorMessage(xhr.responseText);
+ });
+ }
+
+ function closeAddParameterDialog() {
+ $("#addParameterDialog").dialog("close");
+ $("#addParameterDialog").html("");
+ }
+
+ function submitAddOutputParameterDialog() {
+
+ var absPath = $("#newParameterAbsPath").val();
+ if (absPath == null || absPath == "") {
+ setErrorMessage("no absPath for rule");
+ return false;
+ }
+
+ var inputParamKey = $("#addParameterName").val();
+ if (inputParamKey == null || inputParamKey == "") {
+ setErrorMessage("no input parameter key for rule");
+ return false;
+ }
+
+ var params = {
+ ruleAbsPath : absPath,
+ addParameterName : inputParamKey,
+ }
+ var url = "/rule/submitAddOutputParameterDialog";
+
+ showBlockingPanel();
+
+ var jqxhr = $.post(context + url, params, "html")
+ .success(
+ function(returnedData, status, xhr) {
+ var continueReq = checkForSessionTimeout(
+ returnedData, xhr);
+ if (!continueReq) {
+ unblockPanel();
+ return false;
+ }
+ $("#ruleDetailDiv").html(returnedData);
+
+ $("#addParameterDialog").dialog("close");
+ $("#addParameterDialog").html("");
+ unblockPanel();
+
+ }).error(function(xhr, status, error) {
+ unblockPanel();
+
+ setErrorMessage(xhr.responseText);
+ });
+ }
+</script>
diff --git a/idrop-web/grails-app/views/rule/delayExecQueue.gsp b/idrop-web/grails-app/views/rule/delayExecQueue.gsp
new file mode 100644
index 0000000..8ad4dec
--- /dev/null
+++ b/idrop-web/grails-app/views/rule/delayExecQueue.gsp
@@ -0,0 +1,39 @@
+<head>
+<meta name="layout" content="mainNoSidebar" />
+</head>
+<div id="delayExecQueueDiv">
+ <g:render template="ruleDelayExecQueueDetails" />
+</div>
+<script>
+$(document).ready(function() {
+
+ $.ajaxSetup({
+ cache : false
+ });
+ $("#topbarTools").addClass("active");
+ });
+
+
+function deleteRulesBulkAction() {
+
+ var formData = $("#delayExecForm").serializeArray();
+ showBlockingPanel();
+
+ var jqxhr = $.post(context + "/rule/deleteDelayExecQueue", formData, "html")
+ .success(function(returnedData, status, xhr) {
+ var continueReq = checkForSessionTimeout(returnedData, xhr);
+ if (!continueReq) {
+ return false;
+ }
+
+ setMessage("Delete action successful");
+ $("#delayExecQueueDiv").html(returnedData);
+ unblockPanel();
+ }).error(function(xhr, status, error) {
+ setErrorMessage(xhr.responseText);
+ unblockPanel();
+ });
+
+}
+
+</script> \ No newline at end of file
diff --git a/idrop-web/grails-app/views/rule/index.gsp b/idrop-web/grails-app/views/rule/index.gsp
new file mode 100644
index 0000000..8ee551f
--- /dev/null
+++ b/idrop-web/grails-app/views/rule/index.gsp
@@ -0,0 +1,229 @@
+<head>
+
+<g:javascript library="codemirror" />
+<g:javascript library="addon/search/searchcursor" />
+<g:javascript library="codemirror-ui" />
+
+
+<g:javascript library="clike" />
+<link rel="stylesheet" href="${resource(dir:'css',file:'codemirror.css')}" />
+<link rel="stylesheet" href="${resource(dir:'css',file:'codemirror-ui.css')}" />
+
+<link rel="stylesheet" href="${resource(dir:'css',file:'eclipse.css')}" />
+
+</head>
+<h3><a ><g:message code="text.rule" /></a></h3>
+<div id="detailsTopSection">
+
+ <div id="detailsToolbar" >
+ <button type="button" id="reloadRuleButton" class="ruleEdit"
+ value="reloadRule"
+ onclick="callReloadRule()">
+ <i class="icon-refresh"></i><g:message code="default.button.reload.label" />
+ </button>
+ <span id="saveRuleButton"><button type="button" id="saveRuleButton" class="ruleEdit"
+ value="saveRule"
+ onclick="callSaveRule()"><i class="icon-ok"></i>
+ <g:message code="text.update" />
+ </button></span>
+ <span id="runRuleButton"><button type="button" id="runRuleButton"
+ value="runRule"
+ onclick="callRunRule()"><i class="icon-play"></i>
+ <g:message code="text.run.rule" />
+ </button></span>
+ </button></span>
+ <span id="showRuleButton"><button hidden type="button" id="showRuleButton" class="ruleResultView"
+ value="showRule"
+ onclick="callShowRule()"><i class="icon-edit"></i>
+ <g:message code="text.edit" />
+ </button></span>
+ </div>
+ </div>
+
+ <div id="ruleDetailDiv">
+ <!-- div for audit table -->
+ <g:render template="/rule/ruleDetails" />
+ </div>
+
+ <div id="ruleResultDiv">
+ <!-- result of rule exec -->
+
+
+ </div>
+
+ <script type="text/javascript">
+
+
+ function deleteInputParam(param) {
+
+ if (!param) {
+ return false;
+ }
+
+ var absPath = $("#ruleAbsPath").val();
+ if (absPath == null || absPath == "") {
+ setErrorMessage("no absPath for rule");
+ return false;
+ }
+
+ var params = {
+ ruleAbsPath : absPath,
+ inputParamName : param
+ }
+
+
+ var jqxhr = $.post(context + "/rule/deleteRuleInputParameter", params, "html").success(
+ function(returnedData, status, xhr) {
+ var continueReq = checkForSessionTimeout(returnedData, xhr);
+ if (!continueReq) {
+ return false;
+ }
+ setMessage("Parameter deleted");
+ $("#ruleDetailDiv").html(returnedData);
+ }).error(function(xhr, status, error) {
+ setErrorMessage(xhr.responseText);
+ });
+ }
+
+
+ function deleteOutputParam(param) {
+ var absPath = $("#ruleAbsPath").val();
+ if (absPath == null || absPath == "") {
+ setErrorMessage("no absPath for rule");
+ return false;
+ }
+
+ var params = {
+ ruleAbsPath : absPath,
+ outputParamName : param
+ }
+
+
+ var jqxhr = $.post(context + "/rule/deleteRuleOutputParameter", params, "html").success(
+ function(returnedData, status, xhr) {
+ var continueReq = checkForSessionTimeout(returnedData, xhr);
+ if (!continueReq) {
+ return false;
+ }
+ setMessage("Parameter deleted");
+ $("#ruleDetailDiv").html(returnedData);
+ }).error(function(xhr, status, error) {
+ setErrorMessage(xhr.responseText);
+ }); }
+
+ function callSaveRule() {
+ editor.mirror.save();
+ var formData = $("#ruleDetailsForm").serializeArray();
+ var jqxhr = $.post(context + "/rule/updateRule", formData, "html").success(
+ function(returnedData, status, xhr) {
+ var continueReq = checkForSessionTimeout(returnedData, xhr);
+ if (!continueReq) {
+ return false;
+ }
+ setMessage("rule saved");
+ $("#ruleDetailDiv").html(returnedData);
+ }).error(function(xhr, status, error) {
+ setErrorMessage(xhr.responseText);
+ });
+
+
+ }
+
+ function callShowRule() {
+
+ $("#ruleDetailDiv").show("slow");
+ $(".ruleEdit").show("slow");
+ $("#ruleResultDiv").html("");
+ $("#ruleResultDiv").hide("slow");
+ $(".ruleResultView").hide("slow");
+
+ }
+
+ function callReloadRule(absPath) {
+ var absPath = $("#ruleAbsPath").val();
+ if (absPath == null || absPath == "") {
+ showError("no absPath for rule");
+ return false;
+ }
+
+ var params = {
+ absPath : absPath
+
+ }
+ var jqxhr = $.get(context + "/rule/reloadRule", params, "html").success(
+ function(returnedData, status, xhr) {
+ var continueReq = checkForSessionTimeout(returnedData, xhr);
+ if (!continueReq) {
+ return false;
+ }
+ $("#ruleDetailDiv").html(returnedData);
+ }).error(function(xhr, status, error) {
+ setErrorMessage(xhr.responseText);
+ });
+
+
+ }
+
+ function callRunRule() {
+ editor.mirror.save();
+ var formData = $("#ruleDetailsForm").serializeArray();
+ $("#ruleDetailDiv").hide("slow");
+ $(".ruleEdit").hide("slow");
+ $("#ruleResultDiv").html("");
+ $("#ruleResultDiv").show("slow");
+ $(".ruleResultView").show("slow");
+
+ showBlockingPanel();
+
+ var jqxhr = $.post(context + "/rule/runRule", formData, "html").success(
+ function(returnedData, status, xhr) {
+ var continueReq = checkForSessionTimeout(returnedData, xhr);
+ if (!continueReq) {
+ unblockPanel();
+ return false;
+ }
+ $("#ruleResultDiv").html(returnedData);
+ unblockPanel();
+
+
+
+ }).error(function(xhr, status, error) {
+ unblockPanel();
+
+ setErrorMessage(xhr.responseText);
+ });
+ }
+
+ function callAddInputParameter() {
+
+ var absPath = $("#ruleAbsPath").val();
+ if (absPath == null || absPath == "") {
+ setErrorMessage("no absPath for rule");
+ return false;
+ }
+
+ var params = {
+ ruleAbsPath : absPath
+ }
+ var url = "/rule/addRuleInputParameterDialog";
+
+ lcSendValueWithParamsAndPlugHtmlInDiv(url, params, "#addParamDialogDiv", null);
+ }
+
+ function callAddOutputParameter() {
+ var absPath = $("#ruleAbsPath").val();
+ if (absPath == null || absPath == "") {
+ setErrorMessage("no absPath for rule");
+ return false;
+ }
+
+ var params = {
+ ruleAbsPath : absPath
+ }
+ var url = "/rule/addRuleOutputParameterDialog";
+
+ lcSendValueWithParamsAndPlugHtmlInDiv(url, params, "#addParamDialogDiv", null);
+ }
+
+
+ </script>
diff --git a/idrop-web/grails-app/views/rule/ruleErrorResult.gsp b/idrop-web/grails-app/views/rule/ruleErrorResult.gsp
new file mode 100644
index 0000000..fb05fbf
--- /dev/null
+++ b/idrop-web/grails-app/views/rule/ruleErrorResult.gsp
@@ -0,0 +1,23 @@
+
+<div class="container">
+ <div class="row-fluid content">
+ <div class="span12 alert alert-error">
+ <h2><g:message code="error.in.rule.execution" /></h2>
+ </div>
+ </div>
+ <div class="row-fluid content alert alert-success">
+ <div class="span12">
+ ${message}
+ </div>
+ </div>
+ <div class="row-fluid content alert alert-error">
+ <div class="span12">
+ ${stackTrace}
+ </div>
+ </div>
+</div>
+
+
+
+
+
diff --git a/idrop-web/grails-app/views/rule/ruleResult.gsp b/idrop-web/grails-app/views/rule/ruleResult.gsp
new file mode 100644
index 0000000..077a950
--- /dev/null
+++ b/idrop-web/grails-app/views/rule/ruleResult.gsp
@@ -0,0 +1,41 @@
+
+<div class="container">
+ <div class="row-fluid content">
+ <div class="span12">
+
+ <table class="table">
+ <g:each in="${ruleResult.outputParameterResults.keySet()}">
+
+ <g:if test="${it == "ruleExecOut" || it == "ruleExecErrorOut" }">
+ </g:if>
+ <g:else>
+ <tr>
+ <td>
+ ${it}
+ </td>
+ <td>
+ ${ruleResult.outputParameterResults.get(it).resultObject}
+ </td>
+ </tr>
+ </g:else>
+ </g:each>
+ </table>
+
+ </div>
+ </div>
+ <div class="row-fluid content alert alert-success">
+ <div class="span12">
+ ${execOut}
+ </div>
+ </div>
+ <div class="row-fluid content alert alert-error">
+ <div class="span12">
+ ${errorOut}
+ </div>
+ </div>
+</div>
+
+
+
+
+