Example #1
0
    def __init__(self, sosRequest, method, requestObject, sosConfig):
        f.sosFilter.__init__(self, sosRequest, method, requestObject,
                             sosConfig)
        # @TODO Declare attribute first!
        # self.offering = None
        # etc..

        #**************************
        if method == "GET":
            #---------- THE OFFERING
            if requestObject.has_key("offering"):
                self.offering = get_name_from_urn(requestObject["offering"],
                                                  "offering", sosConfig)
            else:
                raise sosException.SOSException(
                    1,
                    "Parameter \"offering\" is mandatory with multiplicity 1")

            #---------- THE OBSERVED PROPERTY
            if requestObject.has_key("observedProperty"):
                self.observedProperty = []
                oprs = requestObject["observedProperty"].split(",")
                for opr in oprs:
                    # get_name_from_urn limit the ability to ask for an observedProperty with LIKE:
                    # eg: ask "water" to get all the water related data, "water:discharge", "water:temperature" ...
                    #oprName = get_name_from_urn(opr,"property")
                    oprName = opr
                    self.observedProperty.append(oprName)  # one-many ID
            else:
                raise sosException.SOSException(
                    1,
                    "Parameter \"observedProperty\" is mandatory with multiplicity N"
                )

            #---------- RESPONSE FORMAT
            if requestObject.has_key("responseFormat"):
                if not requestObject["responseFormat"] in sosConfig.parameters[
                        "GO_responseFormat"]:
                    raise sosException.SOSException(
                        2,
                        "Parameter \"responseFormat\" sent with invalid value : use one of %s"
                        % "; ".join(sosConfig.parameters["GO_responseFormat"]))
                else:
                    self.responseFormat = requestObject["responseFormat"]
            else:
                raise sosException.SOSException(
                    1,
                    "Parameter \"responseFormat\" is mandatory with multiplicity 1"
                )  #one

            #OPTIONAL request parameters
            #---------- SRS FILTER
            if requestObject.has_key("srsName"):
                self.srsName = get_name_from_urn(requestObject["srsName"],
                                                 "refsystem", sosConfig)
                if not self.srsName in sosConfig.parameters["GO_srs"]:
                    raise sosException.SOSException(
                        2, "srsName \"%s\" not supported, use one of: %s" %
                        (self.srsName, ",".join(
                            sosConfig.parameters["GO_srs"])))
            else:
                self.srsName = sosConfig.parameters["GO_srs"][0]

            #---------- TIME FILTER
            if requestObject.has_key('eventTime'):
                self.eventTime = []
                for i in requestObject["eventTime"].replace(" ",
                                                            "+").split(","):
                    if len(i.split("/")) < 3:
                        self.eventTime.append(i.split("/"))
                    else:
                        raise sosException.SOSException(
                            2, "Parameter \"eventTime\" bad formatted")

                tp = []
                for t in self.eventTime:
                    if len(t) == 2:
                        tp.append(iso.parse_datetime(t[0]))
                        tp.append(iso.parse_datetime(t[1]))
                    if len(t) == 1:
                        tp.append(iso.parse_datetime(t[0]))

                # Checking if some event limitation is reached
                #if sosConfig["maxGoPeriod"]:
                if int(sosConfig.maxGoPeriod) > 0:
                    from datetime import timedelta
                    d = timedelta(hours=int(sosConfig.maxGoPeriod))
                    userPeriod = max(tp) - min(tp)
                    if d < userPeriod:
                        raise sosException.SOSException(
                            2,
                            "You are requesting data for a period of [%s hours], but you are not permitted to ask for a period longer than: %s hours"
                            % (userPeriod, d))

            else:
                self.eventTime = None

            #---------- PROCEDURES FILTER
            if requestObject.has_key("procedure"):
                self.procedure = []
                prcs = requestObject["procedure"].split(",")
                for prc in prcs:
                    prcName = get_name_from_urn(prc, "procedure", sosConfig)
                    self.procedure.append(prcName)
            else:
                self.procedure = None

            #---------- FEATURES OF INTEREST FILTER
            self.featureOfInterest = None
            self.featureOfInterestSpatial = None
            if requestObject.has_key("featureOfInterest"):
                foi = requestObject["featureOfInterest"]
                if foi.find("<ogc:") >= 0 and foi.find("<gml:") >= 0:
                    #raise sosException.SOSException(3,"FOI SPATIAL: %s" %(foi))
                    self.featureOfInterestSpatial = sosUtils.ogcSpatCons2PostgisSql(
                        foi, 'geom_foi', sosConfig.istsosepsg)
                else:
                    self.featureOfInterest = get_name_from_urn(
                        foi, "feature", sosConfig)

                #fois = requestObject["featureOfInterest"].split(",")
                #for foi in fois:
                #    foiName = get_name_from_urn(foi,"feature")
                #    self.featureOfInterest.append(foiName)

            #---------- FILTERS FOR QUERY NOT SUPPORTED YET
            if requestObject.has_key("result"):
                #raise sosException.SOSException(3,"Parameter \"result\" not yet supported")
                self.result = sosUtils.ogcCompCons2PostgisSql(
                    requestObject["result"])
            else:
                self.result = None  #zero-one optional

            #---------- RESULT MODEL
            if requestObject.has_key("resultModel"):
                if requestObject["resultModel"] in sosConfig.parameters[
                        "GO_resultModel"]:
                    self.resultModel = requestObject["resultModel"]
                else:
                    raise sosException.SOSException(
                        2,
                        "Parameter \"resultModel\" sent with invalid value: supported values are: %s"
                        % ",".join(sosConfig.parameters["GO_resultModel"]))
            else:
                self.resultModel = sosConfig.parameters["GO_resultModel"][0]

            #---------- RESPONSE MODE
            if requestObject.has_key("responseMode"):
                if requestObject["responseMode"] in sosConfig.parameters[
                        "GO_responseMode"]:
                    self.responseMode = requestObject["responseMode"]
                else:
                    raise sosException.SOSException(
                        2,
                        "Parameter \"responseMode\" sent with invalid value, supported values are: %s"
                        % (",".join(sosConfig.parameters["GO_responseMode"])))

            else:
                self.responseMode = sosConfig.parameters["GO_responseMode"][0]

            ###########################
            # NON STANDARD PARAMETERS #
            ###########################
            #---------- AGGREGATE INTERVAL
            # In ISO 8601 duration format
            if requestObject.has_key("aggregateInterval"):
                # Check on the eventTime parameter: it must be only one interval: 2010-01-01T00:00:00+00/2011-01-01T00:00:01+00
                exeMsg = "Using aggregate functions, the event time must exist with an interval composed by a begin and an end date (ISO8601)"
                if self.eventTime == None or len(self.eventTime) != 1 or len(
                        self.eventTime[0]) != 2:
                    raise sosException.SOSException(2, exeMsg)
                self.aggregate_interval = requestObject["aggregateInterval"]
                try:
                    iso.parse_duration(self.aggregate_interval)
                except Exception as ex:
                    raise sosException.SOSException(
                        2,
                        "Parameter \"aggregate_interval\" sent with invalid format (check ISO8601 duration spec): %s"
                        % ex)
            else:
                self.aggregate_interval = None

            #---------- AGGREGATE FUNCTION
            # sum,avg,max,min
            if requestObject.has_key("aggregateFunction"):
                if self.aggregate_interval == None:
                    raise sosException.SOSException(
                        2,
                        "Using aggregate functions parameters \"aggregateInterval\" and \"aggregateFunction\" are both mandatory"
                    )
                self.aggregate_function = requestObject["aggregateFunction"]
                if not (self.aggregate_function.upper()
                        in ["AVG", "COUNT", "MAX", "MIN", "SUM"]):
                    raise sosException.SOSException(
                        2,
                        "Available aggregation functions: avg, count, max, min, sum."
                    )
            else:
                self.aggregate_function = None

            #---------- AGGREGATE NODATA
            if requestObject.has_key("aggregateNodata"):
                if self.aggregate_interval == None or self.aggregate_function == None:
                    raise sosException.SOSException(
                        2,
                        "Using aggregateNodata parameter requires both \"aggregateInterval\" and \"aggregateFunction\""
                    )
                self.aggregate_nodata = requestObject["aggregateNodata"]
            else:
                self.aggregate_nodata = sosConfig.aggregate_nodata

            #---------- AGGREGATE NODATA QUALITY INDEX
            if requestObject.has_key("aggregateNodataQi"):
                if self.aggregate_interval == None or self.aggregate_function == None:
                    raise sosException.SOSException(
                        2,
                        "Using aggregateNodataQi parameter requires both \"aggregateInterval\" and \"aggregateFunction\""
                    )
                self.aggregate_nodata_qi = requestObject["aggregateNodataQi"]
            else:
                self.aggregate_nodata_qi = sosConfig.aggregate_nodata_qi

            #------------ QUALITY INDEX
            self.qualityIndex = False
            if requestObject.has_key("qualityIndex"):
                if requestObject["qualityIndex"].upper() == "TRUE":
                    self.qualityIndex = True
                elif requestObject["qualityIndex"].upper() == "FALSE":
                    self.qualityIndex = False
                else:
                    raise sosException.SOSException(
                        2, "qualityIndex can only be True or False!")
                #    self.qualityIndex = sosUtils.CQLvalueFilter2PostgisSql("id_qi_fk",requestObject["qualityIndex"])

        #**********************
        if method == "POST":
            from xml.dom import minidom
            #---------- THE OFFERING
            offs = requestObject.getElementsByTagName('offering')
            if len(offs) == 1:
                val = offs[0].firstChild
                if val.nodeType == val.TEXT_NODE:
                    self.offering = get_name_from_urn(str(val.data),
                                                      "offering", sosConfig)
                else:
                    err_txt = "XML parsing error (get value: offering)"
                    raise sosException.SOSException(1, err_txt)
            else:
                err_txt = "Parameter \"offering\" is mandatory with multiplicity 1"
                raise sosException.SOSException(1, err_txt)

            #---------- THE OBSERVED PROPERTY
            obsProps = requestObject.getElementsByTagName('observedProperty')
            self.observedProperty = []
            if len(obsProps) > 0:
                for obsProp in obsProps:
                    val = obsProp.firstChild
                    if val.nodeType == val.TEXT_NODE:
                        # get_name_from_urn limit the ability to ask for an observedProperty with LIKE:
                        # eg: ask "water" to get all the water related data, "water:discharge", "water:temperature" ...
                        #self.observedProperty.append(get_name_from_urn(str(val.data),"property"))
                        self.observedProperty.append(str(val.data))
                    else:
                        err_txt = "XML parsing error (get value: observedProperty)"
                        raise sosException.SOSException(1, err_txt)
            else:
                err_txt = "Parameter \"observedProperty\" is mandatory with multiplicity N"
                raise sosException.SOSException(1, err_txt)

            #---------- RESPONSE FORMAT
            respF = requestObject.getElementsByTagName('responseFormat')
            if len(respF) == 1:
                val = respF[0].firstChild
                if val.nodeType == val.TEXT_NODE:
                    self.responseFormat = str(val.data)
                    if self.responseFormat not in sosConfig.parameters[
                            "GO_responseFormat"]:
                        raise sosException.SOSException(
                            2,
                            "Parameter \"responseFormat\" sent with invalid value: use one of %s"
                            % "; ".join(
                                sosConfig.parameters["GO_responseFormat"]))
                else:
                    err_txt = "XML parsing error (get value: responseFormat)"
                    raise sosException.SOSException(1, err_txt)
            else:
                err_txt = "Parameter \"responseFormat\" is mandatory with multiplicity 1"
                raise sosException.SOSException(1, err_txt)

            #OPTIONAL request parameters
            #---------- SRS OF RETURNED GML FEATURES
            srss = requestObject.getElementsByTagName('srsName')
            if len(srss) > 0:
                if len(srss) < 2:
                    val = srss[0].firstChild
                    if val.nodeType == val.TEXT_NODE:
                        self.srsName = get_name_from_urn(
                            str(val.data), "refsystem", sosConfig)
                    else:
                        err_txt = "XML parsing error (get value: srsName)"
                        raise sosException.SOSException(1, err_txt)
                else:
                    err_txt = "Allowed only ONE parameter \"srsName\""
                    raise sosException.SOSException(1, err_txt)
            else:
                self.srsName = sosConfig.parameters["GO_srs"][0]

            #---------- TIME FILTER
            evtms = requestObject.getElementsByTagName('eventTime')
            self.eventTime = []
            if len(evtms) > 0:
                for evtm in evtms:
                    tps = evtm.getElementsByTagName('gml:TimePeriod')
                    for tp in tps:
                        begin = tp.getElementsByTagName('gml:beginPosition')
                        end = tp.getElementsByTagName('gml:endPosition')
                        if len(begin) == 1 and len(end) == 1:
                            Bval = begin[0].firstChild
                            Eval = end[0].firstChild
                            #raise sosException.SOSException(1,end[0].toprettyxml())
                            if Bval.nodeType == Bval.TEXT_NODE and Eval.nodeType == Eval.TEXT_NODE:
                                self.eventTime.append([
                                    str(Bval.data).replace(" ", "+"),
                                    str(Eval.data).replace(" ", "+")
                                ])
                                #raise sosException.SOSException(1,str(self.eventTime))
                            else:
                                err_txt = "XML parsing error (get value: TimePeriod)"
                                raise sosException.SOSException(1, err_txt)

                    tis = evtm.getElementsByTagName('gml:TimeInstant')
                    for ti in tis:
                        instant = ti.getElementsByTagName('gml:timePosition')
                        if len(instant) > 0 and len(instant) < 2:
                            Ival = instant[0].firstChild
                            if Ival.nodeType == Ival.TEXT_NODE:
                                self.eventTime.append(
                                    [str(Ival.data).replace(" ", "+")])
                            else:
                                err_txt = "XML parsing error (get value: Timeinstant)"
                                raise sosException.SOSException(1, err_txt)
            else:
                self.eventTime = None

            #---------- PROCEDURES FILTER
            procs = requestObject.getElementsByTagName('procedure')
            if len(procs) > 0:
                self.procedure = []
                for proc in procs:
                    if "xlink:href" in proc.attributes.keys():
                        self.procedure.append(
                            str(proc.getAttribute("xlink:href")))
                    elif proc.hasChildNodes():
                        val = proc.firstChild
                        if val.nodeType == val.TEXT_NODE:
                            self.procedure.append(
                                get_name_from_urn(str(val.data), "procedure",
                                                  sosConfig))
                    else:
                        err_txt = "XML parsing error (get value: procedure)"
                        raise sosException.SOSException(1, err_txt)
            else:
                self.procedure = None

            #---------- FEATURES OF INTEREST FILTER
            fets = requestObject.getElementsByTagName('featureOfInterest')
            self.featureOfInterest = None
            self.featureOfInterestSpatial = None
            if len(fets) > 0:
                if len(fets) < 2:
                    elements = [
                        e for e in fets[0].childNodes
                        if e.nodeType == e.ELEMENT_NODE
                    ]
                    if len(elements) == 1:
                        self.featureOfInterestSpatial = sosUtils.ogcSpatCons2PostgisSql(
                            elements[0], 'geom_foi', sosConfig.istsosepsg)
                    else:
                        if "xlink:href" in fets[0].attributes.keys():
                            self.featureOfInterest = str(
                                fets[0].getAttribute("xlink:href"))
                        elif fets[0].hasChildNodes():
                            val = fets[0].firstChild
                            if val.nodeType == val.TEXT_NODE:
                                self.featureOfInterest = get_name_from_urn(
                                    str(val.data), "feature", sosConfig)
                        else:
                            err_txt = "XML parsing error (get value: featureOfInterest)"
                            raise sosException.SOSException(1, err_txt)
                else:
                    err_txt = "Allowed only ONE parameter \"featureOfInterest\""
                    raise sosException.SOSException(1, err_txt)

            #---------- FILTERS FOR QUERY NOT SUPPORTED YET
            ress = requestObject.getElementsByTagName('result')
            if len(ress) > 0:
                raise sosException.SOSException(
                    3, "Parameter \"result\" not yet supported")
            else:
                self.result = None  #zero-one optional

            #---------- RESULT MODEL
            mods = requestObject.getElementsByTagName('resultModel')
            if len(mods) > 0:
                if len(mods) < 2:
                    val = mods[0].firstChild
                    if val.nodeType == val.TEXT_NODE:
                        self.resultModel = str(val.data)
                        if self.resultModel not in sosConfig.parameters[
                                "GO_resultModel"]:
                            raise sosException.SOSException(
                                2,
                                "Parameter \"resultModel\" sent with invalid value"
                            )
                    else:
                        err_txt = "XML parsing error (get value: resultModel)"
                        raise sosException.SOSException(1, err_txt)
                else:
                    err_txt = "Allowed only ONE parameter \"resultModel\""
                    raise sosException.SOSException(1, err_txt)
            else:
                self.resultModel = None

            #---------- RESPONSE MODE
            rsmods = requestObject.getElementsByTagName('responseMode')
            if len(rsmods) > 0:
                if len(rsmods) < 2:
                    val = rsmods[0].firstChild
                    if val.nodeType == val.TEXT_NODE:
                        self.responseMode = str(val.data)
                        if self.responseMode not in sosConfig.parameters[
                                "GO_responseMode"]:
                            raise sosException.SOSException(
                                2,
                                "Parameter \"responseMode\" sent with invalid value"
                            )
                    else:
                        err_txt = "XML parsing error (get value: responseMode)"
                        raise sosException.SOSException(1, err_txt)
                else:
                    err_txt = "Allowed only ONE parameter \"responseMode\""
                    raise sosException.SOSException(1, err_txt)
            else:
                self.responseMode = sosConfig.parameters["GO_responseMode"][0]

            #-------------- AGGREGATE INTERVAL & FUNCTION
            self.aggregate_interval = None
            self.aggregate_function = None
            aggint = requestObject.getElementsByTagName('aggregateInterval')
            aggfun = requestObject.getElementsByTagName('aggregateFunction')
            aggnodata = requestObject.getElementsByTagName('aggregateNodata')

            if len(aggint) == 1 and len(aggfun) == 1:
                #-----------------------
                # -- aggregate_interval
                #-----------------------
                # Check on the eventTime parameter: it must be only one interval: 2010-01-01T00:00:00+00/2011-01-01T00:00:01+00
                exeMsg = "Using aggregate functions, the event time must exist with an interval composed by a begin and an end date (ISO8601)"
                if self.eventTime == None or len(self.eventTime) != 1 or len(
                        self.eventTime[0]) != 2:
                    raise sosException.SOSException(2, exeMsg)
                val = aggint[0].firstChild
                if val.nodeType == val.TEXT_NODE:
                    self.aggregate_interval = str(val.data)
                    try:
                        iso.parse_duration(self.aggregate_interval)
                    except Exception as ex:
                        raise sosException.SOSException(
                            2,
                            "Parameter \"aggregate_interval\" sent with invalid format (check ISO8601 duration spec): %s"
                            % ex)
                else:
                    err_txt = "cannot get ISO8601 duration value in \"aggregateInterval\""
                    raise sosException.SOSException(1, err_txt)
                #-----------------------
                # -- aggregate_function
                #-----------------------
                val = aggfun[0].firstChild
                if val.nodeType == val.TEXT_NODE:
                    self.aggregate_function = str(val.data)
                    if not (self.aggregate_function.upper()
                            in ["AVG", "COUNT", "MAX", "MIN", "SUM"]):
                        raise sosException.SOSException(
                            2,
                            "Available aggregation functions: avg, count, max, min, sum."
                        )

                #-----------------------------------
                # -- aggregate_no_data default value
                #-----------------------------------
                if len(aggnodata) == 1:
                    val = aggnodata[0].firstChild
                    self.aggregate_nodata = str(val.data)
                else:
                    self.aggregate_nodata = sosConfig.aggregate_nodata

        #================================
        #MISSING AGGREGATE QUALITY INDEX
        #================================

            elif len(aggint) == 0 and len(aggfun) == 0:
                pass
            else:
                err_txt = "\"aggregateInterval\" and \"aggregate_function\" are both required with multiplicity 1"
                raise sosException.SOSException(1, err_txt)

            #------------ QUALITY INDEX
            self.qualityIndex = False
            qidx = requestObject.getElementsByTagName('qualityIndex')
            if len(qidx) > 0:
                if len(qidx) < 2:
                    val = qidx[0].firstChild
                    if val.nodeType == val.TEXT_NODE:
                        self.qualityIndex = str(val.data)
                        if self.qualityIndex.upper() == "TRUE":
                            self.qualityIndex = True
                        elif self.qualityIndex.upper() == "FALSE":
                            pass
                        else:
                            raise sosException.SOSException(
                                2,
                                "qualityIndex can only be \'True\' or \'False\'"
                            )
            elif len(qidx) == 0:
                pass
            else:
                err_txt = "\"qualityIndex\" is allowed with multiplicity 1 only"
                raise sosException.SOSException(1, err_txt)
