class RegistrySearchAgent(Agent):
    def __init__(self, identity=None):
        Agent.__init__(self)
        self.identity = identity
        self.entity = Entity()
        self.entity.clearTypes()
        self.server_uri = REGISTRY_SEARCH_SERVER_ADDRESS
        self.serialization = SERIALIZATION.TURTLE

    def setSenderUri(self, generatedBy):
        self.identity = generatedBy

    def search(self):
        payload = self.generateSearchMessage()
        try:
            if debug:
                print "Request to SMARTAPI Search Service:"
                print payload

            resp_str = self.runQuery(self.server_uri, content_type,
                                     content_type, payload)

            response = Response().fromString(resp_str, self.serialization)
            if response != None:
                if debug:
                    print "Response from SMARTAPI Search Service:"
                    print resp_str
                return response.getEntities()
            else:
                if debug:
                    print "Response from SMARTAPI Search Service:"
                    print resp_str
                return None
        except:
            print "Exception while sending an HTTP request to " + REGISTRY_SEARCH_SERVER_ADDRESS
            traceback.print_exc()
            return None

    def clear(self):
        self.entity = Entity()

    def setEntity(self, searchEntity):
        self.entity = searchEntity

    def generateSearchMessage(self):
        request = RequestFactory().create(self.identity)
        request.setMethod(RESOURCE.READ)
        request.addEntity(self.entity)
        return Tools().toString(request, self.serialization)

    def setServiceUri(self, serviceUri):
        self.server_uri = serviceUri

    def ofDescription(self, searchString):
        condition = Condition()
        condition.addRegex("(?i)" + searchString)
        self.entity.add(URIRef(PROPERTY.COMMENT), condition)

    def anyOfNames(self, searchStrings):
        if len(searchStrings) > 0:
            condition = Condition()
            for s in searchStrings:
                condition.addRegex("(?i)" + s)
            self.entity.add(URIRef(PROPERTY.RDFS_LABEL), condition)

    def ofName(self, searchString, exactMatch=False):
        if exactMatch:
            self.entity.setName(searchString)
        else:
            condition = Condition()
            condition.addRegex("(?i)" + searchString)
            self.entity.add(URIRef(PROPERTY.RDFS_LABEL), condition)

    def ofPartialId(self, searchString):
        condition = Condition()
        condition.addRegex("(?i)" + searchString)
        self.entity.add(URIRef(PROPERTY.ID), condition)

    def ofType(self, type):
        self.entity.addType(type)

    def anyOfTypes(self, types):
        if len(types) == 1:
            self.ofType(types[0])
        if len(types) > 1:
            condition = Condition()
            for type in types:
                condition.addOr(Obj(type))
            self.entity.setType(condition)

    def clearTypes(self):
        self.entity.clearTypes()

    def ofInputType(self, type):
        if self.entity.hasCapability():
            a = self.entity.getCapabilities()[0]
            i = Input()
            i.setType(type)
            a.addInput(i)
        else:
            a = Activity()
            i = Input()
            i.setType(type)
            a.addInput(i)
            self.entity.addCapability(a)

    def ofOutputType(self, type):
        if self.entity.hasCapability():
            a = self.entity.getCapabilities()[0]
            o = Output()
            o.setType(type)
            a.addOutput(o)
        else:
            a = Activity()
            o = Output()
            o.setType(type)
            a.addOutput(o)
            self.entity.addCapability(a)

    def polygonSearchArea(self, polygon):
        self.entity.add(URIRef(RESOURCE.POLYGON), polygon)

    def multipolygonSearchArea(self, polygons):
        for polygon in polygons:
            self.entity.add(URIRef(RESOURCE.POLYGON), polygon)

    def rectangeSearchArea(self, minCoords, maxCoords):
        self.entity.add(URIRef(PROPERTY.MINLOCATION), minCoords)
        self.entity.add(URIRef(PROPERTY.MAXLOCATION), maxCoords)

    def pointSearchArea(self, center, kilometers):
        ring = Ring()
        ring.add(URIRef(PROPERTY.LAT), center.getLatitude())
        ring.add(URIRef(PROPERTY.LONG), center.getLongitude())
        maxR = ValueObject()
        maxR.setQuantity(RESOURCE.LENGTH)
        maxR.setUnit(RESOURCE.KILOMETER)
        maxR.setValue(Variant(kilometers))
        ring.setMaxRadius(maxR)
        self.entity.add(URIRef(NS.SMARTAPI + "ring"), ring)

    def debugMode(self, value):
        global debug
        debug = value

    def searchByPointAndType(self, myUri, latitude, longitude, distanceInKm,
                             types):
        agent = RegistrySearchAgent()
        agent.clear()
        agent.setSenderUri(myUri)
        agent.anyOfTypes(types)
        coords = Coordinates()
        coords.setLatitude(latitude)
        coords.setLongitude(longitude)
        agent.pointSearchArea(coords, distanceInKm)
        return agent.search()

    def searchByNameAndType(self, myUri, keywords, types):
        agent = RegistrySearchAgent()
        agent.clear()
        agent.setSenderUri(myUri)
        agent.anyOfTypes(types)
        agent.anyOfNames(keywords)
        return agent.search()

    def searchServicesByOutputType(self, myUri, type):
        agent = RegistrySearchAgent()
        agent.clear()
        agent.setSenderUri(myUri)
        agent.ofType(RESOURCE.SERVICE)
        agent.ofOutputType(type)
        return agent.search()

    def searchServicesByInputType(self, myUri, type):
        agent = RegistrySearchAgent()
        agent.clear()
        agent.setSenderUri(myUri)
        agent.ofType(RESOURCE.SERVICE)
        agent.ofInputType(type)
        return agent.search()

    def searchByDescription(self,
                            myUri,
                            searchString,
                            types=[RESOURCE.ENTITY]):
        agent = RegistrySearchAgent()
        agent.clear()
        agent.setSenderUri(myUri)
        agent.anyOfTypes(types)
        agent.ofDescription(searchString)
        return agent.search()

    def searchByPartialId(self, myUri, searchString):
        agent = RegistrySearchAgent()
        agent.clear()
        agent.setSenderUri(myUri)
        agent.ofPartialId(searchString)
        return agent.search()

    def fetchById(self, myUri, idToFetch):
        agent = RegistrySearchAgent()
        agent.clear()
        agent.setSenderUri(myUri)
        entity = Entity(idToFetch)
        entity.clearTypes()
        agent.setEntity(entity)
        resEntities = agent.search()
        if len(resEntities) > 0:
            return resEntities[0]
        else:
            return None
