summaryrefslogtreecommitdiffstats
path: root/idrop-web/grails-app/controllers/org
diff options
context:
space:
mode:
authorhanna <nowakh3d@wp.pl>2013-09-10 10:38:51 (GMT)
committer hanna <nowakh3d@wp.pl>2013-09-10 10:38:51 (GMT)
commit62fdcbb9362e6d0e9bc9b4dafa9ba0edd7433d3a (patch)
treeca23753f43180360fbbb1fd6ea8db4de23ce358d /idrop-web/grails-app/controllers/org
parent9794dc10c810d9d7b3e95bcaa82ff73b53b1c687 (diff)
parentdc9747ef3458ff5a695227c30f8adf338e9b8878 (diff)
downloadQCG-Data-master.zip
QCG-Data-master.tar.gz
QCG-Data-master.tar.bz2
metasearchHEADmaster
Diffstat (limited to 'idrop-web/grails-app/controllers/org')
-rwxr-xr-xidrop-web/grails-app/controllers/org/irods/mydrop/controller/MetadataController.groovy1
-rw-r--r--idrop-web/grails-app/controllers/org/irods/mydrop/controller/MetadataSearchController.groovy267
2 files changed, 268 insertions, 0 deletions
diff --git a/idrop-web/grails-app/controllers/org/irods/mydrop/controller/MetadataController.groovy b/idrop-web/grails-app/controllers/org/irods/mydrop/controller/MetadataController.groovy
index ece2f82..1edb684 100755
--- a/idrop-web/grails-app/controllers/org/irods/mydrop/controller/MetadataController.groovy
+++ b/idrop-web/grails-app/controllers/org/irods/mydrop/controller/MetadataController.groovy
@@ -43,6 +43,7 @@ class MetadataController {
irodsAccessObjectFactory.closeSession()
}
+ def index = { }
/**
* Load the metadata details area, this will show the main form, and subsequently, the table will be loaded via AJAX
*/
diff --git a/idrop-web/grails-app/controllers/org/irods/mydrop/controller/MetadataSearchController.groovy b/idrop-web/grails-app/controllers/org/irods/mydrop/controller/MetadataSearchController.groovy
new file mode 100644
index 0000000..f9dd3fb
--- /dev/null
+++ b/idrop-web/grails-app/controllers/org/irods/mydrop/controller/MetadataSearchController.groovy
@@ -0,0 +1,267 @@
+package org.irods.mydrop.controller
+
+import org.apache.commons.collections.FactoryUtils
+import org.apache.commons.collections.ListUtils
+import org.irods.jargon.core.connection.IRODSAccount
+import org.irods.jargon.core.pub.CollectionAO
+import org.irods.jargon.core.pub.CollectionAndDataObjectListAndSearchAO;
+import org.irods.jargon.core.pub.IRODSAccessObjectFactory
+import org.irods.jargon.core.query.AVUQueryElement
+import org.irods.jargon.core.query.AVUQueryOperatorEnum
+import org.irods.jargon.core.query.CollectionAndDataObjectListingEntry;
+import org.irods.jargon.core.query.MetaDataAndDomainData
+import org.irods.jargon.core.query.AVUQueryElement.AVUQueryPart
+import org.irods.jargon.core.pub.DataObjectAO;
+
+
+
+import java.util.ArrayList;
+
+class MetadataSearchController {
+
+ IRODSAccessObjectFactory irodsAccessObjectFactory
+ IRODSAccount irodsAccount
+
+ /**
+ * 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()
+ }
+
+ def index = {
+
+ }
+
+ /**
+ * Search iRODS metadata
+ * Here the data from inputs is posted.
+ */
+ def search (MetadataSearchCommand metadataSearchCommand) {
+
+ CollectionAndDataObjectListAndSearchAO collectionAndDataObjectListAndSearchAO = irodsAccessObjectFactory.getCollectionAndDataObjectListAndSearchAO(irodsAccount)
+ DataObjectAO dataObjAO = irodsAccessObjectFactory.getDataObjectAO(irodsAccount) //dataObjects
+ CollectionAO collectionAO = irodsAccessObjectFactory.getCollectionAO(irodsAccount) //folders
+
+ List<CollectionAndDataObjectListingEntry> results = new ArrayList<CollectionAndDataObjectListingEntry>()
+ List<MetaDataAndDomainData> queryResults = new ArrayList<MetaDataAndDomainData>()
+ List<MetaDataAndDomainData> finalResults = new ArrayList<MetaDataAndDomainData>()
+
+ int counter = -1
+
+ for(AVUNode avuNode in metadataSearchCommand.AVUNodes) { //for every condition node do:
+ if(avuNode.andOr == "Every") { //if every condition has to be fulfilled
+ queryResults = connectedByAnd(avuNode, dataObjAO, collectionAO)
+ } else { //if at least one condition has to be fulfilled
+ queryResults = connectedByOr(avuNode, dataObjAO, collectionAO)
+ }
+ if(counter >= 0) { //if there's more than one node, check operator between nodes
+ log.info("OPERATOR:" + metadataSearchCommand.AVUOps[counter])
+ if (metadataSearchCommand.AVUOps[counter] == "AND") {
+ finalResults = intersectLists(finalResults, queryResults)
+ } else {
+ finalResults = sumOfLists(finalResults, queryResults)
+ }
+ } else {
+ finalResults = sumOfLists(finalResults, queryResults)
+ }
+ counter++
+ }
+
+
+
+ for (MetaDataAndDomainData data : finalResults){
+ results.add(collectionAndDataObjectListAndSearchAO.getCollectionAndDataObjectListingEntryAtGivenAbsolutePath(data.domainObjectUniqueName))
+ }
+
+
+ render(view:"/search/searchResult", model:[results:results])
+ }
+ //method used to finding files as well as folders matching every metadata query, final result is the sum of these results
+ private def connectedByAnd(AVUNode avuNode, DataObjectAO dataObjAO, CollectionAO collectionAO) {
+ List<MetaDataAndDomainData> queryRes1 = collectionAO.findMetadataValuesByMetadataQuery(createAVUQ(avuNode), true) //match folders names
+ List<MetaDataAndDomainData> queryRes2 = dataObjAO.findMetadataValuesByMetadataQuery(createAVUQ(avuNode)) //match dataObj names
+ List<MetaDataAndDomainData> queryResults = ListUtils.sum(queryRes1, queryRes2) //connect lists
+
+ queryResults
+ }
+
+ //method used to finding files as well as folders matching AT LEAST ONE metadata query
+ private def connectedByOr(AVUNode avuNode, DataObjectAO dataObjAO, CollectionAO collectionAO) {
+ List<AVUQueryElement> metadataQuery = new ArrayList<AVUQueryElement>()
+ List<MetaDataAndDomainData> finalResult = new ArrayList<MetaDataAndDomainData>()
+ List<MetaDataAndDomainData> queryRes1 = new ArrayList<MetaDataAndDomainData>()
+ List<MetaDataAndDomainData> queryRes2 = new ArrayList<MetaDataAndDomainData>()
+ List<MetaDataAndDomainData> queryResults = new ArrayList<MetaDataAndDomainData>()
+
+ for(AVUCommand avu in avuNode.AVUs) {
+ metadataQuery.clear()
+ metadataQuery.add(AVUQueryElement.instanceForValueQuery(AVUQueryPart.ATTRIBUTE, AVUQueryOperatorEnum.EQUAL, avu.attribute));
+ if((avu.value).isNumber() && avu.operator in ["<", "<=", ">="]) //">"
+ {
+ metadataQuery.add(AVUQueryElement.instanceForValueQuery(AVUQueryPart.VALUE, chooseNumOperator(avu.operator), avu.value));
+ } else {
+ metadataQuery.add(AVUQueryElement.instanceForValueQuery(AVUQueryPart.VALUE, chooseOperator(avu.operator), avu.value));
+ }
+
+ if(!avu.unit.empty){
+ metadataQuery.add(AVUQueryElement.instanceForValueQuery(AVUQueryPart.UNITS, AVUQueryOperatorEnum.EQUAL, avu.unit));
+ }
+
+ queryRes1 = collectionAO.findMetadataValuesByMetadataQuery(metadataQuery, true)
+ queryRes2 = dataObjAO.findMetadataValuesByMetadataQuery(metadataQuery)
+ queryResults = ListUtils.sum(queryRes1, queryRes2)
+
+ finalResult = sumOfLists(finalResult, queryResults)
+ }
+
+ finalResult //return list without duplicates
+
+ }
+
+ def createAVUQ(AVUNode avuNode) { //create list of metadata queries
+
+ List<AVUQueryElement> metadataQuery = new ArrayList<AVUQueryElement>()
+
+ for(AVUCommand avu in avuNode.AVUs){
+
+ metadataQuery.add(AVUQueryElement.instanceForValueQuery(AVUQueryPart.ATTRIBUTE, AVUQueryOperatorEnum.EQUAL, avu.attribute));
+ if((avu.value).isNumber() && avu.operator in ["<", "<=", ">="]) //">"
+ {
+ metadataQuery.add(AVUQueryElement.instanceForValueQuery(AVUQueryPart.VALUE, chooseNumOperator(avu.operator), avu.value));
+ } else {
+ metadataQuery.add(AVUQueryElement.instanceForValueQuery(AVUQueryPart.VALUE, chooseOperator(avu.operator), avu.value));
+ }
+
+ if(!avu.unit.empty){
+ metadataQuery.add(AVUQueryElement.instanceForValueQuery(AVUQueryPart.UNITS, AVUQueryOperatorEnum.EQUAL, avu.unit));
+ }
+ }
+
+ metadataQuery
+ }
+
+ //create one list from two ones without duplicates
+ private def sumOfLists(List<MetaDataAndDomainData> list1, List<MetaDataAndDomainData> list2) {
+
+ boolean alreadyEx = false
+
+ for(MetaDataAndDomainData elem1 in list1) {
+ alreadyEx = false
+ for(MetaDataAndDomainData elem2 in list2) {
+ if(elem1.getDomainObjectUniqueName() == elem2.getDomainObjectUniqueName())
+ alreadyEx = true
+ }
+ if(!alreadyEx) list2.add(elem1)
+ }
+ list2
+ }
+
+
+ //create list in which there are files and collections occured in both input lists
+ private def intersectLists(List<MetaDataAndDomainData> list1, List<MetaDataAndDomainData> list2) {
+
+ List<MetaDataAndDomainData> finalList = new ArrayList<MetaDataAndDomainData>()
+ boolean ex = false
+
+ for(MetaDataAndDomainData elem1 in list1) {
+ ex = false
+ for(MetaDataAndDomainData elem2 in list2) {
+ if(elem1.getDomainObjectUniqueName() == elem2.getDomainObjectUniqueName())
+ ex = true
+ }
+ if(ex) finalList.add(elem1)
+ }
+ finalList
+ }
+
+
+
+ def chooseOperator(String op) {
+ switch(op){
+ case "=":
+ AVUQueryOperatorEnum.EQUAL;
+ break
+ case ">":
+ AVUQueryOperatorEnum.GREATER_THAN;
+ break
+ case "<":
+ AVUQueryOperatorEnum.LESS_THAN;
+ break
+ case ">=":
+ AVUQueryOperatorEnum.GREATER_OR_EQUAL;
+ break
+ case "<=":
+ AVUQueryOperatorEnum.LESS_OR_EQUAL;
+ break
+ case "<>":
+ AVUQueryOperatorEnum.NOT_EQUAL;
+ break
+ case "like":
+ AVUQueryOperatorEnum.LIKE;
+ break
+ case "not like":
+ AVUQueryOperatorEnum.NOT_LIKE;
+ break
+ }
+ }
+
+ def chooseNumOperator(String op) {
+ switch(op) {
+ /*case ">":
+ AVUQueryOperatorEnum.NUM_GREATER_THAN;
+ break*/
+ case "<":
+ AVUQueryOperatorEnum.NUM_LESS_THAN;
+ break
+ case ">=":
+ AVUQueryOperatorEnum.NUM_GREATER_OR_EQUAL;
+ break
+ case "<=":
+ AVUQueryOperatorEnum.NUM_LESS_OR_EQUAL;
+ break
+ }
+ }
+
+}
+
+
+//Class which constists of the list of condition nodes and list of operators connecting them
+class MetadataSearchCommand {
+ List <AVUNode> AVUNodes = ListUtils.lazyList([], FactoryUtils.instantiateFactory(AVUNode))
+ List <String> AVUOps = ListUtils.lazyList([], FactoryUtils.instantiateFactory(String))
+
+}
+
+//class consisted of AVU + operator
+class AVUCommand {
+ String attribute
+ String operator //=, <, >, <=, >=, <>, like, not like
+ String value
+ String unit
+
+ static constraints = {
+ attribute(blank:false)
+ value(blank:false)
+ }
+
+}
+
+//Class consisted of list of conditions and the option (in GUI radiobutton), decripted below
+class AVUNode {
+ List <AVUCommand> AVUs = ListUtils.lazyList([], FactoryUtils.instantiateFactory(AVUCommand))
+ String andOr //every condition fulfilled or at least one
+}
+