Example #2
0
    def __init__(self, sosRequest, method, requestObject, sosConfig):
        f.sosFilter.__init__(
            self, sosRequest,
            method, requestObject, sosConfig
        )
        if method == "GET":

            self.eventTime = None
            self.featureOfInterest = None
            self.featureOfInterestSpatial = None
            self.result = None  # zero-one optional
            self.observedProperty = [':']

            # OBSERVED PROPERTY
            #   get_name_from_urn limit the ability to ask for an observedProperty with LIKE:
            #   eg: ask "water" to get all the water related data, "water:discharge", "water:temperature" ...
            if "observedproperty" in requestObject:
                self.observedProperty = []
                oprs = requestObject["observedproperty"].split(",")

                for opr in oprs:
                    if opr == '':
                        raise sosException.SOSException(
                            "MissingParameterValue", "observedProperty",
                            "Missing 'observedProperty' parameter"
                        )

                    oprName = opr
                    self.observedProperty.append(oprName)  # one-many ID

            # PROCEDURES FILTER
            if "procedure" in requestObject:
                self.procedure = []
                prcs = requestObject["procedure"].split(",")

                for prc in prcs:
                    if prc == '':
                        raise sosException.SOSException(
                            "MissingParameterValue", "procedure",
                            "Missing 'procedure' parameter"
                        )

                    try:
                        prcName = get_name_from_urn(
                            prc, "procedure", sosConfig
                        )

                    except Exception as e:
                        raise sosException.SOSException(
                            "InvalidParameterValue",
                            "procedure", str(e)
                        )

                    self.procedure.append(prcName)

            else:
                self.procedure = None

            if self.version == '2.0.0':

                # THE OFFERING
                #  > in istSOS offerings are equals to procedures
                #  > so offerings are inserted into the procedure array filter

                if "offering" in requestObject:
                    prcs = requestObject["offering"].split(",")
                    if self.procedure is None:
                        self.procedure = []

                    for prc in prcs:
                        if prc == '':
                            raise sosException.SOSException(
                                "MissingParameterValue", "offering",
                                "Missing 'offering' parameter"
                            )
                        try:
                            prcName = get_name_from_urn(
                                prc, "offering",
                                sosConfig
                            )

                        except Exception as e:
                            raise sosException.SOSException(
                                "InvalidParameterValue",
                                "offering", str(e)
                            )

                        # Check for name redundancy
                        if prcName not in self.procedure:
                            self.procedure.append(prcName)

                # RESPONSE FORMAT
                self.responseFormat = 'text/xml;subtype="om/2.0"'
                if "responseformat" in requestObject:
                    if requestObject["responseformat"] == '':
                        raise sosException.SOSException(
                            "MissingParameterValue", "responseformat",
                            "Missing 'responseformat' parameter"
                        )
                    if not requestObject["responseformat"] in sosConfig.parameters["GO_responseFormat_2_0_0"]:
                        raise sosException.SOSException(
                            "InvalidParameterValue", "responseFormat",
                            "Parameter \"responseFormat\" sent with invalid value : use one of %s" % "; ".join(sosConfig.parameters["GO_responseFormat_2_0_0"])
                        )
                    elif requestObject["responseformat"] == sosConfig.parameters["GO_responseFormat_2_0_0"][0]:
                        self.responseFormat = 'text/xml;subtype="om/2.0"'
                    else:
                        self.responseFormat = requestObject["responseformat"]

                # OPTIONAL SRS FILTER
                if "crs" in requestObject:
                    try:
                        self.srsName = requestObject["crs"].split(':')[-1]

                    except Exception as e:
                        raise sosException.SOSException("InvalidParameterValue", "crs", "%s" % e)

                    if self.srsName not in sosConfig.parameters["GO_srs"]:
                        raise sosException.SOSException(
                            "InvalidParameterValue", "crs",
                            "crs \"%s\" not supported, use one of: %s" %(self.srsName, ",".join(sosConfig.parameters["GO_srs"]))
                        )

                else:
                    self.srsName = sosConfig.parameters["GO_srs"][0]

                # TIME FILTER
                # istSOS supports
                #     kvp examples:
                #     - during:       temporalFilter=om:phenomenonTime,2012-11-19T14:00:00+01:00/2012-11-19T14:15:00+01:00
                #     - equals:       temporalFilter=om:phenomenonTime,2012-11-19T14:00:00.000+01:00
                #     - combination:  temporalFilter=om:phenomenonTime,2012-11-19T14:00:00+01:00/2012-11-19T14:15:00+01:00,2012-11-19T14:00:00.000+01:00
                if 'temporalfilter' in requestObject:
                    self.eventTime = []
                    temporalfilter = requestObject["temporalfilter"].replace(
                        " ", "+").split(",")

                    #  > in istSOS om:phenomenonTime is equals to om:resultTime
                    if temporalfilter.pop(0) not in ['om:phenomenonTime','phenomenonTime','om:resultTime','resultTime']:
                        raise sosException.SOSException("InvalidParameterValue", "temporalfilter",
                            "Parameter \"temporalFilter\" bad formatted")

                    for i in temporalfilter:
                        if '/' in i:
                            interval = i.split("/")
                            if len(interval) != 2:
                                raise sosException.SOSException(
                                    "InvalidParameterValue", "temporalfilter",
                                    "Parameter \"temporalfilter\" bad formatted"
                                )
                            try:
                                iso.parse_date(interval[0])
                                iso.parse_date(interval[1])

                            except iso.ISO8601Error as isoerr:
                                raise sosException.SOSException(
                                    "InvalidParameterValue", "temporalfilter",
                                    "Parameter \"temporalfilter\" bad formatted, %s" % isoerr
                                )

                            self.eventTime.append(interval)

                        else:
                            try:
                                iso.parse_date(i)

                            except iso.ISO8601Error as isoerr:
                                raise sosException.SOSException(
                                    "InvalidParameterValue", "temporalfilter",
                                    "Parameter \"temporalfilter\" bad formatted, %s" % isoerr
                                )

                            self.eventTime.append([i])

                # FEATURES OF INTEREST FILTER
                if "featureofinterest" in requestObject:
                    if requestObject["featureofinterest"] == '':
                        raise sosException.SOSException("MissingParameterValue", "featureOfInterest", "Missing 'featureOfInterest' parameter")
                    if sosConfig.urn["feature"] in requestObject["featureofinterest"]:
                        self.featureOfInterest = get_name_from_urn(requestObject["featureofinterest"], "feature", sosConfig)
                    else:
                        self.featureOfInterest = requestObject["featureofinterest"]

                # SPATIAL FILTER
                # example1: spatialFilter=om:featureOfInterest/*/sams:shape,0.0,0.0,60.0,60.0,http://www.opengis.net/def/crs/EPSG/0/4326
                # example2: spatialFilter=om:featureOfInterest/*/sams:shape,0.0,0.0,60.0,60.0,urn:ogc:def:crs:EPSG::4326
                if "spatialfilter" in requestObject:

                    sfs = requestObject["spatialfilter"].split(",")

                    if len(sfs) != 6:
                        raise sosException.SOSException(
                            "InvalidParameterValue", "spatialfilter",
                            "Invalid spatial filter '%s'" % requestObject["spatialfilter"]
                        )

                    if sfs[0] != 'om:featureOfInterest/*/sams:shape':
                        raise sosException.SOSException("InvalidParameterValue", "spatialfilter",
                            "Invalid spatial filter '%s'" % requestObject["spatialfilter"])

                    srsName = None

                    if sfs[5].index(':')>-1:
                        srsName = sfs[5].split(':')[-1]

                    if sfs[5].index('/')>-1:
                        srsName = sfs[5].split('/')[-1]

                    ogcfilter = (
                        "<ogc:BBOX>" +
                          "<ogc:PropertyName>the_geom</ogc:PropertyName>"+
                          ("<gml:Box srsName='EPSG:%s'>" % (srsName) )+
                             ("<gml:coordinates>%s,%s %s,%s</gml:coordinates>" % (sfs[1], sfs[2], sfs[3], sfs[4])) +
                          "</gml:Box>"+
                        "</ogc:BBOX>")

                    self.featureOfInterestSpatial = sosUtils.ogcSpatCons2PostgisSql(
                        ogcfilter, 'geom_foi', sosConfig.istsosepsg
                    )


            else:

                # THE OFFERING
                if "offering" in requestObject:
                    try:
                        self.offering = get_name_from_urn(requestObject["offering"], "offering", sosConfig)

                    except Exception as e:
                        raise sosException.SOSException("InvalidParameterValue","offering",str(e))

                # RESPONSE FORMAT
                if "responseformat" in requestObject:
                    if requestObject["responseformat"] == '':
                        raise sosException.SOSException("MissingParameterValue", "responseFormat", "Missing 'responseFormat' parameter")

                    if not requestObject["responseformat"] in sosConfig.parameters["GO_responseFormat"]:
                        raise sosException.SOSException("InvalidParameterValue", "responseFormat",
                            "Parameter \"responseFormat\" sent with invalid value : use one of %s" % "; ".join(sosConfig.parameters["GO_responseFormat"]))

                    else:
                        self.responseFormat = requestObject["responseformat"]

                if "offering" not in requestObject:
                    raise sosException.SOSException("MissingParameterValue", "offering",
                        "Parameter \"offering\" is mandatory with multiplicity 1")

                if "observedproperty" not in requestObject:
                    raise sosException.SOSException("MissingParameterValue", "observedProperty",
                        "Parameter \"observedProperty\" is mandatory with multiplicity N")

                if "responseformat" not in requestObject:
                    raise sosException.SOSException("MissingParameterValue", "responseFormat",
                        "Parameter \"responseFormat\" is mandatory with multiplicity 1") #one

                # OPTIONAL SRS FILTER
                if "srsname" in requestObject:
                    try:
                        self.srsName = get_name_from_urn(requestObject["srsname"], "refsystem", sosConfig)
                    except Exception as e:
                        raise sosException.SOSException("InvalidParameterValue", "srsname", "%s" % e)

                    if not self.srsName in sosConfig.parameters["GO_srs"]:
                        raise sosException.SOSException("InvalidParameterValue", "srsName",
                            "srsName \"%s\" not supported, use one of: %s" %(self.srsName, ",".join(sosConfig.parameters["GO_srs"])))
                else:
                    self.srsName = sosConfig.parameters["GO_srs"][0]

                # TIME FILTER
                if 'eventtime' in requestObject:
                    self.eventTime = []
                    for i in requestObject["eventtime"].replace(" ","+").split(","):
                        if len(i.split("/")) < 3:
                            self.eventTime.append(i.split("/"))

                        else:
                            raise sosException.SOSException("InvalidParameterValue", "eventTime",
                                "Parameter \"eventTime\" bad formatted")

                # FEATURES OF INTEREST FILTER
                if "featureofinterest" in requestObject:
                    foi = requestObject["featureofinterest"]
                    if foi.find("<ogc:") >= 0 and foi.find("<gml:")>=0:
                        self.featureOfInterestSpatial = sosUtils.ogcSpatCons2PostgisSql(foi, 'geom_foi', sosConfig.istsosepsg)

                    else:
                        try:
                            self.featureOfInterest = get_name_from_urn(foi, "feature", sosConfig)

                        except Exception as e:
                            raise sosException.SOSException("InvalidParameterValue", "featureofinterest", str(e))

                # FILTERS FOR QUERY NOT SUPPORTED YET
                if "result" in requestObject:
                    self.result = sosUtils.ogcCompCons2PostgisSql(requestObject["result"])

                # RESULT MODEL
                if "resultmodel" in requestObject:
                    if requestObject["resultmodel"] in sosConfig.parameters["GO_resultModel"]:
                        self.resultModel = requestObject["resultmodel"]

                    else:
                        raise sosException.SOSException("InvalidParameterValue", "resultModel",
                            "Parameter \"resultModel\" sent with invalid value: supported values are: %s" %",".join(sosConfig.parameters["GO_resultModel"]))

                else:
                    self.resultModel = sosConfig.parameters["GO_resultModel"][0]

                # RESPONSE MODE
                if "responsemode" in requestObject:
                    if requestObject["responsemode"] in sosConfig.parameters["GO_responseMode"]:
                        self.responseMode = requestObject["responsemode"]

                    else:
                        raise sosException.SOSException("InvalidParameterValue", "responseMode",
                            "Parameter \"responseMode\" sent with invalid value, supported values are: %s" %(",".join(sosConfig.parameters["GO_responseMode"])))

                else:
                    self.responseMode = sosConfig.parameters["GO_responseMode"][0]

            # Checking if some event limitation is reached
            if self.eventTime != None:
                tp=[]
                for t in self.eventTime:
                    if len(t) == 2:
                        tp.append(iso.parse_datetime(t[0]))
                        tp.append(iso.parse_datetime(t[1]))

                    if len(t)==1:
                        tp.append(iso.parse_datetime(t[0]))

                if int(sosConfig.maxGoPeriod) > 0:
                    maxhours = timedelta(hours=int(sosConfig.maxGoPeriod))
                    userPeriod = max(tp)-min(tp)

                    if maxhours < userPeriod:
                        if self.version == '2.0.0':
                            # REQ39 - http://www.opengis.net/spec/SOS/2.0/req/core/go-too-many-obs-exception
                            #     The service determined that the requested result set exceeds the response
                            #     size limit of the service and thus cannot be delivered.
                            raise sosException.SOSException("ResponseExceedsSizeLimit", "",
                                "You are requesting data for a period of [%s hours], but you are not permitted to ask for a period longer than: %s hours" % (userPeriod, maxhours))

                        else:
                            raise sosException.SOSException("InvalidParameterValue", "eventTime",
                                "You are requesting data for a period of [%s hours], but you are not permitted to ask for a period longer than: %s hours" % (userPeriod, maxhours))

            elif (
                    sosConfig.strictogc in ['True','true',1]
                    and self.version == '2.0.0'
                    and self.eventTime == None
                    and self.featureOfInterest == None
                    and self.featureOfInterestSpatial == None
                    and self.procedure == None
                ):
                # ResponseExceedsSizeLimit fake exception
                raise sosException.SOSException("ResponseExceedsSizeLimit", "",
                    "Sorry but, You are requesting too many data")


            #####################################
            # NON STANDARD PARAMETERS by istSOS #
            #####################################

            # AGGREGATE INTERVAL
            #  In ISO 8601 duration format
            if "aggregateinterval" in requestObject:
                # Check on the eventTime parameter: it must be only one interval: 2010-01-01T00:00:00+00/2011-01-01T00:00:01+00
                exeMsg = "Using aggregate functions, the event time must exist with an interval composed by a begin and an end date (ISO8601)"
                if self.eventTime == None or len(self.eventTime)!=1 or len(self.eventTime[0])!=2:
                    raise sosException.SOSException("InvalidParameterValue", "aggregateInterval", exeMsg)

                self.aggregate_interval = requestObject["aggregateinterval"]
                try:
                    iso.parse_duration(self.aggregate_interval)

                except Exception as ex:
                    raise sosException.SOSException("InvalidParameterValue", "aggregateInterval",
                        "Parameter \"aggregate_interval\" sent with invalid format (check ISO8601 duration spec): %s" % ex)
            else:
                self.aggregate_interval = None

            # AGGREGATE FUNCTION
            #  sum,avg,max,min
            if "aggregatefunction" in requestObject:
                if self.aggregate_interval==None:
                    raise sosException.SOSException("InvalidParameterValue", "aggregateFunction",
                        "Using aggregate functions parameters \"aggregateInterval\" and \"aggregateFunction\" are both mandatory")

                self.aggregate_function = requestObject["aggregatefunction"]
                if not (self.aggregate_function.upper() in ["AVG", "COUNT", "MAX", "MIN", "SUM"]):
                    raise sosException.SOSException("InvalidParameterValue", "aggregateFunction",
                        "Available aggregation functions: avg, count, max, min, sum.")

            else:
                self.aggregate_function = None

            # AGGREGATE NODATA
            if "aggregatenodata" in requestObject:
                if self.aggregate_interval==None or self.aggregate_function==None:
                    raise sosException.SOSException("InvalidParameterValue", "aggregateNodata",
                        "Using aggregateNodata parameter requires both \"aggregateInterval\" and \"aggregateFunction\"")

                self.aggregate_nodata = requestObject["aggregatenodata"]

            else:
                self.aggregate_nodata = sosConfig.aggregate_nodata

            # AGGREGATE NODATA QUALITY INDEX
            if "aggregatenodataqi" in requestObject:
                if self.aggregate_interval==None or self.aggregate_function==None:
                    raise sosException.SOSException("InvalidParameterValue", "aggregateNodataQi",
                        "Using aggregateNodataQi parameter requires both \"aggregateInterval\" and \"aggregateFunction\"")
                self.aggregate_nodata_qi = requestObject["aggregatenodataqi"]

            else:
                self.aggregate_nodata_qi = sosConfig.aggregate_nodata_qi

            # QUALITY INDEX
            self.qualityIndex=False
            if "qualityindex" in requestObject:
                if requestObject["qualityindex"].upper() == "TRUE":
                    self.qualityIndex = True

                elif requestObject["qualityindex"].upper() == "FALSE":
                    self.qualityIndex = False

                else:
                    raise sosException.SOSException("InvalidParameterValue", "qualityIndex",
                        "qualityIndex can only be True or False!")

            # QUALITY INDEX FILTERING
            self.qualityFilter=False
            if "qualityfilter" in requestObject:
                if len(requestObject["qualityfilter"])>=2:
                    try:
                        if requestObject["qualityfilter"][0:2]=='<=' or requestObject["qualityfilter"][0:2]=='>=':
                            self.qualityFilter = (requestObject["qualityfilter"][0:2], float(requestObject["qualityfilter"][2:]))

                        elif (requestObject["qualityfilter"][0]=='>' or
                                requestObject["qualityfilter"][0]=='=' or
                                requestObject["qualityfilter"][0]=='<'):
                            self.qualityFilter = (requestObject["qualityfilter"][0], float(requestObject["qualityfilter"][1:]))

                        # If qualityFilter is defined qualityIndex are automatically returned
                        self.qualityIndex=True

                    except ValueError as ve:
                        raise sosException.SOSException("InvalidParameterValue", "qualityFilter",
                            "invalid quality index value in qualityFilter")

                else:
                    raise sosException.SOSException("InvalidParameterValue", "qualityFilter",
                        "qualityFilter operator can only be in ['<','>','<=','>=','=']")

        if method == "POST":
            from xml.dom import minidom
            # THE OFFERING
            offs = requestObject.getElementsByTagName('offering')
            if len(offs) == 1:
                val = offs[0].firstChild
                if val.nodeType == val.TEXT_NODE:
                    try:
                        self.offering = get_name_from_urn(str(val.data), "offering", sosConfig)

                    except Exception as e:
                        raise sosException.SOSException("InvalidParameterValue", "offering", str(e))

                else:
                    err_txt = "XML parsing error (get value: offering)"
                    raise sosException.SOSException("NoApplicableCode", None, err_txt)

            else:
                err_txt = "Parameter \"offering\" is mandatory with multiplicity 1"
                raise sosException.SOSException("MissingParameterValue", "offering", err_txt)

            # THE OBSERVED PROPERTY
            obsProps = requestObject.getElementsByTagName('observedProperty')
            self.observedProperty = []
            if len(obsProps) > 0:
                for obsProp in obsProps:
                    val = obsProp.firstChild
                    if val.nodeType == val.TEXT_NODE:
                        # get_name_from_urn limit the ability to ask for an observedProperty with LIKE:
                        # eg: ask "water" to get all the water related data, "water:discharge", "water:temperature" ...
                        #self.observedProperty.append(get_name_from_urn(str(val.data),"property"))
                        self.observedProperty.append(str(val.data))

                    else:
                        err_txt = "XML parsing error (get value: observedProperty)"
                        raise sosException.SOSException("NoApplicableCode", None, err_txt)

            else:
                err_txt = "Parameter \"observedProperty\" is mandatory with multiplicity N"
                raise sosException.SOSException("MissingParameterValue", "observedProperty", err_txt)

            # RESPONSE FORMAT
            respF = requestObject.getElementsByTagName('responseFormat')
            if len(respF) == 1:
                val = respF[0].firstChild
                if val.nodeType == val.TEXT_NODE:
                    self.responseFormat = str(val.data)
                    if self.responseFormat not in sosConfig.parameters["GO_responseFormat"]:
                        raise sosException.SOSException("InvalidParameterValue", "responseFormat",
                            "Parameter \"responseFormat\" sent with invalid value: use one of %s" % "; ".join(sosConfig.parameters["GO_responseFormat"]))

                else:
                    err_txt = "XML parsing error (get value: responseFormat)"
                    raise sosException.SOSException("NoApplicableCode", None, err_txt)

            else:
                err_txt = "Parameter \"responseFormat\" is mandatory with multiplicity 1"
                raise sosException.SOSException("MissingParameterValue", "responseFormat", err_txt)

            # OPTIONAL request parameters
            #  SRS OF RETURNED GML FEATURES
            srs = requestObject.getAttributeNode('srsName')
            if srs:
                self.srsName = srs.nodeValue
                if not self.srsName in sosConfig.parameters["GO_srs"]:
                    raise sosException.SOSException("InvalidParameterValue", "srsName",
                        "srsName \"%s\" not supported, use one of: %s" %(self.srsName, ",".join(sosConfig.parameters["GO_srs"])))

            else:
                self.srsName = sosConfig.parameters["GO_srs"][0]

            # TIME FILTER
            evtms = requestObject.getElementsByTagName('eventTime')
            self.eventTime = []
            if len(evtms) > 0:
                for evtm in evtms:
                    tps = evtm.getElementsByTagName('gml:TimePeriod')
                    for tp in tps:
                        begin = tp.getElementsByTagName('gml:beginPosition')
                        end = tp.getElementsByTagName('gml:endPosition')
                        if len(begin)==1 and len(end)==1:
                            Bval = begin[0].firstChild
                            Eval = end[0].firstChild
                            if Bval.nodeType == Bval.TEXT_NODE and Eval.nodeType == Eval.TEXT_NODE:
                                self.eventTime.append([str(Bval.data).replace(" ","+"), str(Eval.data).replace(" ","+")])

                            else:
                                err_txt = "XML parsing error (get value: TimePeriod)"
                                raise sosException.SOSException("NoApplicableCode",None,err_txt)

                    tis = evtm.getElementsByTagName('gml:TimeInstant')
                    for ti in tis:
                        instant = ti.getElementsByTagName('gml:timePosition')
                        if len(instant)>0 and len(instant)<2:
                            Ival = instant[0].firstChild
                            if Ival.nodeType == Ival.TEXT_NODE:
                                self.eventTime.append([str(Ival.data).replace(" ","+")])
                            else:
                                err_txt = "XML parsing error (get value: Timeinstant)"
                                raise sosException.SOSException("NoApplicableCode", None, err_txt)
            else:
                self.eventTime = None

            # PROCEDURES FILTER
            procs = requestObject.getElementsByTagName('procedure')
            if len(procs) > 0:
                self.procedure=[]
                for proc in procs:
                    if "xlink:href" in list(proc.attributes.keys()):
                        self.procedure.append(str(proc.getAttribute("xlink:href")))

                    elif proc.hasChildNodes():
                        val = proc.firstChild
                        if val.nodeType == val.TEXT_NODE:
                            try:
                                self.procedure.append(get_name_from_urn(str(val.data), "procedure", sosConfig))

                            except Exception as e:
                                raise sosException.SOSException("InvalidParameterValue", "procedure", str(e))
                    else:
                        err_txt = "XML parsing error (get value: procedure)"
                        raise sosException.SOSException("NoApplicableCode", None, err_txt)

            else:
                self.procedure = None

            # FEATURES OF INTEREST FILTER
            fets = requestObject.getElementsByTagName('featureOfInterest')
            self.featureOfInterest = None
            self.featureOfInterestSpatial = None

            # get sub-elements of FOI
            if fets:
                elements = [e for e in fets[0].childNodes if e.nodeType == e.ELEMENT_NODE]
                if len(elements)==0:
                    err_txt = "ObjectID or ogc:spatialOps elements in parameter \"featureOfInterest\" are mandatory"
                    raise sosException.SOSException("NoApplicableCode",None,err_txt)

                # only one sub element
                elif len(elements)==1 and elements[0].tagName!="ObjectID" :
                    self.featureOfInterestSpatial = sosUtils.ogcSpatCons2PostgisSql(elements[0], 'geom_foi', sosConfig.istsosepsg)

                else:
                    tempfois=[]
                    for e in elements:
                        if not e.tagName=="ObjectID":
                            err_txt = "Allowed only ObjectID or ogc:spatialOps elements in parameter \"featureOfInterest\""
                            raise sosException.SOSException("NoApplicableCode", None, err_txt)

                        try:
                            val = e.firstChild
                            if val.nodeType == val.TEXT_NODE:
                                try:
                                    tempfois.append( get_name_from_urn(str(val.data), "feature", sosConfig))

                                except Exception as e:
                                     raise sosException.SOSException("InvalidParameterValue", "featureOfInterest", str(e))

                        except Exception as e:
                            raise e

                    self.featureOfInterest = ",".join(tempfois)

            # FILTERS FOR QUERY NOT SUPPORTED YET
            ress = requestObject.getElementsByTagName('result')
            if len(ress)>0:
                raise sosException.SOSException("NoApplicableCode", None, "Parameter \"result\" not yet supported")
            else:
                self.result = None #zero-one optional

            # RESULT MODEL
            mods = requestObject.getElementsByTagName('resultModel')
            if len(mods)>0:
                if len(mods)<2:
                    val = mods[0].firstChild
                    if val.nodeType == val.TEXT_NODE:
                        self.resultModel = str(val.data)
                        if self.resultModel not in sosConfig.parameters["GO_resultModel"]:
                            raise sosException.SOSException("InvalidParameterValue", "resultModel",
                                "Parameter \"resultModel\" sent with invalid value")

                    else:
                        err_txt = "XML parsing error (get value: resultModel)"
                        raise sosException.SOSException("NoApplicableCode", None, err_txt)

                else:
                    err_txt = "Allowed only ONE parameter \"resultModel\""
                    raise sosException.SOSException("NoApplicableCode", None, err_txt)

            else:
                self.resultModel = None

            # RESPONSE MODE
            rsmods = requestObject.getElementsByTagName('responseMode')
            if len(rsmods)>0:
                if len(rsmods)<2:
                    val = rsmods[0].firstChild
                    if val.nodeType == val.TEXT_NODE:
                        self.responseMode = str(val.data)
                        if self.responseMode not in sosConfig.parameters["GO_responseMode"]:
                            raise sosException.SOSException("InvalidParameterValue", "responseMode",
                                "Parameter \"responseMode\" sent with invalid value")

                    else:
                        err_txt = "XML parsing error (get value: responseMode)"
                        raise sosException.SOSException("NoApplicableCode", None, err_txt)

                else:
                    err_txt = "Allowed only ONE parameter \"responseMode\""
                    raise sosException.SOSException("NoApplicableCode", None, err_txt)

            else:
                self.responseMode = sosConfig.parameters["GO_responseMode"][0]

            # AGGREGATE INTERVAL & FUNCTION
            self.aggregate_interval = None
            self.aggregate_function = None
            self.aggregate_nodata = None
            self.aggregate_nodata_qi = None

            aggint = requestObject.getElementsByTagName('aggregateInterval')
            aggfun = requestObject.getElementsByTagName('aggregateFunction')
            aggnodata = requestObject.getElementsByTagName('aggregateNodata')

            if len(aggint)==1 and len(aggfun)==1:
                # aggregate_interval
                #  Check on the eventTime parameter: it must be only one interval: 2010-01-01T00:00:00+00/2011-01-01T00:00:01+00
                exeMsg = "Using aggregate functions, the event time must exist with an interval composed by a begin and an end date (ISO8601)"
                if self.eventTime == None or len(self.eventTime)!=1 or len(self.eventTime[0])!=2:
                    raise sosException.SOSException("NoApplicableCode", None, exeMsg)

                val = aggint[0].firstChild
                if val.nodeType == val.TEXT_NODE:
                    self.aggregate_interval = str(val.data)
                    try:
                        iso.parse_duration(self.aggregate_interval)

                    except Exception as ex:
                        raise sosException.SOSException("InvalidParameterValue", "aggregateInterval",
                            "Parameter \"aggregate_interval\" sent with invalid format (check ISO8601 duration spec): %s" % ex)

                else:
                    err_txt = "cannot get ISO8601 duration value in \"aggregateInterval\""
                    raise sosException.SOSException("InvalidParameterValue", "aggregateInterval", err_txt)

                # aggregate_function
                val = aggfun[0].firstChild
                if val.nodeType == val.TEXT_NODE:
                    self.aggregate_function = str(val.data)
                    if not (self.aggregate_function.upper() in ["AVG", "COUNT", "MAX", "MIN", "SUM"]):
                        raise sosException.SOSException("InvalidParameterValue", "aggregateFunction",
                            "Available aggregation functions: avg, count, max, min, sum.")

                # aggregate_no_data default value
                if len(aggnodata)==1:
                    val = aggnodata[0].firstChild
                    self.aggregate_nodata = str(val.data)

                else:
                    self.aggregate_nodata = sosConfig.aggregate_nodata

           #================================
           # MISSING AGGREGATE QUALITY INDEX
           #================================

            elif len(aggint)==0 and len(aggfun)==0:
                pass
            else:
                err_txt = "\"aggregateInterval\" and \"aggregate_function\" are both required with multiplicity 1"
                raise sosException.SOSException("NoApplicableCode", None, err_txt)

            # QUALITY INDEX
            self.qualityIndex=False
            qidx = requestObject.getElementsByTagName('qualityIndex')

            if len(qidx)>0:
                if len(qidx)<2:
                    val = qidx[0].firstChild
                    if val.nodeType == val.TEXT_NODE:
                        self.qualityIndex = str(val.data)
                        if self.qualityIndex.upper() == "TRUE":
                            self.qualityIndex=True

                        elif self.qualityIndex.upper() == "FALSE":
                            pass

                        else:
                            raise sosException.SOSException("InvalidParameterValue", "qualityIndex",
                                "qualityIndex can only be \'True\' or \'False\'")

            elif len(qidx)==0:
                pass

            else:
                err_txt = "\"qualityIndex\" is allowed with multiplicity 1 only"
                raise sosException.SOSException("NoApplicableCode", None, err_txt)

            self.qualityFilter=False