示例#2
0
class SearchAgent(object):
    # uri of the SEAS registration service
    rsUri = "http://seas.asema.com/webapps/rs/v1.0e1.2/search" 
    debug = False
    
    def __init__(self, myUri=''):        
        self.generatedBy = myUri
        self.entity = Entity()
        self.entity.clearTypes()
        self.httpClient = HttpClient()
        self.serialization = 'text/turtle'
    
    def search(self):
        from SmartAPI.model.Response import Response
        
        # serialize data
        messageBody = self._generateSearchMessage()
        if self.debug:
            print '\n Request to SEAS Search Service:'
            print messageBody, '\n'
        
        try:
            # send message
            responseStr = self.httpClient.sendPost(self.rsUri, messageBody, self.serialization, self.serialization, seasMethod=self.httpClient.SMARTAPI_METHOD_REQUEST)[0]
            response = Response.fromString(responseStr, self.serialization)
            if response is not None:
                if self.debug:
                    print '\n Response from SEAS Search Service:'
                    print Tools.toString(response, self.serialization)
                    Tools.printErrors(response)
                return response.getEntities()
            else:
                if self.debug:
                    print '\n Response from SEAS Search Service:'
                    print responseStr, '\n'
                return None
        except:
            print 'Exception while sending an HTTP request to ', self.rsUri
            traceback.print_exc()
        
        
    def _generateSearchMessage(self):
        from SmartAPI.factory.RequestFactory import RequestFactory
    
        request = RequestFactory().create(self.generatedBy)        
        request.setMethod(RESOURCE.READ)        
        request.addEntity(self.entity)
        
        return Tools.toString(request, self.serialization)       
    
    @classmethod
    def searchByNameAndType(cls, mySeasUri, freshnessInDays, keywords, types):
        '''
        @type keywords, types: list of Strings
        @type freshnessInDays: integer
        @type mySeasUri: String
        '''
        agent = SearchAgent(mySeasUri)
        agent.anyOfTypes(types)
        agent.daysOldData(freshnessInDays)
        agent.anyOfNames(keywords)
        return agent.search()
    
    @classmethod
    def searchByDescription(cls,  mySeasUri, freshnessInDays, searchString, types = [RESOURCE.ENTITY]):
        agent = SearchAgent(mySeasUri)        
        agent.anyOfTypes(types)
        agent.daysOldData(freshnessInDays)
        agent.ofDescription(searchString)
        return agent.search()
    
    @classmethod
    def searchById(cls, mySeasUri, freshnessInDays, searchString):
        agent = SearchAgent(mySeasUri)
        agent.ofType(RESOURCE.ENTITY);
        agent.ofId(searchString)
        agent.daysOldData(freshnessInDays)
        return agent.search()
    
    @classmethod
    def searchByPointAndType(cls, mySeasUri, freshnessInDays, latitude, longitude, distanceInKm, types):
        agent = SearchAgent(mySeasUri)
        agent.anyOfTypes(types)
        agent.daysOldData(freshnessInDays)
        
        coords = Coordinates(latitude=latitude, longitude=longitude)        
        agent.pointSearchArea(coords, distanceInKm)
        return agent.search()
    
    def pointSearchArea(self, center, kilometers):
        '''
        define circular search area
        '''
        ring = Ring()
        ring.add(URIRef(PROPERTY.LAT), center.getLatitude())
        ring.add(URIRef(PROPERTY.LONG), center.getLongitude())
        maxR = ValueObject()
        maxR.setQuantity(RESOURCE.LENGTH)
        maxR.setUnit(RESOURCE.KILOMETER)
        maxR.setValue(Variant(kilometers))
        ring.setMaxRadius(maxR)
        self.entity.add(URIRef(NS.SMARTAPI + "ring"), ring)
    
    def ofId(self, searchString):
        condition = Condition()
        condition.addRegex("(?i)" + searchString)
        self.entity.add(URIRef(PROPERTY.ID), condition)
    
    def ofDescription(self, searchString):
        condition = Condition()
        condition.addRegex("(?i)" + searchString)
        self.entity.add(URIRef(PROPERTY.COMMENT), condition)
       
    def ofType(self, type):
        '''
        define type to search
        '''
        if isinstance(type, str):
            type = URIRef(type)
        self.entity.addType(type)
        
    def anyOfTypes(self, types):
        '''
        Define all the types that can match
        '''
        if len(types) == 1:
            self.ofType(types[0])
        elif len(types) > 1:
            condition = Condition()
            for type in types:
                condition.addOr(Obj(type))
            self.entity.clearTypes()
            self.entity.addType(condition)
            
    def daysOldData(self, days):
        '''
        Define how many days old data will be searched.
        '''
        duration = Duration(days=days)
        self.entity.add(URIRef(PROPERTY.FRESHNESS), duration)
        
    def monthsOldData(self, months):
        '''
        Define how many months old data will be searched.
        '''
        duration = Duration(months=months)
        self.entity.add(URIRef(PROPERTY.FRESHNESS), duration)
        
    def anyOfNames(self, searchStrings):
        '''
        Define multiple search strings for the entity name (label). Will return also partial hits 
        for any of the strings.
        '''
        if len(searchStrings) > 0:
            condition = Condition()
            for stri in searchStrings:
                condition.addRegex("(?i)" + stri)
            
            self.entity.add(URIRef(PROPERTY.RDFS_LABEL), condition);