diff options
Diffstat (limited to 'idrop-web/grails-app/controllers/org/irods/mydrop/controller/MetadataSearchController.groovy')
-rw-r--r-- | idrop-web/grails-app/controllers/org/irods/mydrop/controller/MetadataSearchController.groovy | 202 |
1 files changed, 202 insertions, 0 deletions
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..4fe3012 --- /dev/null +++ b/idrop-web/grails-app/controllers/org/irods/mydrop/controller/MetadataSearchController.groovy @@ -0,0 +1,202 @@ +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 + */ + 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 = 0 + + 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) + log.info(queryResults.toString()) + } + log.info("OPERATOR:" + metadataSearchCommand.AVUOps[counter]) + counter++ + } + + + + for (MetaDataAndDomainData data : queryResults){ + results.add(collectionAndDataObjectListAndSearchAO.getCollectionAndDataObjectListingEntryAtGivenAbsolutePath(data.domainObjectUniqueName)) + } + + + render(view:"/search/searchResult", model:[results: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 + } + + 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)); + metadataQuery.add(AVUQueryElement.instanceForValueQuery(AVUQueryPart.VALUE, chooseOperator(avu.operator), avu.value)); + + 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) { + + List<AVUQueryElement> metadataQuery = new ArrayList<AVUQueryElement>() + + for(AVUCommand avu in avuNode.AVUs){ + metadataQuery.add(AVUQueryElement.instanceForValueQuery(AVUQueryPart.ATTRIBUTE, AVUQueryOperatorEnum.EQUAL, avu.attribute)); + metadataQuery.add(AVUQueryElement.instanceForValueQuery(AVUQueryPart.VALUE, chooseOperator(avu.operator), avu.value)); + } + + 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 + } + log.info("ATR:" + elem1.getAvuAttribute()) + if(!alreadyEx) list2.add(elem1) + } + list2 + } + + 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": + + log.info("OP: notlike " + op) + AVUQueryOperatorEnum.NOT_LIKE; + + } + } + +} + + + +class MetadataSearchCommand { //constists of the condition nodes and operators connecting them + List <AVUNode> AVUNodes = ListUtils.lazyList([], FactoryUtils.instantiateFactory(AVUNode)) + List <String> AVUOps = ListUtils.lazyList([], FactoryUtils.instantiateFactory(String)) + +} + +class AVUCommand { + String attribute + String operator //=, <, >, <=, >=, <>, like, not like + String value + String unit //unused + + static constraints = { + attribute(blank:false) + value(blank:false) + } + +} + +class AVUNode { + List <AVUCommand> AVUs = ListUtils.lazyList([], FactoryUtils.instantiateFactory(AVUCommand)) + String andOr //every condition fulfilled or at least one +} + |