Example #3
0
    def __init__(self,sosRequest,method,requestObject,sosConfig):
        f.sosFilter.__init__(self,sosRequest,method,requestObject,sosConfig)
        # @TODO Declare attribute first!
        # self.offering = None
        # etc..

        #**************************
        if method == "GET":
            #---------- THE OFFERING
            if requestObject.has_key("offering"):
                self.offering = get_name_from_urn(requestObject["offering"],"offering",sosConfig)
            else:
                raise sosException.SOSException(1,"Parameter \"offering\" is mandatory with multiplicity 1")
                
            #---------- THE OBSERVED PROPERTY
            if requestObject.has_key("observedProperty"):
                self.observedProperty = []
                oprs = requestObject["observedProperty"].split(",")
                for opr in oprs:
                    # get_name_from_urn limit the ability to ask for an observedProperty with LIKE:
                    # eg: ask "water" to get all the water related data, "water:discharge", "water:temperature" ...
                    #oprName = get_name_from_urn(opr,"property")
                    oprName = opr
                    self.observedProperty.append(oprName) # one-many ID 
            else:
                raise sosException.SOSException(1,"Parameter \"observedProperty\" is mandatory with multiplicity N")
                
            #---------- RESPONSE FORMAT
            if requestObject.has_key("responseFormat"):
                if not requestObject["responseFormat"] in sosConfig.parameters["GO_responseFormat"]:   
                    raise sosException.SOSException(2,"Parameter \"responseFormat\" sent with invalid value : use one of %s" % "; ".join(sosConfig.parameters["GO_responseFormat"]))
                else:
                    self.responseFormat = requestObject["responseFormat"]
            else:
                raise sosException.SOSException(1,"Parameter \"responseFormat\" is mandatory with multiplicity 1") #one
                
            #OPTIONAL request parameters
            #---------- SRS FILTER                
            if requestObject.has_key("srsName"):
                self.srsName = get_name_from_urn(requestObject["srsName"],"refsystem",sosConfig)         
                if not self.srsName in sosConfig.parameters["GO_srs"]:
                    raise sosException.SOSException(2,"srsName \"%s\" not supported, use one of: %s" %(self.srsName,",".join(sosConfig.parameters["GO_srs"])))
            else:
                self.srsName = sosConfig.parameters["GO_srs"][0]

            #---------- TIME FILTER                
            if requestObject.has_key('eventTime'):
                self.eventTime = []
                for i in requestObject["eventTime"].replace(" ","+").split(","):
                    if len(i.split("/")) < 3:
                        self.eventTime.append(i.split("/"))
                    else:
                        raise sosException.SOSException(2,"Parameter \"eventTime\" bad formatted")
                
                tp=[]
                for t in self.eventTime:
                    if len(t) == 2:
                        tp.append(iso.parse_datetime(t[0]))
                        tp.append(iso.parse_datetime(t[1]))
                    if len(t)==1:
                        tp.append(iso.parse_datetime(t[0]))
                
                # Checking if some event limitation is reached
                #if sosConfig["maxGoPeriod"]:
                if int(sosConfig.maxGoPeriod) > 0:
                    from datetime import timedelta
                    d = timedelta(hours=int(sosConfig.maxGoPeriod))
                    userPeriod = max(tp)-min(tp)
                    if d < userPeriod:
                        raise sosException.SOSException(2,"You are requesting data for a period of [%s hours], but you are not permitted to ask for a period longer than: %s hours" % (userPeriod,d))
                
            else:
                self.eventTime = None
            
            #---------- PROCEDURES FILTER
            if requestObject.has_key("procedure"):
                self.procedure = []
                prcs = requestObject["procedure"].split(",")
                for prc in prcs:
                    prcName = get_name_from_urn(prc,"procedure",sosConfig)
                    self.procedure.append(prcName)
            else:
                self.procedure = None
            
            #---------- FEATURES OF INTEREST FILTER
            self.featureOfInterest = None
            self.featureOfInterestSpatial = None
            if requestObject.has_key("featureOfInterest"):
                foi = requestObject["featureOfInterest"]
                if foi.find("<ogc:")>=0 and foi.find("<gml:")>=0:
                    #raise sosException.SOSException(3,"FOI SPATIAL: %s" %(foi))
                    self.featureOfInterestSpatial = sosUtils.ogcSpatCons2PostgisSql(foi,'geom_foi',sosConfig.istsosepsg)
                else:
                    self.featureOfInterest = get_name_from_urn(foi,"feature",sosConfig)
                    
                #fois = requestObject["featureOfInterest"].split(",")
                #for foi in fois:
                #    foiName = get_name_from_urn(foi,"feature")
                #    self.featureOfInterest.append(foiName)
            
            #---------- FILTERS FOR QUERY NOT SUPPORTED YET            
            if requestObject.has_key("result"):
                #raise sosException.SOSException(3,"Parameter \"result\" not yet supported")
                self.result = sosUtils.ogcCompCons2PostgisSql(requestObject["result"])
            else:
                self.result = None #zero-one optional
            
            #---------- RESULT MODEL
            if requestObject.has_key("resultModel"):
                if requestObject["resultModel"] in sosConfig.parameters["GO_resultModel"]:
                    self.resultModel = requestObject["resultModel"]                    
                else:
                    raise sosException.SOSException(2,"Parameter \"resultModel\" sent with invalid value: supported values are: %s" %",".join(sosConfig.parameters["GO_resultModel"]))                    
            else:
                self.resultModel = sosConfig.parameters["GO_resultModel"][0]
            
            #---------- RESPONSE MODE
            if requestObject.has_key("responseMode"):
                if requestObject["responseMode"] in sosConfig.parameters["GO_responseMode"]:
                    self.responseMode = requestObject["responseMode"]
                else:
                    raise sosException.SOSException(2,"Parameter \"responseMode\" sent with invalid value, supported values are: %s" %(",".join(sosConfig.parameters["GO_responseMode"])))
                    
            else:
                self.responseMode = sosConfig.parameters["GO_responseMode"][0]

            ###########################
            # NON STANDARD PARAMETERS #
            ###########################
            #---------- AGGREGATE INTERVAL
            # In ISO 8601 duration format
            if requestObject.has_key("aggregateInterval"):
                # Check on the eventTime parameter: it must be only one interval: 2010-01-01T00:00:00+00/2011-01-01T00:00:01+00
                exeMsg = "Using aggregate functions, the event time must exist with an interval composed by a begin and an end date (ISO8601)"
                if self.eventTime == None or len(self.eventTime)!=1 or len(self.eventTime[0])!=2:
                    raise sosException.SOSException(2,exeMsg)
                self.aggregate_interval = requestObject["aggregateInterval"]
                try:
                    iso.parse_duration(self.aggregate_interval)
                except Exception as ex:
                    raise sosException.SOSException(2,"Parameter \"aggregate_interval\" sent with invalid format (check ISO8601 duration spec): %s" % ex)
            else:
                self.aggregate_interval = None

            #---------- AGGREGATE FUNCTION
            # sum,avg,max,min
            if requestObject.has_key("aggregateFunction"):
                if self.aggregate_interval==None:
                    raise sosException.SOSException(2,"Using aggregate functions parameters \"aggregateInterval\" and \"aggregateFunction\" are both mandatory")
                self.aggregate_function = requestObject["aggregateFunction"]
                if not (self.aggregate_function.upper() in ["AVG","COUNT","MAX","MIN","SUM"]):
                    raise sosException.SOSException(2,"Available aggregation functions: avg, count, max, min, sum.")
            else:
                self.aggregate_function = None
                
            #---------- AGGREGATE NODATA
            if requestObject.has_key("aggregateNodata"):
                if self.aggregate_interval==None or self.aggregate_function==None:
                    raise sosException.SOSException(2,"Using aggregateNodata parameter requires both \"aggregateInterval\" and \"aggregateFunction\"")
                self.aggregate_nodata = requestObject["aggregateNodata"]
            else:
                self.aggregate_nodata = sosConfig.aggregate_nodata
                
            #---------- AGGREGATE NODATA QUALITY INDEX
            if requestObject.has_key("aggregateNodataQi"):
                if self.aggregate_interval==None or self.aggregate_function==None:
                    raise sosException.SOSException(2,"Using aggregateNodataQi parameter requires both \"aggregateInterval\" and \"aggregateFunction\"")
                self.aggregate_nodata_qi = requestObject["aggregateNodataQi"]
            else:
                self.aggregate_nodata_qi = sosConfig.aggregate_nodata_qi
                
            #------------ QUALITY INDEX
            self.qualityIndex=False
            if requestObject.has_key("qualityIndex"):
                if requestObject["qualityIndex"].upper() == "TRUE":
                    self.qualityIndex = True
                elif requestObject["qualityIndex"].upper() == "FALSE":
                    self.qualityIndex = False
                else:
                    raise sosException.SOSException(2,"qualityIndex can only be True or False!")
                #    self.qualityIndex = sosUtils.CQLvalueFilter2PostgisSql("id_qi_fk",requestObject["qualityIndex"])

                
                
        #**********************
        if method == "POST":
            from xml.dom import minidom
            #---------- THE OFFERING
            offs = requestObject.getElementsByTagName('offering')
            if len(offs) == 1:
                val = offs[0].firstChild
                if val.nodeType == val.TEXT_NODE:
                    self.offering = get_name_from_urn(str(val.data),"offering",sosConfig)
                else:
                    err_txt = "XML parsing error (get value: offering)"
                    raise sosException.SOSException(1,err_txt)
            else:
                err_txt = "Parameter \"offering\" is mandatory with multiplicity 1"
                raise sosException.SOSException(1,err_txt)
            
            
            #---------- THE OBSERVED PROPERTY
            obsProps = requestObject.getElementsByTagName('observedProperty')
            self.observedProperty = []
            if len(obsProps) > 0:
                for obsProp in obsProps:
                    val = obsProp.firstChild
                    if val.nodeType == val.TEXT_NODE:                    
                        # get_name_from_urn limit the ability to ask for an observedProperty with LIKE:
                        # eg: ask "water" to get all the water related data, "water:discharge", "water:temperature" ...
                        #self.observedProperty.append(get_name_from_urn(str(val.data),"property"))
                        self.observedProperty.append(str(val.data))
                    else:
                        err_txt = "XML parsing error (get value: observedProperty)"
                        raise sosException.SOSException(1,err_txt)
            else:
                err_txt = "Parameter \"observedProperty\" is mandatory with multiplicity N"
                raise sosException.SOSException(1,err_txt)
            
            #---------- RESPONSE FORMAT
            respF = requestObject.getElementsByTagName('responseFormat')
            if len(respF) == 1:
                val = respF[0].firstChild
                if val.nodeType == val.TEXT_NODE:
                    self.responseFormat = str(val.data)
                    if self.responseFormat not in sosConfig.parameters["GO_responseFormat"]:   
                        raise sosException.SOSException(2,"Parameter \"responseFormat\" sent with invalid value: use one of %s" % "; ".join(sosConfig.parameters["GO_responseFormat"]))
                else:
                    err_txt = "XML parsing error (get value: responseFormat)"
                    raise sosException.SOSException(1,err_txt)
            else:
                err_txt = "Parameter \"responseFormat\" is mandatory with multiplicity 1"
                raise sosException.SOSException(1,err_txt)
            
            #OPTIONAL request parameters
            #---------- SRS OF RETURNED GML FEATURES
            srss = requestObject.getElementsByTagName('srsName')
            if len(srss) > 0:
                if len(srss) < 2:
                    val = srss[0].firstChild
                    if val.nodeType == val.TEXT_NODE:
                        self.srsName = get_name_from_urn(str(val.data),"refsystem",sosConfig)
                    else:
                        err_txt = "XML parsing error (get value: srsName)"
                        raise sosException.SOSException(1,err_txt)
                else:
                    err_txt = "Allowed only ONE parameter \"srsName\""
                    raise sosException.SOSException(1,err_txt)
            else:
                self.srsName = sosConfig.parameters["GO_srs"][0]
            
            #---------- TIME FILTER  
            evtms = requestObject.getElementsByTagName('eventTime')
            self.eventTime = []
            if len(evtms) > 0:
                for evtm in evtms:
                    tps = evtm.getElementsByTagName('gml:TimePeriod')
                    for tp in tps:
                        begin = tp.getElementsByTagName('gml:beginPosition')
                        end = tp.getElementsByTagName('gml:endPosition')
                        if len(begin)==1 and len(end)==1:
                            Bval = begin[0].firstChild
                            Eval = end[0].firstChild
                            #raise sosException.SOSException(1,end[0].toprettyxml())
                            if Bval.nodeType == Bval.TEXT_NODE and Eval.nodeType == Eval.TEXT_NODE:
                                self.eventTime.append([str(Bval.data).replace(" ","+"),str(Eval.data).replace(" ","+")])
                                #raise sosException.SOSException(1,str(self.eventTime))
                            else:
                                err_txt = "XML parsing error (get value: TimePeriod)"
                                raise sosException.SOSException(1,err_txt)
                            
                    tis = evtm.getElementsByTagName('gml:TimeInstant')
                    for ti in tis:
                        instant = ti.getElementsByTagName('gml:timePosition')
                        if len(instant)>0 and len(instant)<2:
                            Ival = instant[0].firstChild
                            if Ival.nodeType == Ival.TEXT_NODE:
                                self.eventTime.append([str(Ival.data).replace(" ","+")])
                            else:
                                err_txt = "XML parsing error (get value: Timeinstant)"
                                raise sosException.SOSException(1,err_txt)
            else:
                self.eventTime = None
                
            #---------- PROCEDURES FILTER
            procs = requestObject.getElementsByTagName('procedure')
            if len(procs) > 0:
                self.procedure=[]
                for proc in procs:
                    if "xlink:href" in proc.attributes.keys():
                        self.procedure.append(str(proc.getAttribute("xlink:href")))
                    elif proc.hasChildNodes():
                        val = proc.firstChild
                        if val.nodeType == val.TEXT_NODE:
                            self.procedure.append(get_name_from_urn(str(val.data),"procedure",sosConfig))
                    else:
                        err_txt = "XML parsing error (get value: procedure)"
                        raise sosException.SOSException(1,err_txt)
            else:
                self.procedure = None
            
            #---------- FEATURES OF INTEREST FILTER
            fets = requestObject.getElementsByTagName('featureOfInterest')
            self.featureOfInterest = None
            self.featureOfInterestSpatial = None
            if len(fets)>0:
                if len(fets)<2:
                    elements = [e for e in fets[0].childNodes if e.nodeType == e.ELEMENT_NODE]
                    if len(elements)==1:
                        self.featureOfInterestSpatial = sosUtils.ogcSpatCons2PostgisSql(elements[0],'geom_foi',sosConfig.istsosepsg)
                    else:
                        if "xlink:href" in fets[0].attributes.keys():
                            self.featureOfInterest = str(fets[0].getAttribute("xlink:href"))
                        elif fets[0].hasChildNodes():
                            val = fets[0].firstChild
                            if val.nodeType == val.TEXT_NODE:
                                self.featureOfInterest = get_name_from_urn(str(val.data),"feature",sosConfig)
                        else:
                            err_txt = "XML parsing error (get value: featureOfInterest)"
                            raise sosException.SOSException(1,err_txt)
                else:
                    err_txt = "Allowed only ONE parameter \"featureOfInterest\""
                    raise sosException.SOSException(1,err_txt)
            
            #---------- FILTERS FOR QUERY NOT SUPPORTED YET            
            ress = requestObject.getElementsByTagName('result')
            if len(ress)>0:
                raise sosException.SOSException(3,"Parameter \"result\" not yet supported")
            else:
                self.result = None #zero-one optional
            
            #---------- RESULT MODEL
            mods = requestObject.getElementsByTagName('resultModel')
            if len(mods)>0:
                if len(mods)<2:
                    val = mods[0].firstChild
                    if val.nodeType == val.TEXT_NODE:
                        self.resultModel = str(val.data)
                        if self.resultModel not in sosConfig.parameters["GO_resultModel"]:
                            raise sosException.SOSException(2,"Parameter \"resultModel\" sent with invalid value")
                    else:
                        err_txt = "XML parsing error (get value: resultModel)"
                        raise sosException.SOSException(1,err_txt)
                else:
                    err_txt = "Allowed only ONE parameter \"resultModel\""
                    raise sosException.SOSException(1,err_txt)
            else:
                self.resultModel = None
            
            #---------- RESPONSE MODE
            rsmods = requestObject.getElementsByTagName('responseMode')
            if len(rsmods)>0:
                if len(rsmods)<2:
                    val = rsmods[0].firstChild
                    if val.nodeType == val.TEXT_NODE:
                        self.responseMode = str(val.data)
                        if self.responseMode not in sosConfig.parameters["GO_responseMode"]:
                            raise sosException.SOSException(2,"Parameter \"responseMode\" sent with invalid value")
                    else:
                        err_txt = "XML parsing error (get value: responseMode)"
                        raise sosException.SOSException(1,err_txt)
                else:
                    err_txt = "Allowed only ONE parameter \"responseMode\""
                    raise sosException.SOSException(1,err_txt)
            else:
                self.responseMode = sosConfig.parameters["GO_responseMode"][0]
        

            #-------------- AGGREGATE INTERVAL & FUNCTION
            self.aggregate_interval = None
            self.aggregate_function = None
            aggint = requestObject.getElementsByTagName('aggregateInterval')
            aggfun = requestObject.getElementsByTagName('aggregateFunction')
            aggnodata = requestObject.getElementsByTagName('aggregateNodata')
            
            if len(aggint)==1 and len(aggfun)==1:
                #-----------------------
                # -- aggregate_interval
                #-----------------------
                # Check on the eventTime parameter: it must be only one interval: 2010-01-01T00:00:00+00/2011-01-01T00:00:01+00
                exeMsg = "Using aggregate functions, the event time must exist with an interval composed by a begin and an end date (ISO8601)"
                if self.eventTime == None or len(self.eventTime)!=1 or len(self.eventTime[0])!=2:
                    raise sosException.SOSException(2,exeMsg)
                val = aggint[0].firstChild
                if val.nodeType == val.TEXT_NODE:
                    self.aggregate_interval = str(val.data)
                    try:
                        iso.parse_duration(self.aggregate_interval)
                    except Exception as ex:
                        raise sosException.SOSException(2,"Parameter \"aggregate_interval\" sent with invalid format (check ISO8601 duration spec): %s" % ex)
                else:
                    err_txt = "cannot get ISO8601 duration value in \"aggregateInterval\""
                    raise sosException.SOSException(1,err_txt)
                #-----------------------
                # -- aggregate_function
                #-----------------------
                val = aggfun[0].firstChild
                if val.nodeType == val.TEXT_NODE:
                    self.aggregate_function = str(val.data)
                    if not (self.aggregate_function.upper() in ["AVG","COUNT","MAX","MIN","SUM"]):
                        raise sosException.SOSException(2,"Available aggregation functions: avg, count, max, min, sum.")
                
                
                #-----------------------------------
                # -- aggregate_no_data default value
                #-----------------------------------
                if len(aggnodata)==1:
                    val = aggnodata[0].firstChild
                    self.aggregate_nodata = str(val.data)
                else:
                    self.aggregate_nodata = sosConfig.aggregate_nodata

           #================================
           #MISSING AGGREGATE QUALITY INDEX
           #================================         
                    
            elif len(aggint)==0 and len(aggfun)==0:
                pass
            else:
                err_txt = "\"aggregateInterval\" and \"aggregate_function\" are both required with multiplicity 1"
                raise sosException.SOSException(1,err_txt)

            #------------ QUALITY INDEX
            self.qualityIndex=False
            qidx = requestObject.getElementsByTagName('qualityIndex')
            if len(qidx)>0:
                if len(qidx)<2:
                    val = qidx[0].firstChild
                    if val.nodeType == val.TEXT_NODE:
                        self.qualityIndex = str(val.data)
                        if self.qualityIndex.upper() == "TRUE":
                            self.qualityIndex=True
                        elif self.qualityIndex.upper() == "FALSE":
                            pass
                        else:
                            raise sosException.SOSException(2,"qualityIndex can only be \'True\' or \'False\'")
            elif len(qidx)==0:
                pass
            else:
                err_txt = "\"qualityIndex\" is allowed with multiplicity 1 only"
                raise sosException.SOSException(1,err_txt)